From: Yonghong Song <yhs@fb.com>
To: Arnaldo Carvalho de Melo <arnaldo.melo@gmail.com>,
<dwarves@vger.kernel.org>
Cc: Alexei Starovoitov <ast@kernel.org>,
Andrii Nakryiko <andrii@kernel.org>, <bpf@vger.kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>, <kernel-team@fb.com>
Subject: [PATCH dwarves 2/2] btf: Support BTF_KIND_ENUM64
Date: Mon, 13 Jun 2022 07:44:50 -0700 [thread overview]
Message-ID: <20220613144450.4107806-1-yhs@fb.com> (raw)
In-Reply-To: <20220613144440.4107327-1-yhs@fb.com>
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
prev parent reply other threads:[~2022-06-13 18:30 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
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 [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220613144450.4107806-1-yhs@fb.com \
--to=yhs@fb.com \
--cc=andrii@kernel.org \
--cc=arnaldo.melo@gmail.com \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=dwarves@vger.kernel.org \
--cc=kernel-team@fb.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.