dwarves.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH dwarves 0/2] btf: support BTF_KIND_ENUM64
@ 2022-06-13 14:44 Yonghong Song
  2022-06-13 14:44 ` [PATCH dwarves 1/2] libbpf: Sync with latest libbpf repo Yonghong Song
  2022-06-13 14:44 ` [PATCH dwarves 2/2] btf: Support BTF_KIND_ENUM64 Yonghong Song
  0 siblings, 2 replies; 3+ messages in thread
From: Yonghong Song @ 2022-06-13 14:44 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo, dwarves
  Cc: Alexei Starovoitov, Andrii Nakryiko, bpf, Daniel Borkmann, kernel-team

Add support for enum64. For 64-bit enumerator value,
previously, the value is truncated into 32bit, e.g.,
for the following enum in linux uapi bpf.h,
  enum {
        BPF_F_INDEX_MASK                = 0xffffffffULL,
        BPF_F_CURRENT_CPU               = BPF_F_INDEX_MASK,
  /* BPF_FUNC_perf_event_output for sk_buff input context. */
        BPF_F_CTXLEN_MASK               = (0xfffffULL << 32),
  };

BPF_F_CTXLEN_MASK will be encoded with 0 with BTF_KIND_ENUM
after pahole dwarf-to-btf conversion.
With this patch, the BPF_F_CTXLEN_MASK will be encoded properly
with BTF_KIND_ENUM64.

This patch is on top of tmp.master since tmp.master has not
been sync'ed with master branch yet.

Yonghong Song (2):
  libbpf: Sync with latest libbpf repo
  btf: Support BTF_KIND_ENUM64

 btf_encoder.c     | 38 +++++++++++++++++++++++++++-----------
 dwarf_loader.c    | 12 ++++++++++++
 dwarves.h         |  3 ++-
 dwarves_fprintf.c |  6 +++++-
 lib/bpf           |  2 +-
 5 files changed, 47 insertions(+), 14 deletions(-)

-- 
2.30.2


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

* [PATCH dwarves 1/2] libbpf: Sync with latest libbpf repo
  2022-06-13 14:44 [PATCH dwarves 0/2] btf: support BTF_KIND_ENUM64 Yonghong Song
@ 2022-06-13 14:44 ` Yonghong Song
  2022-06-13 14:44 ` [PATCH dwarves 2/2] btf: Support BTF_KIND_ENUM64 Yonghong Song
  1 sibling, 0 replies; 3+ messages in thread
From: Yonghong Song @ 2022-06-13 14:44 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo, dwarves
  Cc: Alexei Starovoitov, Andrii Nakryiko, bpf, Daniel Borkmann, kernel-team

Sync up to commit
  645500dd7d2d ci: blacklist mptcp test on s390x

Signed-off-by: Yonghong Song <yhs@fb.com>
---
 lib/bpf | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/bpf b/lib/bpf
index 87dff0a..645500d 160000
--- a/lib/bpf
+++ b/lib/bpf
@@ -1 +1 @@
-Subproject commit 87dff0a2c775c5943ca9233e69c81a25f2ed1a77
+Subproject commit 645500dd7d2d6b5bb76e4c0375d597d4f0c4814e
-- 
2.30.2


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

* [PATCH dwarves 2/2] btf: Support BTF_KIND_ENUM64
  2022-06-13 14:44 [PATCH dwarves 0/2] btf: support BTF_KIND_ENUM64 Yonghong Song
  2022-06-13 14:44 ` [PATCH dwarves 1/2] libbpf: Sync with latest libbpf repo Yonghong Song
@ 2022-06-13 14:44 ` Yonghong Song
  1 sibling, 0 replies; 3+ messages in thread
From: Yonghong Song @ 2022-06-13 14:44 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo, dwarves
  Cc: Alexei Starovoitov, Andrii Nakryiko, bpf, Daniel Borkmann, kernel-team

BTF_KIND_ENUM64 is supported with latest libbpf, which
supports 64-bit enum values. Latest libbpf also supports
signedness for enum values. Add enum64 support in
dwarf-to-btf conversion.

The following is an example of new encoding which covers
signed/unsigned enum64/enum variations.

  $cat t.c
  enum { /* signed, enum64 */
    A = -1,
    B = 0xffffffff,
  } g1;
  enum { /* unsigned, enum64 */
    C = 1,
    D = 0xfffffffff,
  } g2;
  enum { /* signed, enum */
    E = -1,
    F = 0xfffffff,
  } g3;
  enum { /* unsigned, enum */
    G = 1,
    H = 0xfffffff,
  } g4;
  $ clang -g -c t.c
  $ pahole -JV t.o
  btf_encoder__new: 't.o' doesn't have '.data..percpu' section
  Found 0 per-CPU variables!
  File t.o:
  [1] ENUM64 (anon) size=8
          A val=-1
          B val=4294967295
  [2] INT long size=8 nr_bits=64 encoding=SIGNED
  [3] ENUM64 (anon) size=8
          C val=1
          D val=68719476735
  [4] INT unsigned long size=8 nr_bits=64 encoding=(none)
  [5] ENUM (anon) size=4
          E val=-1
          F val=268435455
  [6] INT int size=4 nr_bits=32 encoding=SIGNED
  [7] ENUM (anon) size=4
          G val=1
          H val=268435455
  [8] INT unsigned int size=4 nr_bits=32 encoding=(none)

Signed-off-by: Yonghong Song <yhs@fb.com>
---
 btf_encoder.c     | 38 +++++++++++++++++++++++++++-----------
 dwarf_loader.c    | 12 ++++++++++++
 dwarves.h         |  3 ++-
 dwarves_fprintf.c |  6 +++++-
 4 files changed, 46 insertions(+), 13 deletions(-)

diff --git a/btf_encoder.c b/btf_encoder.c
index 9e708e4..4b33b95 100644
--- a/btf_encoder.c
+++ b/btf_encoder.c
@@ -144,6 +144,7 @@ static const char * const btf_kind_str[NR_BTF_KINDS] = {
 	[BTF_KIND_FLOAT]        = "FLOAT",
 	[BTF_KIND_DECL_TAG]     = "DECL_TAG",
 	[BTF_KIND_TYPE_TAG]     = "TYPE_TAG",
+	[BTF_KIND_ENUM64]	= "ENUM64",
 };
 
 static const char *btf__printable_name(const struct btf *btf, uint32_t offset)
@@ -490,34 +491,48 @@ static int32_t btf_encoder__add_struct(struct btf_encoder *encoder, uint8_t kind
 	return id;
 }
 
-static int32_t btf_encoder__add_enum(struct btf_encoder *encoder, const char *name, uint32_t bit_size)
+static int32_t btf_encoder__add_enum(struct btf_encoder *encoder, const char *name, uint32_t bit_size,
+				     bool is_signed)
 {
 	struct btf *btf = encoder->btf;
 	const struct btf_type *t;
 	int32_t id, size;
 
 	size = BITS_ROUNDUP_BYTES(bit_size);
-	id = btf__add_enum(btf, name, size);
+	if (size > 4)
+		id = btf__add_enum64(btf, name, size, is_signed);
+	else
+		id = btf__add_enum(btf, name, size);
 	if (id > 0) {
 		t = btf__type_by_id(btf, id);
 		btf_encoder__log_type(encoder, t, false, true, "size=%u", t->size);
 	} else {
-		btf__log_err(btf, BTF_KIND_ENUM, name, true,
+		btf__log_err(btf, size <= 4 ? BTF_KIND_ENUM : BTF_KIND_ENUM64, name, true,
 			      "size=%u Error emitting BTF type", size);
 	}
 	return id;
 }
 
-static int btf_encoder__add_enum_val(struct btf_encoder *encoder, const char *name, int32_t value)
+static int btf_encoder__add_enum_val(struct btf_encoder *encoder, const char *name, int64_t value,
+				     bool is_signed, bool is_enum64)
 {
-	int err = btf__add_enum_value(encoder->btf, name, value);
+	const char *fmt_str;
+	int err;
+
+	if (is_enum64)
+		err = btf__add_enum64_value(encoder->btf, name, value);
+	else
+		err = btf__add_enum_value(encoder->btf, name, value);
 
 	if (!err) {
-		if (encoder->verbose)
-			printf("\t%s val=%d\n", name, value);
+		if (encoder->verbose) {
+			fmt_str = is_signed ? "\t%s val=%lld\n" : "\t%s val=%llu\n";
+			printf(fmt_str, name, (unsigned long long)value);
+		}
 	} else {
-		fprintf(stderr, "\t%s val=%d Error emitting BTF enum value\n",
-			name, value);
+		fmt_str = is_signed ? "\t%s val=%lld Error emitting BTF enum value\n"
+				    : "\t%s val=%llu Error emitting BTF enum value\n";
+		fprintf(stderr, fmt_str, name, (unsigned long long)value);
 	}
 	return err;
 }
@@ -851,13 +866,14 @@ static int32_t btf_encoder__add_enum_type(struct btf_encoder *encoder, struct ta
 	const char *name = type__name(etype);
 	int32_t type_id;
 
-	type_id = btf_encoder__add_enum(encoder, name, etype->size);
+	type_id = btf_encoder__add_enum(encoder, name, etype->size, etype->is_signed_enum);
 	if (type_id < 0)
 		return type_id;
 
 	type__for_each_enumerator(etype, pos) {
 		name = enumerator__name(pos);
-		if (btf_encoder__add_enum_val(encoder, name, pos->value))
+		if (btf_encoder__add_enum_val(encoder, name, pos->value, etype->is_signed_enum,
+					      etype->size > 32))
 			return -1;
 	}
 
diff --git a/dwarf_loader.c b/dwarf_loader.c
index a0d964b..4767602 100644
--- a/dwarf_loader.c
+++ b/dwarf_loader.c
@@ -632,6 +632,18 @@ static void type__init(struct type *type, Dwarf_Die *die, struct cu *cu, struct
 	type->resized		 = 0;
 	type->nr_members	 = 0;
 	type->nr_static_members	 = 0;
+	type->is_signed_enum	 = 0;
+
+	Dwarf_Attribute attr;
+	if (dwarf_attr(die, DW_AT_type, &attr) != NULL) {
+		Dwarf_Die type_die;
+		if (dwarf_formref_die(&attr, &type_die) != NULL) {
+			uint64_t encoding = attr_numeric(&type_die, DW_AT_encoding);
+
+			if (encoding == DW_ATE_signed || encoding == DW_ATE_signed_char)
+				type->is_signed_enum = 1;
+		}
+	}
 }
 
 static struct type *type__new(Dwarf_Die *die, struct cu *cu, struct conf_load *conf)
diff --git a/dwarves.h b/dwarves.h
index 4d0e4b6..32c9508 100644
--- a/dwarves.h
+++ b/dwarves.h
@@ -1046,6 +1046,7 @@ struct type {
 	uint8_t		 definition_emitted:1;
 	uint8_t		 fwd_decl_emitted:1;
 	uint8_t		 resized:1;
+	uint8_t		 is_signed_enum:1;
 };
 
 void __type__init(struct type *type);
@@ -1365,7 +1366,7 @@ static inline struct string_type *tag__string_type(const struct tag *tag)
 struct enumerator {
 	struct tag	 tag;
 	const char	 *name;
-	uint32_t	 value;
+	uint64_t	 value;
 	struct tag_cu	 type_enum; // To cache the type_enum searches
 };
 
diff --git a/dwarves_fprintf.c b/dwarves_fprintf.c
index 2cec584..ce64c79 100644
--- a/dwarves_fprintf.c
+++ b/dwarves_fprintf.c
@@ -437,7 +437,11 @@ size_t enumeration__fprintf(const struct tag *tag, const struct conf_fprintf *co
 	type__for_each_enumerator(type, pos) {
 		printed += fprintf(fp, "%.*s\t%-*s = ", indent, tabs,
 				   max_entry_name_len, enumerator__name(pos));
-		printed += fprintf(fp, conf->hex_fmt ?  "%#x" : "%u", pos->value);
+		if (conf->hex_fmt)
+			printed += fprintf(fp, "%#llx", (unsigned long long)pos->value);
+		else
+			printed += fprintf(fp, type->is_signed_enum ?  "%lld" : "%llu",
+					   (unsigned long long)pos->value);
 		printed += fprintf(fp, ",\n");
 	}
 
-- 
2.30.2


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

end of thread, other threads:[~2022-06-13 18:30 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-13 14:44 [PATCH dwarves 0/2] btf: support BTF_KIND_ENUM64 Yonghong Song
2022-06-13 14:44 ` [PATCH dwarves 1/2] libbpf: Sync with latest libbpf repo Yonghong Song
2022-06-13 14:44 ` [PATCH dwarves 2/2] btf: Support BTF_KIND_ENUM64 Yonghong Song

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 NNTP newsgroup(s).