]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
libctf: create, types: conflicting types
authorNick Alcock <nick.alcock@oracle.com>
Fri, 25 Apr 2025 10:23:46 +0000 (11:23 +0100)
committerNick Alcock <nick.alcock@oracle.com>
Fri, 25 Apr 2025 17:07:43 +0000 (18:07 +0100)
The conflicting type kind is a CTF-specific prefix kind consisting purely of
an optional translation unit name.  It takes the place of the old hidden
bit: we have already seen it used to prefix types added with a
CTF_ADD_NONROOT flag.  The deduplicator will also use them to label
conflicting types from different TUs smushed into the same dict by the
CU-mapping mechanism: unlike the hidden bit, with this scheme users can tell
which CUs the conflicting types came from.

New API:

+int ctf_type_conflicting (ctf_dict_t *, ctf_id_t, const char **cuname);
+int ctf_set_conflicting (ctf_dict_t *, ctf_id_t, const char *);

(Frankly I expect ctf_set_conflicting to be used only by deduplicators and
things like that, but if we provide an option to query something we should
also provide an option to produce it...)

include/ctf-api.h
libctf/ctf-create.c
libctf/ctf-types.c
libctf/libctf.ver

index e986cadee091a61fbea8065397cff1a73e162c59..dd159c3836c4d0b28380b592e746a33866fb2c8d 100644 (file)
@@ -674,6 +674,13 @@ extern int ctf_type_kind (ctf_dict_t *, ctf_id_t);
 
 extern int ctf_type_kind_forwarded (ctf_dict_t *, ctf_id_t);
 
+/* Return nonzero if this type is conflicting, zero if it's not, < 0 on error; if
+   CUNAME is set, set it to the name of the conflicting compilation unit for the
+   passed-in type (which may be a null string if the cuname is not known, or if
+   this is not a conflicting type).  */
+
+extern int ctf_type_conflicting (ctf_dict_t *, ctf_id_t, const char **cuname);
+
 /* Return the type a pointer, typedef, cvr-qual, or slice refers to, or return
    an ECTF_NOTREF error otherwise.  ctf_type_kind pretends that slices are
    actually the type they are a slice of: this is usually want you want, but if
@@ -1008,7 +1015,13 @@ extern ctf_id_t ctf_add_section_variable (ctf_dict_t *, uint32_t,
 
 extern int ctf_set_array (ctf_dict_t *, ctf_id_t, const ctf_arinfo_t *);
 
-/* Add a function oor object symbol type with a particular name, without saying
+/* Mark a type as conflicting, residing in some other translation unit with a
+   given name.  The type is hidden from all name lookups, just like
+   CTF_ADD_NONROOT.  */
+
+extern int ctf_set_conflicting (ctf_dict_t *, ctf_id_t, const char *);
+
+/* Add a function or object symbol type with a particular name, without saying
    anything about the actual symbol index.  (The linker will then associate them
    with actual symbol indexes using the ctf_link functions below.)  */
 
index 6a22aca1d678b82d3443a62bfdb503e2dbeba62f..ba8c266dd8d3a795935319f37f7f1dfd4c670926 100644 (file)
@@ -928,6 +928,43 @@ ctf_set_array (ctf_dict_t *fp, ctf_id_t type, const ctf_arinfo_t *arp)
   return 0;
 }
 
+/* Set this type as conflicting in compilation unit CUNAME.  */
+int
+ctf_set_conflicting (ctf_dict_t *fp, ctf_id_t type, const char *cuname)
+{
+  ctf_dict_t *ofp = fp;
+  ctf_dtdef_t *dtd;
+  ctf_type_t *prefix;
+  uint32_t idx;
+
+  if (ctf_lookup_by_id (&fp, type, NULL) == NULL)
+    return -1;                         /* errno is set for us.  */
+
+  idx = ctf_type_to_index (fp, type);
+  dtd = ctf_dtd_lookup (fp, type);
+
+  /* You can only call ctf_set_conflicting on a type you have added, not a type
+     that was read in via ctf_open.  */
+  if (idx < fp->ctf_stypes)
+    return (ctf_set_errno (ofp, ECTF_RDONLY));
+
+  if (dtd == NULL)
+    return (ctf_set_errno (ofp, ECTF_BADID));
+
+  if ((prefix = (ctf_type_t *) ctf_find_prefix (fp, dtd->dtd_buf,
+                                               CTF_K_CONFLICTING)) == NULL)
+    {
+      if ((prefix = ctf_add_prefix (fp, dtd, 0)) == NULL)
+       return -1;                      /* errno is set for us.  */
+    }
+  prefix->ctt_name = ctf_str_add (fp, cuname);
+  prefix->ctt_info = CTF_TYPE_INFO (CTF_K_CONFLICTING, 0,
+                                   dtd->dtd_vlen_size < 65536
+                                   ? dtd->dtd_vlen_size : 0);
+
+  return 0;
+}
+
 /* Add a type or decl tag applying to some whole type, or to some
    component of a type.  Component -1 is a whole type.  */
 
index dac1ec50468f2a06c692478d4a9a4d0409777054..275e5c00e159a36116e0c31adcef9ddf8c202e94 100644 (file)
@@ -1631,6 +1631,49 @@ ctf_type_kind_forwarded (ctf_dict_t *fp, ctf_id_t type)
   return ret;
 }
 
+/* Return nonzero if this type is conflicting, nonzero if it's not, < 0 on
+   error; if CUNAME is set, set it to the name of the conflicting compilation
+   unit for the passed-in type (which may be a null string if the cuname is not
+   known).  */
+
+int
+ctf_type_conflicting (ctf_dict_t *fp, ctf_id_t type, const char **cuname)
+{
+  ctf_dict_t *ofp = fp;
+  const ctf_type_t *tp;
+
+  /* The unimplemented / void type is never conflicting.  */
+  if (type == 0)
+    return 0;
+
+  if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
+    return -1;                 /* errno is set for us.  */
+
+  if ((tp = ctf_lookup_by_id (&fp, type, NULL)) == NULL)
+    return -1;                 /* errno is set for us.  */
+
+  if (cuname)
+    *cuname = 0;
+
+  if (LCTF_INFO_ISROOT (fp, tp->ctt_info))
+    return 0;
+
+  if (!cuname)
+    return 1;
+
+  while (LCTF_INFO_UNPREFIXED_KIND (fp, tp->ctt_info) != CTF_K_CONFLICTING
+        && LCTF_IS_PREFIXED_INFO (tp->ctt_info))
+    tp++;
+
+  /* We already checked that this is a non-root-visible type, so this must be
+     CTF_K_CONFLICTING.  */
+  if (!ctf_assert (ofp, LCTF_IS_PREFIXED_INFO (tp->ctt_info)))
+    return -1;                                 /* errno is set for us.  */
+
+  *cuname = ctf_strptr (fp, tp->ctt_name);
+  return 1;
+}
+
 /* If the type is one that directly references another type (such as POINTER),
    then return the ID of the type to which it refers.  */
 
index 66ddb530a1b907508874a4a43c6e62c4f6108cfc..c8525b5f1d5a90ce43420626d250f310ff839f1e 100644 (file)
@@ -77,6 +77,7 @@ LIBCTF_2.0 {
        ctf_type_align;
        ctf_type_kind;
        ctf_type_kind_forwarded;
+       ctf_type_conflicting;
        ctf_type_reference;
        ctf_type_linkage;
        ctf_type_pointer;
@@ -155,6 +156,7 @@ LIBCTF_2.0 {
        ctf_add_member_bitfield;
 
        ctf_set_array;
+       ctf_set_conflicting;
 
        ctf_update;
        ctf_discard;