From be5173b4df0fa8c2fda481bdf8fdfa873bf504e9 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 26 Feb 2019 10:26:14 -0300 Subject: [PATCH] dwarves: Fixup sizeof(long double) in bits in base_type_name_to_size table We were erroneously setting it to 64 bits everywhere, i.e. 8 bytes, when it in fact is 16 bytes, 128 bits, as we can see with: $ btfdiff libc-2.28.so.debug --- /tmp/btfdiff.dwarf.RuqA9q 2019-02-26 10:25:49.828150761 -0300 +++ /tmp/btfdiff.btf.t3XqV6 2019-02-26 10:25:49.835150835 -0300 @@ -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 */ And: $ cat long_double.c #include int main(void) { return printf("sizeof(long double)=%zd\n", sizeof(long double)); } $ ./long_double sizeof(long double)=16 $ file long_double long_double: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=c876603879d49905fbd7fc5907dc65ad3bca422f, not stripped $ So use sizeof to at least match the running machine, this is insufficient for cross-platform analysis, so a new fix is needed to cover those cases, this at least improves the current situation a bit. Reported-by: Andrii Nakryiko Cc: Alexei Starovoitov Cc: Yonghong Song link: https://lore.kernel.org/bpf/20190226131156.GA26786@kernel.org/ Signed-off-by: Arnaldo Carvalho de Melo --- dwarves.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dwarves.c b/dwarves.c index fd21845..111797b 100644 --- a/dwarves.c +++ b/dwarves.c @@ -168,8 +168,8 @@ static struct base_type_name_to_size { { .name = "double double", .size = 64, }, { .name = "single float", .size = 32, }, { .name = "float", .size = 32, }, - { .name = "long double", .size = 64, }, - { .name = "long double long double", .size = 64, }, + { .name = "long double", .size = sizeof(long double) * 8, }, + { .name = "long double long double", .size = sizeof(long double) * 8, }, { .name = "__int128", .size = 128, }, { .name = "unsigned __int128", .size = 128, }, { .name = "__int128 unsigned", .size = 128, },