libctf: add the ctf_link machinery
[deliverable/binutils-gdb.git] / libctf / ctf-open.c
index 2979ef8d287b747e58bf5841c96cb3f748aa30d5..3bc102a37d185fa4625d146afa61d0d0d4aa2d48 100644 (file)
@@ -278,7 +278,7 @@ init_symtab (ctf_file_t *fp, const ctf_header_t *hp,
          break;
 
        case STT_FUNC:
-         if (funcoff >= hp->cth_typeoff)
+         if (funcoff >= hp->cth_objtidxoff)
            {
              *xp = -1u;
              break;
@@ -376,6 +376,8 @@ upgrade_header (ctf_header_t *hp)
   hp->cth_stroff = oldhp->cth_stroff;
   hp->cth_typeoff = oldhp->cth_typeoff;
   hp->cth_varoff = oldhp->cth_varoff;
+  hp->cth_funcidxoff = hp->cth_varoff;         /* No index sections.  */
+  hp->cth_objtidxoff = hp->cth_funcidxoff;
   hp->cth_funcoff = oldhp->cth_funcoff;
   hp->cth_objtoff = oldhp->cth_objtoff;
   hp->cth_lbloff = oldhp->cth_lbloff;
@@ -388,6 +390,9 @@ upgrade_header (ctf_header_t *hp)
    The upgrade is not done in-place: the ctf_base is moved.  ctf_strptr() must
    not be called before reallocation is complete.
 
+   Sections not checked here due to nonexistence or nonpopulated state in older
+   formats: objtidx, funcidx.
+
    Type kinds not checked here due to nonexistence in older formats:
       CTF_K_SLICE.  */
 static int
@@ -780,7 +785,7 @@ init_types (ctf_file_t *fp, ctf_header_t *cth)
              err = ctf_hash_define_type (fp->ctf_names, fp,
                                          LCTF_INDEX_TO_TYPE (fp, id, child),
                                          tp->ctt_name);
-             if (err != 0 && err != ECTF_STRTAB)
+             if (err != 0)
                return err;
            }
          break;
@@ -795,7 +800,7 @@ init_types (ctf_file_t *fp, ctf_header_t *cth)
          err = ctf_hash_insert_type (fp->ctf_names, fp,
                                      LCTF_INDEX_TO_TYPE (fp, id, child),
                                      tp->ctt_name);
-         if (err != 0 && err != ECTF_STRTAB)
+         if (err != 0)
            return err;
          break;
 
@@ -804,7 +809,7 @@ init_types (ctf_file_t *fp, ctf_header_t *cth)
                                      LCTF_INDEX_TO_TYPE (fp, id, child),
                                      tp->ctt_name);
 
-         if (err != 0 && err != ECTF_STRTAB)
+         if (err != 0)
            return err;
 
          if (size >= CTF_LSTRUCT_THRESH)
@@ -816,7 +821,7 @@ init_types (ctf_file_t *fp, ctf_header_t *cth)
                                      LCTF_INDEX_TO_TYPE (fp, id, child),
                                      tp->ctt_name);
 
-         if (err != 0 && err != ECTF_STRTAB)
+         if (err != 0)
            return err;
 
          if (size >= CTF_LSTRUCT_THRESH)
@@ -828,7 +833,7 @@ init_types (ctf_file_t *fp, ctf_header_t *cth)
                                      LCTF_INDEX_TO_TYPE (fp, id, child),
                                      tp->ctt_name);
 
-         if (err != 0 && err != ECTF_STRTAB)
+         if (err != 0)
            return err;
          break;
 
@@ -836,7 +841,7 @@ init_types (ctf_file_t *fp, ctf_header_t *cth)
          err = ctf_hash_insert_type (fp->ctf_names, fp,
                                      LCTF_INDEX_TO_TYPE (fp, id, child),
                                      tp->ctt_name);
-         if (err != 0 && err != ECTF_STRTAB)
+         if (err != 0)
            return err;
          break;
 
@@ -863,7 +868,7 @@ init_types (ctf_file_t *fp, ctf_header_t *cth)
              err = ctf_hash_insert_type (hp, fp,
                                          LCTF_INDEX_TO_TYPE (fp, id, child),
                                          tp->ctt_name);
-             if (err != 0 && err != ECTF_STRTAB)
+             if (err != 0)
                return err;
            }
          break;
@@ -884,7 +889,7 @@ init_types (ctf_file_t *fp, ctf_header_t *cth)
          err = ctf_hash_insert_type (fp->ctf_names, fp,
                                      LCTF_INDEX_TO_TYPE (fp, id, child),
                                      tp->ctt_name);
-         if (err != 0 && err != ECTF_STRTAB)
+         if (err != 0)
            return err;
          break;
        default:
@@ -967,6 +972,8 @@ flip_header (ctf_header_t *cth)
   swap_thing (cth->cth_cuname);
   swap_thing (cth->cth_objtoff);
   swap_thing (cth->cth_funcoff);
+  swap_thing (cth->cth_objtidxoff);
+  swap_thing (cth->cth_funcidxoff);
   swap_thing (cth->cth_varoff);
   swap_thing (cth->cth_typeoff);
   swap_thing (cth->cth_stroff);
@@ -987,10 +994,10 @@ flip_lbls (void *start, size_t len)
     }
 }
 
-/* Flip the endianness of the data-object or function sections, an array of
-   uint32_t.  (The function section has more internal structure, but that
-   structure is an array of uint32_t, so can be treated as one big array for
-   byte-swapping.)  */
+/* Flip the endianness of the data-object or function sections or their indexes,
+   all arrays of uint32_t.  (The function section has more internal structure,
+   but that structure is an array of uint32_t, so can be treated as one big
+   array for byte-swapping.)  */
 
 static void
 flip_objts (void *start, size_t len)
@@ -1176,17 +1183,34 @@ flip_ctf (ctf_header_t *cth, unsigned char *buf)
 {
   flip_lbls (buf + cth->cth_lbloff, cth->cth_objtoff - cth->cth_lbloff);
   flip_objts (buf + cth->cth_objtoff, cth->cth_funcoff - cth->cth_objtoff);
-  flip_objts (buf + cth->cth_funcoff, cth->cth_varoff - cth->cth_funcoff);
+  flip_objts (buf + cth->cth_funcoff, cth->cth_objtidxoff - cth->cth_funcoff);
+  flip_objts (buf + cth->cth_objtidxoff, cth->cth_funcidxoff - cth->cth_objtidxoff);
+  flip_objts (buf + cth->cth_funcidxoff, cth->cth_varoff - cth->cth_funcidxoff);
   flip_vars (buf + cth->cth_varoff, cth->cth_typeoff - cth->cth_varoff);
   return flip_types (buf + cth->cth_typeoff, cth->cth_stroff - cth->cth_typeoff);
 }
 
 /* Open a CTF file, mocking up a suitable ctf_sect.  */
+
 ctf_file_t *ctf_simple_open (const char *ctfsect, size_t ctfsect_size,
                             const char *symsect, size_t symsect_size,
                             size_t symsect_entsize,
                             const char *strsect, size_t strsect_size,
                             int *errp)
+{
+  return ctf_simple_open_internal (ctfsect, ctfsect_size, symsect, symsect_size,
+                                  symsect_entsize, strsect, strsect_size, NULL,
+                                  errp);
+}
+
+/* Open a CTF file, mocking up a suitable ctf_sect and overriding the external
+   strtab with a synthetic one.  */
+
+ctf_file_t *ctf_simple_open_internal (const char *ctfsect, size_t ctfsect_size,
+                                     const char *symsect, size_t symsect_size,
+                                     size_t symsect_entsize,
+                                     const char *strsect, size_t strsect_size,
+                                     ctf_dynhash_t *syn_strtab, int *errp)
 {
   ctf_sect_t skeleton;
 
@@ -1223,7 +1247,7 @@ ctf_file_t *ctf_simple_open (const char *ctfsect, size_t ctfsect_size,
       strsectp = &str_sect;
     }
 
-  return ctf_bufopen (ctfsectp, symsectp, strsectp, errp);
+  return ctf_bufopen_internal (ctfsectp, symsectp, strsectp, syn_strtab, errp);
 }
 
 /* Decode the specified CTF buffer and optional symbol table, and create a new
@@ -1234,6 +1258,16 @@ ctf_file_t *ctf_simple_open (const char *ctfsect, size_t ctfsect_size,
 ctf_file_t *
 ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect,
             const ctf_sect_t *strsect, int *errp)
+{
+  return ctf_bufopen_internal (ctfsect, symsect, strsect, NULL, errp);
+}
+
+/* Like ctf_bufopen, but overriding the external strtab with a synthetic one.  */
+
+ctf_file_t *
+ctf_bufopen_internal (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect,
+                     const ctf_sect_t *strsect, ctf_dynhash_t *syn_strtab,
+                     int *errp)
 {
   const ctf_preamble_t *pp;
   size_t hdrsz = sizeof (ctf_header_t);
@@ -1244,7 +1278,8 @@ ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect,
 
   libctf_init_debug();
 
-  if (ctfsect == NULL || ((symsect == NULL) != (strsect == NULL)))
+  if ((ctfsect == NULL) || ((symsect != NULL) &&
+                           ((strsect == NULL) && syn_strtab == NULL)))
     return (ctf_set_open_errno (errp, EINVAL));
 
   if (symsect != NULL && symsect->cts_entsize != sizeof (Elf32_Sym) &&
@@ -1330,19 +1365,23 @@ ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect,
               (unsigned long) fp->ctf_size);
 
   if (hp->cth_lbloff > fp->ctf_size || hp->cth_objtoff > fp->ctf_size
-      || hp->cth_funcoff > fp->ctf_size || hp->cth_typeoff > fp->ctf_size
+      || hp->cth_funcoff > fp->ctf_size || hp->cth_objtidxoff > fp->ctf_size
+      || hp->cth_funcidxoff > fp->ctf_size || hp->cth_typeoff > fp->ctf_size
       || hp->cth_stroff > fp->ctf_size)
     return (ctf_set_open_errno (errp, ECTF_CORRUPT));
 
   if (hp->cth_lbloff > hp->cth_objtoff
       || hp->cth_objtoff > hp->cth_funcoff
       || hp->cth_funcoff > hp->cth_typeoff
-      || hp->cth_funcoff > hp->cth_varoff
+      || hp->cth_funcoff > hp->cth_objtidxoff
+      || hp->cth_objtidxoff > hp->cth_funcidxoff
+      || hp->cth_funcidxoff > hp->cth_varoff
       || hp->cth_varoff > hp->cth_typeoff || hp->cth_typeoff > hp->cth_stroff)
     return (ctf_set_open_errno (errp, ECTF_CORRUPT));
 
   if ((hp->cth_lbloff & 3) || (hp->cth_objtoff & 2)
-      || (hp->cth_funcoff & 2) || (hp->cth_varoff & 3)
+      || (hp->cth_funcoff & 2) || (hp->cth_objtidxoff & 2)
+      || (hp->cth_funcidxoff & 2) || (hp->cth_varoff & 3)
       || (hp->cth_typeoff & 3))
     return (ctf_set_open_errno (errp, ECTF_CORRUPT));
 
@@ -1453,6 +1492,7 @@ ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect,
       fp->ctf_str[CTF_STRTAB_1].cts_strs = strsect->cts_data;
       fp->ctf_str[CTF_STRTAB_1].cts_len = strsect->cts_size;
     }
+  fp->ctf_syn_ext_strtab = syn_strtab;
 
   if (foreign_endian &&
       (err = flip_ctf (hp, fp->ctf_buf)) != 0)
@@ -1579,12 +1619,15 @@ ctf_file_close (ctf_file_t *fp)
 
   if (fp->ctf_strtab.cts_name != _CTF_NULLSTR)
     ctf_free ((char *) fp->ctf_strtab.cts_name);
-
   else if (fp->ctf_data_mmapped)
     ctf_munmap (fp->ctf_data_mmapped, fp->ctf_data_mmapped_len);
 
   ctf_free (fp->ctf_dynbase);
 
+  ctf_dynhash_destroy (fp->ctf_syn_ext_strtab);
+  ctf_dynhash_destroy (fp->ctf_link_inputs);
+  ctf_dynhash_destroy (fp->ctf_link_outputs);
+
   ctf_free (fp->ctf_sxlate);
   ctf_free (fp->ctf_txlate);
   ctf_free (fp->ctf_ptrtab);
This page took 0.029651 seconds and 4 git commands to generate.