From 5a86729946f0dd3536970841085846614568188c194cd25d080e8392ffa18aa0 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Fri, 17 Feb 2023 17:03:26 +0000 Subject: [PATCH] Accepting request 1066397 from home:marxin:branches:devel:tools - Add 0001-pahole-Support-lang-lang_exclude-asm.patch, 0002-btf_encoder-Add-extra-debug-info-for-unsupported-DWA.patch, 0003-btf_encoder-Store-the-CU-being-processed-to-avoid-ch.patch, 0004-core-Add-DW_TAG_unspecified_type-to-tag__is_tag_type.patch, 0005-core-Record-if-a-CU-has-a-DW_TAG_unspecified_type.patch, 0006-btf_encoder-Encode-DW_TAG_unspecified_type-returning.patch, 0007-dwarves-Zero-initialize-struct-cu-in-cu__new-to-prev.patch as in order to support DW_TAG_unspecified_type that is newly emitted by binutils 2.40+. OBS-URL: https://build.opensuse.org/request/show/1066397 OBS-URL: https://build.opensuse.org/package/show/devel:tools/dwarves?expand=0&rev=89 --- ...pahole-Support-lang-lang_exclude-asm.patch | 62 +++++++ ...extra-debug-info-for-unsupported-DWA.patch | 39 +++++ ...e-the-CU-being-processed-to-avoid-ch.patch | 65 ++++++++ ...unspecified_type-to-tag__is_tag_type.patch | 32 ++++ ...f-a-CU-has-a-DW_TAG_unspecified_type.patch | 82 ++++++++++ ...de-DW_TAG_unspecified_type-returning.patch | 153 ++++++++++++++++++ ...tialize-struct-cu-in-cu__new-to-prev.patch | 93 +++++++++++ dwarves.changes | 13 ++ dwarves.spec | 11 +- 9 files changed, 548 insertions(+), 2 deletions(-) create mode 100644 0001-pahole-Support-lang-lang_exclude-asm.patch create mode 100644 0002-btf_encoder-Add-extra-debug-info-for-unsupported-DWA.patch create mode 100644 0003-btf_encoder-Store-the-CU-being-processed-to-avoid-ch.patch create mode 100644 0004-core-Add-DW_TAG_unspecified_type-to-tag__is_tag_type.patch create mode 100644 0005-core-Record-if-a-CU-has-a-DW_TAG_unspecified_type.patch create mode 100644 0006-btf_encoder-Encode-DW_TAG_unspecified_type-returning.patch create mode 100644 0007-dwarves-Zero-initialize-struct-cu-in-cu__new-to-prev.patch diff --git a/0001-pahole-Support-lang-lang_exclude-asm.patch b/0001-pahole-Support-lang-lang_exclude-asm.patch new file mode 100644 index 0000000..8920959 --- /dev/null +++ b/0001-pahole-Support-lang-lang_exclude-asm.patch @@ -0,0 +1,62 @@ +From 5d27afaf31ac124edfef09862d26247b2c12b6a1 Mon Sep 17 00:00:00 2001 +From: Arnaldo Carvalho de Melo +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 +Cc: Nick Clifton +Signed-off-by: Arnaldo Carvalho de Melo +--- + 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 + diff --git a/0002-btf_encoder-Add-extra-debug-info-for-unsupported-DWA.patch b/0002-btf_encoder-Add-extra-debug-info-for-unsupported-DWA.patch new file mode 100644 index 0000000..48b9598 --- /dev/null +++ b/0002-btf_encoder-Add-extra-debug-info-for-unsupported-DWA.patch @@ -0,0 +1,39 @@ +From 145fd522e786962dd00f946c574a8d59daf945b4 Mon Sep 17 00:00:00 2001 +From: Arnaldo Carvalho de Melo +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 +--- + 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 + diff --git a/0003-btf_encoder-Store-the-CU-being-processed-to-avoid-ch.patch b/0003-btf_encoder-Store-the-CU-being-processed-to-avoid-ch.patch new file mode 100644 index 0000000..fffc66f --- /dev/null +++ b/0003-btf_encoder-Store-the-CU-being-processed-to-avoid-ch.patch @@ -0,0 +1,65 @@ +From 79f560f1418f7cacb50746c33a116f8ab5396a2d Mon Sep 17 00:00:00 2001 +From: Arnaldo Carvalho de Melo +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 +--- + 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 + diff --git a/0004-core-Add-DW_TAG_unspecified_type-to-tag__is_tag_type.patch b/0004-core-Add-DW_TAG_unspecified_type-to-tag__is_tag_type.patch new file mode 100644 index 0000000..76f8a5c --- /dev/null +++ b/0004-core-Add-DW_TAG_unspecified_type-to-tag__is_tag_type.patch @@ -0,0 +1,32 @@ +From e2a15e14e74224f7fdd909aeec0b5ec52731bfeb Mon Sep 17 00:00:00 2001 +From: Arnaldo Carvalho de Melo +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 +--- + 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 + diff --git a/0005-core-Record-if-a-CU-has-a-DW_TAG_unspecified_type.patch b/0005-core-Record-if-a-CU-has-a-DW_TAG_unspecified_type.patch new file mode 100644 index 0000000..77b9cc1 --- /dev/null +++ b/0005-core-Record-if-a-CU-has-a-DW_TAG_unspecified_type.patch @@ -0,0 +1,82 @@ +From 0d8c32c4b61de23acfe46e089d3470bbd02ce339 Mon Sep 17 00:00:00 2001 +From: Arnaldo Carvalho de Melo +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 +--- + 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 + diff --git a/0006-btf_encoder-Encode-DW_TAG_unspecified_type-returning.patch b/0006-btf_encoder-Encode-DW_TAG_unspecified_type-returning.patch new file mode 100644 index 0000000..9527362 --- /dev/null +++ b/0006-btf_encoder-Encode-DW_TAG_unspecified_type-returning.patch @@ -0,0 +1,153 @@ +From b55a35326c9ea1cd9287a7ce87193443bb523c9b Mon Sep 17 00:00:00 2001 +From: Arnaldo Carvalho de Melo +Date: Mon, 10 Oct 2022 11:20:07 -0300 +Subject: [PATCH 6/7] btf_encoder: Encode DW_TAG_unspecified_type returning + routines as void +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Since we don´t have how to encode this info in BTF, and from what we +saw, at least in this case: + +Built binutils from git://sourceware.org/git/binutils-gdb.git, then used +gcc's -B option to point to the directory with the new as, that is built +as as-new, so make a symlink, ending up with: + + 15e20ce2324a:~/git/linux # readelf -wi ./arch/x86/entry/entry.o + Contents of the .debug_info section: + + Compilation Unit @ offset 0: + Length: 0x35 (32-bit) + Version: 5 + Unit Type: DW_UT_compile (1) + Abbrev Offset: 0 + Pointer Size: 8 + <0>: Abbrev Number: 1 (DW_TAG_compile_unit) + DW_AT_stmt_list : 0 + <11> DW_AT_low_pc : 0 + <19> DW_AT_high_pc : 19 + <1a> DW_AT_name : (indirect string, offset: 0): arch/x86/entry/entry.S + <1e> DW_AT_comp_dir : (indirect string, offset: 0x17): /root/git/linux + <22> DW_AT_producer : (indirect string, offset: 0x27): GNU AS 2.39.50 + <26> DW_AT_language : 32769 (MIPS assembler) + <1><28>: Abbrev Number: 2 (DW_TAG_subprogram) + <29> DW_AT_name : (indirect string, offset: 0x36): entry_ibpb + <2d> DW_AT_external : 1 + <2d> DW_AT_type : <0x37> + <2e> DW_AT_low_pc : 0 + <36> DW_AT_high_pc : 19 + <1><37>: Abbrev Number: 3 (DW_TAG_unspecified_type) + <1><38>: Abbrev Number: 0 + +So we have that asm label encoded by GNU AS 2.39.50 as a +DW_TAG_subprogram that has as its DW_AT_type the DW_TAG_unspecified_type +0x37 that we convert to 0 (void): + + 15e20ce2324a:~/git/linux # pahole -J ./arch/x86/entry/entry.o + 15e20ce2324a:~/git/linux # pahole -JV ./arch/x86/entry/entry.o + btf_encoder__new: 'entry.o' doesn't have '.data..percpu' section + Found 0 per-CPU variables! + Found 1 functions! + File entry.o: + [1] FUNC_PROTO (anon) return=0 args=(void) + [2] FUNC entry_ibpb type_id=1 + 15e20ce2324a:~/git/linux # pfunct -F btf ./arch/x86/entry/entry.o + entry_ibpb + 15e20ce2324a:~/git/linux # pfunct --proto -F btf ./arch/x86/entry/entry.o + void entry_ibpb(void); + 15e20ce2324a:~/git/linux # + + 15e20ce2324a:~/git/linux # tools/bpf/bpftool/bpftool btf dump file ./arch/x86/entry/entry.o format raw + [1] FUNC_PROTO '(anon)' ret_type_id=0 vlen=0 + [2] FUNC 'entry_ibpb' type_id=1 linkage=static + 15e20ce2324a:~/git/linux # + +I think this is what can be done to avoid having to skip ASM DWARF when +gets widely used, i.e. binutils gets updated. + +Acked-by: Yonghong Song +Cc: Andrii Nakryiko , +Cc: Martin Liška +Link: https://lore.kernel.org/all/Y0R7uu3s%2FimnvPzM@kernel.org/ +Signed-off-by: Arnaldo Carvalho de Melo +--- + btf_encoder.c | 33 ++++++++++++++++++++++++++++++--- + 1 file changed, 30 insertions(+), 3 deletions(-) + +diff --git a/btf_encoder.c b/btf_encoder.c +index e74862cfc0a3a802..eee55a0ade5e74ee 100644 +--- a/btf_encoder.c ++++ b/btf_encoder.c +@@ -570,6 +570,19 @@ static int32_t btf_encoder__add_func_param(struct btf_encoder *encoder, const ch + } + } + ++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; ++} ++ + static int32_t btf_encoder__add_func_proto(struct btf_encoder *encoder, struct ftype *ftype, uint32_t type_id_off) + { + struct btf *btf = encoder->btf; +@@ -580,7 +593,7 @@ static int32_t btf_encoder__add_func_proto(struct btf_encoder *encoder, struct f + + /* add btf_type for func_proto */ + nr_params = ftype->nr_parms + (ftype->unspec_parms ? 1 : 0); +- type_id = ftype->tag.type == 0 ? 0 : type_id_off + ftype->tag.type; ++ type_id = btf_encoder__tag_type(encoder, type_id_off, ftype->tag.type); + + id = btf__add_func_proto(btf, type_id); + if (id > 0) { +@@ -943,6 +956,15 @@ static int btf_encoder__encode_tag(struct btf_encoder *encoder, struct tag *tag, + return btf_encoder__add_enum_type(encoder, tag, conf_load); + case DW_TAG_subroutine_type: + return btf_encoder__add_func_proto(encoder, tag__ftype(tag), type_id_off); ++ case DW_TAG_unspecified_type: ++ /* Just don't encode this for now, converting anything with this type to void (0) instead. ++ * ++ * If we end up needing to encode this, one possible hack is to do as follows, as "const void". ++ * ++ * Returning zero means we skipped encoding a DWARF type. ++ */ ++ // btf_encoder__add_ref_type(encoder, BTF_KIND_CONST, 0, NULL, false); ++ return 0; + default: + fprintf(stderr, "Unsupported DW_TAG_%s(0x%x): type: 0x%x\n", + dwarf_tag_name(tag->tag), tag->tag, ref_type_id); +@@ -1464,7 +1486,7 @@ int btf_encoder__encode_cu(struct btf_encoder *encoder, struct cu *cu, struct co + { + uint32_t type_id_off = btf__type_cnt(encoder->btf) - 1; + struct llvm_annotation *annot; +- int btf_type_id, tag_type_id; ++ int btf_type_id, tag_type_id, skipped_types = 0; + uint32_t core_id; + struct function *fn; + struct tag *pos; +@@ -1487,8 +1509,13 @@ int btf_encoder__encode_cu(struct btf_encoder *encoder, struct cu *cu, struct co + cu__for_each_type(cu, core_id, pos) { + btf_type_id = btf_encoder__encode_tag(encoder, pos, type_id_off, conf_load); + ++ if (btf_type_id == 0) { ++ ++skipped_types; ++ continue; ++ } ++ + if (btf_type_id < 0 || +- tag__check_id_drift(pos, core_id, btf_type_id, type_id_off)) { ++ tag__check_id_drift(pos, core_id, btf_type_id + skipped_types, type_id_off)) { + err = -1; + goto out; + } +-- +2.39.1 + diff --git a/0007-dwarves-Zero-initialize-struct-cu-in-cu__new-to-prev.patch b/0007-dwarves-Zero-initialize-struct-cu-in-cu__new-to-prev.patch new file mode 100644 index 0000000..00f84fd --- /dev/null +++ b/0007-dwarves-Zero-initialize-struct-cu-in-cu__new-to-prev.patch @@ -0,0 +1,93 @@ +From 4639af69cb52367f22ac39a51607c7af57ef5029 Mon Sep 17 00:00:00 2001 +From: Alan Maguire +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 +Acked-by: Andrii Nakryiko +Acked-by: Jiri Olsa +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 +--- + 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 + diff --git a/dwarves.changes b/dwarves.changes index adcd472..3224507 100644 --- a/dwarves.changes +++ b/dwarves.changes @@ -1,3 +1,16 @@ +------------------------------------------------------------------- +Fri Feb 17 14:36:32 UTC 2023 - Martin Liška + +- Add 0001-pahole-Support-lang-lang_exclude-asm.patch, + 0002-btf_encoder-Add-extra-debug-info-for-unsupported-DWA.patch, + 0003-btf_encoder-Store-the-CU-being-processed-to-avoid-ch.patch, + 0004-core-Add-DW_TAG_unspecified_type-to-tag__is_tag_type.patch, + 0005-core-Record-if-a-CU-has-a-DW_TAG_unspecified_type.patch, + 0006-btf_encoder-Encode-DW_TAG_unspecified_type-returning.patch, + 0007-dwarves-Zero-initialize-struct-cu-in-cu__new-to-prev.patch + as in order to support DW_TAG_unspecified_type that is newly + emitted by binutils 2.40+. + ------------------------------------------------------------------- Tue Oct 4 17:04:49 UTC 2022 - Dirk Müller diff --git a/dwarves.spec b/dwarves.spec index 8deebdd..5764d8a 100644 --- a/dwarves.spec +++ b/dwarves.spec @@ -1,7 +1,7 @@ # # spec file for package dwarves # -# Copyright (c) 2022 SUSE LLC +# Copyright (c) 2023 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -37,6 +37,13 @@ Source: https://fedorapeople.org/~acme/dwarves/dwarves-%version.tar.xz Source2: https://fedorapeople.org/~acme/dwarves/dwarves-%version.tar.sign Source8: dwarves.keyring Source9: baselibs.conf +Patch0: 0001-pahole-Support-lang-lang_exclude-asm.patch +Patch1: 0002-btf_encoder-Add-extra-debug-info-for-unsupported-DWA.patch +Patch2: 0003-btf_encoder-Store-the-CU-being-processed-to-avoid-ch.patch +Patch3: 0004-core-Add-DW_TAG_unspecified_type-to-tag__is_tag_type.patch +Patch4: 0005-core-Record-if-a-CU-has-a-DW_TAG_unspecified_type.patch +Patch5: 0006-btf_encoder-Encode-DW_TAG_unspecified_type-returning.patch +Patch6: 0007-dwarves-Zero-initialize-struct-cu-in-cu__new-to-prev.patch BuildRequires: cmake BuildRequires: libdw-devel >= 0.171 BuildRequires: libelf-devel @@ -97,7 +104,7 @@ This package contains the development files for libdwarves, a library for processing DWARF, a debugging data format for ELF files. %prep -%autosetup +%autosetup -p1 %build sv="$PWD/lib.v"