forked from pool/dwarves
Accepting request 1066420 from devel:tools
OBS-URL: https://build.opensuse.org/request/show/1066420 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/dwarves?expand=0&rev=38factory
commit
5cf24e0915
@ -0,0 +1,62 @@
|
||||
From 5d27afaf31ac124edfef09862d26247b2c12b6a1 Mon Sep 17 00:00:00 2001
|
||||
From: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Date: Tue, 4 Oct 2022 18:09:33 -0300
|
||||
Subject: [PATCH 1/7] pahole: Support '--lang/--lang_exclude=asm'
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
It is disjoint from the other languages and then the first simple
|
||||
implementation of language inclusion/exclusion didn't support it, add
|
||||
an special case to test against 0x8001 (DW_LANG_Mips_Assembler) to cover
|
||||
that.
|
||||
|
||||
This is needed as recently compilers started to add DWARF constructs to
|
||||
represent asm CUs that broke pahole as it didn't support
|
||||
DW_TAG_unspecified_type as a "type", so add it in case in the future we
|
||||
want to exclude such CUs.
|
||||
|
||||
The DW_TAG_unspecified_type tag is going to be supported in the next
|
||||
csets tho.
|
||||
|
||||
We also may want this to exclude new tags that aren't supported in BTF,
|
||||
etc.
|
||||
|
||||
Cc: Martin Liška <mliska@suse.cz>
|
||||
Cc: Nick Clifton <nickc@redhat.com>
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
---
|
||||
dwarves.c | 3 +++
|
||||
man-pages/pahole.1 | 2 +-
|
||||
2 files changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dwarves.c b/dwarves.c
|
||||
index db1dcf5904bc98fe..32bfec5ea0f1a338 100644
|
||||
--- a/dwarves.c
|
||||
+++ b/dwarves.c
|
||||
@@ -2127,6 +2127,9 @@ int lang__str2int(const char *lang)
|
||||
[DW_LANG_UPC] = "upc",
|
||||
};
|
||||
|
||||
+ if (strcasecmp(lang, "asm") == 0)
|
||||
+ return DW_LANG_Mips_Assembler;
|
||||
+
|
||||
// c89 is the first, bliss is the last, see /usr/include/dwarf.h
|
||||
for (int id = DW_LANG_C89; id <= DW_LANG_BLISS; ++id)
|
||||
if (languages[id] && strcasecmp(lang, languages[id]) == 0)
|
||||
diff --git a/man-pages/pahole.1 b/man-pages/pahole.1
|
||||
index bb88e2f5f55a2ee9..f60713a7118d9b63 100644
|
||||
--- a/man-pages/pahole.1
|
||||
+++ b/man-pages/pahole.1
|
||||
@@ -378,7 +378,7 @@ Only process compilation units built from source code written in the specified l
|
||||
|
||||
Supported languages:
|
||||
|
||||
- ada83, ada95, bliss, c, c89, c99, c11, c++, c++03, c++11, c++14, cobol74,
|
||||
+ ada83, ada95, asm, bliss, c, c89, c99, c11, c++, c++03, c++11, c++14, cobol74,
|
||||
cobol85, d, dylan, fortran77, fortran90, fortran95, fortran03, fortran08,
|
||||
go, haskell, java, julia, modula2, modula3, objc, objc++, ocaml, opencl,
|
||||
pascal83, pli, python, renderscript, rust, swift, upc
|
||||
--
|
||||
2.39.1
|
||||
|
@ -0,0 +1,39 @@
|
||||
From 145fd522e786962dd00f946c574a8d59daf945b4 Mon Sep 17 00:00:00 2001
|
||||
From: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Date: Tue, 4 Oct 2022 18:19:46 -0300
|
||||
Subject: [PATCH 2/7] btf_encoder: Add extra debug info for unsupported DWARF
|
||||
tags
|
||||
|
||||
Recently we got a report of DW_TAG_unspecified_type triggering this
|
||||
warning:
|
||||
|
||||
[ 1413s] BTF .btf.vmlinux.bin.o
|
||||
[ 1413s] Unsupported DW_TAG_unspecified_type(0x3b)
|
||||
[ 1413s] Encountered error while encoding BTF.
|
||||
|
||||
Probably tag->type is zero, but would be great to have this offhand, add
|
||||
that info to the error message.
|
||||
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
---
|
||||
btf_encoder.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/btf_encoder.c b/btf_encoder.c
|
||||
index daa8e3b507d4a856..babeefa0dc51e62b 100644
|
||||
--- a/btf_encoder.c
|
||||
+++ b/btf_encoder.c
|
||||
@@ -940,8 +940,8 @@ static int btf_encoder__encode_tag(struct btf_encoder *encoder, struct tag *tag,
|
||||
case DW_TAG_subroutine_type:
|
||||
return btf_encoder__add_func_proto(encoder, tag__ftype(tag), type_id_off);
|
||||
default:
|
||||
- fprintf(stderr, "Unsupported DW_TAG_%s(0x%x)\n",
|
||||
- dwarf_tag_name(tag->tag), tag->tag);
|
||||
+ fprintf(stderr, "Unsupported DW_TAG_%s(0x%x): type: 0x%x\n",
|
||||
+ dwarf_tag_name(tag->tag), tag->tag, ref_type_id);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
--
|
||||
2.39.1
|
||||
|
@ -0,0 +1,65 @@
|
||||
From 79f560f1418f7cacb50746c33a116f8ab5396a2d Mon Sep 17 00:00:00 2001
|
||||
From: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Date: Mon, 10 Oct 2022 09:34:53 -0300
|
||||
Subject: [PATCH 3/7] btf_encoder: Store the CU being processed to avoid
|
||||
changing many functions
|
||||
|
||||
Having it as encoder->cu will make it available to nested function
|
||||
without requiring changing all the functions leading to them.
|
||||
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
---
|
||||
btf_encoder.c | 11 +++++++++--
|
||||
1 file changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/btf_encoder.c b/btf_encoder.c
|
||||
index babeefa0dc51e62b..e74862cfc0a3a802 100644
|
||||
--- a/btf_encoder.c
|
||||
+++ b/btf_encoder.c
|
||||
@@ -44,9 +44,13 @@ struct var_info {
|
||||
uint32_t sz;
|
||||
};
|
||||
|
||||
+/*
|
||||
+ * cu: cu being processed.
|
||||
+ */
|
||||
struct btf_encoder {
|
||||
struct list_head node;
|
||||
struct btf *btf;
|
||||
+ struct cu *cu;
|
||||
struct gobuffer percpu_secinfo;
|
||||
const char *filename;
|
||||
struct elf_symtab *symtab;
|
||||
@@ -1232,8 +1236,9 @@ static bool ftype__has_arg_names(const struct ftype *ftype)
|
||||
return true;
|
||||
}
|
||||
|
||||
-static int btf_encoder__encode_cu_variables(struct btf_encoder *encoder, struct cu *cu, uint32_t type_id_off)
|
||||
+static int btf_encoder__encode_cu_variables(struct btf_encoder *encoder, uint32_t type_id_off)
|
||||
{
|
||||
+ struct cu *cu = encoder->cu;
|
||||
uint32_t core_id;
|
||||
struct tag *pos;
|
||||
int err = -1;
|
||||
@@ -1465,6 +1470,7 @@ int btf_encoder__encode_cu(struct btf_encoder *encoder, struct cu *cu, struct co
|
||||
struct tag *pos;
|
||||
int err = 0;
|
||||
|
||||
+ encoder->cu = cu;
|
||||
|
||||
if (!encoder->has_index_type) {
|
||||
/* cu__find_base_type_by_name() takes "type_id_t *id" */
|
||||
@@ -1580,8 +1586,9 @@ int btf_encoder__encode_cu(struct btf_encoder *encoder, struct cu *cu, struct co
|
||||
}
|
||||
|
||||
if (!encoder->skip_encoding_vars)
|
||||
- err = btf_encoder__encode_cu_variables(encoder, cu, type_id_off);
|
||||
+ err = btf_encoder__encode_cu_variables(encoder, type_id_off);
|
||||
out:
|
||||
+ encoder->cu = NULL;
|
||||
return err;
|
||||
}
|
||||
|
||||
--
|
||||
2.39.1
|
||||
|
@ -0,0 +1,32 @@
|
||||
From e2a15e14e74224f7fdd909aeec0b5ec52731bfeb Mon Sep 17 00:00:00 2001
|
||||
From: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Date: Mon, 10 Oct 2022 16:59:53 -0300
|
||||
Subject: [PATCH 4/7] core: Add DW_TAG_unspecified_type to tag__is_tag_type()
|
||||
set
|
||||
|
||||
It is a type, so make tag__is_tag_type() return true for it.
|
||||
|
||||
Backport notes:
|
||||
|
||||
We aren't backporting the DW_TAG_atomic_type, so cope with that.
|
||||
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
---
|
||||
dwarves.h | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/dwarves.h b/dwarves.h
|
||||
index bec9f08ce879806d..2d0f51ab39df1fbd 100644
|
||||
--- a/dwarves.h
|
||||
+++ b/dwarves.h
|
||||
@@ -540,6 +540,7 @@ static inline int tag__is_tag_type(const struct tag *tag)
|
||||
tag->tag == DW_TAG_subroutine_type ||
|
||||
tag->tag == DW_TAG_unspecified_type ||
|
||||
tag->tag == DW_TAG_volatile_type ||
|
||||
+ tag->tag == DW_TAG_unspecified_type ||
|
||||
tag->tag == DW_TAG_LLVM_annotation;
|
||||
}
|
||||
|
||||
--
|
||||
2.39.1
|
||||
|
@ -0,0 +1,82 @@
|
||||
From 0d8c32c4b61de23acfe46e089d3470bbd02ce339 Mon Sep 17 00:00:00 2001
|
||||
From: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Date: Mon, 10 Oct 2022 09:42:30 -0300
|
||||
Subject: [PATCH 5/7] core: Record if a CU has a DW_TAG_unspecified_type
|
||||
|
||||
So that the BTF encoder can turn such functions into returning void
|
||||
instead, as BTF doesn't have a representation for such tags.
|
||||
|
||||
First noticed with Linux circa v6.1 built with GNU AS 2.39.50, git
|
||||
HEAD at the time building a .S file where the entry_ibpb assembly
|
||||
"function" was encoded as DWARF with DW_TAG_unspecified_type as its
|
||||
return type.
|
||||
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
---
|
||||
dwarf_loader.c | 7 ++++++-
|
||||
dwarves.h | 8 ++++++++
|
||||
2 files changed, 14 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dwarf_loader.c b/dwarf_loader.c
|
||||
index c2ad2a03dbbf24c0..41ba36bcd375f670 100644
|
||||
--- a/dwarf_loader.c
|
||||
+++ b/dwarf_loader.c
|
||||
@@ -2000,9 +2000,11 @@ static struct tag *__die__process_tag(Dwarf_Die *die, struct cu *cu,
|
||||
case DW_TAG_imported_module:
|
||||
case DW_TAG_reference_type:
|
||||
case DW_TAG_restrict_type:
|
||||
- case DW_TAG_unspecified_type:
|
||||
case DW_TAG_volatile_type:
|
||||
tag = die__create_new_tag(die, cu); break;
|
||||
+ case DW_TAG_unspecified_type:
|
||||
+ cu->unspecified_type.tag =
|
||||
+ tag = die__create_new_tag(die, cu); break;
|
||||
case DW_TAG_pointer_type:
|
||||
tag = die__create_new_pointer_tag(die, cu, conf); break;
|
||||
case DW_TAG_ptr_to_member_type:
|
||||
@@ -2063,6 +2065,8 @@ static int die__process_unit(Dwarf_Die *die, struct cu *cu, struct conf_load *co
|
||||
cu__hash(cu, tag);
|
||||
struct dwarf_tag *dtag = tag->priv;
|
||||
dtag->small_id = id;
|
||||
+ if (tag->tag == DW_TAG_unspecified_type)
|
||||
+ cu->unspecified_type.type = id;
|
||||
} while (dwarf_siblingof(die, die) == 0);
|
||||
|
||||
return 0;
|
||||
@@ -2498,6 +2502,7 @@ static int cu__recode_dwarf_types_table(struct cu *cu,
|
||||
if (tag__recode_dwarf_type(tag, cu))
|
||||
return -1;
|
||||
}
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/dwarves.h b/dwarves.h
|
||||
index 2d0f51ab39df1fbd..f152a9fafbba83c1 100644
|
||||
--- a/dwarves.h
|
||||
+++ b/dwarves.h
|
||||
@@ -230,6 +230,10 @@ struct debug_fmt_ops {
|
||||
bool has_alignment_info;
|
||||
};
|
||||
|
||||
+/*
|
||||
+ * unspecified_type: If this CU has a DW_TAG_unspecified_type, as BTF doesn't have a representation for this
|
||||
+ * and thus we need to check functions returning this to convert it to void.
|
||||
+ */
|
||||
struct cu {
|
||||
struct list_head node;
|
||||
struct list_head tags;
|
||||
@@ -238,6 +242,10 @@ struct cu {
|
||||
struct ptr_table functions_table;
|
||||
struct ptr_table tags_table;
|
||||
struct rb_root functions;
|
||||
+ struct {
|
||||
+ struct tag *tag;
|
||||
+ uint32_t type;
|
||||
+ } unspecified_type;
|
||||
char *name;
|
||||
char *filename;
|
||||
void *priv;
|
||||
--
|
||||
2.39.1
|
||||
|
@ -0,0 +1,93 @@
|
||||
From 4639af69cb52367f22ac39a51607c7af57ef5029 Mon Sep 17 00:00:00 2001
|
||||
From: Alan Maguire <alan.maguire@oracle.com>
|
||||
Date: Fri, 21 Oct 2022 16:02:03 +0100
|
||||
Subject: [PATCH 7/7] dwarves: Zero-initialize struct cu in cu__new() to
|
||||
prevent incorrect BTF types
|
||||
|
||||
BTF deduplication was throwing some strange results, where core kernel
|
||||
data types were failing to deduplicate due to the return values
|
||||
of function type members being void (0) instead of the actual type
|
||||
(unsigned int). An example of this can be seen below, where
|
||||
"struct dst_ops" was failing to deduplicate between kernel and
|
||||
module:
|
||||
|
||||
struct dst_ops {
|
||||
short unsigned int family;
|
||||
unsigned int gc_thresh;
|
||||
int (*gc)(struct dst_ops *);
|
||||
struct dst_entry * (*check)(struct dst_entry *, __u32);
|
||||
unsigned int (*default_advmss)(const struct dst_entry *);
|
||||
unsigned int (*mtu)(const struct dst_entry *);
|
||||
...
|
||||
|
||||
struct dst_ops___2 {
|
||||
short unsigned int family;
|
||||
unsigned int gc_thresh;
|
||||
int (*gc)(struct dst_ops___2 *);
|
||||
struct dst_entry___2 * (*check)(struct dst_entry___2 *, __u32);
|
||||
void (*default_advmss)(const struct dst_entry___2 *);
|
||||
void (*mtu)(const struct dst_entry___2 *);
|
||||
...
|
||||
|
||||
This was seen with
|
||||
|
||||
bcc648a10cbc ("btf_encoder: Encode DW_TAG_unspecified_type returning routines as void")
|
||||
|
||||
...which rewrites the return value as 0 (void) when it is marked
|
||||
as matching DW_TAG_unspecified_type:
|
||||
|
||||
static int32_t btf_encoder__tag_type(struct btf_encoder *encoder, uint32_t type_id_off, uint32_t tag_type)
|
||||
{
|
||||
if (tag_type == 0)
|
||||
return 0;
|
||||
|
||||
if (encoder->cu->unspecified_type.tag && tag_type == encoder->cu->unspecified_type.type) {
|
||||
// No provision for encoding this, turn it into void.
|
||||
return 0;
|
||||
}
|
||||
|
||||
return type_id_off + tag_type;
|
||||
}
|
||||
|
||||
However the odd thing was that on further examination, the unspecified type
|
||||
was not being set, so why was this logic being tripped? Futher debugging
|
||||
showed that the encoder->cu->unspecified_type.tag value was garbage, and
|
||||
the type id happened to collide with "unsigned int"; as a result we
|
||||
were replacing unsigned ints with void return values, and since this
|
||||
was being done to function type members in structs, it triggered a
|
||||
type mismatch which failed deduplication between kernel and module.
|
||||
|
||||
The fix is simply to calloc() the cu in cu__new() instead.
|
||||
|
||||
Committer notes:
|
||||
|
||||
We have zalloc(size) as an alias to calloc(1, size), use it instead.
|
||||
|
||||
Fixes: bcc648a10cbcd0b9 ("btf_encoder: Encode DW_TAG_unspecified_type returning routines as void")
|
||||
Signed-off-by: Alan Maguire <alan.maguire@oracle.com>
|
||||
Acked-by: Andrii Nakryiko <andrii@kernel.org>
|
||||
Acked-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Cc: bpf@vger.kernel.org
|
||||
Cc: dwarves@vger.kernel.org
|
||||
Link: https://lore.kernel.org/r/1666364523-9648-1-git-send-email-alan.maguire@oracle.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
---
|
||||
dwarves.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dwarves.c b/dwarves.c
|
||||
index 32bfec5ea0f1a338..ff449affff94b16f 100644
|
||||
--- a/dwarves.c
|
||||
+++ b/dwarves.c
|
||||
@@ -625,7 +625,7 @@ struct cu *cu__new(const char *name, uint8_t addr_size,
|
||||
const unsigned char *build_id, int build_id_len,
|
||||
const char *filename, bool use_obstack)
|
||||
{
|
||||
- struct cu *cu = malloc(sizeof(*cu) + build_id_len);
|
||||
+ struct cu *cu = zalloc(sizeof(*cu) + build_id_len);
|
||||
|
||||
if (cu != NULL) {
|
||||
uint32_t void_id;
|
||||
--
|
||||
2.39.1
|
||||
|
Loading…
Reference in New Issue