]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
libctf: serialize: kind suppression and prohibition
authorNick Alcock <nick.alcock@oracle.com>
Fri, 25 Apr 2025 11:42:12 +0000 (12:42 +0100)
committerNick Alcock <nick.alcock@oracle.com>
Fri, 25 Apr 2025 17:07:44 +0000 (18:07 +0100)
The CTF serialization machinery decides whether to write out a dict as BTF
or CTF (or, in LIBCTF_BTM_BTF mode, whether to write out a dict or fail with
ECTF_NOTBTF) in part by looking at the type kinds in the dictionary.

It is possible that you'd like to extend this check and ban specific type
kinds from the dictionary (possibly even if it's CTF); it's also possible
that you'd like to *not* fail even if a CTF-only kind is found, but rather
replace it with a still-valid stub (CTF_K_UNKNOWN / BTF_KIND_UNKNOWN) and
keep going.  (The kernel's btfarchive machinery does this to ensure that
the compiler and previous link stages have emitted only valid BTF type
kinds.)

ctf_write_suppress_kind supports both these use cases:

+int ctf_write_suppress_kind (ctf_dict_t *fp, int kind, int prohibited);

This commit adds only the core population code: the actual suppression is
spread across the serializer and will be added in the next commits.

include/ctf-api.h
libctf/ctf-impl.h
libctf/ctf-serialize.c
libctf/libctf.ver

index c0aa0db2fed6500f92d8326e63eaa43283e2cec1..e9fadefa67877b3840e99753e8722da7daf34494 100644 (file)
@@ -264,6 +264,8 @@ typedef struct ctf_snapshot_id
   _CTF_ITEM (ECTF_NODATASEC, "Variable not found in datasec.") \
   _CTF_ITEM (ECTF_NOTDECLTAG, "This function requires a decl tag.") \
   _CTF_ITEM (ECTF_NOTTAG, "This function requires a type or decl tag.") \
+  _CTF_ITEM (ECTF_KIND_PROHIBITED, "Writeout of suppressed kind attempted.") \
+  _CTF_ITEM (ECTF_NOTBTF, "Cannot write out this dict as BTF.") \
   _CTF_ITEM (ECTF_TOOLARGE, "Prefix required for correct representation.")
 
 #define        ECTF_BASE       1000    /* Base value for libctf errnos.  */
@@ -1106,6 +1108,11 @@ extern int ctf_arc_write (const char *file, ctf_dict_t **ctf_dicts, size_t,
 extern int ctf_arc_write_fd (int, ctf_dict_t **, size_t, const char **,
                             size_t);
 
+/* Prohibit writeout of this type kind: attempts to write it out cause
+   an ECTF_KIND_PROHIBITED error.  */
+
+extern int ctf_write_suppress_kind (ctf_dict_t *fp, int kind, int prohibited);
+
 /* Linking.  These functions are used by ld to link .ctf sections in input
    object files into a single .ctf section which is an archive possibly
    containing members containing types whose names collide across multiple
index 752eca81ab4233ceacf9afa9d8db658375613923..67ddc1801b2a87929d3c8f5474423fc93bb392a9 100644 (file)
@@ -380,6 +380,8 @@ struct ctf_dict
   const ctf_dictops_t *ctf_dictops; /* Version-specific dict operations.  */
   ctf_header_t *ctf_header;        /* The header from this CTF dict.  */
   ctf_header_v3_t *ctf_v3_header;   /* The header from an upgraded CTF dict.  */
+  ctf_dynset_t *ctf_write_prohibitions; /* Kinds writeout causes error for.  */
+  ctf_dynset_t *ctf_write_suppressions;        /* Kinds that are skipped on write.  */
   unsigned char ctf_openflags;     /* Flags the dict had when opened.  */
   int ctf_opened_btf;              /* Whether this dict was pure BTF when
                                       opened.  */
index 1c516a888d1a6ab68fbb58a680b5c9a8f5a6ecf9..e127ac35e2700ba807dd3dd5ed3738f520540a6a 100644 (file)
@@ -756,6 +756,39 @@ symerr:
 
 /* Type section.  */
 
+/* Kind suppression.  */
+
+int
+ctf_write_suppress_kind (ctf_dict_t *fp, int kind, int prohibited)
+{
+  ctf_dynset_t *set;
+
+  if (kind < CTF_K_UNKNOWN || kind > CTF_K_MAX)
+    return (ctf_set_errno (fp, EINVAL));
+
+  if (prohibited)
+    set = fp->ctf_write_prohibitions;
+  else
+    set = fp->ctf_write_suppressions;
+
+  if (!set)
+    {
+      set = ctf_dynset_create (htab_hash_pointer, htab_eq_pointer, NULL);
+      if (!set)
+       return (ctf_set_errno (fp, errno));
+
+      if (prohibited)
+       fp->ctf_write_prohibitions = set;
+      else
+       fp->ctf_write_suppressions = set;
+    }
+
+  if ((ctf_dynset_cinsert (set, (const void *) (uintptr_t) kind)) < 0)
+    return (ctf_set_errno (fp, errno));
+
+  return 0;
+}
+
 /* Iterate through the static types and the dynamic type definition list and
    compute the size of the CTF type section.
 
index 8aa9f356db76e871c20fb0c524660fad3e435394..3ad5176a14188e7613c4d7c67769781c254a8675 100644 (file)
@@ -167,6 +167,7 @@ LIBCTF_2.0 {
        ctf_write_mem;
        ctf_gzwrite;
        ctf_compress_write;
+       ctf_write_suppress_kind;
        ctf_sect_size;
        ctf_getdatasect;
        ctf_getsymsect;