All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH dwarves v2 0/2] generate BTF_KIND_TAG types from DW_TAG_LLVM_annotation dwarf tags
@ 2021-09-22  2:13 Yonghong Song
  2021-09-22  2:13 ` [PATCH dwarves v2 1/2] dwarf_loader: parse dwarf tag DW_TAG_LLVM_annotation Yonghong Song
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Yonghong Song @ 2021-09-22  2:13 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo, dwarves
  Cc: Alexei Starovoitov, Andrii Nakryiko, bpf, Daniel Borkmann, kernel-team

LLVM has implemented btf_tag attribute ([1]) which intended
to provide a "string" tag for struct/union or its member, var,
a func or its parameter. Such a "string" tag will be encoded
in dwarf. For non-BPF target like x86_64, pahole needs to
convert those dwarf btf_tag annotations to BTF so kernel
can utilize these "string" tags for bpf program verification, etc.
        
Patch 1 enhanced dwarf_loader to encode DW_TAG_LLVM_annotation
tags into internal data structure and Patch 2 will encode
such information to BTF with BTF_KIND_TAGs.

 [1] https://reviews.llvm.org/D106614

Changelog:
  v1 -> v2:
    - handle returning error cases for btf_encoder__add_tag().

Yonghong Song (2):
  dwarf_loader: parse dwarf tag DW_TAG_LLVM_annotation
  btf_encoder: generate BTF_KIND_TAG from llvm annotations

 btf_encoder.c  | 63 ++++++++++++++++++++++++++++++++++++-
 dwarf_loader.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++----
 dwarves.h      | 10 ++++++
 pahole.c       |  8 +++++
 4 files changed, 159 insertions(+), 7 deletions(-)

-- 
2.30.2


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

* [PATCH dwarves v2 1/2] dwarf_loader: parse dwarf tag DW_TAG_LLVM_annotation
  2021-09-22  2:13 [PATCH dwarves v2 0/2] generate BTF_KIND_TAG types from DW_TAG_LLVM_annotation dwarf tags Yonghong Song
@ 2021-09-22  2:13 ` Yonghong Song
  2021-09-22  2:13 ` [PATCH dwarves v2 2/2] btf_encoder: generate BTF_KIND_TAG from llvm annotations Yonghong Song
  2021-09-27 20:40 ` [PATCH dwarves v2 0/2] generate BTF_KIND_TAG types from DW_TAG_LLVM_annotation dwarf tags Arnaldo Carvalho de Melo
  2 siblings, 0 replies; 5+ messages in thread
From: Yonghong Song @ 2021-09-22  2:13 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo, dwarves
  Cc: Alexei Starovoitov, Andrii Nakryiko, bpf, Daniel Borkmann, kernel-team

Parse dwarf tag DW_TAG_LLVM_annotation. Only record
annotations with btf_tag name which corresponds to
btf_tag attributes in C code. Such information will
be used later by btf_encoder for BTF conversion.

LLVM implementation only supports btf_tag annotations
on struct/union, func, func parameter and variable ([1]).
So we only check existence of corresponding DW tags
in these places. A flag "--skip_encoding_btf_tag"
is introduced if for whatever reason this feature
needs to be disabled.

 [1] https://reviews.llvm.org/D106614

Acked-by: Andrii Nakryiko <andrii@kernel.org>
Signed-off-by: Yonghong Song <yhs@fb.com>
---
 dwarf_loader.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++----
 dwarves.h      | 10 ++++++
 pahole.c       |  8 +++++
 3 files changed, 97 insertions(+), 6 deletions(-)

diff --git a/dwarf_loader.c b/dwarf_loader.c
index 0213e42..48e1bf0 100644
--- a/dwarf_loader.c
+++ b/dwarf_loader.c
@@ -52,6 +52,10 @@
 #define DW_OP_addrx 0xa1
 #endif
 
+#ifndef DW_TAG_LLVM_annotation
+#define DW_TAG_LLVM_annotation 0x6000
+#endif
+
 static pthread_mutex_t libdw__lock = PTHREAD_MUTEX_INITIALIZER;
 
 static uint32_t hashtags__bits = 12;
@@ -602,6 +606,7 @@ static void namespace__init(struct namespace *namespace, Dwarf_Die *die,
 {
 	tag__init(&namespace->tag, cu, die);
 	INIT_LIST_HEAD(&namespace->tags);
+	INIT_LIST_HEAD(&namespace->annots);
 	namespace->name  = attr_string(die, DW_AT_name, conf);
 	namespace->nr_tags = 0;
 	namespace->shared_tags = 0;
@@ -719,6 +724,7 @@ static struct variable *variable__new(Dwarf_Die *die, struct cu *cu, struct conf
 		/* non-defining declaration of an object */
 		var->declaration = dwarf_hasattr(die, DW_AT_declaration);
 		var->scope = VSCOPE_UNKNOWN;
+		INIT_LIST_HEAD(&var->annots);
 		var->ip.addr = 0;
 		if (!var->declaration && cu->has_addr_info)
 			var->scope = dwarf__location(die, &var->ip.addr, &var->location);
@@ -854,6 +860,51 @@ static int tag__recode_dwarf_bitfield(struct tag *tag, struct cu *cu, uint16_t b
 	return -ENOMEM;
 }
 
+static int add_llvm_annotation(Dwarf_Die *die, int component_idx, struct conf_load *conf,
+			       struct list_head *head)
+{
+	struct llvm_annotation *annot;
+	const char *name;
+
+	if (conf->skip_encoding_btf_tag)
+		return 0;
+
+	/* Only handle btf_tag annotation for now. */
+	name = attr_string(die, DW_AT_name, conf);
+	if (strcmp(name, "btf_tag") != 0)
+		return 0;
+
+	annot = zalloc(sizeof(*annot));
+	if (!annot)
+		return -ENOMEM;
+
+	annot->value = attr_string(die, DW_AT_const_value, conf);
+	annot->component_idx = component_idx;
+	list_add_tail(&annot->node, head);
+	return 0;
+}
+
+static int add_child_llvm_annotations(Dwarf_Die *die, int component_idx,
+				      struct conf_load *conf, struct list_head *head)
+{
+	Dwarf_Die child;
+	int ret;
+
+	if (!dwarf_haschildren(die) || dwarf_child(die, &child) != 0)
+		return 0;
+
+	die = &child;
+	do {
+		if (dwarf_tag(die) == DW_TAG_LLVM_annotation) {
+			ret = add_llvm_annotation(die, component_idx, conf, head);
+			if (ret)
+				return ret;
+		}
+	} while (dwarf_siblingof(die, die) == 0);
+
+	return 0;
+}
+
 int class_member__dwarf_recode_bitfield(struct class_member *member,
 					struct cu *cu)
 {
@@ -1092,6 +1143,7 @@ static struct function *function__new(Dwarf_Die *die, struct cu *cu, struct conf
 		func->accessibility   = attr_numeric(die, DW_AT_accessibility);
 		func->virtuality      = attr_numeric(die, DW_AT_virtuality);
 		INIT_LIST_HEAD(&func->vtable_node);
+		INIT_LIST_HEAD(&func->annots);
 		INIT_LIST_HEAD(&func->tool_node);
 		func->vtable_entry    = -1;
 		if (dwarf_hasattr(die, DW_AT_vtable_elem_location))
@@ -1304,16 +1356,21 @@ static struct tag *die__create_new_string_type(Dwarf_Die *die, struct cu *cu)
 static struct tag *die__create_new_parameter(Dwarf_Die *die,
 					     struct ftype *ftype,
 					     struct lexblock *lexblock,
-					     struct cu *cu, struct conf_load *conf)
+					     struct cu *cu, struct conf_load *conf,
+					     int param_idx)
 {
 	struct parameter *parm = parameter__new(die, cu, conf);
 
 	if (parm == NULL)
 		return NULL;
 
-	if (ftype != NULL)
+	if (ftype != NULL) {
 		ftype__add_parameter(ftype, parm);
-	else {
+		if (param_idx >= 0) {
+			if (add_child_llvm_annotations(die, param_idx, conf, &(tag__function(&ftype->tag)->annots)))
+				return NULL;
+		}
+	} else {
 		/*
 		 * DW_TAG_formal_parameters on a non DW_TAG_subprogram nor
 		 * DW_TAG_subroutine_type tag happens sometimes, likely due to
@@ -1346,7 +1403,10 @@ static struct tag *die__create_new_variable(Dwarf_Die *die, struct cu *cu, struc
 {
 	struct variable *var = variable__new(die, cu, conf);
 
-	return var ? &var->ip.tag : NULL;
+	if (var == NULL || add_child_llvm_annotations(die, -1, conf, &var->annots))
+		return NULL;
+
+	return &var->ip.tag;
 }
 
 static struct tag *die__create_new_subroutine_type(Dwarf_Die *die,
@@ -1371,7 +1431,7 @@ static struct tag *die__create_new_subroutine_type(Dwarf_Die *die,
 			tag__print_not_supported(dwarf_tag(die));
 			continue;
 		case DW_TAG_formal_parameter:
-			tag = die__create_new_parameter(die, ftype, NULL, cu, conf);
+			tag = die__create_new_parameter(die, ftype, NULL, cu, conf, -1);
 			break;
 		case DW_TAG_unspecified_parameters:
 			ftype->unspec_parms = 1;
@@ -1455,6 +1515,7 @@ static int die__process_class(Dwarf_Die *die, struct type *class,
 			      struct cu *cu, struct conf_load *conf)
 {
 	const bool is_union = tag__is_union(&class->namespace.tag);
+	int member_idx = 0;
 
 	do {
 		switch (dwarf_tag(die)) {
@@ -1497,8 +1558,15 @@ static int die__process_class(Dwarf_Die *die, struct type *class,
 
 			type__add_member(class, member);
 			cu__hash(cu, &member->tag);
+			if (add_child_llvm_annotations(die, member_idx, conf, &class->namespace.annots))
+				return -ENOMEM;
+			member_idx++;
 		}
 			continue;
+		case DW_TAG_LLVM_annotation:
+			if (add_llvm_annotation(die, -1, conf, &class->namespace.annots))
+				return -ENOMEM;
+			continue;
 		default: {
 			struct tag *tag = die__process_tag(die, cu, 0, conf);
 
@@ -1699,6 +1767,7 @@ static struct tag *die__create_new_inline_expansion(Dwarf_Die *die,
 static int die__process_function(Dwarf_Die *die, struct ftype *ftype,
 				 struct lexblock *lexblock, struct cu *cu, struct conf_load *conf)
 {
+	int param_idx = 0;
 	Dwarf_Die child;
 	struct tag *tag;
 
@@ -1742,7 +1811,7 @@ static int die__process_function(Dwarf_Die *die, struct ftype *ftype,
 			tag__print_not_supported(dwarf_tag(die));
 			continue;
 		case DW_TAG_formal_parameter:
-			tag = die__create_new_parameter(die, ftype, lexblock, cu, conf);
+			tag = die__create_new_parameter(die, ftype, lexblock, cu, conf, param_idx++);
 			break;
 		case DW_TAG_variable:
 			tag = die__create_new_variable(die, cu, conf);
@@ -1771,6 +1840,10 @@ static int die__process_function(Dwarf_Die *die, struct ftype *ftype,
 			if (die__create_new_lexblock(die, cu, lexblock, conf) != 0)
 				goto out_enomem;
 			continue;
+		case DW_TAG_LLVM_annotation:
+			if (add_llvm_annotation(die, -1, conf, &(tag__function(&ftype->tag)->annots)))
+				goto out_enomem;
+			continue;
 		default:
 			tag = die__process_tag(die, cu, 0, conf);
 
diff --git a/dwarves.h b/dwarves.h
index 0b69312..30d33fa 100644
--- a/dwarves.h
+++ b/dwarves.h
@@ -58,6 +58,7 @@ struct conf_load {
 	bool			ignore_inline_expansions;
 	bool			ignore_labels;
 	bool			ptr_table_stats;
+	bool			skip_encoding_btf_tag;
 	uint8_t			hashtable_bits;
 	uint8_t			max_hashtable_bits;
 	uint16_t		kabi_prefix_len;
@@ -594,6 +595,12 @@ static inline struct ptr_to_member_type *
 	return (struct ptr_to_member_type *)tag;
 }
 
+struct llvm_annotation {
+	const char		*value;
+	int16_t			component_idx;
+	struct list_head	node;
+};
+
 /** struct namespace - base class for enums, structs, unions, typedefs, etc
  *
  * @tags - class_member, enumerators, etc
@@ -605,6 +612,7 @@ struct namespace {
 	uint16_t	 nr_tags;
 	uint8_t		 shared_tags;
 	struct list_head tags;
+	struct list_head annots;
 };
 
 static inline struct namespace *tag__namespace(const struct tag *tag)
@@ -686,6 +694,7 @@ struct variable {
 	enum vscope	 scope;
 	struct location	 location;
 	struct hlist_node tool_hnode;
+	struct list_head annots;
 	struct variable  *spec;
 };
 
@@ -818,6 +827,7 @@ struct function {
 	uint8_t		 btf:1;
 	int32_t		 vtable_entry;
 	struct list_head vtable_node;
+	struct list_head annots;
 	/* fields used by tools */
 	union {
 		struct list_head  tool_node;
diff --git a/pahole.c b/pahole.c
index 7f1771b..80271b5 100644
--- a/pahole.c
+++ b/pahole.c
@@ -1124,6 +1124,7 @@ ARGP_PROGRAM_VERSION_HOOK_DEF = dwarves_print_version;
 #define ARGP_sort_output	   328
 #define ARGP_hashbits		   329
 #define ARGP_devel_stats	   330
+#define ARGP_skip_encoding_btf_tag 331
 
 static const struct argp_option pahole__options[] = {
 	{
@@ -1494,6 +1495,11 @@ static const struct argp_option pahole__options[] = {
 		.key  = ARGP_devel_stats,
 		.doc  = "Print internal data structures stats",
 	},
+	{
+		.name = "skip_encoding_btf_tag",
+		.key  = ARGP_skip_encoding_btf_tag,
+		.doc  = "Do not encode TAGs in BTF."
+	},
 	{
 		.name = NULL,
 	}
@@ -1642,6 +1648,8 @@ static error_t pahole__options_parser(int key, char *arg,
 		conf_load.hashtable_bits = atoi(arg);	break;
 	case ARGP_devel_stats:
 		conf_load.ptr_table_stats = true;	break;
+	case ARGP_skip_encoding_btf_tag:
+		conf_load.skip_encoding_btf_tag = true;	break;
 	default:
 		return ARGP_ERR_UNKNOWN;
 	}
-- 
2.30.2


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

* [PATCH dwarves v2 2/2] btf_encoder: generate BTF_KIND_TAG from llvm annotations
  2021-09-22  2:13 [PATCH dwarves v2 0/2] generate BTF_KIND_TAG types from DW_TAG_LLVM_annotation dwarf tags Yonghong Song
  2021-09-22  2:13 ` [PATCH dwarves v2 1/2] dwarf_loader: parse dwarf tag DW_TAG_LLVM_annotation Yonghong Song
@ 2021-09-22  2:13 ` Yonghong Song
  2021-09-27 20:40 ` [PATCH dwarves v2 0/2] generate BTF_KIND_TAG types from DW_TAG_LLVM_annotation dwarf tags Arnaldo Carvalho de Melo
  2 siblings, 0 replies; 5+ messages in thread
From: Yonghong Song @ 2021-09-22  2:13 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo, dwarves
  Cc: Alexei Starovoitov, Andrii Nakryiko, bpf, Daniel Borkmann, kernel-team

The following is an example with latest upstream clang:
  $ cat t.c
  #define __tag1 __attribute__((btf_tag("tag1")))
  #define __tag2 __attribute__((btf_tag("tag2")))

  struct t {
          int a:1 __tag1;
          int b __tag2;
  } __tag1 __tag2;

  int g __tag1 __attribute__((section(".data..percpu")));

  int __tag1 foo(struct t *a1, int a2 __tag2) {
    return a1->b + a2 + g;
  }

  $ clang -O2 -g -c t.c
  $ pahole -JV t.o
  Found per-CPU symbol 'g' at address 0x0
  Found 1 per-CPU variables!
  Found 1 functions!
  File t.o:
  [1] INT int size=4 nr_bits=32 encoding=SIGNED
  [2] PTR (anon) type_id=3
  [3] STRUCT t size=8
        a type_id=1 bitfield_size=1 bits_offset=0
        b type_id=1 bitfield_size=0 bits_offset=32
  [4] TAG tag1 type_id=3 component_idx=0
  [5] TAG tag2 type_id=3 component_idx=1
  [6] TAG tag1 type_id=3 component_idx=-1
  [7] TAG tag2 type_id=3 component_idx=-1
  [8] FUNC_PROTO (anon) return=1 args=(2 a1, 1 a2)
  [9] FUNC foo type_id=8
  [10] TAG tag2 type_id=9 component_idx=1
  [11] TAG tag1 type_id=9 component_idx=-1
  search cu 't.c' for percpu global variables.
  Variable 'g' from CU 't.c' at address 0x0 encoded
  [12] VAR g type=1 linkage=1
  [13] TAG tag1 type_id=12 component_idx=-1
  [14] DATASEC .data..percpu size=4 vlen=1
        type=12 offset=0 size=4
  $ ...

With additional option --skip_encoding_btf_tag, pahole doesn't
generate BTF_KIND_TAGs any more.
  $ pahole -JV --skip_encoding_btf_tag t.o
  Found per-CPU symbol 'g' at address 0x0
  Found 1 per-CPU variables!
  Found 1 functions!
  File t.o:
  [1] INT int size=4 nr_bits=32 encoding=SIGNED
  [2] PTR (anon) type_id=3
  [3] STRUCT t size=8
        a type_id=1 bitfield_size=1 bits_offset=0
        b type_id=1 bitfield_size=0 bits_offset=32
  [4] FUNC_PROTO (anon) return=1 args=(2 a1, 1 a2)
  [5] FUNC foo type_id=4
  search cu 't.c' for percpu global variables.
  Variable 'g' from CU 't.c' at address 0x0 encoded
  [6] VAR g type=1 linkage=1
  [7] DATASEC .data..percpu size=4 vlen=1
        type=6 offset=0 size=4
  $ ...

Signed-off-by: Yonghong Song <yhs@fb.com>
---
 btf_encoder.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 62 insertions(+), 1 deletion(-)

diff --git a/btf_encoder.c b/btf_encoder.c
index 1b4e83d..c341f95 100644
--- a/btf_encoder.c
+++ b/btf_encoder.c
@@ -141,6 +141,7 @@ static const char * const btf_kind_str[NR_BTF_KINDS] = {
 	[BTF_KIND_VAR]          = "VAR",
 	[BTF_KIND_DATASEC]      = "DATASEC",
 	[BTF_KIND_FLOAT]        = "FLOAT",
+	[BTF_KIND_TAG]          = "TAG",
 };
 
 static const char *btf__printable_name(const struct btf *btf, uint32_t offset)
@@ -644,6 +645,26 @@ static int32_t btf_encoder__add_datasec(struct btf_encoder *encoder, const char
 	return id;
 }
 
+static int32_t btf_encoder__add_tag(struct btf_encoder *encoder, const char *value, uint32_t type,
+				    int component_idx)
+{
+	struct btf *btf = encoder->btf;
+	const struct btf_type *t;
+	int32_t id;
+
+	id = btf__add_tag(btf, value, type, component_idx);
+	if (id > 0) {
+		t = btf__type_by_id(btf, id);
+		btf_encoder__log_type(encoder, t, false, true, "type_id=%u component_idx=%d",
+				      t->type, component_idx);
+	} else {
+		btf__log_err(btf, BTF_KIND_TAG, value, true, "component_idx=%d Error emitting BTF type",
+			     component_idx);
+	}
+
+	return id;
+}
+
 /*
  * This corresponds to the same macro defined in
  * include/linux/kallsyms.h
@@ -1158,6 +1179,7 @@ static int btf_encoder__encode_cu_variables(struct btf_encoder *encoder, struct
 		struct variable *var = tag__variable(pos);
 		uint32_t size, type, linkage;
 		const char *name, *dwarf_name;
+		struct llvm_annotation *annot;
 		const struct tag *tag;
 		uint64_t addr;
 		int id;
@@ -1244,6 +1266,15 @@ static int btf_encoder__encode_cu_variables(struct btf_encoder *encoder, struct
 			goto out;
 		}
 
+		list_for_each_entry(annot, &var->annots, node) {
+			int tag_type_id = btf_encoder__add_tag(encoder, annot->value, id, annot->component_idx);
+			if (tag_type_id < 0) {
+				fprintf(stderr, "error: failed to encode tag '%s' to variable '%s' with component_idx %d\n",
+					annot->value, name, annot->component_idx);
+				goto out;
+			}
+		}
+
 		/*
 		 * add a BTF_VAR_SECINFO in encoder->percpu_secinfo, which will be added into
 		 * encoder->types later when we add BTF_VAR_DATASEC.
@@ -1359,6 +1390,8 @@ void btf_encoder__delete(struct btf_encoder *encoder)
 int btf_encoder__encode_cu(struct btf_encoder *encoder, struct cu *cu)
 {
 	uint32_t type_id_off = btf__get_nr_types(encoder->btf);
+	struct llvm_annotation *annot;
+	int btf_type_id, tag_type_id;
 	uint32_t core_id;
 	struct function *fn;
 	struct tag *pos;
@@ -1378,7 +1411,7 @@ int btf_encoder__encode_cu(struct btf_encoder *encoder, struct cu *cu)
 	}
 
 	cu__for_each_type(cu, core_id, pos) {
-		int32_t btf_type_id = btf_encoder__encode_tag(encoder, pos, type_id_off);
+		btf_type_id = btf_encoder__encode_tag(encoder, pos, type_id_off);
 
 		if (btf_type_id < 0 ||
 		    tag__check_id_drift(pos, core_id, btf_type_id, type_id_off)) {
@@ -1396,6 +1429,25 @@ int btf_encoder__encode_cu(struct btf_encoder *encoder, struct cu *cu)
 		encoder->has_index_type = true;
 	}
 
+	cu__for_each_type(cu, core_id, pos) {
+		struct namespace *ns;
+
+		if (pos->tag != DW_TAG_structure_type && pos->tag != DW_TAG_union_type)
+			continue;
+
+		btf_type_id = type_id_off + core_id;
+		ns = tag__namespace(pos);
+		list_for_each_entry(annot, &ns->annots, node) {
+			tag_type_id = btf_encoder__add_tag(encoder, annot->value, btf_type_id, annot->component_idx);
+			if (tag_type_id < 0) {
+				fprintf(stderr, "error: failed to encode tag '%s' to %s '%s' with component_idx %d\n",
+					annot->value, pos->tag == DW_TAG_structure_type ? "struct" : "union",
+					namespace__name(ns), annot->component_idx);
+				goto out;
+			}
+		}
+	}
+
 	cu__for_each_function(cu, core_id, fn) {
 		int btf_fnproto_id, btf_fn_id;
 		const char *name;
@@ -1436,6 +1488,15 @@ int btf_encoder__encode_cu(struct btf_encoder *encoder, struct cu *cu)
 			printf("error: failed to encode function '%s'\n", function__name(fn));
 			goto out;
 		}
+
+		list_for_each_entry(annot, &fn->annots, node) {
+			tag_type_id = btf_encoder__add_tag(encoder, annot->value, btf_fn_id, annot->component_idx);
+			if (tag_type_id < 0) {
+				fprintf(stderr, "error: failed to encode tag '%s' to func %s with component_idx %d\n",
+					annot->value, name, annot->component_idx);
+				goto out;
+			}
+		}
 	}
 
 	if (!encoder->skip_encoding_vars)
-- 
2.30.2


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

* Re: [PATCH dwarves v2 0/2] generate BTF_KIND_TAG types from DW_TAG_LLVM_annotation dwarf tags
  2021-09-22  2:13 [PATCH dwarves v2 0/2] generate BTF_KIND_TAG types from DW_TAG_LLVM_annotation dwarf tags Yonghong Song
  2021-09-22  2:13 ` [PATCH dwarves v2 1/2] dwarf_loader: parse dwarf tag DW_TAG_LLVM_annotation Yonghong Song
  2021-09-22  2:13 ` [PATCH dwarves v2 2/2] btf_encoder: generate BTF_KIND_TAG from llvm annotations Yonghong Song
@ 2021-09-27 20:40 ` Arnaldo Carvalho de Melo
  2021-09-27 20:59   ` Arnaldo Carvalho de Melo
  2 siblings, 1 reply; 5+ messages in thread
From: Arnaldo Carvalho de Melo @ 2021-09-27 20:40 UTC (permalink / raw)
  To: Yonghong Song
  Cc: Arnaldo Carvalho de Melo, dwarves, Alexei Starovoitov,
	Andrii Nakryiko, bpf, Daniel Borkmann, kernel-team

Em Tue, Sep 21, 2021 at 07:13:21PM -0700, Yonghong Song escreveu:
> LLVM has implemented btf_tag attribute ([1]) which intended
> to provide a "string" tag for struct/union or its member, var,
> a func or its parameter. Such a "string" tag will be encoded
> in dwarf. For non-BPF target like x86_64, pahole needs to
> convert those dwarf btf_tag annotations to BTF so kernel
> can utilize these "string" tags for bpf program verification, etc.
>         
> Patch 1 enhanced dwarf_loader to encode DW_TAG_LLVM_annotation
> tags into internal data structure and Patch 2 will encode
> such information to BTF with BTF_KIND_TAGs.
> 
>  [1] https://reviews.llvm.org/D106614

Applied both locally, now building HEAD llvm/clang to test everything,

- Arnaldo
 
> Changelog:
>   v1 -> v2:
>     - handle returning error cases for btf_encoder__add_tag().
> 
> Yonghong Song (2):
>   dwarf_loader: parse dwarf tag DW_TAG_LLVM_annotation
>   btf_encoder: generate BTF_KIND_TAG from llvm annotations
> 
>  btf_encoder.c  | 63 ++++++++++++++++++++++++++++++++++++-
>  dwarf_loader.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++----
>  dwarves.h      | 10 ++++++
>  pahole.c       |  8 +++++
>  4 files changed, 159 insertions(+), 7 deletions(-)
> 
> -- 
> 2.30.2

-- 

- Arnaldo

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

* Re: [PATCH dwarves v2 0/2] generate BTF_KIND_TAG types from DW_TAG_LLVM_annotation dwarf tags
  2021-09-27 20:40 ` [PATCH dwarves v2 0/2] generate BTF_KIND_TAG types from DW_TAG_LLVM_annotation dwarf tags Arnaldo Carvalho de Melo
@ 2021-09-27 20:59   ` Arnaldo Carvalho de Melo
  0 siblings, 0 replies; 5+ messages in thread
From: Arnaldo Carvalho de Melo @ 2021-09-27 20:59 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Yonghong Song, dwarves, Alexei Starovoitov, Andrii Nakryiko, bpf,
	Daniel Borkmann, kernel-team

Em Mon, Sep 27, 2021 at 05:40:09PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Tue, Sep 21, 2021 at 07:13:21PM -0700, Yonghong Song escreveu:
> > LLVM has implemented btf_tag attribute ([1]) which intended
> > to provide a "string" tag for struct/union or its member, var,
> > a func or its parameter. Such a "string" tag will be encoded
> > in dwarf. For non-BPF target like x86_64, pahole needs to
> > convert those dwarf btf_tag annotations to BTF so kernel
> > can utilize these "string" tags for bpf program verification, etc.
> >         
> > Patch 1 enhanced dwarf_loader to encode DW_TAG_LLVM_annotation
> > tags into internal data structure and Patch 2 will encode
> > such information to BTF with BTF_KIND_TAGs.
> > 
> >  [1] https://reviews.llvm.org/D106614
> 
> Applied both locally, now building HEAD llvm/clang to test everything,

⬢[acme@toolbox pahole]$ pahole -JV t.o
Found per-CPU symbol 'g' at address 0x0
Found 1 per-CPU variables!
Found 1 functions!
File t.o:
[1] INT int size=4 nr_bits=32 encoding=SIGNED
[2] PTR (anon) type_id=3
[3] STRUCT t size=8
	a type_id=1 bitfield_size=1 bits_offset=0
	b type_id=1 bitfield_size=0 bits_offset=32
[4] TAG tag1 type_id=3 component_idx=0
[5] TAG tag2 type_id=3 component_idx=1
[6] TAG tag1 type_id=3 component_idx=-1
[7] TAG tag2 type_id=3 component_idx=-1
[8] FUNC_PROTO (anon) return=1 args=(2 a1, 1 a2)
[9] FUNC foo type_id=8
[10] TAG tag2 type_id=9 component_idx=1
[11] TAG tag1 type_id=9 component_idx=-1
search cu 't.c' for percpu global variables.
Variable 'g' from CU 't.c' at address 0x0 encoded
[12] VAR g type=1 linkage=1
[13] TAG tag1 type_id=12 component_idx=-1
[14] DATASEC .data..percpu size=4 vlen=1
	type=12 offset=0 size=4
⬢[acme@toolbox pahole]$ pahole -JV --skip_encoding_btf_tag t.o
Found per-CPU symbol 'g' at address 0x0
Found 1 per-CPU variables!
Found 1 functions!
File t.o:
[1] INT int size=4 nr_bits=32 encoding=SIGNED
[2] PTR (anon) type_id=3
[3] STRUCT t size=8
	a type_id=1 bitfield_size=1 bits_offset=0
	b type_id=1 bitfield_size=0 bits_offset=32
[4] FUNC_PROTO (anon) return=1 args=(2 a1, 1 a2)
[5] FUNC foo type_id=4
search cu 't.c' for percpu global variables.
Variable 'g' from CU 't.c' at address 0x0 encoded
[6] VAR g type=1 linkage=1
[7] DATASEC .data..percpu size=4 vlen=1
	type=6 offset=0 size=4
⬢[acme@toolbox pahole]$ clang -v
clang version 14.0.0 (https://github.com/llvm/llvm-project f7e82e4fa849376ea9226220847a098dc92d74a0)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/local/bin
Found candidate GCC installation: /usr/lib/gcc/x86_64-redhat-linux/11
Selected GCC installation: /usr/lib/gcc/x86_64-redhat-linux/11
Candidate multilib: .;@m64
Candidate multilib: 32;@m32
Selected multilib: .;@m64
⬢[acme@toolbox pahole]$

And the usual:

⬢[acme@toolbox pahole]$ pahole -J vmlinux
⬢[acme@toolbox pahole]$ btfdiff vmlinux
⬢[acme@toolbox pahole]$

So applied, pushing out to the tmp.master branch so that libbpf's CI can
have a go at it, then after the next run I'll push to master, thanks!

- Arnaldo

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

end of thread, other threads:[~2021-09-27 20:59 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-22  2:13 [PATCH dwarves v2 0/2] generate BTF_KIND_TAG types from DW_TAG_LLVM_annotation dwarf tags Yonghong Song
2021-09-22  2:13 ` [PATCH dwarves v2 1/2] dwarf_loader: parse dwarf tag DW_TAG_LLVM_annotation Yonghong Song
2021-09-22  2:13 ` [PATCH dwarves v2 2/2] btf_encoder: generate BTF_KIND_TAG from llvm annotations Yonghong Song
2021-09-27 20:40 ` [PATCH dwarves v2 0/2] generate BTF_KIND_TAG types from DW_TAG_LLVM_annotation dwarf tags Arnaldo Carvalho de Melo
2021-09-27 20:59   ` Arnaldo Carvalho de Melo

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.