public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 0/9] Add btf_decl_tag C attribute
@ 2023-07-11 21:57 David Faust
  2023-07-11 21:57 ` [PATCH 1/9] c-family: add btf_decl_tag attribute David Faust
                   ` (12 more replies)
  0 siblings, 13 replies; 18+ messages in thread
From: David Faust @ 2023-07-11 21:57 UTC (permalink / raw)
  To: gcc-patches; +Cc: jose.marchesi, yhs

Hello,

This series adds support for a new attribute, "btf_decl_tag" in GCC.
The same attribute is already supported in clang, and is used by various
components of the BPF ecosystem.

The purpose of the attribute is to allow to associate (to "tag")
declarations with arbitrary string annotations, which are emitted into
debugging information (DWARF and/or BTF) to facilitate post-compilation
analysis (the motivating use case being the Linux kernel BPF verifier).
Multiple tags are allowed on the same declaration.

These strings are not interpreted by the compiler, and the attribute
itself has no effect on generated code, other than to produce additional
DWARF DIEs and/or BTF records conveying the annotations.

This entails:

- A new C-language-level attribute which allows to associate (to "tag")
  particular declarations with arbitrary strings.

- The conveyance of that information in DWARF in the form of a new DIE,
  DW_TAG_GNU_annotation, with tag number (0x6000) and format matching
  that of the DW_TAG_LLVM_annotation extension supported in LLVM for
  the same purpose. These DIEs are already supported by BPF tooling,
  such as pahole.

- The conveyance of that information in BTF debug info in the form of
  BTF_KIND_DECL_TAG records. These records are already supported by
  LLVM and other tools in the eBPF ecosystem, such as the Linux kernel
  eBPF verifier.


Background
==========

The purpose of these tags is to convey additional semantic information
to post-compilation consumers, in particular the Linux kernel eBPF
verifier. The verifier can make use of that information while analyzing
a BPF program to aid in determining whether to allow or reject the
program to be run. More background on these tags can be found in the
early support for them in the kernel here [1] and [2].

The "btf_decl_tag" attribute is half the story; the other half is a
sibling attribute "btf_type_tag" which serves the same purpose but
applies to types. Support for btf_type_tag will come in a separate
patch series, since it is impaced by GCC bug 110439 which needs to be
addressed first.

I submitted an initial version of this work (including btf_type_tag)
last spring [3], however at the time there were some open questions
about the behavior of the btf_type_tag attribute and issues with its
implementation. Since then we have clarified these details and agreed
to solutions with the BPF community and LLVM BPF folks.

The main motivation for emitting the tags in DWARF is that the Linux
kernel generates its BTF information via pahole, using DWARF as a source:

    +--------+  BTF                  BTF   +----------+
    | pahole |-------> vmlinux.btf ------->| verifier |
    +--------+                             +----------+
        ^                                        ^
        |                                        |
  DWARF |                                    BTF |
        |                                        |
      vmlinux                              +-------------+
      module1.ko                           | BPF program |
      module2.ko                           +-------------+
        ...

This is because:

a)  pahole adds additional kernel-specific information into the
    produced BTF based on additional analysis of kernel objects.

b)  Unlike GCC, LLVM will only generate BTF for BPF programs.

b)  GCC can generate BTF for whatever target with -gbtf, but there is no
    support for linking/deduplicating BTF in the linker.

In the scenario above, the verifier needs access to the pointer tags of
both the kernel types/declarations (conveyed in the DWARF and translated
to BTF by pahole) and those of the BPF program (available directly in BTF).


DWARF Representation
====================

As noted above, btf_decl_tag is represented in DWARF via a new DIE
DW_TAG_GNU_annotation, with identical format to the LLVM DWARF
extension DW_TAG_LLVM_annotation serving the same purpose. The DIE has
the following format:

  DW_TAG_GNU_annotation (0x6000)
    DW_AT_name: "btf_decl_tag"
    DW_AT_const_value: <string argument>

These DIEs are placed in the DWARF tree as children of the DIE for the
appropriate declaration, and one such DIE is created for each occurrence
of the btf_decl_tag attribute on a declaration.

For example:

  const int * c __attribute__((btf_decl_tag ("__c"), btf_decl_tag ("devicemem")));

This declaration produces the following DWARF:

 <1><1e>: Abbrev Number: 2 (DW_TAG_variable)
    <1f>   DW_AT_name        : c
    <24>   DW_AT_type        : <0x49>
    ...
 <2><36>: Abbrev Number: 3 (User TAG value: 0x6000)
    <37>   DW_AT_name        : (indirect string, offset: 0x4c): btf_decl_tag
    <3b>   DW_AT_const_value : (indirect string, offset: 0): devicemem
 <2><3f>: Abbrev Number: 4 (User TAG value: 0x6000)
    <40>   DW_AT_name        : (indirect string, offset: 0x4c): btf_decl_tag
    <44>   DW_AT_const_value : __c
 <2><48>: Abbrev Number: 0
 <1><49>: Abbrev Number: 5 (DW_TAG_pointer_type)
 ...

The DIEs for btf_decl_tag are placed as children of the DIE for
variable "c".

BTF Representation
==================

In BTF, BTF_KIND_DECL_TAG records convey the annotations. These records refer
to the annotated object by BTF type ID, as well as a component index which is
used for btf_decl_tags placed on struct/union members or function arguments.

For example, the BTF for the above declaration is:

  [1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED
  [2] CONST '(anon)' type_id=1
  [3] PTR '(anon)' type_id=2
  [4] DECL_TAG '__c' type_id=6 component_idx=-1
  [5] DECL_TAG 'devicemem' type_id=6 component_idx=-1
  [6] VAR 'c' type_id=3, linkage=global
  ...

The BTF format is documented here [4].


References
==========

[1] https://lore.kernel.org/bpf/20210914223004.244411-1-yhs@fb.com/
[2] https://lore.kernel.org/bpf/20211011040608.3031468-1-yhs@fb.com/
[3] https://gcc.gnu.org/pipermail/gcc-patches/2022-May/593936.html
[4] https://www.kernel.org/doc/Documentation/bpf/btf.rst


David Faust (9):
  c-family: add btf_decl_tag attribute
  include: add BTF decl tag defines
  dwarf: create annotation DIEs for decl tags
  dwarf: expose get_die_parent
  ctf: add support to pass through BTF tags
  dwarf2ctf: convert annotation DIEs to CTF types
  btf: create and output BTF_KIND_DECL_TAG types
  testsuite: add tests for BTF decl tags
  doc: document btf_decl_tag attribute

 gcc/btfout.cc                                 | 81 ++++++++++++++++++-
 gcc/c-family/c-attribs.cc                     | 23 ++++++
 gcc/ctf-int.h                                 | 28 +++++++
 gcc/ctfc.cc                                   | 10 ++-
 gcc/ctfc.h                                    | 17 +++-
 gcc/doc/extend.texi                           | 47 +++++++++++
 gcc/dwarf2ctf.cc                              | 73 ++++++++++++++++-
 gcc/dwarf2out.cc                              | 37 ++++++++-
 gcc/dwarf2out.h                               |  1 +
 .../gcc.dg/debug/btf/btf-decltag-func.c       | 21 +++++
 .../gcc.dg/debug/btf/btf-decltag-sou.c        | 33 ++++++++
 .../gcc.dg/debug/btf/btf-decltag-var.c        | 19 +++++
 .../gcc.dg/debug/dwarf2/annotation-decl-1.c   |  9 +++
 .../gcc.dg/debug/dwarf2/annotation-decl-2.c   | 18 +++++
 .../gcc.dg/debug/dwarf2/annotation-decl-3.c   | 17 ++++
 include/btf.h                                 | 14 +++-
 include/dwarf2.def                            |  4 +
 17 files changed, 437 insertions(+), 15 deletions(-)
 create mode 100644 gcc/ctf-int.h
 create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-decltag-func.c
 create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-decltag-sou.c
 create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-decltag-var.c
 create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/annotation-decl-1.c
 create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/annotation-decl-2.c
 create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/annotation-decl-3.c

-- 
2.40.1


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 1/9] c-family: add btf_decl_tag attribute
  2023-07-11 21:57 [PATCH 0/9] Add btf_decl_tag C attribute David Faust
@ 2023-07-11 21:57 ` David Faust
  2023-07-11 21:57 ` [PATCH 2/9] include: add BTF decl tag defines David Faust
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 18+ messages in thread
From: David Faust @ 2023-07-11 21:57 UTC (permalink / raw)
  To: gcc-patches; +Cc: jose.marchesi, yhs

Add the "btf_decl_tag" attribute to the attribute table, along with
a simple handler for it.

gcc/c-family/

	* c-attribs.cc (c_common_attribute_table): Add btf_decl_tag.
	(handle_btf_decl_tag_attribute): Handle new attribute.
---
 gcc/c-family/c-attribs.cc | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
index e2792ca6898..0a3de3ea307 100644
--- a/gcc/c-family/c-attribs.cc
+++ b/gcc/c-family/c-attribs.cc
@@ -178,6 +178,8 @@ static tree handle_signed_bool_precision_attribute (tree *, tree, tree, int,
 static tree handle_retain_attribute (tree *, tree, tree, int, bool *);
 static tree handle_fd_arg_attribute (tree *, tree, tree, int, bool *);
 
+static tree handle_btf_decl_tag_attribute (tree *, tree, tree, int, bool *);
+
 /* Helper to define attribute exclusions.  */
 #define ATTR_EXCL(name, function, type, variable)	\
   { name, function, type, variable }
@@ -569,6 +571,9 @@ const struct attribute_spec c_common_attribute_table[] =
             handle_fd_arg_attribute, NULL},
   { "fd_arg_write",       1, 1, false, true, true, false,
             handle_fd_arg_attribute, NULL},         
+  { "btf_decl_tag",	      1, 1, true, false, false, false,
+			      handle_btf_decl_tag_attribute, NULL },
+
   { NULL,                     0, 0, false, false, false, false, NULL, NULL }
 };
 
@@ -5988,6 +5993,24 @@ handle_tainted_args_attribute (tree *node, tree name, tree, int,
   return NULL_TREE;
 }
 
+/* Handle a "btf_decl_tag" attribute; arguments as in
+   struct attribute_spec.handler.  */
+
+static tree
+handle_btf_decl_tag_attribute (tree *, tree name, tree args, int,
+			       bool *no_add_attrs)
+{
+  if (!args)
+    *no_add_attrs = true;
+  else if (TREE_CODE (TREE_VALUE (args)) != STRING_CST)
+    {
+      error ("%qE attribute requires a string", name);
+      *no_add_attrs = true;
+    }
+
+  return NULL_TREE;
+}
+
 /* Attempt to partially validate a single attribute ATTR as if
    it were to be applied to an entity OPER.  */
 
-- 
2.40.1


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 2/9] include: add BTF decl tag defines
  2023-07-11 21:57 [PATCH 0/9] Add btf_decl_tag C attribute David Faust
  2023-07-11 21:57 ` [PATCH 1/9] c-family: add btf_decl_tag attribute David Faust
@ 2023-07-11 21:57 ` David Faust
  2023-07-11 21:57 ` [PATCH 3/9] dwarf: create annotation DIEs for decl tags David Faust
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 18+ messages in thread
From: David Faust @ 2023-07-11 21:57 UTC (permalink / raw)
  To: gcc-patches; +Cc: jose.marchesi, yhs

Add definitions for btf_decl_tag and the DW_TAG_GNU_annotation
DWARF extension.

include/

	* btf.h (struct btf_type): Update comment.
	(BTF_KIND_DECL_TAG): New define.
	(struct btf_decl_tag): New.
	* dwarf2.def (DW_TAG_GNU_annotation): New DW_TAG extension.
---
 include/btf.h      | 14 +++++++++++++-
 include/dwarf2.def |  4 ++++
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/include/btf.h b/include/btf.h
index d0994ab369b..bc808487ab8 100644
--- a/include/btf.h
+++ b/include/btf.h
@@ -69,7 +69,7 @@ struct btf_type
 
   /* SIZE is used by INT, ENUM, STRUCT, UNION, DATASEC kinds.
      TYPE is used by PTR, TYPEDEF, VOLATILE, CONST, RESTRICT, FUNC,
-     FUNC_PROTO and VAR kinds.  */
+     FUNC_PROTO, VAR and DECL_TAG kinds.  */
   union
   {
     uint32_t size;	/* Size of the entire type, in bytes.  */
@@ -109,6 +109,7 @@ struct btf_type
 #define BTF_KIND_VAR		14	/* Variable.  */
 #define BTF_KIND_DATASEC	15	/* Section such as .bss or .data.  */
 #define BTF_KIND_FLOAT		16	/* Floating point.  */
+#define BTF_KIND_DECL_TAG	17	/* Decl Tag.  */
 #define BTF_KIND_ENUM64 	19	/* Enumeration up to 64 bits.  */
 #define BTF_KIND_MAX		BTF_KIND_ENUM64
 #define NR_BTF_KINDS		(BTF_KIND_MAX + 1)
@@ -222,6 +223,17 @@ struct btf_enum64
   uint32_t val_hi32;	/* high 32-bit value for a 64-bit value Enumerator */
 };
 
+/* BTF_KIND_DECL_TAG is followed by a single struct btf_decl_tag, which
+   describes the tag location:
+   - If component_idx == -1, then the tag is applied to a struct, union,
+     variable or function.
+   - Otherwise it is applied to a struct/union member or function argument
+     with the given given index numbered 0..vlen-1.  */
+struct btf_decl_tag
+{
+  int32_t component_idx;
+};
+
 #ifdef	__cplusplus
 }
 #endif
diff --git a/include/dwarf2.def b/include/dwarf2.def
index 7ab3ee611fd..4351498f288 100644
--- a/include/dwarf2.def
+++ b/include/dwarf2.def
@@ -174,6 +174,10 @@ DW_TAG (DW_TAG_GNU_formal_parameter_pack, 0x4108)
    are properly part of DWARF 5.  */
 DW_TAG (DW_TAG_GNU_call_site, 0x4109)
 DW_TAG (DW_TAG_GNU_call_site_parameter, 0x410a)
+
+/* Extension for BTF annotations.  */
+DW_TAG (DW_TAG_GNU_annotation, 0x6000)
+
 /* Extensions for UPC.  See: http://dwarfstd.org/doc/DWARF4.pdf.  */
 DW_TAG (DW_TAG_upc_shared_type, 0x8765)
 DW_TAG (DW_TAG_upc_strict_type, 0x8766)
-- 
2.40.1


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 3/9] dwarf: create annotation DIEs for decl tags
  2023-07-11 21:57 [PATCH 0/9] Add btf_decl_tag C attribute David Faust
  2023-07-11 21:57 ` [PATCH 1/9] c-family: add btf_decl_tag attribute David Faust
  2023-07-11 21:57 ` [PATCH 2/9] include: add BTF decl tag defines David Faust
@ 2023-07-11 21:57 ` David Faust
  2023-07-11 21:57 ` [PATCH 4/9] dwarf: expose get_die_parent David Faust
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 18+ messages in thread
From: David Faust @ 2023-07-11 21:57 UTC (permalink / raw)
  To: gcc-patches; +Cc: jose.marchesi, yhs

The "btf_decl_tag" attribute is handled by constructing a
DW_TAG_GNU_annotation DIE for each occurrence to record the argument
string in debug information. The DIEs are children of the declarations
they annotate, with the following format:

  DW_TAG_GNU_annotation
    DW_AT_name "btf_decl_tag"
    DW_AT_const_value <arbitrary string argument from attribute>

gcc/

	* dwarf2out.cc (gen_btf_decl_tag_dies): New function.
	(gen_formal_parameter_die): Call it here.
	(gen_decl_die): Likewise.
---
 gcc/dwarf2out.cc | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
index 238d0a94400..c8c34db2b5a 100644
--- a/gcc/dwarf2out.cc
+++ b/gcc/dwarf2out.cc
@@ -13620,6 +13620,35 @@ long_double_as_float128 (tree type)
   return NULL_TREE;
 }
 
+/* Given a tree T, which should be a decl, process any btf_decl_tag attributes
+   on T, provided in ATTR.  Construct DW_TAG_GNU_annotation DIEs appropriately
+   as children of TARGET, usually the DIE for T.  */
+
+static void
+gen_btf_decl_tag_dies (tree t, dw_die_ref target)
+{
+  dw_die_ref die;
+  tree attr;
+
+  if (t == NULL_TREE || !DECL_P (t) || !target)
+    return;
+
+  attr = lookup_attribute ("btf_decl_tag", DECL_ATTRIBUTES (t));
+  while (attr != NULL_TREE)
+    {
+      die = new_die (DW_TAG_GNU_annotation, target, t);
+      add_name_attribute (die, IDENTIFIER_POINTER (get_attribute_name (attr)));
+      add_AT_string (die, DW_AT_const_value,
+		     TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr))));
+      attr = lookup_attribute ("btf_decl_tag", TREE_CHAIN (attr));
+    }
+
+  /* Strip the decl tag attribute to avoid creating multiple copies if we hit
+     this tree node again in some recursive call.  */
+  DECL_ATTRIBUTES (t)
+    = remove_attribute ("btf_decl_tag", DECL_ATTRIBUTES (t));
+}
+
 /* Given a pointer to an arbitrary ..._TYPE tree node, return a debugging
    entry that chains the modifiers specified by CV_QUALS in front of the
    given type.  REVERSE is true if the type is to be interpreted in the
@@ -23016,6 +23045,9 @@ gen_formal_parameter_die (tree node, tree origin, bool emit_name_p,
       gcc_unreachable ();
     }
 
+  /* Handle any attribute btf_decl_tag on the decl.  */
+  gen_btf_decl_tag_dies (node, parm_die);
+
   return parm_die;
 }
 
@@ -27170,6 +27202,9 @@ gen_decl_die (tree decl, tree origin, struct vlr_context *ctx,
       break;
     }
 
+  /* Handle any attribute btf_decl_tag on the decl.  */
+  gen_btf_decl_tag_dies (decl_or_origin, lookup_decl_die (decl_or_origin));
+
   return NULL;
 }
 \f
-- 
2.40.1


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 4/9] dwarf: expose get_die_parent
  2023-07-11 21:57 [PATCH 0/9] Add btf_decl_tag C attribute David Faust
                   ` (2 preceding siblings ...)
  2023-07-11 21:57 ` [PATCH 3/9] dwarf: create annotation DIEs for decl tags David Faust
@ 2023-07-11 21:57 ` David Faust
  2023-07-11 21:57 ` [PATCH 5/9] ctf: add support to pass through BTF tags David Faust
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 18+ messages in thread
From: David Faust @ 2023-07-11 21:57 UTC (permalink / raw)
  To: gcc-patches; +Cc: jose.marchesi, yhs

Expose get_die_parent () so it can be used outside of dwarf2out.cc

gcc/

	* dwarf2out.cc (get_die_parent): Make non-static.
	* dwarf2out.h (get_die_parent): Add extern declaration here.
---
 gcc/dwarf2out.cc | 2 +-
 gcc/dwarf2out.h  | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
index c8c34db2b5a..ba6d91f95cf 100644
--- a/gcc/dwarf2out.cc
+++ b/gcc/dwarf2out.cc
@@ -5457,7 +5457,7 @@ get_AT (dw_die_ref die, enum dwarf_attribute attr_kind)
 
 /* Returns the parent of the declaration of DIE.  */
 
-static dw_die_ref
+dw_die_ref
 get_die_parent (dw_die_ref die)
 {
   dw_die_ref t;
diff --git a/gcc/dwarf2out.h b/gcc/dwarf2out.h
index 870b56a6a37..3be918edc21 100644
--- a/gcc/dwarf2out.h
+++ b/gcc/dwarf2out.h
@@ -453,6 +453,7 @@ extern dw_die_ref base_type_die (tree, bool);
 extern dw_die_ref lookup_decl_die (tree);
 extern dw_die_ref lookup_type_die (tree);
 
+extern dw_die_ref get_die_parent (dw_die_ref);
 extern dw_die_ref dw_get_die_child (dw_die_ref);
 extern dw_die_ref dw_get_die_sib (dw_die_ref);
 extern enum dwarf_tag dw_get_die_tag (dw_die_ref);
-- 
2.40.1


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 5/9] ctf: add support to pass through BTF tags
  2023-07-11 21:57 [PATCH 0/9] Add btf_decl_tag C attribute David Faust
                   ` (3 preceding siblings ...)
  2023-07-11 21:57 ` [PATCH 4/9] dwarf: expose get_die_parent David Faust
@ 2023-07-11 21:57 ` David Faust
  2023-07-11 21:57 ` [PATCH 6/9] dwarf2ctf: convert annotation DIEs to CTF types David Faust
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 18+ messages in thread
From: David Faust @ 2023-07-11 21:57 UTC (permalink / raw)
  To: gcc-patches; +Cc: jose.marchesi, yhs

BTF generation currently relies on the internal CTF representation to
convert debug info from DWARF dies. This patch adds a new internal
header, "ctf-int.h", which defines CTF kinds to be used internally to
represent BTF tags which must pass through the CTF container. It also
adds a new type for representing information specific to those tags, and
a member for that type in struct ctf_dtdef.

This patch also updates ctf_add_reftype to accept a const char * name,
and add it for the newly added type.

gcc/

	* ctf-int.h: New file.
	* ctfc.h: Include ctf-int.h.
	(struct ctf_btf_annotation): New.
	(struct ctf_dtdef): Add dtu_btfnote member to dtd_u union.
	(enum ctf_dtu_d_union_enum): Add CTF_DTU_D_BTFNOTE.
	(ctf_add_reftype): Add name argument.
	* ctfc.cc (ctf_dtu_d_union_selector): Handle CTFC_INT_K_DECL_TAG.
	(ctf_add_reftype): Add name argument. Pass it to ctf_add_generic.
	(ctf_add_pointer): Update ctf_add_reftype call.
	* btfout.cc (btf_init_postprocess): Update ctf_add_reftype call.
	* dwarf2ctf.cc (gen_ctf_modifier_type): Update ctf_add_reftype call.
---
 gcc/btfout.cc    |  2 +-
 gcc/ctf-int.h    | 28 ++++++++++++++++++++++++++++
 gcc/ctfc.cc      | 10 ++++++----
 gcc/ctfc.h       | 17 ++++++++++++++---
 gcc/dwarf2ctf.cc |  2 +-
 5 files changed, 50 insertions(+), 9 deletions(-)
 create mode 100644 gcc/ctf-int.h

diff --git a/gcc/btfout.cc b/gcc/btfout.cc
index e07fed302c2..e6acf4e51a5 100644
--- a/gcc/btfout.cc
+++ b/gcc/btfout.cc
@@ -1302,7 +1302,7 @@ btf_init_postprocess (void)
 
 	  /* Create the 'const' modifier type for void.  */
 	  if (constvoid_id == CTF_NULL_TYPEID)
-	    constvoid_id = ctf_add_reftype (tu_ctfc, CTF_ADD_ROOT,
+	    constvoid_id = ctf_add_reftype (tu_ctfc, CTF_ADD_ROOT, NULL,
 					    dvd->dvd_type, CTF_K_CONST, NULL);
 	  dvd->dvd_type = constvoid_id;
 	}
diff --git a/gcc/ctf-int.h b/gcc/ctf-int.h
new file mode 100644
index 00000000000..d5586248f11
--- /dev/null
+++ b/gcc/ctf-int.h
@@ -0,0 +1,28 @@
+/* ctf-int.h - GCC internal definitions used for CTF debug info.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#ifndef GCC_CTF_INT_H
+#define GCC_CTF_INT_H 1
+
+/* This CTF kind exists only as a bridge to generating BTF types for
+   BTF_KIND_DECL_TAG.  It does not correspond to any representable type
+   kind in CTF.  */
+#define CTFC_INT_K_DECL_TAG  63
+
+#endif  /* GCC_CTF_INT_H */
diff --git a/gcc/ctfc.cc b/gcc/ctfc.cc
index ee569b12ac6..ccf090d0567 100644
--- a/gcc/ctfc.cc
+++ b/gcc/ctfc.cc
@@ -107,6 +107,8 @@ ctf_dtu_d_union_selector (ctf_dtdef_ref ctftype)
       return CTF_DTU_D_ARGUMENTS;
     case CTF_K_SLICE:
       return CTF_DTU_D_SLICE;
+    case CTFC_INT_K_DECL_TAG:
+      return CTF_DTU_D_BTFNOTE;
     default:
       /* The largest member as default.  */
       return CTF_DTU_D_ARRAY;
@@ -428,15 +430,15 @@ ctf_add_encoded (ctf_container_ref ctfc, uint32_t flag, const char * name,
 }
 
 ctf_id_t
-ctf_add_reftype (ctf_container_ref ctfc, uint32_t flag, ctf_id_t ref,
-		 uint32_t kind, dw_die_ref die)
+ctf_add_reftype (ctf_container_ref ctfc, uint32_t flag, const char * name,
+		 ctf_id_t ref, uint32_t kind, dw_die_ref die)
 {
   ctf_dtdef_ref dtd;
   ctf_id_t type;
 
   gcc_assert (ref <= CTF_MAX_TYPE);
 
-  type = ctf_add_generic (ctfc, flag, NULL, &dtd, die);
+  type = ctf_add_generic (ctfc, flag, name, &dtd, die);
   dtd->dtd_data.ctti_info = CTF_TYPE_INFO (kind, flag, 0);
   /* Caller of this API must guarantee that a CTF type with id = ref already
      exists.  This will also be validated for us at link-time.  */
@@ -548,7 +550,7 @@ ctf_id_t
 ctf_add_pointer (ctf_container_ref ctfc, uint32_t flag, ctf_id_t ref,
 		 dw_die_ref die)
 {
-  return (ctf_add_reftype (ctfc, flag, ref, CTF_K_POINTER, die));
+  return (ctf_add_reftype (ctfc, flag, NULL, ref, CTF_K_POINTER, die));
 }
 
 ctf_id_t
diff --git a/gcc/ctfc.h b/gcc/ctfc.h
index bf1841a7fcb..b9c6a44545b 100644
--- a/gcc/ctfc.h
+++ b/gcc/ctfc.h
@@ -35,6 +35,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "dwarf2ctf.h"
 #include "ctf.h"
 #include "btf.h"
+#include "ctf-int.h"
 
 /* Invalid CTF type ID definition.  */
 
@@ -151,6 +152,13 @@ typedef struct GTY (()) ctf_func_arg
 
 #define ctf_farg_list_next(elem) ((ctf_func_arg_t *)((elem)->farg_next))
 
+/* BTF support: a BTF type tag or decl tag.  */
+
+typedef struct GTY (()) ctf_btf_annotation
+{
+  uint32_t component_idx;
+} ctf_btf_annotation_t;
+
 /* Type definition for CTF generation.  */
 
 struct GTY ((for_user)) ctf_dtdef
@@ -175,6 +183,8 @@ struct GTY ((for_user)) ctf_dtdef
     ctf_func_arg_t * GTY ((tag ("CTF_DTU_D_ARGUMENTS"))) dtu_argv;
     /* slice.  */
     ctf_sliceinfo_t GTY ((tag ("CTF_DTU_D_SLICE"))) dtu_slice;
+    /* btf annotation.  */
+    ctf_btf_annotation_t GTY ((tag ("CTF_DTU_D_BTFNOTE"))) dtu_btfnote;
   } dtd_u;
 };
 
@@ -214,7 +224,8 @@ enum ctf_dtu_d_union_enum {
   CTF_DTU_D_ARRAY,
   CTF_DTU_D_ENCODING,
   CTF_DTU_D_ARGUMENTS,
-  CTF_DTU_D_SLICE
+  CTF_DTU_D_SLICE,
+  CTF_DTU_D_BTFNOTE
 };
 
 enum ctf_dtu_d_union_enum
@@ -404,8 +415,8 @@ extern bool ctf_dvd_ignore_lookup (const ctf_container_ref ctfc,
 extern const char * ctf_add_string (ctf_container_ref, const char *,
 				    uint32_t *, int);
 
-extern ctf_id_t ctf_add_reftype (ctf_container_ref, uint32_t, ctf_id_t,
-				 uint32_t, dw_die_ref);
+extern ctf_id_t ctf_add_reftype (ctf_container_ref, uint32_t, const char *,
+				 ctf_id_t, uint32_t, dw_die_ref);
 extern ctf_id_t ctf_add_enum (ctf_container_ref, uint32_t, const char *,
 			      HOST_WIDE_INT, bool, dw_die_ref);
 extern ctf_id_t ctf_add_slice (ctf_container_ref, uint32_t, ctf_id_t,
diff --git a/gcc/dwarf2ctf.cc b/gcc/dwarf2ctf.cc
index b2945713036..549b0cb2dc1 100644
--- a/gcc/dwarf2ctf.cc
+++ b/gcc/dwarf2ctf.cc
@@ -511,7 +511,7 @@ gen_ctf_modifier_type (ctf_container_ref ctfc, dw_die_ref modifier)
   gcc_assert (kind != CTF_K_MAX);
   /* Now register the modifier itself.  */
   if (!ctf_type_exists (ctfc, modifier, &modifier_type_id))
-    modifier_type_id = ctf_add_reftype (ctfc, CTF_ADD_ROOT,
+    modifier_type_id = ctf_add_reftype (ctfc, CTF_ADD_ROOT, NULL,
 					qual_type_id, kind,
 					modifier);
 
-- 
2.40.1


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 6/9] dwarf2ctf: convert annotation DIEs to CTF types
  2023-07-11 21:57 [PATCH 0/9] Add btf_decl_tag C attribute David Faust
                   ` (4 preceding siblings ...)
  2023-07-11 21:57 ` [PATCH 5/9] ctf: add support to pass through BTF tags David Faust
@ 2023-07-11 21:57 ` David Faust
  2023-07-11 21:57 ` [PATCH 7/9] btf: create and output BTF_KIND_DECL_TAG types David Faust
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 18+ messages in thread
From: David Faust @ 2023-07-11 21:57 UTC (permalink / raw)
  To: gcc-patches; +Cc: jose.marchesi, yhs

This patch makes the DWARF-to-CTF conversion process aware of the new
DW_TAG_GNU_annotation DIEs. The DIEs are converted to CTF_K_DECL_TAG
types and added to the compilation unit CTF container to be translated
to BTF and output.

gcc/

	* dwarf2ctf.cc (handle_btf_tags): New function.
	(gen_ctf_sou_type): Don't try to create member types for children which
	are not DW_TAG_member. Call handle_btf_tags if appropriate.
	(gen_ctf_function_type): Call handle_btf_tags if appropriate.
	(gen_ctf_variable): Likewise.
	(gen_ctf_type): Likewise.
---
 gcc/dwarf2ctf.cc | 71 +++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 70 insertions(+), 1 deletion(-)

diff --git a/gcc/dwarf2ctf.cc b/gcc/dwarf2ctf.cc
index 549b0cb2dc1..b051aef45a8 100644
--- a/gcc/dwarf2ctf.cc
+++ b/gcc/dwarf2ctf.cc
@@ -32,6 +32,9 @@ along with GCC; see the file COPYING3.  If not see
 static ctf_id_t
 gen_ctf_type (ctf_container_ref, dw_die_ref);
 
+static void
+handle_btf_tags (ctf_container_ref, dw_die_ref, ctf_id_t, int);
+
 /* All the DIE structures we handle come from the DWARF information
    generated by GCC.  However, there are three situations where we need
    to create our own created DIE structures because GCC doesn't
@@ -547,6 +550,7 @@ gen_ctf_sou_type (ctf_container_ref ctfc, dw_die_ref sou, uint32_t kind)
   /* Now process the struct members.  */
   {
     dw_die_ref c;
+    int idx = 0;
 
     c = dw_get_die_child (sou);
     if (c)
@@ -559,6 +563,9 @@ gen_ctf_sou_type (ctf_container_ref ctfc, dw_die_ref sou, uint32_t kind)
 
 	  c = dw_get_die_sib (c);
 
+	  if (dw_get_die_tag (c) != DW_TAG_member)
+	    continue;
+
 	  field_name = get_AT_string (c, DW_AT_name);
 	  field_type = ctf_get_AT_type (c);
 	  field_location = ctf_get_AT_data_member_location (c);
@@ -626,6 +633,12 @@ gen_ctf_sou_type (ctf_container_ref ctfc, dw_die_ref sou, uint32_t kind)
 				 field_name,
 				 field_type_id,
 				 field_location);
+
+	  /* Handle BTF tags on the member.  */
+	  if (btf_debuginfo_p ())
+	    handle_btf_tags (ctfc, c, sou_type_id, idx);
+
+	  idx++;
 	}
       while (c != dw_get_die_child (sou));
   }
@@ -718,6 +731,9 @@ gen_ctf_function_type (ctf_container_ref ctfc, dw_die_ref function,
 	      arg_type = gen_ctf_type (ctfc, ctf_get_AT_type (c));
 	      /* Add the argument to the existing CTF function type.  */
 	      ctf_add_function_arg (ctfc, function, arg_name, arg_type);
+
+	      if (btf_debuginfo_p ())
+		handle_btf_tags (ctfc, c, function_type_id, i - 1);
 	    }
 	  else
 	    /* This is a local variable.  Ignore.  */
@@ -833,6 +849,11 @@ gen_ctf_variable (ctf_container_ref ctfc, dw_die_ref die)
   /* Skip updating the number of global objects at this time.  This is updated
      later after pre-processing as some CTF variable records although
      generated now, will not be emitted later.  [PR105089].  */
+
+  /* Handle any BTF tags on the variable.  */
+  if (btf_debuginfo_p ())
+    handle_btf_tags (ctfc, die, CTF_NULL_TYPEID, -1);
+
 }
 
 /* Add a CTF function record for the given input DWARF DIE.  */
@@ -850,8 +871,13 @@ gen_ctf_function (ctf_container_ref ctfc, dw_die_ref die)
      counter.  Note that DWARF encodes function types in both
      DW_TAG_subroutine_type and DW_TAG_subprogram in exactly the same
      way.  */
-  (void) gen_ctf_function_type (ctfc, die, true /* from_global_func */);
+  function_type_id
+		= gen_ctf_function_type (ctfc, die, true /* from_global_func */);
   ctfc->ctfc_num_global_funcs += 1;
+
+  /* Handle any BTF tags on the function itself.  */
+  if (btf_debuginfo_p ())
+    handle_btf_tags (ctfc, die, function_type_id, -1);
 }
 
 /* Add CTF type record(s) for the given input DWARF DIE and return its type id.
@@ -928,6 +954,10 @@ gen_ctf_type (ctf_container_ref ctfc, dw_die_ref die)
       break;
     }
 
+  /* Handle any BTF tags on the type.  */
+  if (btf_debuginfo_p () && !unrecog_die)
+    handle_btf_tags (ctfc, die, type_id, -1);
+
   /* For all types unrepresented in CTF, use an explicit CTF type of kind
      CTF_K_UNKNOWN.  */
   if ((type_id == CTF_NULL_TYPEID) && (!unrecog_die))
@@ -936,6 +966,45 @@ gen_ctf_type (ctf_container_ref ctfc, dw_die_ref die)
   return type_id;
 }
 
+/* BTF support.  Handle any BTF tags attached to a given DIE, and generate
+   intermediate CTF types for them.  */
+
+static void
+handle_btf_tags (ctf_container_ref ctfc, dw_die_ref die, ctf_id_t type_id,
+		 int component_idx)
+{
+  dw_die_ref c;
+  const char * name = NULL;
+  const char * value = NULL;
+
+  c = dw_get_die_child (die);
+  if (c)
+    do
+      {
+	if (dw_get_die_tag (c) != DW_TAG_GNU_annotation)
+	  {
+	    c = dw_get_die_sib (c);
+	    continue;
+	  }
+
+	name = get_AT_string (c, DW_AT_name);
+
+	/* BTF decl tags add an arbitrary annotation to the thing they
+	   annotate.  The annotated thing could be a variable or a type.  */
+	if (strcmp (name, "btf_decl_tag") == 0)
+	  {
+	    value = get_AT_string (c, DW_AT_const_value);
+	    if (!ctf_type_exists (ctfc, c, NULL))
+	      (void) ctf_add_reftype (ctfc, CTF_ADD_ROOT, value,
+				      type_id, CTFC_INT_K_DECL_TAG, c);
+	    ctf_dtdef_ref dtd = ctf_dtd_lookup (ctfc, c);
+	    dtd->dtd_u.dtu_btfnote.component_idx = component_idx;
+	  }
+	c = dw_get_die_sib (c);
+      }
+    while (c != dw_get_die_child (die));
+}
+
 /* Prepare for output and write out the CTF debug information.  */
 
 static void
-- 
2.40.1


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 7/9] btf: create and output BTF_KIND_DECL_TAG types
  2023-07-11 21:57 [PATCH 0/9] Add btf_decl_tag C attribute David Faust
                   ` (5 preceding siblings ...)
  2023-07-11 21:57 ` [PATCH 6/9] dwarf2ctf: convert annotation DIEs to CTF types David Faust
@ 2023-07-11 21:57 ` David Faust
  2023-07-11 21:57 ` [PATCH 8/9] testsuite: add tests for BTF decl tags David Faust
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 18+ messages in thread
From: David Faust @ 2023-07-11 21:57 UTC (permalink / raw)
  To: gcc-patches; +Cc: jose.marchesi, yhs

This patch updates btfout.cc to be aware of BTF_KIND_DECL_TAG types and
output them appropriately.

gcc/

	* btfout.cc (funcs_map): New hash map.
	(btf_emit_preprocess): ... Initialize it here...
	(btf_collect_datasec): ... Populate it here...
	(btf_finalize): ... And free it here.
	(get_btf_kind): Handle BTF_KIND_DECL_TAG.
	(calc_num_vbytes): Likewise.
	(btf_asm_type): Likewise.
	(output_asm_btf_vlen_bytes): Likewise.
	(btf_asm_type_ref): Update comment.
---
 gcc/btfout.cc | 79 +++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 76 insertions(+), 3 deletions(-)

diff --git a/gcc/btfout.cc b/gcc/btfout.cc
index e6acf4e51a5..087d0b40e0a 100644
--- a/gcc/btfout.cc
+++ b/gcc/btfout.cc
@@ -104,6 +104,9 @@ static vec<ctf_id_t> voids;
    created. This vector holds them.  */
 static GTY (()) vec<ctf_dtdef_ref, va_gc> *funcs;
 
+/* Maps FUNC_PROTO types to the IDs of the corresponding FUNC types.  */
+static GTY (()) hash_map <ctf_dtdef_ref, unsigned> *funcs_map;
+
 /* The number of BTF variables added to the TU CTF container.  */
 static unsigned int num_vars_added = 0;
 
@@ -153,6 +156,7 @@ get_btf_kind (uint32_t ctf_kind)
     case CTF_K_VOLATILE: return BTF_KIND_VOLATILE;
     case CTF_K_CONST:    return BTF_KIND_CONST;
     case CTF_K_RESTRICT: return BTF_KIND_RESTRICT;
+    case CTFC_INT_K_DECL_TAG: return BTF_KIND_DECL_TAG;
     default:;
     }
   return BTF_KIND_UNKN;
@@ -316,6 +320,10 @@ btf_calc_num_vbytes (ctf_dtdef_ref dtd)
       vlen_bytes += vlen * sizeof (struct btf_var_secinfo);
       break;
 
+    case BTF_KIND_DECL_TAG:
+      vlen_bytes += sizeof (struct btf_decl_tag);
+      break;
+
     default:
       break;
     }
@@ -425,13 +433,15 @@ btf_collect_datasec (ctf_container_ref ctfc)
       func_dtd->dtd_data = dtd->dtd_data;
       func_dtd->dtd_data.ctti_type = dtd->dtd_type;
       func_dtd->linkage = dtd->linkage;
-      func_dtd->dtd_type = num_types_added + num_types_created;
+      /* +1 for the sentinel type not in the types map.  */
+      func_dtd->dtd_type = num_types_added + num_types_created + 1;
 
       /* Only the BTF_KIND_FUNC type actually references the name. The
 	 BTF_KIND_FUNC_PROTO is always anonymous.  */
       dtd->dtd_data.ctti_name = 0;
 
       vec_safe_push (funcs, func_dtd);
+      funcs_map->put (dtd, func_dtd->dtd_type);
       num_types_created++;
 
       /* Mark any 'extern' funcs and add DATASEC entries for them.  */
@@ -449,7 +459,7 @@ btf_collect_datasec (ctf_container_ref ctfc)
 	  struct btf_var_secinfo info;
 
 	  /* +1 for the sentinel type not in the types map.  */
-	  info.type = func_dtd->dtd_type + 1;
+	  info.type = func_dtd->dtd_type;
 
 	  /* Both zero at compile time.  */
 	  info.size = 0;
@@ -653,6 +663,7 @@ btf_emit_preprocess (ctf_container_ref ctfc)
     }
 
   btf_var_ids = hash_map<ctf_dvdef_ref, unsigned int>::create_ggc (100);
+  funcs_map = hash_map<ctf_dtdef_ref, unsigned int>::create_ggc (100);
 
   if (num_ctf_vars)
     {
@@ -709,7 +720,8 @@ btf_asm_type_ref (const char *prefix, ctf_container_ref ctfc, ctf_id_t ref_id)
   else if (ref_id >= num_types_added + 1
 	   && ref_id < num_types_added + num_vars_added + 1)
     {
-      /* Ref to a variable.  Should only appear in DATASEC entries.  */
+      /* Ref to a variable.
+	 Should only appear in DATASEC entries or DECL_TAGs.  */
       ctf_id_t var_id = btf_relative_var_id (ref_id);
       ctf_dvdef_ref dvd = ctfc->ctfc_vars_list[var_id];
       dw2_asm_output_data (4, ref_id, "%s: (BTF_KIND_VAR '%s')",
@@ -831,6 +843,59 @@ btf_asm_type (ctf_container_ref ctfc, ctf_dtdef_ref dtd)
 	 and should write 0.  */
       dw2_asm_output_data (4, 0, "(unused)");
       return;
+    case BTF_KIND_DECL_TAG:
+      {
+	/* A decl tag might refer to (be the child DIE of) a variable.  Try to
+	   lookup the parent DIE's CTF variable, and if it exists point to the
+	   corresponding BTF variable.  This is an odd construction - we have a
+	   'type' which refers to a variable, rather than the reverse.  */
+	dw_die_ref parent = get_die_parent (dtd->dtd_key);
+	ctf_dvdef_ref ref_dvd = ctf_dvd_lookup (ctfc, parent);
+	ctf_dtdef_ref ref_dtd = ctf_dtd_lookup (ctfc, parent);
+	if (ref_dvd)
+	  {
+	    /* The decl tag is on a variable.  */
+	    unsigned int *var_id = btf_var_ids->get (ref_dvd);
+	    gcc_assert (var_id);
+	    btf_asm_type_ref ("btt_type", ctfc,
+			      btf_absolute_var_id (*var_id));
+	    return;
+	  }
+	else if (ref_dtd)
+	  {
+	    /* Decl tags on functions refer to the FUNC_PROTO record as a
+	       result of how they are created.  But we want them in the output
+	       to refer to the synthesized FUNC record instead.  */
+	    unsigned int *func_id = funcs_map->get (ref_dtd);
+	    gcc_assert (func_id);
+	    btf_asm_type_ref ("btt_type", ctfc, *func_id);
+	    return;
+	  }
+	else if (parent && dw_get_die_tag (parent) == DW_TAG_formal_parameter)
+	  {
+	    /* The decl tag is on a function argument.  In this case we refer
+	       to the FUNC record, and component_index indicates to which
+	       parameter the tag applies.  */
+	    ref_dtd = ctf_dtd_lookup (ctfc, get_die_parent (parent));
+	    unsigned int *func_id = funcs_map->get (ref_dtd);
+	    gcc_assert (func_id);
+	    btf_asm_type_ref ("btt_type", ctfc, *func_id);
+	    return;
+	  }
+	else if (parent && dw_get_die_tag (parent) == DW_TAG_member)
+	  {
+	    /* The decl tag is on a struct/union member.  In this case we refer
+	       to the struct/union record, and component_index indicates to
+	       which member the tag applies.  */
+	    ref_dtd = ctf_dtd_lookup (ctfc, get_die_parent (parent));
+	    ctf_id_t ref_id = get_btf_id (ref_dtd->dtd_type);
+	    btf_asm_type_ref ("btt_type", ctfc, ref_id);
+	    return;
+	  }
+
+	/* There are no other valid places for decl tag to appear.  */
+	gcc_unreachable ();
+      }
     default:
       break;
     }
@@ -1177,6 +1242,11 @@ output_asm_btf_vlen_bytes (ctf_container_ref ctfc, ctf_dtdef_ref dtd)
 	 at this point.  */
       gcc_unreachable ();
 
+    case BTF_KIND_DECL_TAG:
+      dw2_asm_output_data (4, dtd->dtd_u.dtu_btfnote.component_idx,
+			   "decltag_compidx");
+      break;
+
     default:
       /* All other BTF type kinds have no variable length data.  */
       break;
@@ -1384,6 +1454,9 @@ btf_finalize (void)
   btf_var_ids->empty ();
   btf_var_ids = NULL;
 
+  funcs_map->empty ();
+  funcs_map = NULL;
+
   free (btf_id_map);
   btf_id_map = NULL;
 
-- 
2.40.1


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 8/9] testsuite: add tests for BTF decl tags
  2023-07-11 21:57 [PATCH 0/9] Add btf_decl_tag C attribute David Faust
                   ` (6 preceding siblings ...)
  2023-07-11 21:57 ` [PATCH 7/9] btf: create and output BTF_KIND_DECL_TAG types David Faust
@ 2023-07-11 21:57 ` David Faust
  2023-07-11 21:57 ` [PATCH 9/9] doc: document btf_decl_tag attribute David Faust
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 18+ messages in thread
From: David Faust @ 2023-07-11 21:57 UTC (permalink / raw)
  To: gcc-patches; +Cc: jose.marchesi, yhs

This patch adds tests for the btf_decl_tag attribute, in both DWARF
and BTF.

gcc/testsuite/

	* gcc.dg/debug/btf/btf-decltag-func.c: New test.
	* gcc.dg/debug/btf/btf-decltag-sou.c: New test.
	* gcc.dg/debug/btf/btf-decltag-var.c: New test.
	* gcc.dg/debug/dwarf2/annotation-decl-1.c: New test.
	* gcc.dg/debug/dwarf2/annotation-decl-2.c: New test.
	* gcc.dg/debug/dwarf2/annotation-decl-3.c: New test.
---
 .../gcc.dg/debug/btf/btf-decltag-func.c       | 21 ++++++++++++
 .../gcc.dg/debug/btf/btf-decltag-sou.c        | 33 +++++++++++++++++++
 .../gcc.dg/debug/btf/btf-decltag-var.c        | 19 +++++++++++
 .../gcc.dg/debug/dwarf2/annotation-decl-1.c   |  9 +++++
 .../gcc.dg/debug/dwarf2/annotation-decl-2.c   | 18 ++++++++++
 .../gcc.dg/debug/dwarf2/annotation-decl-3.c   | 17 ++++++++++
 6 files changed, 117 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-decltag-func.c
 create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-decltag-sou.c
 create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-decltag-var.c
 create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/annotation-decl-1.c
 create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/annotation-decl-2.c
 create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/annotation-decl-3.c

diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-decltag-func.c b/gcc/testsuite/gcc.dg/debug/btf/btf-decltag-func.c
new file mode 100644
index 00000000000..12a5eff9ac7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/btf/btf-decltag-func.c
@@ -0,0 +1,21 @@
+/* { dg-do compile }  */
+/* { dg-options "-O0 -gbtf -dA" } */
+
+#define __tag1 __attribute__((btf_decl_tag("decl-tag-1")))
+#define __tag2 __attribute__((btf_decl_tag("decl-tag-2")))
+#define __tag3 __attribute__((btf_decl_tag("decl-tag-3")))
+
+extern int bar (int __tag1, int __tag2) __tag3;
+
+int __tag1 __tag2 foo (int arg1, int *arg2 __tag2)
+  {
+    return bar (arg1 + 1, *arg2 + 2);
+  }
+
+/* { dg-final { scan-assembler-times "\[\t \]0x11000000\[\t \]+\[^\n\]*btt_info" 4 } } */
+/* { dg-final { scan-assembler-times "\[\t \]0xffffffff\[\t \]+\[^\n\]*decltag_compidx" 3 } } */
+/* { dg-final { scan-assembler-times "\[\t \]0x1\[\t \]+\[^\n\]*decltag_compidx" 1 } } */
+
+/* { dg-final { scan-assembler-times " BTF_KIND_DECL_TAG 'decl-tag-1'\[\\r\\n\]+\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\\(BTF_KIND_FUNC" 1 } } */
+/* { dg-final { scan-assembler-times " BTF_KIND_DECL_TAG 'decl-tag-2'\[\\r\\n\]+\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\\(BTF_KIND_FUNC" 2 } } */
+/* { dg-final { scan-assembler-times " BTF_KIND_DECL_TAG 'decl-tag-3'\[\\r\\n\]+\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\\(BTF_KIND_FUNC" 1 } } */
diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-decltag-sou.c b/gcc/testsuite/gcc.dg/debug/btf/btf-decltag-sou.c
new file mode 100644
index 00000000000..13c9f075b1e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/btf/btf-decltag-sou.c
@@ -0,0 +1,33 @@
+
+/* { dg-do compile )  */
+/* { dg-options "-O0 -gbtf -dA" } */
+
+/* { dg-final { scan-assembler-times "\[\t \]0x11000000\[\t \]+\[^\n\]*btt_info" 13 } } */
+/* { dg-final { scan-assembler-times "\[\t \]0\[\t \]+\[^\n\]*decltag_compidx" 2 } } */
+/* { dg-final { scan-assembler-times "\[\t \]0x1\[\t \]+\[^\n\]*decltag_compidx" 1 } } */
+/* { dg-final { scan-assembler-times "\[\t \]0x2\[\t \]+\[^\n\]*decltag_compidx" 3 } } */
+/* { dg-final { scan-assembler-times "\[\t \]0x3\[\t \]+\[^\n\]*decltag_compidx" 3 } } */
+/* { dg-final { scan-assembler-times "\[\t \]0x4\[\t \]+\[^\n\]*decltag_compidx" 1 } } */
+/* { dg-final { scan-assembler-times "\[\t \]0xffffffff\[\t \]+\[^\n\]*decltag_compidx" 3 } } */
+
+#define __tag1 __attribute__((btf_decl_tag("decl-tag-1")))
+#define __tag2 __attribute__((btf_decl_tag("decl-tag-2")))
+#define __tag3 __attribute__((btf_decl_tag("decl-tag-3")))
+
+struct t {
+  int a;
+  long b __tag3;
+  char c __tag2 __tag3;
+};
+
+struct t my_t __tag1 __tag2;
+
+union u {
+  char one __tag1 __tag2;
+  short two;
+  int three __tag1;
+  long four __tag1 __tag2 __tag3;
+  long long five __tag2;
+};
+
+union u my_u __tag3;
diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-decltag-var.c b/gcc/testsuite/gcc.dg/debug/btf/btf-decltag-var.c
new file mode 100644
index 00000000000..563e8838f1a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/btf/btf-decltag-var.c
@@ -0,0 +1,19 @@
+/* { dg-do compile }  */
+/* { dg-options "-O0 -gbtf -dA" } */
+
+unsigned long u __attribute__((btf_decl_tag ("__u")));
+
+const int * c __attribute__((btf_decl_tag ("__c"), btf_decl_tag ("devicemem")));
+
+struct st
+{
+  int a;
+  char c;
+};
+
+struct st my_st __attribute__((btf_decl_tag ("__my_st")));
+
+/* { dg-final { scan-assembler-times " BTF_KIND_DECL_TAG '__u'\[\\r\\n\]+\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\\(BTF_KIND_VAR 'u'" 1 } } */
+/* { dg-final { scan-assembler-times " BTF_KIND_DECL_TAG '__c'\[\\r\\n\]+\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\\(BTF_KIND_VAR 'c'" 1 } } */
+/* { dg-final { scan-assembler-times " BTF_KIND_DECL_TAG 'devicemem'\[\\r\\n\]+\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\\(BTF_KIND_VAR 'c'" 1 } } */
+/* { dg-final { scan-assembler-times " BTF_KIND_DECL_TAG '__my_st'\[\\r\\n\]+\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\\(BTF_KIND_VAR 'my_st'" 1 } } */
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/annotation-decl-1.c b/gcc/testsuite/gcc.dg/debug/dwarf2/annotation-decl-1.c
new file mode 100644
index 00000000000..d5af2188098
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/annotation-decl-1.c
@@ -0,0 +1,9 @@
+/* Test simple generation of decl tag annotations.  */
+/* { dg-do compile } */
+/* { dg-options "-O0 -gdwarf -dA" } */
+
+int *p __attribute__((btf_decl_tag ("p_decl")));
+
+/* { dg-final { scan-assembler-times "DIE \\(\[^\n\]*\\) DW_TAG_GNU_annotation" 1 } } */
+/* { dg-final { scan-assembler-times " DW_AT_name: \"btf_decl_tag\"" 1 } } */
+/* { dg-final { scan-assembler-times " DW_AT_const_value: \"p_decl\"" 1 } } */
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/annotation-decl-2.c b/gcc/testsuite/gcc.dg/debug/dwarf2/annotation-decl-2.c
new file mode 100644
index 00000000000..10f2dbc5def
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/annotation-decl-2.c
@@ -0,0 +1,18 @@
+/* Test generation of decl tag annotation DIEs for structs.  */
+/* { dg-do compile } */
+/* { dg-options "-O0 -gdwarf -dA" } */
+
+struct st {
+  int a __attribute__((btf_decl_tag("__st_a")));
+  char b;
+  int *c __attribute__((btf_decl_tag("__st_c_1"), btf_decl_tag("__st_c_2")));
+};
+
+struct st my_st __attribute__((btf_decl_tag ("__my_st")));
+
+/* { dg-final { scan-assembler-times "DIE \\(\[^\n\]*\\) DW_TAG_GNU_annotation" 4 } } */
+/* { dg-final { scan-assembler-times " DW_AT_name: \"btf_decl_tag\"" 4 } } */
+/* { dg-final { scan-assembler-times " DW_AT_const_value: \"__st_a\"" 1 } } */
+/* { dg-final { scan-assembler-times " DW_AT_const_value: \"__st_c_1\"" 1 } } */
+/* { dg-final { scan-assembler-times " DW_AT_const_value: \"__st_c_2\"" 1 } } */
+/* { dg-final { scan-assembler-times " DW_AT_const_value: \"__my_st\"" 1 } } */
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/annotation-decl-3.c b/gcc/testsuite/gcc.dg/debug/dwarf2/annotation-decl-3.c
new file mode 100644
index 00000000000..e006548fa25
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/annotation-decl-3.c
@@ -0,0 +1,17 @@
+/* Test generation of decl tag annotation DIEs for functions and func args.  */
+/* { dg-do compile } */
+/* { dg-options "-O0 -gdwarf -dA" } */
+
+extern int bar (int, int) __attribute__((btf_decl_tag ("__bar_func")));
+
+int __attribute__((btf_decl_tag ("__foo_func")))
+foo (int arg1, int *arg2 __attribute__((btf_decl_tag ("__foo_arg2"))))
+{
+  return bar (arg1 + 1, *arg2 + 2);
+}
+
+/* { dg-final { scan-assembler-times "DIE \\(\[^\n\]*\\) DW_TAG_GNU_annotation" 3 } } */
+/* { dg-final { scan-assembler-times " DW_AT_name: \"btf_decl_tag\"" 3 } } */
+/* { dg-final { scan-assembler-times " DW_AT_const_value: \"__foo_func\"" 1 } } */
+/* { dg-final { scan-assembler-times " DW_AT_const_value: \"__foo_arg2\"" 1 } } */
+/* { dg-final { scan-assembler-times " DW_AT_const_value: \"__bar_func\"" 1 } } */
-- 
2.40.1


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 9/9] doc: document btf_decl_tag attribute
  2023-07-11 21:57 [PATCH 0/9] Add btf_decl_tag C attribute David Faust
                   ` (7 preceding siblings ...)
  2023-07-11 21:57 ` [PATCH 8/9] testsuite: add tests for BTF decl tags David Faust
@ 2023-07-11 21:57 ` David Faust
  2023-07-12  7:38 ` [PATCH 0/9] Add btf_decl_tag C attribute Richard Biener
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 18+ messages in thread
From: David Faust @ 2023-07-11 21:57 UTC (permalink / raw)
  To: gcc-patches; +Cc: jose.marchesi, yhs

Add documentation for the btf_decl_tag attribute.

gcc/

	* doc/extend.texi (Common Function Attributes): Document btf_decl_tag.
	(Common Variable Attributes): Likewise.
---
 gcc/doc/extend.texi | 47 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index d88fd75e06e..57923621c46 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -2856,6 +2856,29 @@ declares that @code{my_alloc1} returns 16-byte aligned pointers and
 that @code{my_alloc2} returns a pointer whose value modulo 32 is equal
 to 8.
 
+@cindex @code{btf_decl_tag} function attribute
+@item btf_type_tag (@var{argument})
+The @code{btf_decl_tag} attribute may be used to associate (to ``tag'')
+function declarations with arbitrary strings.  Debugging information will
+be emitted to associate the @var{argument} string with the attributed function.
+In DWARF, a @code{DW_TAG_GNU_annotation} DIE will be emitted in the DWARF
+information as a child of the DIE for the function and holding the
+@var{argument} string.  In BTF, a @code{BTF_KIND_DECL_TAG} record is emitted
+in the .BTF ELF section.
+
+For example
+
+@smallexample
+extern int bar (char, int) __attribute__((btf_decl_tag("for_user")))
+@end smallexample
+
+associates the string ``for_user'' to the function ``bar''. This
+string will be recorded in the BTF and/or DWARF information associated
+with the function.
+
+The @code{btf_decl_tag} attribute can also be used on variables
+(@pxref{Common Variable Attributes})  and field declarations.
+
 @cindex @code{cold} function attribute
 @item cold
 The @code{cold} attribute on functions is used to inform the compiler that
@@ -7570,6 +7593,30 @@ This warning can be disabled by @option{-Wno-if-not-aligned}.
 The @code{warn_if_not_aligned} attribute can also be used for types
 (@pxref{Common Type Attributes}.)
 
+@cindex @code{btf_decl_tag} variable attribute
+@item btf_decl_tag (@var{argument})
+The @code{btf_decl_tag} attribute may be used to associate (to ``tag'')
+variable declarations with arbitrary strings.  Debugging information will
+be emitted to associate the @var{argument} string with the attributed variable.
+In DWARF, a @code{DW_TAG_GNU_annotation} DIE will be emitted in the DWARF
+information as a child of the DIE for the variable and holding the
+@var{argument} string.  In BTF, a @code{BTF_KIND_DECL_TAG} record is emitted
+in the .BTF ELF section.
+
+For example
+
+@smallexample
+int * foo __attribute__((btf_decl_tag("user")));
+@end smallexample
+
+@noindent
+associates the string ``user'' to the variable ``foo''. This string
+will be recorded in the BTF and/or DWARF information associated with
+the variable.
+
+The @code{btf_decl_tag} attribute can also be used on functions
+(@pxref{Common Function Attributes}) and field declarations.
+
 @cindex @code{strict_flex_array} variable attribute
 @item strict_flex_array (@var{level})
 The @code{strict_flex_array} attribute should be attached to the trailing
-- 
2.40.1


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 0/9] Add btf_decl_tag C attribute
  2023-07-11 21:57 [PATCH 0/9] Add btf_decl_tag C attribute David Faust
                   ` (8 preceding siblings ...)
  2023-07-11 21:57 ` [PATCH 9/9] doc: document btf_decl_tag attribute David Faust
@ 2023-07-12  7:38 ` Richard Biener
  2023-07-12 12:43   ` Jose E. Marchesi
  2023-07-24 15:56 ` David Faust
                   ` (2 subsequent siblings)
  12 siblings, 1 reply; 18+ messages in thread
From: Richard Biener @ 2023-07-12  7:38 UTC (permalink / raw)
  To: David Faust; +Cc: gcc-patches, jose.marchesi, yhs

On Tue, Jul 11, 2023 at 11:58 PM David Faust via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> Hello,
>
> This series adds support for a new attribute, "btf_decl_tag" in GCC.
> The same attribute is already supported in clang, and is used by various
> components of the BPF ecosystem.
>
> The purpose of the attribute is to allow to associate (to "tag")
> declarations with arbitrary string annotations, which are emitted into
> debugging information (DWARF and/or BTF) to facilitate post-compilation
> analysis (the motivating use case being the Linux kernel BPF verifier).
> Multiple tags are allowed on the same declaration.
>
> These strings are not interpreted by the compiler, and the attribute
> itself has no effect on generated code, other than to produce additional
> DWARF DIEs and/or BTF records conveying the annotations.
>
> This entails:
>
> - A new C-language-level attribute which allows to associate (to "tag")
>   particular declarations with arbitrary strings.
>
> - The conveyance of that information in DWARF in the form of a new DIE,
>   DW_TAG_GNU_annotation, with tag number (0x6000) and format matching
>   that of the DW_TAG_LLVM_annotation extension supported in LLVM for
>   the same purpose. These DIEs are already supported by BPF tooling,
>   such as pahole.
>
> - The conveyance of that information in BTF debug info in the form of
>   BTF_KIND_DECL_TAG records. These records are already supported by
>   LLVM and other tools in the eBPF ecosystem, such as the Linux kernel
>   eBPF verifier.
>
>
> Background
> ==========
>
> The purpose of these tags is to convey additional semantic information
> to post-compilation consumers, in particular the Linux kernel eBPF
> verifier. The verifier can make use of that information while analyzing
> a BPF program to aid in determining whether to allow or reject the
> program to be run. More background on these tags can be found in the
> early support for them in the kernel here [1] and [2].
>
> The "btf_decl_tag" attribute is half the story; the other half is a
> sibling attribute "btf_type_tag" which serves the same purpose but
> applies to types. Support for btf_type_tag will come in a separate
> patch series, since it is impaced by GCC bug 110439 which needs to be
> addressed first.
>
> I submitted an initial version of this work (including btf_type_tag)
> last spring [3], however at the time there were some open questions
> about the behavior of the btf_type_tag attribute and issues with its
> implementation. Since then we have clarified these details and agreed
> to solutions with the BPF community and LLVM BPF folks.
>
> The main motivation for emitting the tags in DWARF is that the Linux
> kernel generates its BTF information via pahole, using DWARF as a source:
>
>     +--------+  BTF                  BTF   +----------+
>     | pahole |-------> vmlinux.btf ------->| verifier |
>     +--------+                             +----------+
>         ^                                        ^
>         |                                        |
>   DWARF |                                    BTF |
>         |                                        |
>       vmlinux                              +-------------+
>       module1.ko                           | BPF program |
>       module2.ko                           +-------------+
>         ...
>
> This is because:
>
> a)  pahole adds additional kernel-specific information into the
>     produced BTF based on additional analysis of kernel objects.
>
> b)  Unlike GCC, LLVM will only generate BTF for BPF programs.
>
> b)  GCC can generate BTF for whatever target with -gbtf, but there is no
>     support for linking/deduplicating BTF in the linker.
>
> In the scenario above, the verifier needs access to the pointer tags of
> both the kernel types/declarations (conveyed in the DWARF and translated
> to BTF by pahole) and those of the BPF program (available directly in BTF).
>
>
> DWARF Representation
> ====================
>
> As noted above, btf_decl_tag is represented in DWARF via a new DIE
> DW_TAG_GNU_annotation, with identical format to the LLVM DWARF
> extension DW_TAG_LLVM_annotation serving the same purpose. The DIE has
> the following format:
>
>   DW_TAG_GNU_annotation (0x6000)
>     DW_AT_name: "btf_decl_tag"
>     DW_AT_const_value: <string argument>
>
> These DIEs are placed in the DWARF tree as children of the DIE for the
> appropriate declaration, and one such DIE is created for each occurrence
> of the btf_decl_tag attribute on a declaration.
>
> For example:
>
>   const int * c __attribute__((btf_decl_tag ("__c"), btf_decl_tag ("devicemem")));
>
> This declaration produces the following DWARF:
>
>  <1><1e>: Abbrev Number: 2 (DW_TAG_variable)
>     <1f>   DW_AT_name        : c
>     <24>   DW_AT_type        : <0x49>
>     ...
>  <2><36>: Abbrev Number: 3 (User TAG value: 0x6000)
>     <37>   DW_AT_name        : (indirect string, offset: 0x4c): btf_decl_tag
>     <3b>   DW_AT_const_value : (indirect string, offset: 0): devicemem
>  <2><3f>: Abbrev Number: 4 (User TAG value: 0x6000)
>     <40>   DW_AT_name        : (indirect string, offset: 0x4c): btf_decl_tag
>     <44>   DW_AT_const_value : __c
>  <2><48>: Abbrev Number: 0
>  <1><49>: Abbrev Number: 5 (DW_TAG_pointer_type)
>  ...
>
> The DIEs for btf_decl_tag are placed as children of the DIE for
> variable "c".

It looks like a bit of overkill, and inefficient as well.  Why's the
tags not referenced
via the existing DW_AT_description?  Iff you want new TAGs why require them
as children for each DIE rather than referencing (and sharing!) them via a DIE
reference from a new attribute?

That said, I'd go with DW_AT_description 'btf_decl_tag ("devicemem")'.

But well ...

Richard.

>
> BTF Representation
> ==================
>
> In BTF, BTF_KIND_DECL_TAG records convey the annotations. These records refer
> to the annotated object by BTF type ID, as well as a component index which is
> used for btf_decl_tags placed on struct/union members or function arguments.
>
> For example, the BTF for the above declaration is:
>
>   [1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED
>   [2] CONST '(anon)' type_id=1
>   [3] PTR '(anon)' type_id=2
>   [4] DECL_TAG '__c' type_id=6 component_idx=-1
>   [5] DECL_TAG 'devicemem' type_id=6 component_idx=-1
>   [6] VAR 'c' type_id=3, linkage=global
>   ...
>
> The BTF format is documented here [4].
>
>
> References
> ==========
>
> [1] https://lore.kernel.org/bpf/20210914223004.244411-1-yhs@fb.com/
> [2] https://lore.kernel.org/bpf/20211011040608.3031468-1-yhs@fb.com/
> [3] https://gcc.gnu.org/pipermail/gcc-patches/2022-May/593936.html
> [4] https://www.kernel.org/doc/Documentation/bpf/btf.rst
>
>
> David Faust (9):
>   c-family: add btf_decl_tag attribute
>   include: add BTF decl tag defines
>   dwarf: create annotation DIEs for decl tags
>   dwarf: expose get_die_parent
>   ctf: add support to pass through BTF tags
>   dwarf2ctf: convert annotation DIEs to CTF types
>   btf: create and output BTF_KIND_DECL_TAG types
>   testsuite: add tests for BTF decl tags
>   doc: document btf_decl_tag attribute
>
>  gcc/btfout.cc                                 | 81 ++++++++++++++++++-
>  gcc/c-family/c-attribs.cc                     | 23 ++++++
>  gcc/ctf-int.h                                 | 28 +++++++
>  gcc/ctfc.cc                                   | 10 ++-
>  gcc/ctfc.h                                    | 17 +++-
>  gcc/doc/extend.texi                           | 47 +++++++++++
>  gcc/dwarf2ctf.cc                              | 73 ++++++++++++++++-
>  gcc/dwarf2out.cc                              | 37 ++++++++-
>  gcc/dwarf2out.h                               |  1 +
>  .../gcc.dg/debug/btf/btf-decltag-func.c       | 21 +++++
>  .../gcc.dg/debug/btf/btf-decltag-sou.c        | 33 ++++++++
>  .../gcc.dg/debug/btf/btf-decltag-var.c        | 19 +++++
>  .../gcc.dg/debug/dwarf2/annotation-decl-1.c   |  9 +++
>  .../gcc.dg/debug/dwarf2/annotation-decl-2.c   | 18 +++++
>  .../gcc.dg/debug/dwarf2/annotation-decl-3.c   | 17 ++++
>  include/btf.h                                 | 14 +++-
>  include/dwarf2.def                            |  4 +
>  17 files changed, 437 insertions(+), 15 deletions(-)
>  create mode 100644 gcc/ctf-int.h
>  create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-decltag-func.c
>  create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-decltag-sou.c
>  create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-decltag-var.c
>  create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/annotation-decl-1.c
>  create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/annotation-decl-2.c
>  create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/annotation-decl-3.c
>
> --
> 2.40.1
>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 0/9] Add btf_decl_tag C attribute
  2023-07-12  7:38 ` [PATCH 0/9] Add btf_decl_tag C attribute Richard Biener
@ 2023-07-12 12:43   ` Jose E. Marchesi
  2023-07-12 13:21     ` Richard Biener
  0 siblings, 1 reply; 18+ messages in thread
From: Jose E. Marchesi @ 2023-07-12 12:43 UTC (permalink / raw)
  To: Richard Biener; +Cc: David Faust, gcc-patches, yhs, Eduard Zingerman


[Added Eduard Zingerman in CC, who is implementing this same feature in
 clang/llvm and also the consumer component in the kernel (pahole).]

Hi Richard.

> On Tue, Jul 11, 2023 at 11:58 PM David Faust via Gcc-patches
> <gcc-patches@gcc.gnu.org> wrote:
>>
>> Hello,
>>
>> This series adds support for a new attribute, "btf_decl_tag" in GCC.
>> The same attribute is already supported in clang, and is used by various
>> components of the BPF ecosystem.
>>
>> The purpose of the attribute is to allow to associate (to "tag")
>> declarations with arbitrary string annotations, which are emitted into
>> debugging information (DWARF and/or BTF) to facilitate post-compilation
>> analysis (the motivating use case being the Linux kernel BPF verifier).
>> Multiple tags are allowed on the same declaration.
>>
>> These strings are not interpreted by the compiler, and the attribute
>> itself has no effect on generated code, other than to produce additional
>> DWARF DIEs and/or BTF records conveying the annotations.
>>
>> This entails:
>>
>> - A new C-language-level attribute which allows to associate (to "tag")
>>   particular declarations with arbitrary strings.
>>
>> - The conveyance of that information in DWARF in the form of a new DIE,
>>   DW_TAG_GNU_annotation, with tag number (0x6000) and format matching
>>   that of the DW_TAG_LLVM_annotation extension supported in LLVM for
>>   the same purpose. These DIEs are already supported by BPF tooling,
>>   such as pahole.
>>
>> - The conveyance of that information in BTF debug info in the form of
>>   BTF_KIND_DECL_TAG records. These records are already supported by
>>   LLVM and other tools in the eBPF ecosystem, such as the Linux kernel
>>   eBPF verifier.
>>
>>
>> Background
>> ==========
>>
>> The purpose of these tags is to convey additional semantic information
>> to post-compilation consumers, in particular the Linux kernel eBPF
>> verifier. The verifier can make use of that information while analyzing
>> a BPF program to aid in determining whether to allow or reject the
>> program to be run. More background on these tags can be found in the
>> early support for them in the kernel here [1] and [2].
>>
>> The "btf_decl_tag" attribute is half the story; the other half is a
>> sibling attribute "btf_type_tag" which serves the same purpose but
>> applies to types. Support for btf_type_tag will come in a separate
>> patch series, since it is impaced by GCC bug 110439 which needs to be
>> addressed first.
>>
>> I submitted an initial version of this work (including btf_type_tag)
>> last spring [3], however at the time there were some open questions
>> about the behavior of the btf_type_tag attribute and issues with its
>> implementation. Since then we have clarified these details and agreed
>> to solutions with the BPF community and LLVM BPF folks.
>>
>> The main motivation for emitting the tags in DWARF is that the Linux
>> kernel generates its BTF information via pahole, using DWARF as a source:
>>
>>     +--------+  BTF                  BTF   +----------+
>>     | pahole |-------> vmlinux.btf ------->| verifier |
>>     +--------+                             +----------+
>>         ^                                        ^
>>         |                                        |
>>   DWARF |                                    BTF |
>>         |                                        |
>>       vmlinux                              +-------------+
>>       module1.ko                           | BPF program |
>>       module2.ko                           +-------------+
>>         ...
>>
>> This is because:
>>
>> a)  pahole adds additional kernel-specific information into the
>>     produced BTF based on additional analysis of kernel objects.
>>
>> b)  Unlike GCC, LLVM will only generate BTF for BPF programs.
>>
>> b)  GCC can generate BTF for whatever target with -gbtf, but there is no
>>     support for linking/deduplicating BTF in the linker.
>>
>> In the scenario above, the verifier needs access to the pointer tags of
>> both the kernel types/declarations (conveyed in the DWARF and translated
>> to BTF by pahole) and those of the BPF program (available directly in BTF).
>>
>>
>> DWARF Representation
>> ====================
>>
>> As noted above, btf_decl_tag is represented in DWARF via a new DIE
>> DW_TAG_GNU_annotation, with identical format to the LLVM DWARF
>> extension DW_TAG_LLVM_annotation serving the same purpose. The DIE has
>> the following format:
>>
>>   DW_TAG_GNU_annotation (0x6000)
>>     DW_AT_name: "btf_decl_tag"
>>     DW_AT_const_value: <string argument>
>>
>> These DIEs are placed in the DWARF tree as children of the DIE for the
>> appropriate declaration, and one such DIE is created for each occurrence
>> of the btf_decl_tag attribute on a declaration.
>>
>> For example:
>>
>>   const int * c __attribute__((btf_decl_tag ("__c"), btf_decl_tag ("devicemem")));
>>
>> This declaration produces the following DWARF:
>>
>>  <1><1e>: Abbrev Number: 2 (DW_TAG_variable)
>>     <1f>   DW_AT_name        : c
>>     <24>   DW_AT_type        : <0x49>
>>     ...
>>  <2><36>: Abbrev Number: 3 (User TAG value: 0x6000)
>>     <37>   DW_AT_name        : (indirect string, offset: 0x4c): btf_decl_tag
>>     <3b>   DW_AT_const_value : (indirect string, offset: 0): devicemem
>>  <2><3f>: Abbrev Number: 4 (User TAG value: 0x6000)
>>     <40>   DW_AT_name        : (indirect string, offset: 0x4c): btf_decl_tag
>>     <44>   DW_AT_const_value : __c
>>  <2><48>: Abbrev Number: 0
>>  <1><49>: Abbrev Number: 5 (DW_TAG_pointer_type)
>>  ...
>>
>> The DIEs for btf_decl_tag are placed as children of the DIE for
>> variable "c".
>
> It looks like a bit of overkill, and inefficient as well.  Why's the
> tags not referenced via the existing DW_AT_description?

The DWARF spec ("Entity Descriptions") seems to imply that the
DW_AT_description attribute is intended to be used to hold alternative
ways to denote the same "debugging information" (object, type, ...),
i.e. alternative aliases to refer to the same entity than the
DW_AT_name.  For example, for a type name='foo' we could have
description='aka. long int'.  We don't think this is the case of the btf
tags, which are more like properties partially characterizing the tagged
"debugging information", but couldn't be used as an alias to the name.

Also, repurposing the DW_AT_description attribute to hold btf tag
information would require to introduce a mini-language and subsequent
parsing by the clients: how to denote several tags, how to encode the
embedded string contents, etc.  You kick the complexity out the door and
it comes back in through the window :)

Finally, for what we know, the existing attribute may already be used by
some language and handled by some debugger the way it is recommended in
the spec.  That would be incompatible with having btf tags encoded
there.

> Iff you want new TAGs why require them as children for each DIE rather
> than referencing (and sharing!) them via a DIE reference from a new
> attribute?

Hmm, thats a very good question.  The Linux kernel sources uses both
declaration tags and type tags and not sharing the DIEs may result in
serious bloating, since the tags are brought in to declarations and type
specifiers via macros...

> That said, I'd go with DW_AT_description 'btf_decl_tag ("devicemem")'.
>
> But well ...
>
> Richard.
>
>>
>> BTF Representation
>> ==================
>>
>> In BTF, BTF_KIND_DECL_TAG records convey the annotations. These records refer
>> to the annotated object by BTF type ID, as well as a component index which is
>> used for btf_decl_tags placed on struct/union members or function arguments.
>>
>> For example, the BTF for the above declaration is:
>>
>>   [1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED
>>   [2] CONST '(anon)' type_id=1
>>   [3] PTR '(anon)' type_id=2
>>   [4] DECL_TAG '__c' type_id=6 component_idx=-1
>>   [5] DECL_TAG 'devicemem' type_id=6 component_idx=-1
>>   [6] VAR 'c' type_id=3, linkage=global
>>   ...
>>
>> The BTF format is documented here [4].
>>
>>
>> References
>> ==========
>>
>> [1] https://lore.kernel.org/bpf/20210914223004.244411-1-yhs@fb.com/
>> [2] https://lore.kernel.org/bpf/20211011040608.3031468-1-yhs@fb.com/
>> [3] https://gcc.gnu.org/pipermail/gcc-patches/2022-May/593936.html
>> [4] https://www.kernel.org/doc/Documentation/bpf/btf.rst
>>
>>
>> David Faust (9):
>>   c-family: add btf_decl_tag attribute
>>   include: add BTF decl tag defines
>>   dwarf: create annotation DIEs for decl tags
>>   dwarf: expose get_die_parent
>>   ctf: add support to pass through BTF tags
>>   dwarf2ctf: convert annotation DIEs to CTF types
>>   btf: create and output BTF_KIND_DECL_TAG types
>>   testsuite: add tests for BTF decl tags
>>   doc: document btf_decl_tag attribute
>>
>>  gcc/btfout.cc                                 | 81 ++++++++++++++++++-
>>  gcc/c-family/c-attribs.cc                     | 23 ++++++
>>  gcc/ctf-int.h                                 | 28 +++++++
>>  gcc/ctfc.cc                                   | 10 ++-
>>  gcc/ctfc.h                                    | 17 +++-
>>  gcc/doc/extend.texi                           | 47 +++++++++++
>>  gcc/dwarf2ctf.cc                              | 73 ++++++++++++++++-
>>  gcc/dwarf2out.cc                              | 37 ++++++++-
>>  gcc/dwarf2out.h                               |  1 +
>>  .../gcc.dg/debug/btf/btf-decltag-func.c       | 21 +++++
>>  .../gcc.dg/debug/btf/btf-decltag-sou.c        | 33 ++++++++
>>  .../gcc.dg/debug/btf/btf-decltag-var.c        | 19 +++++
>>  .../gcc.dg/debug/dwarf2/annotation-decl-1.c   |  9 +++
>>  .../gcc.dg/debug/dwarf2/annotation-decl-2.c   | 18 +++++
>>  .../gcc.dg/debug/dwarf2/annotation-decl-3.c   | 17 ++++
>>  include/btf.h                                 | 14 +++-
>>  include/dwarf2.def                            |  4 +
>>  17 files changed, 437 insertions(+), 15 deletions(-)
>>  create mode 100644 gcc/ctf-int.h
>>  create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-decltag-func.c
>>  create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-decltag-sou.c
>>  create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-decltag-var.c
>>  create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/annotation-decl-1.c
>>  create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/annotation-decl-2.c
>>  create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/annotation-decl-3.c
>>
>> --
>> 2.40.1
>>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 0/9] Add btf_decl_tag C attribute
  2023-07-12 12:43   ` Jose E. Marchesi
@ 2023-07-12 13:21     ` Richard Biener
  2023-07-12 13:49       ` Jose E. Marchesi
  0 siblings, 1 reply; 18+ messages in thread
From: Richard Biener @ 2023-07-12 13:21 UTC (permalink / raw)
  To: Jose E. Marchesi; +Cc: David Faust, gcc-patches, yhs, Eduard Zingerman

On Wed, Jul 12, 2023 at 2:44 PM Jose E. Marchesi
<jose.marchesi@oracle.com> wrote:
>
>
> [Added Eduard Zingerman in CC, who is implementing this same feature in
>  clang/llvm and also the consumer component in the kernel (pahole).]
>
> Hi Richard.
>
> > On Tue, Jul 11, 2023 at 11:58 PM David Faust via Gcc-patches
> > <gcc-patches@gcc.gnu.org> wrote:
> >>
> >> Hello,
> >>
> >> This series adds support for a new attribute, "btf_decl_tag" in GCC.
> >> The same attribute is already supported in clang, and is used by various
> >> components of the BPF ecosystem.
> >>
> >> The purpose of the attribute is to allow to associate (to "tag")
> >> declarations with arbitrary string annotations, which are emitted into
> >> debugging information (DWARF and/or BTF) to facilitate post-compilation
> >> analysis (the motivating use case being the Linux kernel BPF verifier).
> >> Multiple tags are allowed on the same declaration.
> >>
> >> These strings are not interpreted by the compiler, and the attribute
> >> itself has no effect on generated code, other than to produce additional
> >> DWARF DIEs and/or BTF records conveying the annotations.
> >>
> >> This entails:
> >>
> >> - A new C-language-level attribute which allows to associate (to "tag")
> >>   particular declarations with arbitrary strings.
> >>
> >> - The conveyance of that information in DWARF in the form of a new DIE,
> >>   DW_TAG_GNU_annotation, with tag number (0x6000) and format matching
> >>   that of the DW_TAG_LLVM_annotation extension supported in LLVM for
> >>   the same purpose. These DIEs are already supported by BPF tooling,
> >>   such as pahole.
> >>
> >> - The conveyance of that information in BTF debug info in the form of
> >>   BTF_KIND_DECL_TAG records. These records are already supported by
> >>   LLVM and other tools in the eBPF ecosystem, such as the Linux kernel
> >>   eBPF verifier.
> >>
> >>
> >> Background
> >> ==========
> >>
> >> The purpose of these tags is to convey additional semantic information
> >> to post-compilation consumers, in particular the Linux kernel eBPF
> >> verifier. The verifier can make use of that information while analyzing
> >> a BPF program to aid in determining whether to allow or reject the
> >> program to be run. More background on these tags can be found in the
> >> early support for them in the kernel here [1] and [2].
> >>
> >> The "btf_decl_tag" attribute is half the story; the other half is a
> >> sibling attribute "btf_type_tag" which serves the same purpose but
> >> applies to types. Support for btf_type_tag will come in a separate
> >> patch series, since it is impaced by GCC bug 110439 which needs to be
> >> addressed first.
> >>
> >> I submitted an initial version of this work (including btf_type_tag)
> >> last spring [3], however at the time there were some open questions
> >> about the behavior of the btf_type_tag attribute and issues with its
> >> implementation. Since then we have clarified these details and agreed
> >> to solutions with the BPF community and LLVM BPF folks.
> >>
> >> The main motivation for emitting the tags in DWARF is that the Linux
> >> kernel generates its BTF information via pahole, using DWARF as a source:
> >>
> >>     +--------+  BTF                  BTF   +----------+
> >>     | pahole |-------> vmlinux.btf ------->| verifier |
> >>     +--------+                             +----------+
> >>         ^                                        ^
> >>         |                                        |
> >>   DWARF |                                    BTF |
> >>         |                                        |
> >>       vmlinux                              +-------------+
> >>       module1.ko                           | BPF program |
> >>       module2.ko                           +-------------+
> >>         ...
> >>
> >> This is because:
> >>
> >> a)  pahole adds additional kernel-specific information into the
> >>     produced BTF based on additional analysis of kernel objects.
> >>
> >> b)  Unlike GCC, LLVM will only generate BTF for BPF programs.
> >>
> >> b)  GCC can generate BTF for whatever target with -gbtf, but there is no
> >>     support for linking/deduplicating BTF in the linker.
> >>
> >> In the scenario above, the verifier needs access to the pointer tags of
> >> both the kernel types/declarations (conveyed in the DWARF and translated
> >> to BTF by pahole) and those of the BPF program (available directly in BTF).
> >>
> >>
> >> DWARF Representation
> >> ====================
> >>
> >> As noted above, btf_decl_tag is represented in DWARF via a new DIE
> >> DW_TAG_GNU_annotation, with identical format to the LLVM DWARF
> >> extension DW_TAG_LLVM_annotation serving the same purpose. The DIE has
> >> the following format:
> >>
> >>   DW_TAG_GNU_annotation (0x6000)
> >>     DW_AT_name: "btf_decl_tag"
> >>     DW_AT_const_value: <string argument>
> >>
> >> These DIEs are placed in the DWARF tree as children of the DIE for the
> >> appropriate declaration, and one such DIE is created for each occurrence
> >> of the btf_decl_tag attribute on a declaration.
> >>
> >> For example:
> >>
> >>   const int * c __attribute__((btf_decl_tag ("__c"), btf_decl_tag ("devicemem")));
> >>
> >> This declaration produces the following DWARF:
> >>
> >>  <1><1e>: Abbrev Number: 2 (DW_TAG_variable)
> >>     <1f>   DW_AT_name        : c
> >>     <24>   DW_AT_type        : <0x49>
> >>     ...
> >>  <2><36>: Abbrev Number: 3 (User TAG value: 0x6000)
> >>     <37>   DW_AT_name        : (indirect string, offset: 0x4c): btf_decl_tag
> >>     <3b>   DW_AT_const_value : (indirect string, offset: 0): devicemem
> >>  <2><3f>: Abbrev Number: 4 (User TAG value: 0x6000)
> >>     <40>   DW_AT_name        : (indirect string, offset: 0x4c): btf_decl_tag
> >>     <44>   DW_AT_const_value : __c
> >>  <2><48>: Abbrev Number: 0
> >>  <1><49>: Abbrev Number: 5 (DW_TAG_pointer_type)
> >>  ...
> >>
> >> The DIEs for btf_decl_tag are placed as children of the DIE for
> >> variable "c".
> >
> > It looks like a bit of overkill, and inefficient as well.  Why's the
> > tags not referenced via the existing DW_AT_description?
>
> The DWARF spec ("Entity Descriptions") seems to imply that the
> DW_AT_description attribute is intended to be used to hold alternative
> ways to denote the same "debugging information" (object, type, ...),
> i.e. alternative aliases to refer to the same entity than the
> DW_AT_name.  For example, for a type name='foo' we could have
> description='aka. long int'.  We don't think this is the case of the btf
> tags, which are more like properties partially characterizing the tagged
> "debugging information", but couldn't be used as an alias to the name.
>
> Also, repurposing the DW_AT_description attribute to hold btf tag
> information would require to introduce a mini-language and subsequent
> parsing by the clients: how to denote several tags, how to encode the
> embedded string contents, etc.  You kick the complexity out the door and
> it comes back in through the window :)
>
> Finally, for what we know, the existing attribute may already be used by
> some language and handled by some debugger the way it is recommended in
> the spec.  That would be incompatible with having btf tags encoded
> there.

How are the C/C++ standard attributes proposed to be encoded in dwarf?
 I think adding
special encoding just for BTF tags looks wrong.

> > Iff you want new TAGs why require them as children for each DIE rather
> > than referencing (and sharing!) them via a DIE reference from a new
> > attribute?
>
> Hmm, thats a very good question.  The Linux kernel sources uses both
> declaration tags and type tags and not sharing the DIEs may result in
> serious bloating, since the tags are brought in to declarations and type
> specifiers via macros...
>
> > That said, I'd go with DW_AT_description 'btf_decl_tag ("devicemem")'.
> >
> > But well ...
> >
> > Richard.
> >
> >>
> >> BTF Representation
> >> ==================
> >>
> >> In BTF, BTF_KIND_DECL_TAG records convey the annotations. These records refer
> >> to the annotated object by BTF type ID, as well as a component index which is
> >> used for btf_decl_tags placed on struct/union members or function arguments.
> >>
> >> For example, the BTF for the above declaration is:
> >>
> >>   [1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED
> >>   [2] CONST '(anon)' type_id=1
> >>   [3] PTR '(anon)' type_id=2
> >>   [4] DECL_TAG '__c' type_id=6 component_idx=-1
> >>   [5] DECL_TAG 'devicemem' type_id=6 component_idx=-1
> >>   [6] VAR 'c' type_id=3, linkage=global
> >>   ...
> >>
> >> The BTF format is documented here [4].
> >>
> >>
> >> References
> >> ==========
> >>
> >> [1] https://lore.kernel.org/bpf/20210914223004.244411-1-yhs@fb.com/
> >> [2] https://lore.kernel.org/bpf/20211011040608.3031468-1-yhs@fb.com/
> >> [3] https://gcc.gnu.org/pipermail/gcc-patches/2022-May/593936.html
> >> [4] https://www.kernel.org/doc/Documentation/bpf/btf.rst
> >>
> >>
> >> David Faust (9):
> >>   c-family: add btf_decl_tag attribute
> >>   include: add BTF decl tag defines
> >>   dwarf: create annotation DIEs for decl tags
> >>   dwarf: expose get_die_parent
> >>   ctf: add support to pass through BTF tags
> >>   dwarf2ctf: convert annotation DIEs to CTF types
> >>   btf: create and output BTF_KIND_DECL_TAG types
> >>   testsuite: add tests for BTF decl tags
> >>   doc: document btf_decl_tag attribute
> >>
> >>  gcc/btfout.cc                                 | 81 ++++++++++++++++++-
> >>  gcc/c-family/c-attribs.cc                     | 23 ++++++
> >>  gcc/ctf-int.h                                 | 28 +++++++
> >>  gcc/ctfc.cc                                   | 10 ++-
> >>  gcc/ctfc.h                                    | 17 +++-
> >>  gcc/doc/extend.texi                           | 47 +++++++++++
> >>  gcc/dwarf2ctf.cc                              | 73 ++++++++++++++++-
> >>  gcc/dwarf2out.cc                              | 37 ++++++++-
> >>  gcc/dwarf2out.h                               |  1 +
> >>  .../gcc.dg/debug/btf/btf-decltag-func.c       | 21 +++++
> >>  .../gcc.dg/debug/btf/btf-decltag-sou.c        | 33 ++++++++
> >>  .../gcc.dg/debug/btf/btf-decltag-var.c        | 19 +++++
> >>  .../gcc.dg/debug/dwarf2/annotation-decl-1.c   |  9 +++
> >>  .../gcc.dg/debug/dwarf2/annotation-decl-2.c   | 18 +++++
> >>  .../gcc.dg/debug/dwarf2/annotation-decl-3.c   | 17 ++++
> >>  include/btf.h                                 | 14 +++-
> >>  include/dwarf2.def                            |  4 +
> >>  17 files changed, 437 insertions(+), 15 deletions(-)
> >>  create mode 100644 gcc/ctf-int.h
> >>  create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-decltag-func.c
> >>  create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-decltag-sou.c
> >>  create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-decltag-var.c
> >>  create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/annotation-decl-1.c
> >>  create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/annotation-decl-2.c
> >>  create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/annotation-decl-3.c
> >>
> >> --
> >> 2.40.1
> >>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 0/9] Add btf_decl_tag C attribute
  2023-07-12 13:21     ` Richard Biener
@ 2023-07-12 13:49       ` Jose E. Marchesi
  2023-07-12 19:33         ` David Faust
  0 siblings, 1 reply; 18+ messages in thread
From: Jose E. Marchesi @ 2023-07-12 13:49 UTC (permalink / raw)
  To: Richard Biener; +Cc: David Faust, gcc-patches, yhs, Eduard Zingerman


> On Wed, Jul 12, 2023 at 2:44 PM Jose E. Marchesi
> <jose.marchesi@oracle.com> wrote:
>>
>>
>> [Added Eduard Zingerman in CC, who is implementing this same feature in
>>  clang/llvm and also the consumer component in the kernel (pahole).]
>>
>> Hi Richard.
>>
>> > On Tue, Jul 11, 2023 at 11:58 PM David Faust via Gcc-patches
>> > <gcc-patches@gcc.gnu.org> wrote:
>> >>
>> >> Hello,
>> >>
>> >> This series adds support for a new attribute, "btf_decl_tag" in GCC.
>> >> The same attribute is already supported in clang, and is used by various
>> >> components of the BPF ecosystem.
>> >>
>> >> The purpose of the attribute is to allow to associate (to "tag")
>> >> declarations with arbitrary string annotations, which are emitted into
>> >> debugging information (DWARF and/or BTF) to facilitate post-compilation
>> >> analysis (the motivating use case being the Linux kernel BPF verifier).
>> >> Multiple tags are allowed on the same declaration.
>> >>
>> >> These strings are not interpreted by the compiler, and the attribute
>> >> itself has no effect on generated code, other than to produce additional
>> >> DWARF DIEs and/or BTF records conveying the annotations.
>> >>
>> >> This entails:
>> >>
>> >> - A new C-language-level attribute which allows to associate (to "tag")
>> >>   particular declarations with arbitrary strings.
>> >>
>> >> - The conveyance of that information in DWARF in the form of a new DIE,
>> >>   DW_TAG_GNU_annotation, with tag number (0x6000) and format matching
>> >>   that of the DW_TAG_LLVM_annotation extension supported in LLVM for
>> >>   the same purpose. These DIEs are already supported by BPF tooling,
>> >>   such as pahole.
>> >>
>> >> - The conveyance of that information in BTF debug info in the form of
>> >>   BTF_KIND_DECL_TAG records. These records are already supported by
>> >>   LLVM and other tools in the eBPF ecosystem, such as the Linux kernel
>> >>   eBPF verifier.
>> >>
>> >>
>> >> Background
>> >> ==========
>> >>
>> >> The purpose of these tags is to convey additional semantic information
>> >> to post-compilation consumers, in particular the Linux kernel eBPF
>> >> verifier. The verifier can make use of that information while analyzing
>> >> a BPF program to aid in determining whether to allow or reject the
>> >> program to be run. More background on these tags can be found in the
>> >> early support for them in the kernel here [1] and [2].
>> >>
>> >> The "btf_decl_tag" attribute is half the story; the other half is a
>> >> sibling attribute "btf_type_tag" which serves the same purpose but
>> >> applies to types. Support for btf_type_tag will come in a separate
>> >> patch series, since it is impaced by GCC bug 110439 which needs to be
>> >> addressed first.
>> >>
>> >> I submitted an initial version of this work (including btf_type_tag)
>> >> last spring [3], however at the time there were some open questions
>> >> about the behavior of the btf_type_tag attribute and issues with its
>> >> implementation. Since then we have clarified these details and agreed
>> >> to solutions with the BPF community and LLVM BPF folks.
>> >>
>> >> The main motivation for emitting the tags in DWARF is that the Linux
>> >> kernel generates its BTF information via pahole, using DWARF as a source:
>> >>
>> >>     +--------+  BTF                  BTF   +----------+
>> >>     | pahole |-------> vmlinux.btf ------->| verifier |
>> >>     +--------+                             +----------+
>> >>         ^                                        ^
>> >>         |                                        |
>> >>   DWARF |                                    BTF |
>> >>         |                                        |
>> >>       vmlinux                              +-------------+
>> >>       module1.ko                           | BPF program |
>> >>       module2.ko                           +-------------+
>> >>         ...
>> >>
>> >> This is because:
>> >>
>> >> a)  pahole adds additional kernel-specific information into the
>> >>     produced BTF based on additional analysis of kernel objects.
>> >>
>> >> b)  Unlike GCC, LLVM will only generate BTF for BPF programs.
>> >>
>> >> b)  GCC can generate BTF for whatever target with -gbtf, but there is no
>> >>     support for linking/deduplicating BTF in the linker.
>> >>
>> >> In the scenario above, the verifier needs access to the pointer tags of
>> >> both the kernel types/declarations (conveyed in the DWARF and translated
>> >> to BTF by pahole) and those of the BPF program (available directly in BTF).
>> >>
>> >>
>> >> DWARF Representation
>> >> ====================
>> >>
>> >> As noted above, btf_decl_tag is represented in DWARF via a new DIE
>> >> DW_TAG_GNU_annotation, with identical format to the LLVM DWARF
>> >> extension DW_TAG_LLVM_annotation serving the same purpose. The DIE has
>> >> the following format:
>> >>
>> >>   DW_TAG_GNU_annotation (0x6000)
>> >>     DW_AT_name: "btf_decl_tag"
>> >>     DW_AT_const_value: <string argument>
>> >>
>> >> These DIEs are placed in the DWARF tree as children of the DIE for the
>> >> appropriate declaration, and one such DIE is created for each occurrence
>> >> of the btf_decl_tag attribute on a declaration.
>> >>
>> >> For example:
>> >>
>> >>   const int * c __attribute__((btf_decl_tag ("__c"), btf_decl_tag ("devicemem")));
>> >>
>> >> This declaration produces the following DWARF:
>> >>
>> >>  <1><1e>: Abbrev Number: 2 (DW_TAG_variable)
>> >>     <1f>   DW_AT_name        : c
>> >>     <24>   DW_AT_type        : <0x49>
>> >>     ...
>> >>  <2><36>: Abbrev Number: 3 (User TAG value: 0x6000)
>> >>     <37>   DW_AT_name        : (indirect string, offset: 0x4c): btf_decl_tag
>> >>     <3b>   DW_AT_const_value : (indirect string, offset: 0): devicemem
>> >>  <2><3f>: Abbrev Number: 4 (User TAG value: 0x6000)
>> >>     <40>   DW_AT_name        : (indirect string, offset: 0x4c): btf_decl_tag
>> >>     <44>   DW_AT_const_value : __c
>> >>  <2><48>: Abbrev Number: 0
>> >>  <1><49>: Abbrev Number: 5 (DW_TAG_pointer_type)
>> >>  ...
>> >>
>> >> The DIEs for btf_decl_tag are placed as children of the DIE for
>> >> variable "c".
>> >
>> > It looks like a bit of overkill, and inefficient as well.  Why's the
>> > tags not referenced via the existing DW_AT_description?
>>
>> The DWARF spec ("Entity Descriptions") seems to imply that the
>> DW_AT_description attribute is intended to be used to hold alternative
>> ways to denote the same "debugging information" (object, type, ...),
>> i.e. alternative aliases to refer to the same entity than the
>> DW_AT_name.  For example, for a type name='foo' we could have
>> description='aka. long int'.  We don't think this is the case of the btf
>> tags, which are more like properties partially characterizing the tagged
>> "debugging information", but couldn't be used as an alias to the name.
>>
>> Also, repurposing the DW_AT_description attribute to hold btf tag
>> information would require to introduce a mini-language and subsequent
>> parsing by the clients: how to denote several tags, how to encode the
>> embedded string contents, etc.  You kick the complexity out the door and
>> it comes back in through the window :)
>>
>> Finally, for what we know, the existing attribute may already be used by
>> some language and handled by some debugger the way it is recommended in
>> the spec.  That would be incompatible with having btf tags encoded
>> there.
>
> How are the C/C++ standard attributes proposed to be encoded in dwarf?
> I think adding special encoding just for BTF tags looks wrong.

To my knowledge the impact that existing standard C/C++ attributes may
have in the debug info can already be encoded with the existing DWARF
mechanisms.  For example, an attribute that results in some type to be
considered volatile may result in the addition of a DW_TAG_volatile_type
tag in the corresponding DW_AT_type chain.

But for these "btf tags" attributes, whose impact in debug info (and in
fact only purpose) is to associate an arbitrary string to either a
declared object or a type, we couldn't find any way to convey the
information in DWARF without breaking backwards compatibility, other
than introducing the new DIE tag.

[What would have been perfect is to be able to chain the
 DW_TAG_GNU_annotation in the DW_AT_type chains much like qualifiers are
 handled.  But that would break every DWARF reader in existence :( I
 wish DWARF would have a DW_TAG_type_nop.]

By the way, as I think Faust has already mentioned in the cover letter,
we (the BPF GCC folk) think the "btf_{type,decl}_tag" C attribute name
is sort of a misnomer, because these attributes are not necessarily
coupled with BTF.  Granted, the main usage of this is to convey the
annotations (via DWARF) to pahole so it can be converted to BTF.  But
other programs like the drgn debugger have expressed interest to access
the annotations directly from the DWARF, and BTF is not involved at all.
After a (little heated ;P) discussion in the BPF kernel list, the kernel
people said they would be ok with GCC using a different name for the
attributes than clang uses.  They can abstract it using a macro in the
kernel sources.  My personal favorite would be {type,decl}_annotation.

>
>> > Iff you want new TAGs why require them as children for each DIE rather
>> > than referencing (and sharing!) them via a DIE reference from a new
>> > attribute?
>>
>> Hmm, thats a very good question.  The Linux kernel sources uses both
>> declaration tags and type tags and not sharing the DIEs may result in
>> serious bloating, since the tags are brought in to declarations and type
>> specifiers via macros...
>>
>> > That said, I'd go with DW_AT_description 'btf_decl_tag ("devicemem")'.
>> >
>> > But well ...
>> >
>> > Richard.
>> >
>> >>
>> >> BTF Representation
>> >> ==================
>> >>
>> >> In BTF, BTF_KIND_DECL_TAG records convey the annotations. These records refer
>> >> to the annotated object by BTF type ID, as well as a component index which is
>> >> used for btf_decl_tags placed on struct/union members or function arguments.
>> >>
>> >> For example, the BTF for the above declaration is:
>> >>
>> >>   [1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED
>> >>   [2] CONST '(anon)' type_id=1
>> >>   [3] PTR '(anon)' type_id=2
>> >>   [4] DECL_TAG '__c' type_id=6 component_idx=-1
>> >>   [5] DECL_TAG 'devicemem' type_id=6 component_idx=-1
>> >>   [6] VAR 'c' type_id=3, linkage=global
>> >>   ...
>> >>
>> >> The BTF format is documented here [4].
>> >>
>> >>
>> >> References
>> >> ==========
>> >>
>> >> [1] https://lore.kernel.org/bpf/20210914223004.244411-1-yhs@fb.com/
>> >> [2] https://lore.kernel.org/bpf/20211011040608.3031468-1-yhs@fb.com/
>> >> [3] https://gcc.gnu.org/pipermail/gcc-patches/2022-May/593936.html
>> >> [4] https://www.kernel.org/doc/Documentation/bpf/btf.rst
>> >>
>> >>
>> >> David Faust (9):
>> >>   c-family: add btf_decl_tag attribute
>> >>   include: add BTF decl tag defines
>> >>   dwarf: create annotation DIEs for decl tags
>> >>   dwarf: expose get_die_parent
>> >>   ctf: add support to pass through BTF tags
>> >>   dwarf2ctf: convert annotation DIEs to CTF types
>> >>   btf: create and output BTF_KIND_DECL_TAG types
>> >>   testsuite: add tests for BTF decl tags
>> >>   doc: document btf_decl_tag attribute
>> >>
>> >>  gcc/btfout.cc                                 | 81 ++++++++++++++++++-
>> >>  gcc/c-family/c-attribs.cc                     | 23 ++++++
>> >>  gcc/ctf-int.h                                 | 28 +++++++
>> >>  gcc/ctfc.cc                                   | 10 ++-
>> >>  gcc/ctfc.h                                    | 17 +++-
>> >>  gcc/doc/extend.texi                           | 47 +++++++++++
>> >>  gcc/dwarf2ctf.cc                              | 73 ++++++++++++++++-
>> >>  gcc/dwarf2out.cc                              | 37 ++++++++-
>> >>  gcc/dwarf2out.h                               |  1 +
>> >>  .../gcc.dg/debug/btf/btf-decltag-func.c       | 21 +++++
>> >>  .../gcc.dg/debug/btf/btf-decltag-sou.c        | 33 ++++++++
>> >>  .../gcc.dg/debug/btf/btf-decltag-var.c        | 19 +++++
>> >>  .../gcc.dg/debug/dwarf2/annotation-decl-1.c   |  9 +++
>> >>  .../gcc.dg/debug/dwarf2/annotation-decl-2.c   | 18 +++++
>> >>  .../gcc.dg/debug/dwarf2/annotation-decl-3.c   | 17 ++++
>> >>  include/btf.h                                 | 14 +++-
>> >>  include/dwarf2.def                            |  4 +
>> >>  17 files changed, 437 insertions(+), 15 deletions(-)
>> >>  create mode 100644 gcc/ctf-int.h
>> >>  create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-decltag-func.c
>> >>  create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-decltag-sou.c
>> >>  create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-decltag-var.c
>> >>  create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/annotation-decl-1.c
>> >>  create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/annotation-decl-2.c
>> >>  create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/annotation-decl-3.c
>> >>
>> >> --
>> >> 2.40.1
>> >>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 0/9] Add btf_decl_tag C attribute
  2023-07-12 13:49       ` Jose E. Marchesi
@ 2023-07-12 19:33         ` David Faust
  0 siblings, 0 replies; 18+ messages in thread
From: David Faust @ 2023-07-12 19:33 UTC (permalink / raw)
  To: Jose E. Marchesi, Richard Biener; +Cc: gcc-patches, yhs, Eduard Zingerman



On 7/12/23 06:49, Jose E. Marchesi wrote:
> 
>> On Wed, Jul 12, 2023 at 2:44 PM Jose E. Marchesi
>> <jose.marchesi@oracle.com> wrote:
>>>
>>>
>>> [Added Eduard Zingerman in CC, who is implementing this same feature in
>>>  clang/llvm and also the consumer component in the kernel (pahole).]
>>>
>>> Hi Richard.
>>>
>>>> On Tue, Jul 11, 2023 at 11:58 PM David Faust via Gcc-patches
>>>> <gcc-patches@gcc.gnu.org> wrote:
>>>>>
>>>>> Hello,
>>>>>
>>>>> This series adds support for a new attribute, "btf_decl_tag" in GCC.
>>>>> The same attribute is already supported in clang, and is used by various
>>>>> components of the BPF ecosystem.
>>>>>
>>>>> The purpose of the attribute is to allow to associate (to "tag")
>>>>> declarations with arbitrary string annotations, which are emitted into
>>>>> debugging information (DWARF and/or BTF) to facilitate post-compilation
>>>>> analysis (the motivating use case being the Linux kernel BPF verifier).
>>>>> Multiple tags are allowed on the same declaration.
>>>>>
>>>>> These strings are not interpreted by the compiler, and the attribute
>>>>> itself has no effect on generated code, other than to produce additional
>>>>> DWARF DIEs and/or BTF records conveying the annotations.
>>>>>
>>>>> This entails:
>>>>>
>>>>> - A new C-language-level attribute which allows to associate (to "tag")
>>>>>   particular declarations with arbitrary strings.
>>>>>
>>>>> - The conveyance of that information in DWARF in the form of a new DIE,
>>>>>   DW_TAG_GNU_annotation, with tag number (0x6000) and format matching
>>>>>   that of the DW_TAG_LLVM_annotation extension supported in LLVM for
>>>>>   the same purpose. These DIEs are already supported by BPF tooling,
>>>>>   such as pahole.
>>>>>
>>>>> - The conveyance of that information in BTF debug info in the form of
>>>>>   BTF_KIND_DECL_TAG records. These records are already supported by
>>>>>   LLVM and other tools in the eBPF ecosystem, such as the Linux kernel
>>>>>   eBPF verifier.
>>>>>
>>>>>
>>>>> Background
>>>>> ==========
>>>>>
>>>>> The purpose of these tags is to convey additional semantic information
>>>>> to post-compilation consumers, in particular the Linux kernel eBPF
>>>>> verifier. The verifier can make use of that information while analyzing
>>>>> a BPF program to aid in determining whether to allow or reject the
>>>>> program to be run. More background on these tags can be found in the
>>>>> early support for them in the kernel here [1] and [2].
>>>>>
>>>>> The "btf_decl_tag" attribute is half the story; the other half is a
>>>>> sibling attribute "btf_type_tag" which serves the same purpose but
>>>>> applies to types. Support for btf_type_tag will come in a separate
>>>>> patch series, since it is impaced by GCC bug 110439 which needs to be
>>>>> addressed first.
>>>>>
>>>>> I submitted an initial version of this work (including btf_type_tag)
>>>>> last spring [3], however at the time there were some open questions
>>>>> about the behavior of the btf_type_tag attribute and issues with its
>>>>> implementation. Since then we have clarified these details and agreed
>>>>> to solutions with the BPF community and LLVM BPF folks.
>>>>>
>>>>> The main motivation for emitting the tags in DWARF is that the Linux
>>>>> kernel generates its BTF information via pahole, using DWARF as a source:
>>>>>
>>>>>     +--------+  BTF                  BTF   +----------+
>>>>>     | pahole |-------> vmlinux.btf ------->| verifier |
>>>>>     +--------+                             +----------+
>>>>>         ^                                        ^
>>>>>         |                                        |
>>>>>   DWARF |                                    BTF |
>>>>>         |                                        |
>>>>>       vmlinux                              +-------------+
>>>>>       module1.ko                           | BPF program |
>>>>>       module2.ko                           +-------------+
>>>>>         ...
>>>>>
>>>>> This is because:
>>>>>
>>>>> a)  pahole adds additional kernel-specific information into the
>>>>>     produced BTF based on additional analysis of kernel objects.
>>>>>
>>>>> b)  Unlike GCC, LLVM will only generate BTF for BPF programs.
>>>>>
>>>>> b)  GCC can generate BTF for whatever target with -gbtf, but there is no
>>>>>     support for linking/deduplicating BTF in the linker.
>>>>>
>>>>> In the scenario above, the verifier needs access to the pointer tags of
>>>>> both the kernel types/declarations (conveyed in the DWARF and translated
>>>>> to BTF by pahole) and those of the BPF program (available directly in BTF).
>>>>>
>>>>>
>>>>> DWARF Representation
>>>>> ====================
>>>>>
>>>>> As noted above, btf_decl_tag is represented in DWARF via a new DIE
>>>>> DW_TAG_GNU_annotation, with identical format to the LLVM DWARF
>>>>> extension DW_TAG_LLVM_annotation serving the same purpose. The DIE has
>>>>> the following format:
>>>>>
>>>>>   DW_TAG_GNU_annotation (0x6000)
>>>>>     DW_AT_name: "btf_decl_tag"
>>>>>     DW_AT_const_value: <string argument>
>>>>>
>>>>> These DIEs are placed in the DWARF tree as children of the DIE for the
>>>>> appropriate declaration, and one such DIE is created for each occurrence
>>>>> of the btf_decl_tag attribute on a declaration.
>>>>>
>>>>> For example:
>>>>>
>>>>>   const int * c __attribute__((btf_decl_tag ("__c"), btf_decl_tag ("devicemem")));
>>>>>
>>>>> This declaration produces the following DWARF:
>>>>>
>>>>>  <1><1e>: Abbrev Number: 2 (DW_TAG_variable)
>>>>>     <1f>   DW_AT_name        : c
>>>>>     <24>   DW_AT_type        : <0x49>
>>>>>     ...
>>>>>  <2><36>: Abbrev Number: 3 (User TAG value: 0x6000)
>>>>>     <37>   DW_AT_name        : (indirect string, offset: 0x4c): btf_decl_tag
>>>>>     <3b>   DW_AT_const_value : (indirect string, offset: 0): devicemem
>>>>>  <2><3f>: Abbrev Number: 4 (User TAG value: 0x6000)
>>>>>     <40>   DW_AT_name        : (indirect string, offset: 0x4c): btf_decl_tag
>>>>>     <44>   DW_AT_const_value : __c
>>>>>  <2><48>: Abbrev Number: 0
>>>>>  <1><49>: Abbrev Number: 5 (DW_TAG_pointer_type)
>>>>>  ...
>>>>>
>>>>> The DIEs for btf_decl_tag are placed as children of the DIE for
>>>>> variable "c".
>>>>
>>>> It looks like a bit of overkill, and inefficient as well.  Why's the
>>>> tags not referenced via the existing DW_AT_description?

The DWARF format here (with children DIEs) is the format already
in use, supported by the kernel/pahole and emitted by clang. So the
simple answer is just to be compatible with the existing tools.

That's not to say it couldn't be improved, so long as all the relevant
producers/consumers (clang, pahole, whatever else) agree.

>>>
>>> The DWARF spec ("Entity Descriptions") seems to imply that the
>>> DW_AT_description attribute is intended to be used to hold alternative
>>> ways to denote the same "debugging information" (object, type, ...),
>>> i.e. alternative aliases to refer to the same entity than the
>>> DW_AT_name.  For example, for a type name='foo' we could have
>>> description='aka. long int'.  We don't think this is the case of the btf
>>> tags, which are more like properties partially characterizing the tagged
>>> "debugging information", but couldn't be used as an alias to the name.
>>>
>>> Also, repurposing the DW_AT_description attribute to hold btf tag
>>> information would require to introduce a mini-language and subsequent
>>> parsing by the clients: how to denote several tags, how to encode the
>>> embedded string contents, etc.  You kick the complexity out the door and
>>> it comes back in through the window :)
>>>
>>> Finally, for what we know, the existing attribute may already be used by
>>> some language and handled by some debugger the way it is recommended in
>>> the spec.  That would be incompatible with having btf tags encoded
>>> there.
>>
>> How are the C/C++ standard attributes proposed to be encoded in dwarf?
>> I think adding special encoding just for BTF tags looks wrong.
> 
> To my knowledge the impact that existing standard C/C++ attributes may
> have in the debug info can already be encoded with the existing DWARF
> mechanisms.  For example, an attribute that results in some type to be
> considered volatile may result in the addition of a DW_TAG_volatile_type
> tag in the corresponding DW_AT_type chain.
> 
> But for these "btf tags" attributes, whose impact in debug info (and in
> fact only purpose) is to associate an arbitrary string to either a
> declared object or a type, we couldn't find any way to convey the
> information in DWARF without breaking backwards compatibility, other
> than introducing the new DIE tag.
> 
> [What would have been perfect is to be able to chain the
>  DW_TAG_GNU_annotation in the DW_AT_type chains much like qualifiers are
>  handled.  But that would break every DWARF reader in existence :( I
>  wish DWARF would have a DW_TAG_type_nop.]
> 
> By the way, as I think Faust has already mentioned in the cover letter,
> we (the BPF GCC folk) think the "btf_{type,decl}_tag" C attribute name
> is sort of a misnomer, because these attributes are not necessarily
> coupled with BTF.  Granted, the main usage of this is to convey the
> annotations (via DWARF) to pahole so it can be converted to BTF.  But
> other programs like the drgn debugger have expressed interest to access
> the annotations directly from the DWARF, and BTF is not involved at all.
> After a (little heated ;P) discussion in the BPF kernel list, the kernel
> people said they would be ok with GCC using a different name for the
> attributes than clang uses.  They can abstract it using a macro in the
> kernel sources.  My personal favorite would be {type,decl}_annotation.
> 
>>
>>>> Iff you want new TAGs why require them as children for each DIE rather
>>>> than referencing (and sharing!) them via a DIE reference from a new
>>>> attribute?
>>>
>>> Hmm, thats a very good question.  The Linux kernel sources uses both
>>> declaration tags and type tags and not sharing the DIEs may result in
>>> serious bloating, since the tags are brought in to declarations and type
>>> specifiers via macros...

I agree this is a good point and could certainly be an improvement to
the format.

But, I'm not sure how this would work for objects with multiple
btf_tags. As I understand, a given attribute can only be supplied
once for any given DIE. So if there are multiple tags on one object,
it's not clear to me how we would store the references to them. Maybe
with some chaining between the btf_tag DIEs... I think a little
duplication might be unavoidable but it still could be a big
improvement, since the usual use case iiuc is "relatively few distinct
tags, but a lot of objects with those tags".

FWIW and as some background, there was similar discussion in the llvm
list back when the tags were first proposed in this thread:

  https://lists.llvm.org/pipermail/llvm-dev/2021-June/151009.html

which led eventually to the discussion of using multiple DIEs as
children instead (later in the same thread):

  https://lists.llvm.org/pipermail/llvm-dev/2021-June/151256.html


>>>
>>>> That said, I'd go with DW_AT_description 'btf_decl_tag ("devicemem")'.
>>>>
>>>> But well ...
>>>>
>>>> Richard.
>>>>
>>>>>
>>>>> BTF Representation
>>>>> ==================
>>>>>
>>>>> In BTF, BTF_KIND_DECL_TAG records convey the annotations. These records refer
>>>>> to the annotated object by BTF type ID, as well as a component index which is
>>>>> used for btf_decl_tags placed on struct/union members or function arguments.
>>>>>
>>>>> For example, the BTF for the above declaration is:
>>>>>
>>>>>   [1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED
>>>>>   [2] CONST '(anon)' type_id=1
>>>>>   [3] PTR '(anon)' type_id=2
>>>>>   [4] DECL_TAG '__c' type_id=6 component_idx=-1
>>>>>   [5] DECL_TAG 'devicemem' type_id=6 component_idx=-1
>>>>>   [6] VAR 'c' type_id=3, linkage=global
>>>>>   ...
>>>>>
>>>>> The BTF format is documented here [4].
>>>>>
>>>>>
>>>>> References
>>>>> ==========
>>>>>
>>>>> [1] https://lore.kernel.org/bpf/20210914223004.244411-1-yhs@fb.com/
>>>>> [2] https://lore.kernel.org/bpf/20211011040608.3031468-1-yhs@fb.com/
>>>>> [3] https://gcc.gnu.org/pipermail/gcc-patches/2022-May/593936.html
>>>>> [4] https://www.kernel.org/doc/Documentation/bpf/btf.rst
>>>>>
>>>>>
>>>>> David Faust (9):
>>>>>   c-family: add btf_decl_tag attribute
>>>>>   include: add BTF decl tag defines
>>>>>   dwarf: create annotation DIEs for decl tags
>>>>>   dwarf: expose get_die_parent
>>>>>   ctf: add support to pass through BTF tags
>>>>>   dwarf2ctf: convert annotation DIEs to CTF types
>>>>>   btf: create and output BTF_KIND_DECL_TAG types
>>>>>   testsuite: add tests for BTF decl tags
>>>>>   doc: document btf_decl_tag attribute
>>>>>
>>>>>  gcc/btfout.cc                                 | 81 ++++++++++++++++++-
>>>>>  gcc/c-family/c-attribs.cc                     | 23 ++++++
>>>>>  gcc/ctf-int.h                                 | 28 +++++++
>>>>>  gcc/ctfc.cc                                   | 10 ++-
>>>>>  gcc/ctfc.h                                    | 17 +++-
>>>>>  gcc/doc/extend.texi                           | 47 +++++++++++
>>>>>  gcc/dwarf2ctf.cc                              | 73 ++++++++++++++++-
>>>>>  gcc/dwarf2out.cc                              | 37 ++++++++-
>>>>>  gcc/dwarf2out.h                               |  1 +
>>>>>  .../gcc.dg/debug/btf/btf-decltag-func.c       | 21 +++++
>>>>>  .../gcc.dg/debug/btf/btf-decltag-sou.c        | 33 ++++++++
>>>>>  .../gcc.dg/debug/btf/btf-decltag-var.c        | 19 +++++
>>>>>  .../gcc.dg/debug/dwarf2/annotation-decl-1.c   |  9 +++
>>>>>  .../gcc.dg/debug/dwarf2/annotation-decl-2.c   | 18 +++++
>>>>>  .../gcc.dg/debug/dwarf2/annotation-decl-3.c   | 17 ++++
>>>>>  include/btf.h                                 | 14 +++-
>>>>>  include/dwarf2.def                            |  4 +
>>>>>  17 files changed, 437 insertions(+), 15 deletions(-)
>>>>>  create mode 100644 gcc/ctf-int.h
>>>>>  create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-decltag-func.c
>>>>>  create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-decltag-sou.c
>>>>>  create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-decltag-var.c
>>>>>  create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/annotation-decl-1.c
>>>>>  create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/annotation-decl-2.c
>>>>>  create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/annotation-decl-3.c
>>>>>
>>>>> --
>>>>> 2.40.1
>>>>>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 0/9] Add btf_decl_tag C attribute
  2023-07-11 21:57 [PATCH 0/9] Add btf_decl_tag C attribute David Faust
                   ` (9 preceding siblings ...)
  2023-07-12  7:38 ` [PATCH 0/9] Add btf_decl_tag C attribute Richard Biener
@ 2023-07-24 15:56 ` David Faust
  2023-08-09 21:05 ` [PING 2][PATCH " David Faust
  2023-09-11 21:39 ` [PING][PATCH " David Faust
  12 siblings, 0 replies; 18+ messages in thread
From: David Faust @ 2023-07-24 15:56 UTC (permalink / raw)
  To: gcc-patches; +Cc: jose.marchesi, yhs

Gentle ping.

https://gcc.gnu.org/pipermail/gcc-patches/2023-July/624156.html

On 7/11/23 14:57, David Faust via Gcc-patches wrote:
> Hello,
> 
> This series adds support for a new attribute, "btf_decl_tag" in GCC.
> The same attribute is already supported in clang, and is used by various
> components of the BPF ecosystem.
> 
> The purpose of the attribute is to allow to associate (to "tag")
> declarations with arbitrary string annotations, which are emitted into
> debugging information (DWARF and/or BTF) to facilitate post-compilation
> analysis (the motivating use case being the Linux kernel BPF verifier).
> Multiple tags are allowed on the same declaration.
> 
> These strings are not interpreted by the compiler, and the attribute
> itself has no effect on generated code, other than to produce additional
> DWARF DIEs and/or BTF records conveying the annotations.
> 
> This entails:
> 
> - A new C-language-level attribute which allows to associate (to "tag")
>   particular declarations with arbitrary strings.
> 
> - The conveyance of that information in DWARF in the form of a new DIE,
>   DW_TAG_GNU_annotation, with tag number (0x6000) and format matching
>   that of the DW_TAG_LLVM_annotation extension supported in LLVM for
>   the same purpose. These DIEs are already supported by BPF tooling,
>   such as pahole.
> 
> - The conveyance of that information in BTF debug info in the form of
>   BTF_KIND_DECL_TAG records. These records are already supported by
>   LLVM and other tools in the eBPF ecosystem, such as the Linux kernel
>   eBPF verifier.
> 
> 
> Background
> ==========
> 
> The purpose of these tags is to convey additional semantic information
> to post-compilation consumers, in particular the Linux kernel eBPF
> verifier. The verifier can make use of that information while analyzing
> a BPF program to aid in determining whether to allow or reject the
> program to be run. More background on these tags can be found in the
> early support for them in the kernel here [1] and [2].
> 
> The "btf_decl_tag" attribute is half the story; the other half is a
> sibling attribute "btf_type_tag" which serves the same purpose but
> applies to types. Support for btf_type_tag will come in a separate
> patch series, since it is impaced by GCC bug 110439 which needs to be
> addressed first.
> 
> I submitted an initial version of this work (including btf_type_tag)
> last spring [3], however at the time there were some open questions
> about the behavior of the btf_type_tag attribute and issues with its
> implementation. Since then we have clarified these details and agreed
> to solutions with the BPF community and LLVM BPF folks.
> 
> The main motivation for emitting the tags in DWARF is that the Linux
> kernel generates its BTF information via pahole, using DWARF as a source:
> 
>     +--------+  BTF                  BTF   +----------+
>     | pahole |-------> vmlinux.btf ------->| verifier |
>     +--------+                             +----------+
>         ^                                        ^
>         |                                        |
>   DWARF |                                    BTF |
>         |                                        |
>       vmlinux                              +-------------+
>       module1.ko                           | BPF program |
>       module2.ko                           +-------------+
>         ...
> 
> This is because:
> 
> a)  pahole adds additional kernel-specific information into the
>     produced BTF based on additional analysis of kernel objects.
> 
> b)  Unlike GCC, LLVM will only generate BTF for BPF programs.
> 
> b)  GCC can generate BTF for whatever target with -gbtf, but there is no
>     support for linking/deduplicating BTF in the linker.
> 
> In the scenario above, the verifier needs access to the pointer tags of
> both the kernel types/declarations (conveyed in the DWARF and translated
> to BTF by pahole) and those of the BPF program (available directly in BTF).
> 
> 
> DWARF Representation
> ====================
> 
> As noted above, btf_decl_tag is represented in DWARF via a new DIE
> DW_TAG_GNU_annotation, with identical format to the LLVM DWARF
> extension DW_TAG_LLVM_annotation serving the same purpose. The DIE has
> the following format:
> 
>   DW_TAG_GNU_annotation (0x6000)
>     DW_AT_name: "btf_decl_tag"
>     DW_AT_const_value: <string argument>
> 
> These DIEs are placed in the DWARF tree as children of the DIE for the
> appropriate declaration, and one such DIE is created for each occurrence
> of the btf_decl_tag attribute on a declaration.
> 
> For example:
> 
>   const int * c __attribute__((btf_decl_tag ("__c"), btf_decl_tag ("devicemem")));
> 
> This declaration produces the following DWARF:
> 
>  <1><1e>: Abbrev Number: 2 (DW_TAG_variable)
>     <1f>   DW_AT_name        : c
>     <24>   DW_AT_type        : <0x49>
>     ...
>  <2><36>: Abbrev Number: 3 (User TAG value: 0x6000)
>     <37>   DW_AT_name        : (indirect string, offset: 0x4c): btf_decl_tag
>     <3b>   DW_AT_const_value : (indirect string, offset: 0): devicemem
>  <2><3f>: Abbrev Number: 4 (User TAG value: 0x6000)
>     <40>   DW_AT_name        : (indirect string, offset: 0x4c): btf_decl_tag
>     <44>   DW_AT_const_value : __c
>  <2><48>: Abbrev Number: 0
>  <1><49>: Abbrev Number: 5 (DW_TAG_pointer_type)
>  ...
> 
> The DIEs for btf_decl_tag are placed as children of the DIE for
> variable "c".
> 
> BTF Representation
> ==================
> 
> In BTF, BTF_KIND_DECL_TAG records convey the annotations. These records refer
> to the annotated object by BTF type ID, as well as a component index which is
> used for btf_decl_tags placed on struct/union members or function arguments.
> 
> For example, the BTF for the above declaration is:
> 
>   [1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED
>   [2] CONST '(anon)' type_id=1
>   [3] PTR '(anon)' type_id=2
>   [4] DECL_TAG '__c' type_id=6 component_idx=-1
>   [5] DECL_TAG 'devicemem' type_id=6 component_idx=-1
>   [6] VAR 'c' type_id=3, linkage=global
>   ...
> 
> The BTF format is documented here [4].
> 
> 
> References
> ==========
> 
> [1] https://lore.kernel.org/bpf/20210914223004.244411-1-yhs@fb.com/
> [2] https://lore.kernel.org/bpf/20211011040608.3031468-1-yhs@fb.com/
> [3] https://gcc.gnu.org/pipermail/gcc-patches/2022-May/593936.html
> [4] https://www.kernel.org/doc/Documentation/bpf/btf.rst
> 
> 
> David Faust (9):
>   c-family: add btf_decl_tag attribute
>   include: add BTF decl tag defines
>   dwarf: create annotation DIEs for decl tags
>   dwarf: expose get_die_parent
>   ctf: add support to pass through BTF tags
>   dwarf2ctf: convert annotation DIEs to CTF types
>   btf: create and output BTF_KIND_DECL_TAG types
>   testsuite: add tests for BTF decl tags
>   doc: document btf_decl_tag attribute
> 
>  gcc/btfout.cc                                 | 81 ++++++++++++++++++-
>  gcc/c-family/c-attribs.cc                     | 23 ++++++
>  gcc/ctf-int.h                                 | 28 +++++++
>  gcc/ctfc.cc                                   | 10 ++-
>  gcc/ctfc.h                                    | 17 +++-
>  gcc/doc/extend.texi                           | 47 +++++++++++
>  gcc/dwarf2ctf.cc                              | 73 ++++++++++++++++-
>  gcc/dwarf2out.cc                              | 37 ++++++++-
>  gcc/dwarf2out.h                               |  1 +
>  .../gcc.dg/debug/btf/btf-decltag-func.c       | 21 +++++
>  .../gcc.dg/debug/btf/btf-decltag-sou.c        | 33 ++++++++
>  .../gcc.dg/debug/btf/btf-decltag-var.c        | 19 +++++
>  .../gcc.dg/debug/dwarf2/annotation-decl-1.c   |  9 +++
>  .../gcc.dg/debug/dwarf2/annotation-decl-2.c   | 18 +++++
>  .../gcc.dg/debug/dwarf2/annotation-decl-3.c   | 17 ++++
>  include/btf.h                                 | 14 +++-
>  include/dwarf2.def                            |  4 +
>  17 files changed, 437 insertions(+), 15 deletions(-)
>  create mode 100644 gcc/ctf-int.h
>  create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-decltag-func.c
>  create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-decltag-sou.c
>  create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-decltag-var.c
>  create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/annotation-decl-1.c
>  create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/annotation-decl-2.c
>  create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/annotation-decl-3.c
> 

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PING 2][PATCH 0/9] Add btf_decl_tag C attribute
  2023-07-11 21:57 [PATCH 0/9] Add btf_decl_tag C attribute David Faust
                   ` (10 preceding siblings ...)
  2023-07-24 15:56 ` David Faust
@ 2023-08-09 21:05 ` David Faust
  2023-09-11 21:39 ` [PING][PATCH " David Faust
  12 siblings, 0 replies; 18+ messages in thread
From: David Faust @ 2023-08-09 21:05 UTC (permalink / raw)
  To: gcc-patches; +Cc: jose.marchesi, yhs

Ping for this series.

https://gcc.gnu.org/pipermail/gcc-patches/2023-July/624156.html

Thanks

On 7/11/23 14:57, David Faust via Gcc-patches wrote:
> Hello,
> 
> This series adds support for a new attribute, "btf_decl_tag" in GCC.
> The same attribute is already supported in clang, and is used by various
> components of the BPF ecosystem.
> 
> The purpose of the attribute is to allow to associate (to "tag")
> declarations with arbitrary string annotations, which are emitted into
> debugging information (DWARF and/or BTF) to facilitate post-compilation
> analysis (the motivating use case being the Linux kernel BPF verifier).
> Multiple tags are allowed on the same declaration.
> 
> These strings are not interpreted by the compiler, and the attribute
> itself has no effect on generated code, other than to produce additional
> DWARF DIEs and/or BTF records conveying the annotations.
> 
> This entails:
> 
> - A new C-language-level attribute which allows to associate (to "tag")
>   particular declarations with arbitrary strings.
> 
> - The conveyance of that information in DWARF in the form of a new DIE,
>   DW_TAG_GNU_annotation, with tag number (0x6000) and format matching
>   that of the DW_TAG_LLVM_annotation extension supported in LLVM for
>   the same purpose. These DIEs are already supported by BPF tooling,
>   such as pahole.
> 
> - The conveyance of that information in BTF debug info in the form of
>   BTF_KIND_DECL_TAG records. These records are already supported by
>   LLVM and other tools in the eBPF ecosystem, such as the Linux kernel
>   eBPF verifier.
> 
> 
> Background
> ==========
> 
> The purpose of these tags is to convey additional semantic information
> to post-compilation consumers, in particular the Linux kernel eBPF
> verifier. The verifier can make use of that information while analyzing
> a BPF program to aid in determining whether to allow or reject the
> program to be run. More background on these tags can be found in the
> early support for them in the kernel here [1] and [2].
> 
> The "btf_decl_tag" attribute is half the story; the other half is a
> sibling attribute "btf_type_tag" which serves the same purpose but
> applies to types. Support for btf_type_tag will come in a separate
> patch series, since it is impaced by GCC bug 110439 which needs to be
> addressed first.
> 
> I submitted an initial version of this work (including btf_type_tag)
> last spring [3], however at the time there were some open questions
> about the behavior of the btf_type_tag attribute and issues with its
> implementation. Since then we have clarified these details and agreed
> to solutions with the BPF community and LLVM BPF folks.
> 
> The main motivation for emitting the tags in DWARF is that the Linux
> kernel generates its BTF information via pahole, using DWARF as a source:
> 
>     +--------+  BTF                  BTF   +----------+
>     | pahole |-------> vmlinux.btf ------->| verifier |
>     +--------+                             +----------+
>         ^                                        ^
>         |                                        |
>   DWARF |                                    BTF |
>         |                                        |
>       vmlinux                              +-------------+
>       module1.ko                           | BPF program |
>       module2.ko                           +-------------+
>         ...
> 
> This is because:
> 
> a)  pahole adds additional kernel-specific information into the
>     produced BTF based on additional analysis of kernel objects.
> 
> b)  Unlike GCC, LLVM will only generate BTF for BPF programs.
> 
> b)  GCC can generate BTF for whatever target with -gbtf, but there is no
>     support for linking/deduplicating BTF in the linker.
> 
> In the scenario above, the verifier needs access to the pointer tags of
> both the kernel types/declarations (conveyed in the DWARF and translated
> to BTF by pahole) and those of the BPF program (available directly in BTF).
> 
> 
> DWARF Representation
> ====================
> 
> As noted above, btf_decl_tag is represented in DWARF via a new DIE
> DW_TAG_GNU_annotation, with identical format to the LLVM DWARF
> extension DW_TAG_LLVM_annotation serving the same purpose. The DIE has
> the following format:
> 
>   DW_TAG_GNU_annotation (0x6000)
>     DW_AT_name: "btf_decl_tag"
>     DW_AT_const_value: <string argument>
> 
> These DIEs are placed in the DWARF tree as children of the DIE for the
> appropriate declaration, and one such DIE is created for each occurrence
> of the btf_decl_tag attribute on a declaration.
> 
> For example:
> 
>   const int * c __attribute__((btf_decl_tag ("__c"), btf_decl_tag ("devicemem")));
> 
> This declaration produces the following DWARF:
> 
>  <1><1e>: Abbrev Number: 2 (DW_TAG_variable)
>     <1f>   DW_AT_name        : c
>     <24>   DW_AT_type        : <0x49>
>     ...
>  <2><36>: Abbrev Number: 3 (User TAG value: 0x6000)
>     <37>   DW_AT_name        : (indirect string, offset: 0x4c): btf_decl_tag
>     <3b>   DW_AT_const_value : (indirect string, offset: 0): devicemem
>  <2><3f>: Abbrev Number: 4 (User TAG value: 0x6000)
>     <40>   DW_AT_name        : (indirect string, offset: 0x4c): btf_decl_tag
>     <44>   DW_AT_const_value : __c
>  <2><48>: Abbrev Number: 0
>  <1><49>: Abbrev Number: 5 (DW_TAG_pointer_type)
>  ...
> 
> The DIEs for btf_decl_tag are placed as children of the DIE for
> variable "c".
> 
> BTF Representation
> ==================
> 
> In BTF, BTF_KIND_DECL_TAG records convey the annotations. These records refer
> to the annotated object by BTF type ID, as well as a component index which is
> used for btf_decl_tags placed on struct/union members or function arguments.
> 
> For example, the BTF for the above declaration is:
> 
>   [1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED
>   [2] CONST '(anon)' type_id=1
>   [3] PTR '(anon)' type_id=2
>   [4] DECL_TAG '__c' type_id=6 component_idx=-1
>   [5] DECL_TAG 'devicemem' type_id=6 component_idx=-1
>   [6] VAR 'c' type_id=3, linkage=global
>   ...
> 
> The BTF format is documented here [4].
> 
> 
> References
> ==========
> 
> [1] https://lore.kernel.org/bpf/20210914223004.244411-1-yhs@fb.com/
> [2] https://lore.kernel.org/bpf/20211011040608.3031468-1-yhs@fb.com/
> [3] https://gcc.gnu.org/pipermail/gcc-patches/2022-May/593936.html
> [4] https://www.kernel.org/doc/Documentation/bpf/btf.rst
> 
> 
> David Faust (9):
>   c-family: add btf_decl_tag attribute
>   include: add BTF decl tag defines
>   dwarf: create annotation DIEs for decl tags
>   dwarf: expose get_die_parent
>   ctf: add support to pass through BTF tags
>   dwarf2ctf: convert annotation DIEs to CTF types
>   btf: create and output BTF_KIND_DECL_TAG types
>   testsuite: add tests for BTF decl tags
>   doc: document btf_decl_tag attribute
> 
>  gcc/btfout.cc                                 | 81 ++++++++++++++++++-
>  gcc/c-family/c-attribs.cc                     | 23 ++++++
>  gcc/ctf-int.h                                 | 28 +++++++
>  gcc/ctfc.cc                                   | 10 ++-
>  gcc/ctfc.h                                    | 17 +++-
>  gcc/doc/extend.texi                           | 47 +++++++++++
>  gcc/dwarf2ctf.cc                              | 73 ++++++++++++++++-
>  gcc/dwarf2out.cc                              | 37 ++++++++-
>  gcc/dwarf2out.h                               |  1 +
>  .../gcc.dg/debug/btf/btf-decltag-func.c       | 21 +++++
>  .../gcc.dg/debug/btf/btf-decltag-sou.c        | 33 ++++++++
>  .../gcc.dg/debug/btf/btf-decltag-var.c        | 19 +++++
>  .../gcc.dg/debug/dwarf2/annotation-decl-1.c   |  9 +++
>  .../gcc.dg/debug/dwarf2/annotation-decl-2.c   | 18 +++++
>  .../gcc.dg/debug/dwarf2/annotation-decl-3.c   | 17 ++++
>  include/btf.h                                 | 14 +++-
>  include/dwarf2.def                            |  4 +
>  17 files changed, 437 insertions(+), 15 deletions(-)
>  create mode 100644 gcc/ctf-int.h
>  create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-decltag-func.c
>  create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-decltag-sou.c
>  create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-decltag-var.c
>  create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/annotation-decl-1.c
>  create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/annotation-decl-2.c
>  create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/annotation-decl-3.c
> 

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PING][PATCH 0/9] Add btf_decl_tag C attribute
  2023-07-11 21:57 [PATCH 0/9] Add btf_decl_tag C attribute David Faust
                   ` (11 preceding siblings ...)
  2023-08-09 21:05 ` [PING 2][PATCH " David Faust
@ 2023-09-11 21:39 ` David Faust
  12 siblings, 0 replies; 18+ messages in thread
From: David Faust @ 2023-09-11 21:39 UTC (permalink / raw)
  To: gcc-patches

Ping.

This series adds a new C language attribute for recording additional
information in DWARF and BTF, similar to an existing attribute in clang.

https://gcc.gnu.org/pipermail/gcc-patches/2023-July/624156.html

There are components in c-family, dwarf, ctf and btf.
Thanks.

On 7/11/23 14:57, David Faust via Gcc-patches wrote:
> Hello,
> 
> This series adds support for a new attribute, "btf_decl_tag" in GCC.
> The same attribute is already supported in clang, and is used by various
> components of the BPF ecosystem.
> 
> The purpose of the attribute is to allow to associate (to "tag")
> declarations with arbitrary string annotations, which are emitted into
> debugging information (DWARF and/or BTF) to facilitate post-compilation
> analysis (the motivating use case being the Linux kernel BPF verifier).
> Multiple tags are allowed on the same declaration.
> 
> These strings are not interpreted by the compiler, and the attribute
> itself has no effect on generated code, other than to produce additional
> DWARF DIEs and/or BTF records conveying the annotations.
> 
> This entails:
> 
> - A new C-language-level attribute which allows to associate (to "tag")
>   particular declarations with arbitrary strings.
> 
> - The conveyance of that information in DWARF in the form of a new DIE,
>   DW_TAG_GNU_annotation, with tag number (0x6000) and format matching
>   that of the DW_TAG_LLVM_annotation extension supported in LLVM for
>   the same purpose. These DIEs are already supported by BPF tooling,
>   such as pahole.
> 
> - The conveyance of that information in BTF debug info in the form of
>   BTF_KIND_DECL_TAG records. These records are already supported by
>   LLVM and other tools in the eBPF ecosystem, such as the Linux kernel
>   eBPF verifier.
> 
> 
> Background
> ==========
> 
> The purpose of these tags is to convey additional semantic information
> to post-compilation consumers, in particular the Linux kernel eBPF
> verifier. The verifier can make use of that information while analyzing
> a BPF program to aid in determining whether to allow or reject the
> program to be run. More background on these tags can be found in the
> early support for them in the kernel here [1] and [2].
> 
> The "btf_decl_tag" attribute is half the story; the other half is a
> sibling attribute "btf_type_tag" which serves the same purpose but
> applies to types. Support for btf_type_tag will come in a separate
> patch series, since it is impaced by GCC bug 110439 which needs to be
> addressed first.
> 
> I submitted an initial version of this work (including btf_type_tag)
> last spring [3], however at the time there were some open questions
> about the behavior of the btf_type_tag attribute and issues with its
> implementation. Since then we have clarified these details and agreed
> to solutions with the BPF community and LLVM BPF folks.
> 
> The main motivation for emitting the tags in DWARF is that the Linux
> kernel generates its BTF information via pahole, using DWARF as a source:
> 
>     +--------+  BTF                  BTF   +----------+
>     | pahole |-------> vmlinux.btf ------->| verifier |
>     +--------+                             +----------+
>         ^                                        ^
>         |                                        |
>   DWARF |                                    BTF |
>         |                                        |
>       vmlinux                              +-------------+
>       module1.ko                           | BPF program |
>       module2.ko                           +-------------+
>         ...
> 
> This is because:
> 
> a)  pahole adds additional kernel-specific information into the
>     produced BTF based on additional analysis of kernel objects.
> 
> b)  Unlike GCC, LLVM will only generate BTF for BPF programs.
> 
> b)  GCC can generate BTF for whatever target with -gbtf, but there is no
>     support for linking/deduplicating BTF in the linker.
> 
> In the scenario above, the verifier needs access to the pointer tags of
> both the kernel types/declarations (conveyed in the DWARF and translated
> to BTF by pahole) and those of the BPF program (available directly in BTF).
> 
> 
> DWARF Representation
> ====================
> 
> As noted above, btf_decl_tag is represented in DWARF via a new DIE
> DW_TAG_GNU_annotation, with identical format to the LLVM DWARF
> extension DW_TAG_LLVM_annotation serving the same purpose. The DIE has
> the following format:
> 
>   DW_TAG_GNU_annotation (0x6000)
>     DW_AT_name: "btf_decl_tag"
>     DW_AT_const_value: <string argument>
> 
> These DIEs are placed in the DWARF tree as children of the DIE for the
> appropriate declaration, and one such DIE is created for each occurrence
> of the btf_decl_tag attribute on a declaration.
> 
> For example:
> 
>   const int * c __attribute__((btf_decl_tag ("__c"), btf_decl_tag ("devicemem")));
> 
> This declaration produces the following DWARF:
> 
>  <1><1e>: Abbrev Number: 2 (DW_TAG_variable)
>     <1f>   DW_AT_name        : c
>     <24>   DW_AT_type        : <0x49>
>     ...
>  <2><36>: Abbrev Number: 3 (User TAG value: 0x6000)
>     <37>   DW_AT_name        : (indirect string, offset: 0x4c): btf_decl_tag
>     <3b>   DW_AT_const_value : (indirect string, offset: 0): devicemem
>  <2><3f>: Abbrev Number: 4 (User TAG value: 0x6000)
>     <40>   DW_AT_name        : (indirect string, offset: 0x4c): btf_decl_tag
>     <44>   DW_AT_const_value : __c
>  <2><48>: Abbrev Number: 0
>  <1><49>: Abbrev Number: 5 (DW_TAG_pointer_type)
>  ...
> 
> The DIEs for btf_decl_tag are placed as children of the DIE for
> variable "c".
> 
> BTF Representation
> ==================
> 
> In BTF, BTF_KIND_DECL_TAG records convey the annotations. These records refer
> to the annotated object by BTF type ID, as well as a component index which is
> used for btf_decl_tags placed on struct/union members or function arguments.
> 
> For example, the BTF for the above declaration is:
> 
>   [1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED
>   [2] CONST '(anon)' type_id=1
>   [3] PTR '(anon)' type_id=2
>   [4] DECL_TAG '__c' type_id=6 component_idx=-1
>   [5] DECL_TAG 'devicemem' type_id=6 component_idx=-1
>   [6] VAR 'c' type_id=3, linkage=global
>   ...
> 
> The BTF format is documented here [4].
> 
> 
> References
> ==========
> 
> [1] https://lore.kernel.org/bpf/20210914223004.244411-1-yhs@fb.com/
> [2] https://lore.kernel.org/bpf/20211011040608.3031468-1-yhs@fb.com/
> [3] https://gcc.gnu.org/pipermail/gcc-patches/2022-May/593936.html
> [4] https://www.kernel.org/doc/Documentation/bpf/btf.rst
> 
> 
> David Faust (9):
>   c-family: add btf_decl_tag attribute
>   include: add BTF decl tag defines
>   dwarf: create annotation DIEs for decl tags
>   dwarf: expose get_die_parent
>   ctf: add support to pass through BTF tags
>   dwarf2ctf: convert annotation DIEs to CTF types
>   btf: create and output BTF_KIND_DECL_TAG types
>   testsuite: add tests for BTF decl tags
>   doc: document btf_decl_tag attribute
> 
>  gcc/btfout.cc                                 | 81 ++++++++++++++++++-
>  gcc/c-family/c-attribs.cc                     | 23 ++++++
>  gcc/ctf-int.h                                 | 28 +++++++
>  gcc/ctfc.cc                                   | 10 ++-
>  gcc/ctfc.h                                    | 17 +++-
>  gcc/doc/extend.texi                           | 47 +++++++++++
>  gcc/dwarf2ctf.cc                              | 73 ++++++++++++++++-
>  gcc/dwarf2out.cc                              | 37 ++++++++-
>  gcc/dwarf2out.h                               |  1 +
>  .../gcc.dg/debug/btf/btf-decltag-func.c       | 21 +++++
>  .../gcc.dg/debug/btf/btf-decltag-sou.c        | 33 ++++++++
>  .../gcc.dg/debug/btf/btf-decltag-var.c        | 19 +++++
>  .../gcc.dg/debug/dwarf2/annotation-decl-1.c   |  9 +++
>  .../gcc.dg/debug/dwarf2/annotation-decl-2.c   | 18 +++++
>  .../gcc.dg/debug/dwarf2/annotation-decl-3.c   | 17 ++++
>  include/btf.h                                 | 14 +++-
>  include/dwarf2.def                            |  4 +
>  17 files changed, 437 insertions(+), 15 deletions(-)
>  create mode 100644 gcc/ctf-int.h
>  create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-decltag-func.c
>  create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-decltag-sou.c
>  create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-decltag-var.c
>  create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/annotation-decl-1.c
>  create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/annotation-decl-2.c
>  create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/annotation-decl-3.c
> 

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2023-09-11 21:40 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-07-11 21:57 [PATCH 0/9] Add btf_decl_tag C attribute David Faust
2023-07-11 21:57 ` [PATCH 1/9] c-family: add btf_decl_tag attribute David Faust
2023-07-11 21:57 ` [PATCH 2/9] include: add BTF decl tag defines David Faust
2023-07-11 21:57 ` [PATCH 3/9] dwarf: create annotation DIEs for decl tags David Faust
2023-07-11 21:57 ` [PATCH 4/9] dwarf: expose get_die_parent David Faust
2023-07-11 21:57 ` [PATCH 5/9] ctf: add support to pass through BTF tags David Faust
2023-07-11 21:57 ` [PATCH 6/9] dwarf2ctf: convert annotation DIEs to CTF types David Faust
2023-07-11 21:57 ` [PATCH 7/9] btf: create and output BTF_KIND_DECL_TAG types David Faust
2023-07-11 21:57 ` [PATCH 8/9] testsuite: add tests for BTF decl tags David Faust
2023-07-11 21:57 ` [PATCH 9/9] doc: document btf_decl_tag attribute David Faust
2023-07-12  7:38 ` [PATCH 0/9] Add btf_decl_tag C attribute Richard Biener
2023-07-12 12:43   ` Jose E. Marchesi
2023-07-12 13:21     ` Richard Biener
2023-07-12 13:49       ` Jose E. Marchesi
2023-07-12 19:33         ` David Faust
2023-07-24 15:56 ` David Faust
2023-08-09 21:05 ` [PING 2][PATCH " David Faust
2023-09-11 21:39 ` [PING][PATCH " David Faust

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).