libctf: create: forwards are always in the namespace of their referent
authorNick Alcock <nick.alcock@oracle.com>
Tue, 5 Nov 2019 17:57:55 +0000 (17:57 +0000)
committerNick Alcock <nick.alcock@oracle.com>
Fri, 26 Jun 2020 14:56:39 +0000 (15:56 +0100)
The C namespace a forward is located in is always the same as the
namespace of the corresponding complete type: 'struct foo' is in the
struct namespace and does not collide with, say, 'union foo'.

libctf allowed for this in many places, but inconsistently: in
particular, forward *addition* never allowed for this, and was interning
forwards in the default namespace, which is always wrong, since you can
only forward structs, unions and enums, all of which are in their own
namespaces in C.

Forward removal needs corresponding adjustment to remove the names form
the right namespace, as does ctf_rollback.

libctf/
* ctf-create.c (ctf_add_forward): Intern in the right namespace.
(ctf_dtd_delete): Remove correspondingly.
(ctf_rollback): Likewise.

libctf/ChangeLog
libctf/ctf-create.c

index 1b019a3e5f762fa8789478d3d62d4e85d99ad6eb..3ab0a6c0376dd49df8343a585997410ca3fa9d8f 100644 (file)
@@ -1,3 +1,9 @@
+2020-06-26  Nick Alcock  <nick.alcock@oracle.com>
+
+       * ctf-create.c (ctf_add_forward): Intern in the right namespace.
+       (ctf_dtd_delete): Remove correspondingly.
+       (ctf_rollback): Likewise.
+
 2020-06-26  Nick Alcock  <nick.alcock@oracle.com>
 
        * ctf-create.c (ctf_add_type_internal): Hand back existing types
index 7e94a254c500954243b6c1e5047703956f86a42a..a01250bc4d4198d666a25b495ad4498e10254c5a 100644 (file)
@@ -622,6 +622,7 @@ ctf_dtd_delete (ctf_file_t *fp, ctf_dtdef_t *dtd)
 {
   ctf_dmdef_t *dmd, *nmd;
   int kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
+  int name_kind = kind;
   const char *name;
 
   ctf_dynhash_remove (fp->ctf_dthash, (void *) dtd->dtd_type);
@@ -643,13 +644,16 @@ ctf_dtd_delete (ctf_file_t *fp, ctf_dtdef_t *dtd)
     case CTF_K_FUNCTION:
       free (dtd->dtd_u.dtu_argv);
       break;
+    case CTF_K_FORWARD:
+      name_kind = dtd->dtd_data.ctt_type;
+      break;
     }
 
   if (dtd->dtd_data.ctt_name
       && (name = ctf_strraw (fp, dtd->dtd_data.ctt_name)) != NULL
       && LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info))
     {
-      ctf_dynhash_remove (ctf_name_table (fp, kind)->ctn_writable,
+      ctf_dynhash_remove (ctf_name_table (fp, name_kind)->ctn_writable,
                          name);
       ctf_str_remove_ref (fp, name, &dtd->dtd_data.ctt_name);
     }
@@ -761,6 +765,8 @@ ctf_rollback (ctf_file_t *fp, ctf_snapshot_id_t id)
        continue;
 
       kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
+      if (kind == CTF_K_FORWARD)
+       kind = dtd->dtd_data.ctt_type;
 
       if (dtd->dtd_data.ctt_name
          && (name = ctf_strraw (fp, dtd->dtd_data.ctt_name)) != NULL
@@ -1232,7 +1238,7 @@ ctf_add_forward (ctf_file_t *fp, uint32_t flag, const char *name,
   if (type)
     return type;
 
-  if ((type = ctf_add_generic (fp, flag, name, CTF_K_FORWARD, &dtd)) == CTF_ERR)
+  if ((type = ctf_add_generic (fp, flag, name, kind, &dtd)) == CTF_ERR)
     return CTF_ERR;            /* errno is set for us.  */
 
   dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_FORWARD, flag, 0);