btf_loader: Simplify fixup code by relying on BTF data more
btf_loader relies on guessing base integral type size for enums and integers, which is unreliable. There doesn't seem to be a need for that, as all this information could be extracted from BTF information. Before: $ PAHOLE=~/local/pahole/build/pahole ./btfdiff ~/local/btf/libc-2.28.so.debug base_type__name_to_size: base_type _Float128 class__fixup_btf_bitfields: unknown base type name "_Float128"! base_type__name_to_size: base_type _Float128 class__fixup_btf_bitfields: unknown base type name "_Float128"! base_type__name_to_size: base_type _Float128 class__fixup_btf_bitfields: unknown base type name "_Float128"! base_type__name_to_size: base_type _Float128 class__fixup_btf_bitfields: unknown base type name "_Float128"! base_type__name_to_size: base_type _Float128 class__fixup_btf_bitfields: unknown base type name "_Float128"! base_type__name_to_size: base_type _Float128 class__fixup_btf_bitfields: unknown base type name "_Float128"! --- /tmp/btfdiff.dwarf.aV4wSL 2019-02-25 13:31:54.787923673 -0800 +++ /tmp/btfdiff.btf.22NQmJ 2019-02-25 13:31:54.802923668 -0800 @@ -461,9 +461,15 @@ struct La_x86_64_retval { uint64_t lrv_rdx; /* 8 8 */ La_x86_64_xmm lrv_xmm0; /* 16 16 */ La_x86_64_xmm lrv_xmm1; /* 32 16 */ - long double lrv_st0; /* 48 16 */ + long double lrv_st0; /* 48 8 */ + + /* XXX 8 bytes hole, try to pack */ + /* --- cacheline 1 boundary (64 bytes) --- */ - long double lrv_st1; /* 64 16 */ + long double lrv_st1; /* 64 8 */ + + /* XXX 8 bytes hole, try to pack */ + La_x86_64_vector lrv_vector0; /* 80 64 */ /* --- cacheline 2 boundary (128 bytes) was 16 bytes ago --- */ La_x86_64_vector lrv_vector1; /* 144 64 */ @@ -472,6 +478,7 @@ struct La_x86_64_retval { __int128 lrv_bnd1; /* 224 16 */ /* size: 240, cachelines: 4, members: 10 */ + /* sum members: 224, holes: 2, sum holes: 16 */ /* last cacheline: 48 bytes */ }; struct r_debug { @@ -2044,7 +2051,7 @@ union ieee754_float { } ieee_nan; /* 0 4 */ }; union ieee854_long_double { - long double d; /* 0 16 */ + long double d; /* 0 8 */ struct { unsigned int mantissa1:32; /* 0: 0 4 */ unsigned int mantissa0:32; /* 4: 0 4 */ @@ -2141,7 +2148,7 @@ struct ucontext_t { /* last cacheline: 8 bytes */ }; union ieee854_float128 { - _Float128 d; /* 0 16 */ + _Float128 d; /* 0 0 */ struct { unsigned int mantissa3:32; /* 0: 0 4 */ unsigned int mantissa2:32; /* 4: 0 4 */ @@ -2219,7 +2226,7 @@ union printf_arg { long unsigned int pa_u_long_int; /* 0 8 */ long long unsigned int pa_u_long_long_int; /* 0 8 */ double pa_double; /* 0 8 */ - long double pa_long_double; /* 0 16 */ + long double pa_long_double; /* 0 8 */ const char * pa_string; /* 0 8 */ const wchar_t * pa_wstring; /* 0 8 */ void * pa_pointer; /* 0 8 */ $ PAHOLE=~/local/pahole/build/pahole ./btfdiff ~/local/btf/libc-2.28.so.debug <empty output> Still good for kernel image: $ PAHOLE=~/local/pahole/build/pahole ./btfdiff ~/local/btf/vmlinux4 <empty output> Signed-off-by: Andrii Nakryiko <andriin@fb.com> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Alexei Starovoitov <ast@fb.com> Cc: Yonghong Song <yhs@fb.com> Cc: bpf@vger.kernel.org Cc: dwarves@vger.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
be5173b4df
commit
8f4f280163
59
btf_loader.c
59
btf_loader.c
|
@ -463,64 +463,27 @@ static int class__fixup_btf_bitfields(struct tag *tag, struct cu *cu, struct btf
|
|||
continue;
|
||||
|
||||
pos->bitfield_offset = 0;
|
||||
pos->byte_size = tag__size(type, cu);
|
||||
pos->bit_size = pos->byte_size * 8;
|
||||
|
||||
uint16_t type_bit_size;
|
||||
size_t integral_bit_size;
|
||||
|
||||
switch (type->tag) {
|
||||
case DW_TAG_enumeration_type:
|
||||
type_bit_size = tag__type(type)->size;
|
||||
/* Best we can do to check if this is a packed enum */
|
||||
if (is_power_of_2(type_bit_size))
|
||||
integral_bit_size = roundup(type_bit_size, 8);
|
||||
else
|
||||
integral_bit_size = sizeof(int) * 8;
|
||||
break;
|
||||
case DW_TAG_base_type: {
|
||||
struct base_type *bt = tag__base_type(type);
|
||||
char name[256];
|
||||
type_bit_size = bt->bit_size;
|
||||
integral_bit_size = base_type__name_to_size(bt, cu);
|
||||
if (integral_bit_size == 0) {
|
||||
fprintf(stderr, "%s: unknown base type name \"%s\"!\n",
|
||||
__func__, base_type__name(bt, cu, name,
|
||||
sizeof(name)));
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
pos->byte_size = tag__size(type, cu);
|
||||
pos->bit_size = pos->byte_size * 8;
|
||||
/* bitfield fixup is needed for enums and base types only */
|
||||
if (type->tag != DW_TAG_base_type && type->tag != DW_TAG_enumeration_type)
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX: integral_bit_size can be zero if base_type__name_to_size doesn't
|
||||
* know about the base_type name, so one has to add there when
|
||||
* such base_type isn't found. pahole will put zero on the
|
||||
* struct output so it should be easy to spot the name when
|
||||
* such unlikely thing happens.
|
||||
*/
|
||||
pos->byte_size = integral_bit_size / 8;
|
||||
pos->bit_size = type_bit_size;
|
||||
|
||||
if (integral_bit_size == 0) {
|
||||
pos->bit_size = 0;
|
||||
/* if BTF data is incorrect and has size == 0, skip field,
|
||||
* instead of crashing */
|
||||
if (pos->byte_size == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pos->bitfield_size) {
|
||||
/* bitfields seem to be always aligned, no matter the packing */
|
||||
pos->byte_offset = pos->bit_offset / integral_bit_size * integral_bit_size / 8;
|
||||
} else {
|
||||
pos->byte_offset = pos->bit_offset / 8;
|
||||
}
|
||||
|
||||
|
||||
if (pos->bitfield_size) {
|
||||
pos->byte_offset = pos->bit_offset / pos->bit_size * pos->bit_size / 8;
|
||||
pos->bitfield_offset = pos->bit_offset - pos->byte_offset * 8;
|
||||
if (!btfe->is_big_endian)
|
||||
pos->bitfield_offset = integral_bit_size - pos->bitfield_offset - pos->bitfield_size;
|
||||
pos->bitfield_offset = pos->bit_size - pos->bitfield_offset - pos->bitfield_size;
|
||||
} else {
|
||||
pos->byte_offset = pos->bit_offset / 8;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue