libctf: installable libctf as a shared library
[deliverable/binutils-gdb.git] / libctf / ctf-create.c
index d75de916eaeca1db14e06c400ac205085906f1a1..8eb16738a11844cb15b98ae22e44895d526465bb 100644 (file)
@@ -470,7 +470,13 @@ ctf_update (ctf_file_t *fp)
   nfp->ctf_dtoldid = fp->ctf_dtnextid - 1;
   nfp->ctf_snapshots = fp->ctf_snapshots + 1;
   nfp->ctf_specific = fp->ctf_specific;
+  nfp->ctf_link_inputs = fp->ctf_link_inputs;
+  nfp->ctf_link_outputs = fp->ctf_link_outputs;
   nfp->ctf_syn_ext_strtab = fp->ctf_syn_ext_strtab;
+  nfp->ctf_link_cu_mapping = fp->ctf_link_cu_mapping;
+  nfp->ctf_link_type_mapping = fp->ctf_link_type_mapping;
+  nfp->ctf_link_memb_name_changer = fp->ctf_link_memb_name_changer;
+  nfp->ctf_link_memb_name_changer_arg = fp->ctf_link_memb_name_changer_arg;
 
   nfp->ctf_snapshot_lu = fp->ctf_snapshots;
 
@@ -480,7 +486,11 @@ ctf_update (ctf_file_t *fp)
   nfp->ctf_str_atoms = fp->ctf_str_atoms;
   fp->ctf_str_atoms = NULL;
   memset (&fp->ctf_dtdefs, 0, sizeof (ctf_list_t));
+  fp->ctf_link_inputs = NULL;
+  fp->ctf_link_outputs = NULL;
   fp->ctf_syn_ext_strtab = NULL;
+  fp->ctf_link_cu_mapping = NULL;
+  fp->ctf_link_type_mapping = NULL;
 
   fp->ctf_dvhash = NULL;
   memset (&fp->ctf_dvdefs, 0, sizeof (ctf_list_t));
@@ -1542,7 +1552,7 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
   ctf_id_t tmp;
 
   const char *name;
-  uint32_t kind, flag, vlen;
+  uint32_t kind, forward_kind, flag, vlen;
 
   const ctf_type_t *src_tp, *dst_tp;
   ctf_bundle_t src, dst;
@@ -1553,6 +1563,7 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
   ctf_funcinfo_t ctc;
 
   ctf_hash_t *hp;
+  ctf_id_t orig_src_type = src_type;
 
   if (!(dst_fp->ctf_flags & LCTF_RDWR))
     return (ctf_set_errno (dst_fp, ECTF_RDONLY));
@@ -1565,7 +1576,11 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
   flag = LCTF_INFO_ISROOT (src_fp, src_tp->ctt_info);
   vlen = LCTF_INFO_VLEN (src_fp, src_tp->ctt_info);
 
-  switch (kind)
+  forward_kind = kind;
+  if (kind == CTF_K_FORWARD)
+    forward_kind = src_tp->ctt_type;
+
+  switch (forward_kind)
     {
     case CTF_K_STRUCT:
       hp = dst_fp->ctf_structs;
@@ -1594,16 +1609,30 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
 
   /* If an identically named dst_type exists, fail with ECTF_CONFLICT
      unless dst_type is a forward declaration and src_type is a struct,
-     union, or enum (i.e. the definition of the previous forward decl).  */
+     union, or enum (i.e. the definition of the previous forward decl).
 
-  if (dst_type != CTF_ERR && dst_kind != kind
-      && (dst_kind != CTF_K_FORWARD
-         || (kind != CTF_K_ENUM && kind != CTF_K_STRUCT
-             && kind != CTF_K_UNION)))
+     We also allow addition in the opposite order (addition of a forward when a
+     struct, union, or enum already exists), which is a NOP and returns the
+     already-present struct, union, or enum.  */
+
+  if (dst_type != CTF_ERR && dst_kind != kind)
     {
-      ctf_dprintf ("Conflict for type %s: kinds differ, new: %i; "
-                  "old (ID %lx): %i\n", name, kind, dst_type, dst_kind);
-      return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
+      if (kind == CTF_K_FORWARD
+         && (dst_kind == CTF_K_ENUM || dst_kind == CTF_K_STRUCT
+             || dst_kind == CTF_K_UNION))
+       {
+         ctf_add_type_mapping (src_fp, src_type, dst_fp, dst_type);
+         return dst_type;
+       }
+
+      if (dst_kind != CTF_K_FORWARD
+         || (kind != CTF_K_ENUM && kind != CTF_K_STRUCT
+             && kind != CTF_K_UNION))
+       {
+         ctf_dprintf ("Conflict for type %s: kinds differ, new: %i; "
+                      "old (ID %lx): %i\n", name, kind, dst_type, dst_kind);
+         return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
+       }
     }
 
   /* We take special action for an integer, float, or slice since it is
@@ -1636,7 +1665,10 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
              if (memcmp (&src_en, &dst_en, sizeof (ctf_encoding_t)) == 0)
                {
                  if (kind != CTF_K_SLICE)
-                   return dst_type;
+                   {
+                     ctf_add_type_mapping (src_fp, src_type, dst_fp, dst_type);
+                     return dst_type;
+                   }
                }
              else
                  {
@@ -1675,7 +1707,10 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
              int match;        /* Do the encodings match?  */
 
              if (kind != CTF_K_INTEGER && kind != CTF_K_FLOAT && kind != CTF_K_SLICE)
-               return dtd->dtd_type;
+               {
+                 ctf_add_type_mapping (src_fp, src_type, dst_fp, dtd->dtd_type);
+                 return dtd->dtd_type;
+               }
 
              sroot = (flag & CTF_ADD_ROOT);
              droot = (LCTF_INFO_ISROOT (dst_fp,
@@ -1694,7 +1729,10 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
              if (match && sroot == droot)
                {
                  if (kind != CTF_K_SLICE)
-                   return dtd->dtd_type;
+                   {
+                     ctf_add_type_mapping (src_fp, src_type, dst_fp, dtd->dtd_type);
+                     return dtd->dtd_type;
+                   }
                }
              else if (!match && sroot && droot)
                {
@@ -1904,10 +1942,7 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
 
     case CTF_K_FORWARD:
       if (dst_type == CTF_ERR)
-       {
-         dst_type = ctf_add_forward (dst_fp, flag,
-                                     name, CTF_K_STRUCT); /* Assume STRUCT. */
-       }
+         dst_type = ctf_add_forward (dst_fp, flag, name, forward_kind);
       break;
 
     case CTF_K_TYPEDEF:
@@ -1935,6 +1970,8 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
       return (ctf_set_errno (dst_fp, ECTF_CORRUPT));
     }
 
+  if (dst_type != CTF_ERR)
+    ctf_add_type_mapping (src_fp, orig_src_type, dst_fp, dst_type);
   return dst_type;
 }
 
This page took 0.024566 seconds and 4 git commands to generate.