Debian Patches

Status for dwarves/1.24-4.1

Patch Description Author Forwarded Bugs Origin Last update
00-store-the-CU-being-processed-to-avoid-changing-many-functions.patch commit 121a46a026afac197652cb8a4cdf2d3879d7f587

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 <>
Arnaldo Carvalho de Melo <> no 2022-10-10
01-record-if-a-CU-has-a-DW_TAG_unspecified_type.patch commit cffe5e1f75e1612e1ffd8da5fab30e0230fbcdd4

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 <>
Arnaldo Carvalho de Melo <> no 2022-10-10
02-encode-DW_TAG_unspecified_type-returning-routines-as-void.patch commit bcc648a10cbcd0b96b84ff7c737d56ce70f7b501

btf_encoder: Encode DW_TAG_unspecified_type returning routines as void

Since we dont have how to encode this info in BTF, and from what we
saw, at least in this case:

Built binutils from 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><c>: Abbrev Number: 1 (DW_TAG_compile_unit)
<d> 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
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 Lika <>
Signed-off-by: Arnaldo Carvalho de Melo <>
Arnaldo Carvalho de Melo <> no 2022-10-10
03-dwarves-Zero-initialize-struct-cu-in-cu__new-to-prev.patch 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

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.
Alan Maguire <> no debian 2022-10-21

All known versions for source package 'dwarves'