-
Notifications
You must be signed in to change notification settings - Fork 51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Correctly handle DW_FORM_flag and add DW_FORM_flag_present support #2
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Before this patch, running pahole on an executable compiled with -gdwarf-4 gave: DW_AT_<0x3c>=0x19 0x19 is DW_FORM_flag_present. Also, DW_FORM_flag takes an argument. Changing attr_numeric to call dwarf_formflag fixes both problems.
acmel
pushed a commit
that referenced
this pull request
Mar 25, 2019
This patch fixed two issues with BTF. One is related to struct/union bitfield encoding and the other is related to forward type. Issue #1 and solution: ====================== Current btf encoding of bitfield follows what pahole generates. For each bitfield, pahole will duplicate the type chain and put the bitfield size at the final int or enum type. Since the BTF enum type cannot encode bit size, commit b18354f ("btf: Generate correct struct bitfield member types") workarounds the issue by generating an int type whenever the enum bit size is not 32. The above workaround is not ideal as we lost original type in BTF. Another undesiable fact is the type duplication as the pahole duplicates the type chain. To fix this issue, this patch implemented a compatible change for BTF struct type encoding: . the bit 31 of type->info, previously reserved, now is used to indicate whether bitfield_size is encoded in btf_member or not. . if bit 31 of struct_type->info is set, btf_member->offset will encode like: bit 0 - 23: bit offset bit 24 - 31: bitfield size if bit 31 is not set, the old behavior is preserved: bit 0 - 31: bit offset So if the struct contains a bit field, the maximum bit offset will be reduced to (2^24 - 1) instead of MAX_UINT. The maximum bitfield size will be 255 which is enough for today as maximum bitfield in compiler can be 128 where int128 type is supported. A new global, no_bitfield_type_recode, is introduced and which will be set to true if BTF encoding is enabled. This global will prevent pahole duplicating the bitfield types to avoid type duplication in BTF. Issue #2 and solution: ====================== Current forward type in BTF does not specify whether the original type is struct or union. This will not work for type pretty print and BTF-to-header-file conversion as struct/union must be specified. To fix this issue, similar to issue #1, type->info bit 31 is used. If the bit is set, it is union type. Otherwise, it is a struct type. Examples: ========= -bash-4.4$ cat t.c struct s; union u; typedef int ___int; enum A { A1, A2, A3 }; struct t { int a[5]; ___int b:4; volatile enum A c:4; struct s *p1; union u *p2; } g; -bash-4.4$ gcc -c -O2 -g t.c Without this patch: $ pahole -JV t.o [1] TYPEDEF ___int type_id=2 [2] INT int size=4 bit_offset=0 nr_bits=32 encoding=SIGNED [3] ENUM A size=4 vlen=3 A1 val=0 A2 val=1 A3 val=2 [4] STRUCT t size=40 vlen=5 a type_id=5 bits_offset=0 b type_id=13 bits_offset=160 c type_id=15 bits_offset=164 p1 type_id=9 bits_offset=192 p2 type_id=11 bits_offset=256 [5] ARRAY (anon) type_id=2 index_type_id=2 nr_elems=5 [6] INT sizetype size=8 bit_offset=0 nr_bits=64 encoding=(none) [7] VOLATILE (anon) type_id=3 [8] FWD s type_id=0 [9] PTR (anon) type_id=8 [10] FWD u type_id=0 [11] PTR (anon) type_id=10 [12] INT int size=1 bit_offset=0 nr_bits=4 encoding=(none) [13] TYPEDEF ___int type_id=12 [14] INT (anon) size=1 bit_offset=0 nr_bits=4 encoding=SIGNED [15] VOLATILE (anon) type_id=14 With this patch: $ pahole -JV t.o File t.o: [1] TYPEDEF ___int type_id=2 [2] INT int size=4 bit_offset=0 nr_bits=32 encoding=SIGNED [3] ENUM A size=4 vlen=3 A1 val=0 A2 val=1 A3 val=2 [4] STRUCT t kind_flag=1 size=40 vlen=5 a type_id=5 bitfield_size=0 bits_offset=0 b type_id=1 bitfield_size=4 bits_offset=160 c type_id=7 bitfield_size=4 bits_offset=164 p1 type_id=9 bitfield_size=0 bits_offset=192 p2 type_id=11 bitfield_size=0 bits_offset=256 [5] ARRAY (anon) type_id=2 index_type_id=2 nr_elems=5 [6] INT sizetype size=8 bit_offset=0 nr_bits=64 encoding=(none) [7] VOLATILE (anon) type_id=3 [8] FWD s struct [9] PTR (anon) type_id=8 [10] FWD u union [11] PTR (anon) type_id=10 The fix removed the type duplication, preserved the enum type for the bitfield, and have correct struct/union information for the forward type. Signed-off-by: Yonghong Song <yhs@fb.com> Acked-by: Martin KaFai Lau <kafai@fb.com> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Alexei Starovoitov <ast@fb.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
acmel
added a commit
that referenced
this pull request
Jul 1, 2019
Will Cohen reported this NULL pointer dereference while processing some object linking with cuda: #0 0x00007ffff7f91453 in __class__fprintf (class=0x522560, cu=0x40ff80, conf=0x7fffffffa930, fp=0x7ffff7ece780 <_IO_2_1_stdout_>) at /home/acme/git/pahole/dwarves_fprintf.c:1624 #1 0x00007ffff7f92195 in tag__fprintf (tag=0x522560, cu=0x40ff80, conf=0x7fffffffa930, fp=0x7ffff7ece780 <_IO_2_1_stdout_>) at /home/acme/git/pahole/dwarves_fprintf.c:1835 #2 0x00007ffff7f90b57 in __class__fprintf (class=0x5224c0, cu=0x40ff80, conf=0x7fffffffaaa0, fp=0x7ffff7ece780 <_IO_2_1_stdout_>) at /home/acme/git/pahole/dwarves_fprintf.c:1406 #3 0x00007ffff7f92195 in tag__fprintf (tag=0x5224c0, cu=0x40ff80, conf=0x40a200 <conf>, fp=0x7ffff7ece780 <_IO_2_1_stdout_>) at /home/acme/git/pahole/dwarves_fprintf.c:1835 #4 0x0000000000402d03 in class_formatter (class=0x5224c0, cu=0x40ff80, id=1257) at /home/acme/git/pahole/pahole.c:224 #5 0x0000000000403074 in print_classes (cu=0x40ff80) at /home/acme/git/pahole/pahole.c:319 #6 0x0000000000404bb2 in pahole_stealer (cu=0x40ff80, conf_load=0x40a240 <conf_load>) at /home/acme/git/pahole/pahole.c:1174 #7 0x00007ffff7f9ff73 in finalize_cu (cus=0x40b2b0, cu=0x40ff80, dcu=0x7fffffffacf0, conf=0x40a240 <conf_load>) at /home/acme/git/pahole/dwarf_loader.c:2227 #8 0x00007ffff7f9ffac in finalize_cu_immediately (cus=0x40b2b0, cu=0x40ff80, dcu=0x7fffffffacf0, conf=0x40a240 <conf_load>) at /home/acme/git/pahole/dwarf_loader.c:2236 #9 0x00007ffff7fa064c in cus__load_module (cus=0x40b2b0, conf=0x40a240 <conf_load>, mod=0x40d760, dw=0x40e980, elf=0x40b360, filename=0x7fffffffd5e3 "examples/wcohen/02_Exercise.cuda") at /home/acme/git/pahole/dwarf_loader.c:2389 #10 0x00007ffff7fa0760 in cus__process_dwflmod (dwflmod=0x40d760, userdata=0x40d770, name=0x40d910 "examples/wcohen/02_Exercise.cuda", base=4194304, arg=0x7fffffffcf10) at /home/acme/git/pahole/dwarf_loader.c:2434 #11 0x00007ffff7f32be1 in dwfl_getmodules () from /lib64/libdw.so.1 #12 0x00007ffff7fa0820 in cus__process_file (cus=0x40b2b0, conf=0x40a240 <conf_load>, fd=3, filename=0x7fffffffd5e3 "examples/wcohen/02_Exercise.cuda") at /home/acme/git/pahole/dwarf_loader.c:2487 #13 0x00007ffff7fa089c in dwarf__load_file (cus=0x40b2b0, conf=0x40a240 <conf_load>, filename=0x7fffffffd5e3 "examples/wcohen/02_Exercise.cuda") at /home/acme/git/pahole/dwarf_loader.c:2504 #14 0x00007ffff7f8b0dd in cus__load_file (cus=0x40b2b0, conf=0x40a240 <conf_load>, filename=0x7fffffffd5e3 "examples/wcohen/02_Exercise.cuda") at /home/acme/git/pahole/dwarves.c:1745 #15 0x00007ffff7f8bc2a in cus__load_files (cus=0x40b2b0, conf=0x40a240 <conf_load>, filenames=0x7fffffffd150) at /home/acme/git/pahole/dwarves.c:2109 #16 0x0000000000404ff0 in main (argc=2, argv=0x7fffffffd148) at /home/acme/git/pahole/pahole.c:1294 (gdb) (gdb) p class__name(class, cu) $6 = 0x5cbb85 "__nv_hdl_helper_trait<__nv_dl_tag<int (*)(int, char**), main, 1u>, void (main(int, char**)::__lambda0::*)(int, double&)const>" (gdb) p class->type.nr_members $7 = 0 (gdb) p last $8 = (struct class_member *) 0x0 (gdb) So, before checking for bitfield details, first check if there were members. Now, if we show all structs/classes in that object file and look for the above data structure, we find it inside another: $ pahole examples/wcohen/02_Exercise.cuda <SNIP> struct __nv_hdl_helper_trait_outer<false, false, int, Kokkos::View<double**>, Kokkos::View<double*>, Kokkos::View<double*> > { struct __nv_hdl_helper_trait<__nv_dl_tag<int (*)(int, char**), main, 1u>, void (main(int, char**)::__lambda0::*)(int, double&)const> { class __nv_hdl_wrapper_t<false, false, __nv_dl_tag<int (*)(int, char**), main, 1u>, void(int, double&), int, Kokkos::View<doubl get<main(int, char**)::__lambda0>(class __lambda0, int, class View<double**>, class View<double*>, class View<double*>); /* size: 1, cachelines: 0, members: 0 */ /* padding: 1 */ /* last cacheline: 1 bytes */ }; /* size: 1, cachelines: 0, members: 0 */ /* padding: 1 */ /* last cacheline: 1 bytes */ }; <SNIP> $ Reported-by: William Cohen <wcohen@redhat.com> Fixes: 13e5b9f ("fprintf: Add unnamed bitfield padding at the end to rebuild original type") Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
acmel
pushed a commit
that referenced
this pull request
Jan 21, 2020
pahole -J .tmp_linux.btf during Linux build process always crashes on my system. Problem is that when gobuffer is initialized via gobuffer__init(), it is in state where 'index' (AKA its size) is set to 1, but 'entries' is NULL. State corrects itself if 'gobuffer__add()' is invoked, as that will allocate buffer (even if added len == 0). But if __add() is never invoked because only anonymous symbols are present, one ends up with gobuffer that crashes gobuffer__copy. Instead of allocating single-byte buffer always I opted for checking if gobuffer entries is NULL before use in copy and compress - gobuffer__init() would need prototype change to report malloc failures, and it seems unnecessary to allocate memory always - even if file does not have any symbols after all. (gdb) bt #0 __memmove_sse2_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:287 #1 0x00007f2f2c1ec2ee in btf_elf__encode (btfe=0x5654e31e2e30, flags=flags@entry=0 '\000') at libbtf.c:750 #2 0x00007f2f2c1e9af0 in btf_encoder__encode () at btf_encoder.c:164 #3 0x00005654e2407599 in main (argc=3, argv=0x7ffcd8783f18) at pahole.c:1344 (gdb) frame 1 #1 0x00007f2f2c1ec2ee in btf_elf__encode (btfe=0x5654e31e2e30, flags=flags@entry=0 '\000') at libbtf.c:750 750 gobuffer__copy(btfe->strings, btf_elf__nohdr_data(btfe) + hdr->str_off); (gdb) print btfe->strings $1 = (struct gobuffer *) 0x5654e31db2c8 (gdb) print *btfe->strings $2 = {entries = 0x0, nr_entries = 0, index = 1, allocated_size = 0} (gdb) print btfe->types $3 = {entries = 0x5654e31e2ef0 "", nr_entries = 1, index = 16, allocated_size = 8192} (gdb) x /16bx btfe->types.entries 0x5654e31e2ef0: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x01 0x5654e31e2ef8: 0x04 0x00 0x00 0x00 0x20 0x00 0x00 0x00 Signed-off-by: Petr Vandrovec <petr@vmware.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
acmel
added a commit
that referenced
this pull request
Jul 8, 2021
…() calls As this ends up racing on a tsearch() call, probably for some libdw cache that gets updated/lookedup in concurrent pahole threads (-j N). This cures the following, a patch for libdw will be cooked up and sent. (gdb) run -j -I -F dwarf vmlinux > /dev/null Starting program: /var/home/acme/git/pahole/build/pahole -j -I -F dwarf vmlinux > /dev/null warning: Expected absolute pathname for libpthread in the inferior, but got .gnu_debugdata for /lib64/libpthread.so.0. warning: File "/usr/lib64/libthread_db-1.0.so" auto-loading has been declined by your `auto-load safe-path' set to "$debugdir:$datadir/auto-load". warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available. [New LWP 844789] [New LWP 844790] [New LWP 844791] [New LWP 844792] [New LWP 844793] [New LWP 844794] [New LWP 844795] [New LWP 844796] [New LWP 844797] [New LWP 844798] [New LWP 844799] [New LWP 844800] [New LWP 844801] [New LWP 844802] [New LWP 844803] [New LWP 844804] [New LWP 844805] [New LWP 844806] [New LWP 844807] [New LWP 844808] [New LWP 844809] [New LWP 844810] [New LWP 844811] [New LWP 844812] [New LWP 844813] [New LWP 844814] Thread 2 "pahole" received signal SIGSEGV, Segmentation fault. [Switching to LWP 844789] 0x00007ffff7dfa321 in ?? () from /lib64/libc.so.6 (gdb) bt #0 0x00007ffff7dfa321 in ?? () from /lib64/libc.so.6 #1 0x00007ffff7dfa4bb in ?? () from /lib64/libc.so.6 #2 0x00007ffff7f5eaa6 in __libdw_getsrclines (dbg=0x4a7f90, debug_line_offset=10383710, comp_dir=0x7ffff3c29f01 "/var/home/acme/git/build/v5.13.0-rc6+", address_size=address_size@entry=8, linesp=linesp@entry=0x7fffcfe04ba0, filesp=filesp@entry=0x7fffcfe04ba8) at dwarf_getsrclines.c:1129 #3 0x00007ffff7f5ed14 in dwarf_getsrclines (cudie=cudie@entry=0x7fffd210caf0, lines=lines@entry=0x7fffd210cac0, nlines=nlines@entry=0x7fffd210cac8) at dwarf_getsrclines.c:1213 #4 0x00007ffff7f64883 in dwarf_decl_file (die=<optimized out>) at dwarf_decl_file.c:66 #5 0x0000000000425f24 in tag__init (tag=0x7fff0421b710, cu=0x7fffcc001e40, die=0x7fffd210cd30) at /var/home/acme/git/pahole/dwarf_loader.c:476 #6 0x00000000004262ec in namespace__init (namespace=0x7fff0421b710, die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:576 #7 0x00000000004263ac in type__init (type=0x7fff0421b710, die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:595 #8 0x00000000004264d1 in type__new (die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:614 #9 0x0000000000427ba6 in die__create_new_typedef (die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:1212 #10 0x0000000000428df5 in __die__process_tag (die=0x7fffd210cd30, cu=0x7fffcc001e40, top_level=1, fn=0x45cee0 <__FUNCTION__.10> "die__process_unit", conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:1823 #11 0x0000000000428ea1 in die__process_unit (die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:1848 #12 0x0000000000429e45 in die__process (die=0x7fffd210ce20, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:2311 #13 0x0000000000429ecb in die__process_and_recode (die=0x7fffd210ce20, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:2326 #14 0x000000000042a9d6 in dwarf_cus__create_and_process_cu (dcus=0x7fffffffddc0, cu_die=0x7fffd210ce20, pointer_size=8 '\b') at /var/home/acme/git/pahole/dwarf_loader.c:2644 #15 0x000000000042ab28 in dwarf_cus__process_cu_thread (arg=0x7fffffffddc0) at /var/home/acme/git/pahole/dwarf_loader.c:2687 #16 0x00007ffff7ed6299 in start_thread () from /lib64/libpthread.so.0 #17 0x00007ffff7dfe353 in ?? () from /lib64/libc.so.6 (gdb) (gdb) fr 2 1085 (gdb) list files_lines_compare 1086 static int 1087 files_lines_compare (const void *p1, const void *p2) 1088 { 1089 const struct files_lines_s *t1 = p1; 1090 const struct files_lines_s *t2 = p2; 1091 1092 if (t1->debug_line_offset < t2->debug_line_offset) (gdb) 1093 return -1; 1094 if (t1->debug_line_offset > t2->debug_line_offset) 1095 return 1; 1096 1097 return 0; 1098 } 1099 1100 int 1101 internal_function 1102 __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset, (gdb) list __libdw_getsrclines 1100 int 1101 internal_function 1102 __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset, 1103 const char *comp_dir, unsigned address_size, 1104 Dwarf_Lines **linesp, Dwarf_Files **filesp) 1105 { 1106 struct files_lines_s fake = { .debug_line_offset = debug_line_offset }; 1107 struct files_lines_s **found = tfind (&fake, &dbg->files_lines, 1108 files_lines_compare); 1109 if (found == NULL) (gdb) 1110 { 1111 Elf_Data *data = __libdw_checked_get_data (dbg, IDX_debug_line); 1112 if (data == NULL 1113 || __libdw_offset_in_section (dbg, IDX_debug_line, 1114 debug_line_offset, 1) != 0) 1115 return -1; 1116 1117 const unsigned char *linep = data->d_buf + debug_line_offset; 1118 const unsigned char *lineendp = data->d_buf + data->d_size; 1119 (gdb) 1120 struct files_lines_s *node = libdw_alloc (dbg, struct files_lines_s, 1121 sizeof *node, 1); 1122 1123 if (read_srclines (dbg, linep, lineendp, comp_dir, address_size, 1124 &node->lines, &node->files) != 0) 1125 return -1; 1126 1127 node->debug_line_offset = debug_line_offset; 1128 1129 found = tsearch (node, &dbg->files_lines, files_lines_compare); (gdb) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
acmel
added a commit
that referenced
this pull request
Jul 27, 2021
…() calls As this ends up racing on a tsearch() call, probably for some libdw cache that gets updated/lookedup in concurrent pahole threads (-j N). This cures the following, a patch for libdw will be cooked up and sent. (gdb) run -j -I -F dwarf vmlinux > /dev/null Starting program: /var/home/acme/git/pahole/build/pahole -j -I -F dwarf vmlinux > /dev/null warning: Expected absolute pathname for libpthread in the inferior, but got .gnu_debugdata for /lib64/libpthread.so.0. warning: File "/usr/lib64/libthread_db-1.0.so" auto-loading has been declined by your `auto-load safe-path' set to "$debugdir:$datadir/auto-load". warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available. [New LWP 844789] [New LWP 844790] [New LWP 844791] [New LWP 844792] [New LWP 844793] [New LWP 844794] [New LWP 844795] [New LWP 844796] [New LWP 844797] [New LWP 844798] [New LWP 844799] [New LWP 844800] [New LWP 844801] [New LWP 844802] [New LWP 844803] [New LWP 844804] [New LWP 844805] [New LWP 844806] [New LWP 844807] [New LWP 844808] [New LWP 844809] [New LWP 844810] [New LWP 844811] [New LWP 844812] [New LWP 844813] [New LWP 844814] Thread 2 "pahole" received signal SIGSEGV, Segmentation fault. [Switching to LWP 844789] 0x00007ffff7dfa321 in ?? () from /lib64/libc.so.6 (gdb) bt #0 0x00007ffff7dfa321 in ?? () from /lib64/libc.so.6 #1 0x00007ffff7dfa4bb in ?? () from /lib64/libc.so.6 #2 0x00007ffff7f5eaa6 in __libdw_getsrclines (dbg=0x4a7f90, debug_line_offset=10383710, comp_dir=0x7ffff3c29f01 "/var/home/acme/git/build/v5.13.0-rc6+", address_size=address_size@entry=8, linesp=linesp@entry=0x7fffcfe04ba0, filesp=filesp@entry=0x7fffcfe04ba8) at dwarf_getsrclines.c:1129 #3 0x00007ffff7f5ed14 in dwarf_getsrclines (cudie=cudie@entry=0x7fffd210caf0, lines=lines@entry=0x7fffd210cac0, nlines=nlines@entry=0x7fffd210cac8) at dwarf_getsrclines.c:1213 #4 0x00007ffff7f64883 in dwarf_decl_file (die=<optimized out>) at dwarf_decl_file.c:66 #5 0x0000000000425f24 in tag__init (tag=0x7fff0421b710, cu=0x7fffcc001e40, die=0x7fffd210cd30) at /var/home/acme/git/pahole/dwarf_loader.c:476 #6 0x00000000004262ec in namespace__init (namespace=0x7fff0421b710, die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:576 #7 0x00000000004263ac in type__init (type=0x7fff0421b710, die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:595 #8 0x00000000004264d1 in type__new (die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:614 #9 0x0000000000427ba6 in die__create_new_typedef (die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:1212 #10 0x0000000000428df5 in __die__process_tag (die=0x7fffd210cd30, cu=0x7fffcc001e40, top_level=1, fn=0x45cee0 <__FUNCTION__.10> "die__process_unit", conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:1823 #11 0x0000000000428ea1 in die__process_unit (die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:1848 #12 0x0000000000429e45 in die__process (die=0x7fffd210ce20, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:2311 #13 0x0000000000429ecb in die__process_and_recode (die=0x7fffd210ce20, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:2326 #14 0x000000000042a9d6 in dwarf_cus__create_and_process_cu (dcus=0x7fffffffddc0, cu_die=0x7fffd210ce20, pointer_size=8 '\b') at /var/home/acme/git/pahole/dwarf_loader.c:2644 #15 0x000000000042ab28 in dwarf_cus__process_cu_thread (arg=0x7fffffffddc0) at /var/home/acme/git/pahole/dwarf_loader.c:2687 #16 0x00007ffff7ed6299 in start_thread () from /lib64/libpthread.so.0 #17 0x00007ffff7dfe353 in ?? () from /lib64/libc.so.6 (gdb) (gdb) fr 2 1085 (gdb) list files_lines_compare 1086 static int 1087 files_lines_compare (const void *p1, const void *p2) 1088 { 1089 const struct files_lines_s *t1 = p1; 1090 const struct files_lines_s *t2 = p2; 1091 1092 if (t1->debug_line_offset < t2->debug_line_offset) (gdb) 1093 return -1; 1094 if (t1->debug_line_offset > t2->debug_line_offset) 1095 return 1; 1096 1097 return 0; 1098 } 1099 1100 int 1101 internal_function 1102 __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset, (gdb) list __libdw_getsrclines 1100 int 1101 internal_function 1102 __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset, 1103 const char *comp_dir, unsigned address_size, 1104 Dwarf_Lines **linesp, Dwarf_Files **filesp) 1105 { 1106 struct files_lines_s fake = { .debug_line_offset = debug_line_offset }; 1107 struct files_lines_s **found = tfind (&fake, &dbg->files_lines, 1108 files_lines_compare); 1109 if (found == NULL) (gdb) 1110 { 1111 Elf_Data *data = __libdw_checked_get_data (dbg, IDX_debug_line); 1112 if (data == NULL 1113 || __libdw_offset_in_section (dbg, IDX_debug_line, 1114 debug_line_offset, 1) != 0) 1115 return -1; 1116 1117 const unsigned char *linep = data->d_buf + debug_line_offset; 1118 const unsigned char *lineendp = data->d_buf + data->d_size; 1119 (gdb) 1120 struct files_lines_s *node = libdw_alloc (dbg, struct files_lines_s, 1121 sizeof *node, 1); 1122 1123 if (read_srclines (dbg, linep, lineendp, comp_dir, address_size, 1124 &node->lines, &node->files) != 0) 1125 return -1; 1126 1127 node->debug_line_offset = debug_line_offset; 1128 1129 found = tsearch (node, &dbg->files_lines, files_lines_compare); (gdb) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
acmel
added a commit
that referenced
this pull request
Jul 28, 2021
…() calls As this ends up racing on a tsearch() call, probably for some libdw cache that gets updated/lookedup in concurrent pahole threads (-j N). This cures the following, a patch for libdw will be cooked up and sent. (gdb) run -j -I -F dwarf vmlinux > /dev/null Starting program: /var/home/acme/git/pahole/build/pahole -j -I -F dwarf vmlinux > /dev/null warning: Expected absolute pathname for libpthread in the inferior, but got .gnu_debugdata for /lib64/libpthread.so.0. warning: File "/usr/lib64/libthread_db-1.0.so" auto-loading has been declined by your `auto-load safe-path' set to "$debugdir:$datadir/auto-load". warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available. [New LWP 844789] [New LWP 844790] [New LWP 844791] [New LWP 844792] [New LWP 844793] [New LWP 844794] [New LWP 844795] [New LWP 844796] [New LWP 844797] [New LWP 844798] [New LWP 844799] [New LWP 844800] [New LWP 844801] [New LWP 844802] [New LWP 844803] [New LWP 844804] [New LWP 844805] [New LWP 844806] [New LWP 844807] [New LWP 844808] [New LWP 844809] [New LWP 844810] [New LWP 844811] [New LWP 844812] [New LWP 844813] [New LWP 844814] Thread 2 "pahole" received signal SIGSEGV, Segmentation fault. [Switching to LWP 844789] 0x00007ffff7dfa321 in ?? () from /lib64/libc.so.6 (gdb) bt #0 0x00007ffff7dfa321 in ?? () from /lib64/libc.so.6 #1 0x00007ffff7dfa4bb in ?? () from /lib64/libc.so.6 #2 0x00007ffff7f5eaa6 in __libdw_getsrclines (dbg=0x4a7f90, debug_line_offset=10383710, comp_dir=0x7ffff3c29f01 "/var/home/acme/git/build/v5.13.0-rc6+", address_size=address_size@entry=8, linesp=linesp@entry=0x7fffcfe04ba0, filesp=filesp@entry=0x7fffcfe04ba8) at dwarf_getsrclines.c:1129 #3 0x00007ffff7f5ed14 in dwarf_getsrclines (cudie=cudie@entry=0x7fffd210caf0, lines=lines@entry=0x7fffd210cac0, nlines=nlines@entry=0x7fffd210cac8) at dwarf_getsrclines.c:1213 #4 0x00007ffff7f64883 in dwarf_decl_file (die=<optimized out>) at dwarf_decl_file.c:66 #5 0x0000000000425f24 in tag__init (tag=0x7fff0421b710, cu=0x7fffcc001e40, die=0x7fffd210cd30) at /var/home/acme/git/pahole/dwarf_loader.c:476 #6 0x00000000004262ec in namespace__init (namespace=0x7fff0421b710, die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:576 #7 0x00000000004263ac in type__init (type=0x7fff0421b710, die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:595 #8 0x00000000004264d1 in type__new (die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:614 #9 0x0000000000427ba6 in die__create_new_typedef (die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:1212 #10 0x0000000000428df5 in __die__process_tag (die=0x7fffd210cd30, cu=0x7fffcc001e40, top_level=1, fn=0x45cee0 <__FUNCTION__.10> "die__process_unit", conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:1823 #11 0x0000000000428ea1 in die__process_unit (die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:1848 #12 0x0000000000429e45 in die__process (die=0x7fffd210ce20, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:2311 #13 0x0000000000429ecb in die__process_and_recode (die=0x7fffd210ce20, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:2326 #14 0x000000000042a9d6 in dwarf_cus__create_and_process_cu (dcus=0x7fffffffddc0, cu_die=0x7fffd210ce20, pointer_size=8 '\b') at /var/home/acme/git/pahole/dwarf_loader.c:2644 #15 0x000000000042ab28 in dwarf_cus__process_cu_thread (arg=0x7fffffffddc0) at /var/home/acme/git/pahole/dwarf_loader.c:2687 #16 0x00007ffff7ed6299 in start_thread () from /lib64/libpthread.so.0 #17 0x00007ffff7dfe353 in ?? () from /lib64/libc.so.6 (gdb) (gdb) fr 2 1085 (gdb) list files_lines_compare 1086 static int 1087 files_lines_compare (const void *p1, const void *p2) 1088 { 1089 const struct files_lines_s *t1 = p1; 1090 const struct files_lines_s *t2 = p2; 1091 1092 if (t1->debug_line_offset < t2->debug_line_offset) (gdb) 1093 return -1; 1094 if (t1->debug_line_offset > t2->debug_line_offset) 1095 return 1; 1096 1097 return 0; 1098 } 1099 1100 int 1101 internal_function 1102 __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset, (gdb) list __libdw_getsrclines 1100 int 1101 internal_function 1102 __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset, 1103 const char *comp_dir, unsigned address_size, 1104 Dwarf_Lines **linesp, Dwarf_Files **filesp) 1105 { 1106 struct files_lines_s fake = { .debug_line_offset = debug_line_offset }; 1107 struct files_lines_s **found = tfind (&fake, &dbg->files_lines, 1108 files_lines_compare); 1109 if (found == NULL) (gdb) 1110 { 1111 Elf_Data *data = __libdw_checked_get_data (dbg, IDX_debug_line); 1112 if (data == NULL 1113 || __libdw_offset_in_section (dbg, IDX_debug_line, 1114 debug_line_offset, 1) != 0) 1115 return -1; 1116 1117 const unsigned char *linep = data->d_buf + debug_line_offset; 1118 const unsigned char *lineendp = data->d_buf + data->d_size; 1119 (gdb) 1120 struct files_lines_s *node = libdw_alloc (dbg, struct files_lines_s, 1121 sizeof *node, 1); 1122 1123 if (read_srclines (dbg, linep, lineendp, comp_dir, address_size, 1124 &node->lines, &node->files) != 0) 1125 return -1; 1126 1127 node->debug_line_offset = debug_line_offset; 1128 1129 found = tsearch (node, &dbg->files_lines, files_lines_compare); (gdb) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
acmel
added a commit
that referenced
this pull request
Aug 6, 2021
…() calls As this ends up racing on a tsearch() call, probably for some libdw cache that gets updated/lookedup in concurrent pahole threads (-j N). This cures the following, a patch for libdw will be cooked up and sent. (gdb) run -j -I -F dwarf vmlinux > /dev/null Starting program: /var/home/acme/git/pahole/build/pahole -j -I -F dwarf vmlinux > /dev/null warning: Expected absolute pathname for libpthread in the inferior, but got .gnu_debugdata for /lib64/libpthread.so.0. warning: File "/usr/lib64/libthread_db-1.0.so" auto-loading has been declined by your `auto-load safe-path' set to "$debugdir:$datadir/auto-load". warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available. [New LWP 844789] [New LWP 844790] [New LWP 844791] [New LWP 844792] [New LWP 844793] [New LWP 844794] [New LWP 844795] [New LWP 844796] [New LWP 844797] [New LWP 844798] [New LWP 844799] [New LWP 844800] [New LWP 844801] [New LWP 844802] [New LWP 844803] [New LWP 844804] [New LWP 844805] [New LWP 844806] [New LWP 844807] [New LWP 844808] [New LWP 844809] [New LWP 844810] [New LWP 844811] [New LWP 844812] [New LWP 844813] [New LWP 844814] Thread 2 "pahole" received signal SIGSEGV, Segmentation fault. [Switching to LWP 844789] 0x00007ffff7dfa321 in ?? () from /lib64/libc.so.6 (gdb) bt #0 0x00007ffff7dfa321 in ?? () from /lib64/libc.so.6 #1 0x00007ffff7dfa4bb in ?? () from /lib64/libc.so.6 #2 0x00007ffff7f5eaa6 in __libdw_getsrclines (dbg=0x4a7f90, debug_line_offset=10383710, comp_dir=0x7ffff3c29f01 "/var/home/acme/git/build/v5.13.0-rc6+", address_size=address_size@entry=8, linesp=linesp@entry=0x7fffcfe04ba0, filesp=filesp@entry=0x7fffcfe04ba8) at dwarf_getsrclines.c:1129 #3 0x00007ffff7f5ed14 in dwarf_getsrclines (cudie=cudie@entry=0x7fffd210caf0, lines=lines@entry=0x7fffd210cac0, nlines=nlines@entry=0x7fffd210cac8) at dwarf_getsrclines.c:1213 #4 0x00007ffff7f64883 in dwarf_decl_file (die=<optimized out>) at dwarf_decl_file.c:66 #5 0x0000000000425f24 in tag__init (tag=0x7fff0421b710, cu=0x7fffcc001e40, die=0x7fffd210cd30) at /var/home/acme/git/pahole/dwarf_loader.c:476 #6 0x00000000004262ec in namespace__init (namespace=0x7fff0421b710, die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:576 #7 0x00000000004263ac in type__init (type=0x7fff0421b710, die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:595 #8 0x00000000004264d1 in type__new (die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:614 #9 0x0000000000427ba6 in die__create_new_typedef (die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:1212 #10 0x0000000000428df5 in __die__process_tag (die=0x7fffd210cd30, cu=0x7fffcc001e40, top_level=1, fn=0x45cee0 <__FUNCTION__.10> "die__process_unit", conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:1823 #11 0x0000000000428ea1 in die__process_unit (die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:1848 #12 0x0000000000429e45 in die__process (die=0x7fffd210ce20, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:2311 #13 0x0000000000429ecb in die__process_and_recode (die=0x7fffd210ce20, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:2326 #14 0x000000000042a9d6 in dwarf_cus__create_and_process_cu (dcus=0x7fffffffddc0, cu_die=0x7fffd210ce20, pointer_size=8 '\b') at /var/home/acme/git/pahole/dwarf_loader.c:2644 #15 0x000000000042ab28 in dwarf_cus__process_cu_thread (arg=0x7fffffffddc0) at /var/home/acme/git/pahole/dwarf_loader.c:2687 #16 0x00007ffff7ed6299 in start_thread () from /lib64/libpthread.so.0 #17 0x00007ffff7dfe353 in ?? () from /lib64/libc.so.6 (gdb) (gdb) fr 2 1085 (gdb) list files_lines_compare 1086 static int 1087 files_lines_compare (const void *p1, const void *p2) 1088 { 1089 const struct files_lines_s *t1 = p1; 1090 const struct files_lines_s *t2 = p2; 1091 1092 if (t1->debug_line_offset < t2->debug_line_offset) (gdb) 1093 return -1; 1094 if (t1->debug_line_offset > t2->debug_line_offset) 1095 return 1; 1096 1097 return 0; 1098 } 1099 1100 int 1101 internal_function 1102 __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset, (gdb) list __libdw_getsrclines 1100 int 1101 internal_function 1102 __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset, 1103 const char *comp_dir, unsigned address_size, 1104 Dwarf_Lines **linesp, Dwarf_Files **filesp) 1105 { 1106 struct files_lines_s fake = { .debug_line_offset = debug_line_offset }; 1107 struct files_lines_s **found = tfind (&fake, &dbg->files_lines, 1108 files_lines_compare); 1109 if (found == NULL) (gdb) 1110 { 1111 Elf_Data *data = __libdw_checked_get_data (dbg, IDX_debug_line); 1112 if (data == NULL 1113 || __libdw_offset_in_section (dbg, IDX_debug_line, 1114 debug_line_offset, 1) != 0) 1115 return -1; 1116 1117 const unsigned char *linep = data->d_buf + debug_line_offset; 1118 const unsigned char *lineendp = data->d_buf + data->d_size; 1119 (gdb) 1120 struct files_lines_s *node = libdw_alloc (dbg, struct files_lines_s, 1121 sizeof *node, 1); 1122 1123 if (read_srclines (dbg, linep, lineendp, comp_dir, address_size, 1124 &node->lines, &node->files) != 0) 1125 return -1; 1126 1127 node->debug_line_offset = debug_line_offset; 1128 1129 found = tsearch (node, &dbg->files_lines, files_lines_compare); (gdb) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
acmel
added a commit
that referenced
this pull request
Aug 12, 2021
…() calls As this ends up racing on a tsearch() call, probably for some libdw cache that gets updated/lookedup in concurrent pahole threads (-j N). This cures the following, a patch for libdw will be cooked up and sent. (gdb) run -j -I -F dwarf vmlinux > /dev/null Starting program: /var/home/acme/git/pahole/build/pahole -j -I -F dwarf vmlinux > /dev/null warning: Expected absolute pathname for libpthread in the inferior, but got .gnu_debugdata for /lib64/libpthread.so.0. warning: File "/usr/lib64/libthread_db-1.0.so" auto-loading has been declined by your `auto-load safe-path' set to "$debugdir:$datadir/auto-load". warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available. [New LWP 844789] [New LWP 844790] [New LWP 844791] [New LWP 844792] [New LWP 844793] [New LWP 844794] [New LWP 844795] [New LWP 844796] [New LWP 844797] [New LWP 844798] [New LWP 844799] [New LWP 844800] [New LWP 844801] [New LWP 844802] [New LWP 844803] [New LWP 844804] [New LWP 844805] [New LWP 844806] [New LWP 844807] [New LWP 844808] [New LWP 844809] [New LWP 844810] [New LWP 844811] [New LWP 844812] [New LWP 844813] [New LWP 844814] Thread 2 "pahole" received signal SIGSEGV, Segmentation fault. [Switching to LWP 844789] 0x00007ffff7dfa321 in ?? () from /lib64/libc.so.6 (gdb) bt #0 0x00007ffff7dfa321 in ?? () from /lib64/libc.so.6 #1 0x00007ffff7dfa4bb in ?? () from /lib64/libc.so.6 #2 0x00007ffff7f5eaa6 in __libdw_getsrclines (dbg=0x4a7f90, debug_line_offset=10383710, comp_dir=0x7ffff3c29f01 "/var/home/acme/git/build/v5.13.0-rc6+", address_size=address_size@entry=8, linesp=linesp@entry=0x7fffcfe04ba0, filesp=filesp@entry=0x7fffcfe04ba8) at dwarf_getsrclines.c:1129 #3 0x00007ffff7f5ed14 in dwarf_getsrclines (cudie=cudie@entry=0x7fffd210caf0, lines=lines@entry=0x7fffd210cac0, nlines=nlines@entry=0x7fffd210cac8) at dwarf_getsrclines.c:1213 #4 0x00007ffff7f64883 in dwarf_decl_file (die=<optimized out>) at dwarf_decl_file.c:66 #5 0x0000000000425f24 in tag__init (tag=0x7fff0421b710, cu=0x7fffcc001e40, die=0x7fffd210cd30) at /var/home/acme/git/pahole/dwarf_loader.c:476 #6 0x00000000004262ec in namespace__init (namespace=0x7fff0421b710, die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:576 #7 0x00000000004263ac in type__init (type=0x7fff0421b710, die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:595 #8 0x00000000004264d1 in type__new (die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:614 #9 0x0000000000427ba6 in die__create_new_typedef (die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:1212 #10 0x0000000000428df5 in __die__process_tag (die=0x7fffd210cd30, cu=0x7fffcc001e40, top_level=1, fn=0x45cee0 <__FUNCTION__.10> "die__process_unit", conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:1823 #11 0x0000000000428ea1 in die__process_unit (die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:1848 #12 0x0000000000429e45 in die__process (die=0x7fffd210ce20, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:2311 #13 0x0000000000429ecb in die__process_and_recode (die=0x7fffd210ce20, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:2326 #14 0x000000000042a9d6 in dwarf_cus__create_and_process_cu (dcus=0x7fffffffddc0, cu_die=0x7fffd210ce20, pointer_size=8 '\b') at /var/home/acme/git/pahole/dwarf_loader.c:2644 #15 0x000000000042ab28 in dwarf_cus__process_cu_thread (arg=0x7fffffffddc0) at /var/home/acme/git/pahole/dwarf_loader.c:2687 #16 0x00007ffff7ed6299 in start_thread () from /lib64/libpthread.so.0 #17 0x00007ffff7dfe353 in ?? () from /lib64/libc.so.6 (gdb) (gdb) fr 2 1085 (gdb) list files_lines_compare 1086 static int 1087 files_lines_compare (const void *p1, const void *p2) 1088 { 1089 const struct files_lines_s *t1 = p1; 1090 const struct files_lines_s *t2 = p2; 1091 1092 if (t1->debug_line_offset < t2->debug_line_offset) (gdb) 1093 return -1; 1094 if (t1->debug_line_offset > t2->debug_line_offset) 1095 return 1; 1096 1097 return 0; 1098 } 1099 1100 int 1101 internal_function 1102 __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset, (gdb) list __libdw_getsrclines 1100 int 1101 internal_function 1102 __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset, 1103 const char *comp_dir, unsigned address_size, 1104 Dwarf_Lines **linesp, Dwarf_Files **filesp) 1105 { 1106 struct files_lines_s fake = { .debug_line_offset = debug_line_offset }; 1107 struct files_lines_s **found = tfind (&fake, &dbg->files_lines, 1108 files_lines_compare); 1109 if (found == NULL) (gdb) 1110 { 1111 Elf_Data *data = __libdw_checked_get_data (dbg, IDX_debug_line); 1112 if (data == NULL 1113 || __libdw_offset_in_section (dbg, IDX_debug_line, 1114 debug_line_offset, 1) != 0) 1115 return -1; 1116 1117 const unsigned char *linep = data->d_buf + debug_line_offset; 1118 const unsigned char *lineendp = data->d_buf + data->d_size; 1119 (gdb) 1120 struct files_lines_s *node = libdw_alloc (dbg, struct files_lines_s, 1121 sizeof *node, 1); 1122 1123 if (read_srclines (dbg, linep, lineendp, comp_dir, address_size, 1124 &node->lines, &node->files) != 0) 1125 return -1; 1126 1127 node->debug_line_offset = debug_line_offset; 1128 1129 found = tsearch (node, &dbg->files_lines, files_lines_compare); (gdb) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
acmel
added a commit
that referenced
this pull request
Jan 28, 2022
…ne_size field tldr; gdb pfunct (gdb) run --compile tcp.o Program received signal SIGFPE, Arithmetic exception. 0x00007ffff7f18551 in class__fprintf_cacheline_boundary (conf=0x7fffffffda10, offset=0, fp=0x7ffff7e17520 <_IO_2_1_stdout_>) at /var/home/acme/git/pahole/dwarves_fprintf.c:1319 1319 uint32_t cacheline = offset / conf->cacheline_size; (gdb) bt #0 0x00007ffff7f18551 in class__fprintf_cacheline_boundary (conf=0x7fffffffda10, offset=0, fp=0x7ffff7e17520 <_IO_2_1_stdout_>) at /var/home/acme/git/pahole/dwarves_fprintf.c:1319 #1 0x00007ffff7f16af2 in class_member__fprintf (member=0x45de10, union_member=false, type=0x45dfb0, cu=0x435a40, conf=0x7fffffffda10, fp=0x7ffff7e17520 <_IO_2_1_stdout_>) at /var/home/acme/git/pahole/dwarves_fprintf.c:869 #2 0x00007ffff7f1717b in struct_member__fprintf (member=0x45de10, type=0x45dfb0, cu=0x435a40, conf=0x7fffffffda10, fp=0x7ffff7e17520 <_IO_2_1_stdout_>) at /var/home/acme/git/pahole/dwarves_fprintf.c:983 #3 0x00007ffff7f1945c in __class__fprintf (class=0x45dcc0, cu=0x435a40, conf=0x7fffffffdbb0, fp=0x7ffff7e17520 <_IO_2_1_stdout_>) at /var/home/acme/git/pahole/dwarves_fprintf.c:1583 #4 0x00007ffff7f1a6bd in tag__fprintf (tag=0x45dcc0, cu=0x435a40, conf=0x7fffffffdc70, fp=0x7ffff7e17520 <_IO_2_1_stdout_>) at /var/home/acme/git/pahole/dwarves_fprintf.c:1906 #5 0x00007ffff7fbf022 in type__emit (tag=0x45dcc0, cu=0x435a40, prefix=0x0, suffix=0x0, fp=0x7ffff7e17520 <_IO_2_1_stdout_>) at /var/home/acme/git/pahole/dwarves_emit.c:333 #6 0x00007ffff7fbed3d in tag__emit_definitions (tag=0x6b21e0, cu=0x435a40, emissions=0x408300 <emissions>, fp=0x7ffff7e17520 <_IO_2_1_stdout_>) at /var/home/acme/git/pahole/dwarves_emit.c:265 #7 0x00007ffff7fbef45 in type__emit_definitions (tag=0x6b20c0, cu=0x435a40, emissions=0x408300 <emissions>, fp=0x7ffff7e17520 <_IO_2_1_stdout_>) at /var/home/acme/git/pahole/dwarves_emit.c:315 #8 0x00007ffff7fbed15 in tag__emit_definitions (tag=0x6b3b40, cu=0x435a40, emissions=0x408300 <emissions>, fp=0x7ffff7e17520 <_IO_2_1_stdout_>) at /var/home/acme/git/pahole/dwarves_emit.c:264 #9 0x00007ffff7fbef45 in type__emit_definitions (tag=0x6b31d0, cu=0x435a40, emissions=0x408300 <emissions>, fp=0x7ffff7e17520 <_IO_2_1_stdout_>) at /var/home/acme/git/pahole/dwarves_emit.c:315 #10 0x00007ffff7fbed15 in tag__emit_definitions (tag=0x4cb920, cu=0x435a40, emissions=0x408300 <emissions>, fp=0x7ffff7e17520 <_IO_2_1_stdout_>) at /var/home/acme/git/pahole/dwarves_emit.c:264 #11 0x00007ffff7fbef45 in type__emit_definitions (tag=0x4cb7d0, cu=0x435a40, emissions=0x408300 <emissions>, fp=0x7ffff7e17520 <_IO_2_1_stdout_>) at /var/home/acme/git/pahole/dwarves_emit.c:315 #12 0x0000000000403592 in function__emit_type_definitions (func=0x738ad0, cu=0x435a40, fp=0x7ffff7e17520 <_IO_2_1_stdout_>) at /var/home/acme/git/pahole/pfunct.c:353 #13 0x0000000000403670 in function__show (func=0x738ad0, cu=0x435a40) at /var/home/acme/git/pahole/pfunct.c:371 #14 0x00000000004038e9 in cu_function_iterator (cu=0x435a40, cookie=0x0) at /var/home/acme/git/pahole/pfunct.c:404 #15 0x00007ffff7f1296b in cus__for_each_cu (cus=0x4369e0, iterator=0x403869 <cu_function_iterator>, cookie=0x0, filter=0x0) at /var/home/acme/git/pahole/dwarves.c:1919 #16 0x000000000040432a in main (argc=3, argv=0x7fffffffe1f8) at /var/home/acme/git/pahole/pfunct.c:776 (gdb) p conf->cacheline_size $2 = 0 We need to pass a conf_fprintf pointer to the chain starting with function__emit_type_definitions(), i.e. dwarves_emit.c needs to receive the printing configuration instead of, right at type__emit() synthesize a conf_fprintf without initializing conf_fprintf->cacheline_size which ends up in a division by zero. But to fix this quicker just add a helper that checks if it is zero and uses the conf_fprintf__defaults.cacheline_size field that is being initialized by all tools via: dwarves__resolve_cacheline_size(&conf_load, 0); Fixes: 772725a ("dwarves_fprintf: Move cacheline_size into struct conf_fprintf") Cc: Douglas Raillard <douglas.raillard@arm.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
eddyz87
added a commit
to eddyz87/dwarves
that referenced
this pull request
Mar 19, 2023
In recent discussion in BPF mailing list ([1]) participants agreed to add a new DWARF representation for "btf_type_tag" annotations. Existing representation is DW_TAG_LLVM_annotation object attached as a child to a DW_TAG_pointer_type. It means that "btf_type_tag" annotation is attached to a pointee type. New representation is DW_TAG_LLVM_annotation object attached as a child to *any* type. It means that "btf_type_tag" annotation is attached to the parent type. For example, consider the following C code: struct alpha { int __attribute__((btf_type_tag("__alpha_a"))) *a; } g; And corresponding DWARF: 0x29: DW_TAG_structure_type DW_AT_name ("alpha") 0x2e: DW_TAG_member DW_AT_name ("a") DW_AT_type (0x38 "int *") 0x38: DW_TAG_pointer_type DW_AT_type (0x41 "int") 0x3d: DW_TAG_LLVM_annotation DW_AT_name ("btf_type_tag") DW_AT_const_value ("__alpha_a") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Old style representation 0x41: DW_TAG_base_type DW_AT_name ("int") DW_AT_encoding (DW_ATE_signed) DW_AT_byte_size (0x04) 0x45: DW_TAG_LLVM_annotation DW_AT_name ("btf:type_tag") DW_AT_const_value ("__alpha_a") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ New style representation This means that new style type tags could be attached to any type from the list below: - base types; - arrays; - pointers; - structs - unions; - enums; - typedefs. This commit is a preparatory step for `btf:type_tag` support: - structs, unions and typedefs could be annotated with two kinds of `DW_TAG_LLVM_annotation` when new type tag representation is used: - BTF_DECL_TAG - BTF_TYPE_TAG In order to keep these objects in a single annotations list `struct llvm_annotation` and `struct btf_type_tag_type` are consolidated as a single type with a special discriminator field to distinguish one from the other; - Because many types could be annotated with `btf:type_tag` the `annots` field is moved to `struct tag`, consequently: - type `struct btf_type_tag_type_ptr` is removed; - field `struct namespace::annots` is removed. [1] Mailing list discussion regarding `btf:type_tag` Various approaches are discussed, Solution acmel#2 is accepted https://lore.kernel.org/bpf/87r0w9jjoq.fsf@oracle.com/ Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
eddyz87
added a commit
to eddyz87/dwarves
that referenced
this pull request
Mar 19, 2023
In recent discussion in BPF mailing list ([1]) participants agreed to add a new DWARF representation for "btf_type_tag" annotations. The agreed representation of void pointers uses unspecified types. For example, consider the following C code: struct alpha { void __attribute__((btf_type_tag("__alpha_a"))) *a; } g; And corresponding DWARF: 0x29: DW_TAG_structure_type DW_AT_name ("alpha") 0x2e: DW_TAG_member DW_AT_name ("a") DW_AT_type (0x38 "void *") 0x38: DW_TAG_pointer_type DW_AT_type (0x41 "void") 0x41: DW_TAG_unspecified_type DW_AT_name ("void") 0x43: DW_TAG_LLVM_annotation DW_AT_name ("btf:type_tag") DW_AT_const_value ("__alpha_a") This is a preparatory patch for new type tags representation support, specifically it adds `struct unspecified_type` and a new `cu` field `struct cu::unspecified_types`. These would be used in a subsequent patch to recode type tags attached to DW_TAG_unspecified_type as in the example above. [1] Mailing list discussion regarding `btf:type_tag` Various approaches are discussed, Solution acmel#2 is accepted https://lore.kernel.org/bpf/87r0w9jjoq.fsf@oracle.com/ Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
eddyz87
added a commit
to eddyz87/dwarves
that referenced
this pull request
Mar 19, 2023
"btf:type_tag" is an DW_TAG_LLVM_annotation object that encodes btf_type_tag attributes in DWARF. Contrary to existing "btf_type_tag" it allows to associate such attributes with non-pointer types. When "btf:type_tag" is attached to a type it applies to this type. For example the following C code: struct echo { int __attribute__((btf_type_tag("__c"))) c; } Produces the following DWARF: 0x29: DW_TAG_structure_type DW_AT_name ("echo") 0x40: DW_TAG_member DW_AT_name ("c") DW_AT_type (0x8c "int") 0x8c: DW_TAG_base_type DW_AT_name ("int") DW_AT_encoding (DW_ATE_signed) DW_AT_byte_size (0x04) 0x90: DW_TAG_LLVM_annotation DW_AT_name ("btf:type_tag") DW_AT_const_value ("__c") Meaning that type 0x8c is an `int` with type tag `__c`. Corresponding BTF looks as follows: [1] STRUCT 'echo' ... 'c' type_id=8 bits_offset=128 [4] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED [8] TYPE_TAG '__c' type_id=4 This commit adds support for DW_TAG_LLVM_annotation "btf:type_tag" attached to the following entities: - base types; - arrays; - pointers; - structs - unions; - enums; - typedefs. To allow backwards compatibility and void additional invocation options, implementation acts in a following way: - both `btf_type_tag` and `btf:type_tag` could be present in the debug info; - if `btf:type_tag` are present in the debug info, `btf_type_tag` annotations are ignored. Modifications done by this commit: - DWARF load phase is updated: - `annots` fields are filled for the above mentioned types; - `cu` instance is updated to reflect which version of type tags is used in the debug info; - Recode phase is split in several sub-phases: - `cu__allocate_btf_type_tags()` `llvm_annotation` instances corresponding to preferred version of type tags are added to types table; - `tag__recode_dwarf_type()` (the original phase logic); - `update_btf_type_tag_refs()` Updates `->type` field of each tag if that type refers to a type with `btf:type_tag` annotation. The id of the type is replaced by id of the type tag. See also: [1] Mailing list discussion regarding `btf:type_tag` Various approaches are discussed, Solution acmel#2 is accepted https://lore.kernel.org/bpf/87r0w9jjoq.fsf@oracle.com/ Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
eddyz87
added a commit
to eddyz87/dwarves
that referenced
this pull request
May 15, 2023
In recent discussion in BPF mailing list ([1]) participants agreed to add a new DWARF representation for "btf_type_tag" annotations. The agreed representation of void pointers uses unspecified types. For example, consider the following C code: struct alpha { void __attribute__((btf_type_tag("__alpha_a"))) *a; } g; And corresponding DWARF: 0x29: DW_TAG_structure_type DW_AT_name ("alpha") 0x2e: DW_TAG_member DW_AT_name ("a") DW_AT_type (0x38 "void *") 0x38: DW_TAG_pointer_type DW_AT_type (0x41 "void") 0x41: DW_TAG_unspecified_type DW_AT_name ("void") 0x43: DW_TAG_LLVM_annotation DW_AT_name ("btf:type_tag") DW_AT_const_value ("__alpha_a") This is a preparatory patch for new type tags representation support, specifically it adds `struct unspecified_type` and a new `cu` field `struct cu::unspecified_types`. These would be used in a subsequent patch to recode type tags attached to DW_TAG_unspecified_type as in the example above. [1] Mailing list discussion regarding `btf:type_tag` Various approaches are discussed, Solution acmel#2 is accepted https://lore.kernel.org/bpf/87r0w9jjoq.fsf@oracle.com/ Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
eddyz87
added a commit
to eddyz87/dwarves
that referenced
this pull request
May 15, 2023
Currently BTF type tags could only be associated with "pointee" types. (Types pointed to by some pointer). This is an artifact of type tags encoding in DWARF. For example, for the following C code: int __attribute__((type_tag("tag"))) *p; Clang produces the following DWARF: 0x51: DW_TAG_pointer_type DW_AT_type (0x4d "int") 0x56: DW_TAG_LLVM_annotation DW_AT_name ("btf_type_tag") DW_AT_const_value ("tag") The assumption is that such DW_TAG_LLVM_annotation entries are only attached to DW_TAG_pointer_type entries and apply to the pointee type (0x4d "int" in this case). This is handled by dwarf_loader using a special pointer sub-type: `struct btf_type_tag_ptr_type`, which adds a list of type tags to a regular pointer and has additional processing on the recode phase. However, recent discussion [1] agreed to introduce a new kind of type tags encoding in DWARF, allowing to associate such tags with any types, not only pointee types. As a preparation step to handle such encoding this commit removes `struct btf_type_tag_ptr_type`, instead information about a set of type tags associated with a pointer is stored in a new `struct dwarf_cu` field: struct dwarf_cu { ... struct type_tags_table type_tags; ... } Creation of `struct btf_type_tag_ptr_type` is delayed until all CU members are scanned. To avoid second scan the `type_tags` field is used to accumulate information necessary for type tag creation. For each DIE with type tag children this information includes: - struct tag corresponding to this DIE - list of type tag values attached to DIE Which means that each record varies in size. To accommodate this treat `struct dwarf_cu::type_tags` as a stream of records with the following format: ... parent-pointer tag-value* NULL ... ^ ^ ^ | | '----- terminator struct tag* char* This information is used on the recode phase to establish correct `struct tag::type` links. Delayed creation of type tag objects would be exploited in the follow-up patch. [1] Mailing list discussion regarding `btf:type_tag` Various approaches are discussed, Solution acmel#2 is accepted https://lore.kernel.org/bpf/87r0w9jjoq.fsf@oracle.com/ Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
eddyz87
added a commit
to eddyz87/dwarves
that referenced
this pull request
May 15, 2023
"btf:type_tag" is an DW_TAG_LLVM_annotation object that encodes btf_type_tag attributes in DWARF. Contrary to existing "btf_type_tag" it allows to associate such attributes with non-pointer types. When "btf:type_tag" is attached to a type it applies to this type. For example, the following C code: struct echo { int __attribute__((btf_type_tag("__c"))) c; } Produces the following DWARF: 0x29: DW_TAG_structure_type DW_AT_name ("echo") 0x40: DW_TAG_member DW_AT_name ("c") DW_AT_type (0x8c "int") 0x8c: DW_TAG_base_type DW_AT_name ("int") DW_AT_encoding (DW_ATE_signed) DW_AT_byte_size (0x04) 0x90: DW_TAG_LLVM_annotation DW_AT_name ("btf:type_tag") DW_AT_const_value ("__c") Meaning that type 0x8c is an `int` with type tag `__c`. Corresponding BTF looks as follows: [1] STRUCT 'echo' ... 'c' type_id=8 bits_offset=128 [4] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED [8] TYPE_TAG '__c' type_id=4 This commit adds support for DW_TAG_LLVM_annotation "btf:type_tag" attached to the following entities: - base types; - arrays; - pointers; - structs - unions; - enums; - typedefs. To allow backwards compatibility and void additional invocation options, implementation acts in a following way: - both `btf_type_tag` and `btf:type_tag` could be present in the debug info; - if `btf:type_tag` are present in the debug info, `btf_type_tag` annotations are ignored. Code changes could be summarized as follows: - add `enum type_tag_kind` with the following values: - TYPE_TAG_SELF for `btf:type_tag` - TYPE_TAG_POINTEE for `btf_type_tag`; - add field `struct dwarf_cu::effective_type_tag_kind` to decide which type tag kind should be used for CU; - change `dwarf_cu::type_tags` records format to convey tag kind; - add calls to add_btf_type_tag() / add_child_btf_type_tags() for die__create_new_*** functions corresponding to types listed above; - change dwarf_cu__recode_type_tags() to recode TYPE_TAG_SELF type tags *before* main recode phase, so `struct dwarf_cu::hash_types` changes would be visible during main phase. See also: [1] Mailing list discussion regarding `btf:type_tag` Various approaches are discussed, Solution acmel#2 is accepted https://lore.kernel.org/bpf/87r0w9jjoq.fsf@oracle.com/ Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
eddyz87
added a commit
to eddyz87/dwarves
that referenced
this pull request
May 23, 2023
In recent discussion in BPF mailing list ([1]) participants agreed to add a new DWARF representation for "btf_type_tag" annotations. The agreed representation of void pointers uses unspecified types. For example, consider the following C code: struct alpha { void __attribute__((btf_type_tag("__alpha_a"))) *a; } g; And corresponding DWARF: 0x29: DW_TAG_structure_type DW_AT_name ("alpha") 0x2e: DW_TAG_member DW_AT_name ("a") DW_AT_type (0x38 "void *") 0x38: DW_TAG_pointer_type DW_AT_type (0x41 "void") 0x41: DW_TAG_unspecified_type DW_AT_name ("void") 0x43: DW_TAG_LLVM_annotation DW_AT_name ("btf:type_tag") DW_AT_const_value ("__alpha_a") This is a preparatory patch for new type tags representation support, specifically it adds `struct unspecified_type` and a new `cu` field `struct cu::unspecified_types`. These would be used in a subsequent patch to recode type tags attached to DW_TAG_unspecified_type as in the example above. [1] Mailing list discussion regarding `btf:type_tag` Various approaches are discussed, Solution acmel#2 is accepted https://lore.kernel.org/bpf/87r0w9jjoq.fsf@oracle.com/ Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
eddyz87
added a commit
to eddyz87/dwarves
that referenced
this pull request
May 23, 2023
Currently BTF type tags could only be associated with "pointee" types. (Types pointed to by some pointer). This is an artifact of type tags encoding in DWARF. For example, for the following C code: int __attribute__((type_tag("tag"))) *p; Clang produces the following DWARF: 0x51: DW_TAG_pointer_type DW_AT_type (0x4d "int") 0x56: DW_TAG_LLVM_annotation DW_AT_name ("btf_type_tag") DW_AT_const_value ("tag") The assumption is that such DW_TAG_LLVM_annotation entries are only attached to DW_TAG_pointer_type entries and apply to the pointee type (0x4d "int" in this case). This is handled by dwarf_loader using a special pointer sub-type: `struct btf_type_tag_ptr_type`, which adds a list of type tags to a regular pointer and has additional processing on the recode phase. However, recent discussion [1] agreed to introduce a new kind of type tags encoding in DWARF, allowing to associate such tags with any types, not only pointee types. As a preparation step to handle such encoding this commit removes `struct btf_type_tag_ptr_type`, instead information about a set of type tags associated with a pointer is stored in a new `struct dwarf_cu` field: struct dwarf_cu { ... struct type_tags_table type_tags; ... } Creation of `struct btf_type_tag_ptr_type` is delayed until all CU members are scanned. To avoid second scan the `type_tags` field is used to accumulate information necessary for type tag creation. For each DIE with type tag children this information includes: - struct tag corresponding to this DIE - list of type tag values attached to DIE Which means that each record varies in size. To accommodate this treat `struct dwarf_cu::type_tags` as a stream of records with the following format: ... parent-pointer tag-value* NULL ... ^ ^ ^ | | '----- terminator struct tag* char* This information is used on the recode phase to establish correct `struct tag::type` links. Delayed creation of type tag objects would be exploited in the follow-up patch. [1] Mailing list discussion regarding `btf:type_tag` Various approaches are discussed, Solution acmel#2 is accepted https://lore.kernel.org/bpf/87r0w9jjoq.fsf@oracle.com/ Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
eddyz87
added a commit
to eddyz87/dwarves
that referenced
this pull request
May 23, 2023
"btf:type_tag" is an DW_TAG_LLVM_annotation object that encodes btf_type_tag attributes in DWARF. Contrary to existing "btf_type_tag" it allows to associate such attributes with non-pointer types. When "btf:type_tag" is attached to a type it applies to this type. For example, the following C code: struct echo { int __attribute__((btf_type_tag("__c"))) c; } Produces the following DWARF: 0x29: DW_TAG_structure_type DW_AT_name ("echo") 0x40: DW_TAG_member DW_AT_name ("c") DW_AT_type (0x8c "int") 0x8c: DW_TAG_base_type DW_AT_name ("int") DW_AT_encoding (DW_ATE_signed) DW_AT_byte_size (0x04) 0x90: DW_TAG_LLVM_annotation DW_AT_name ("btf:type_tag") DW_AT_const_value ("__c") Meaning that type 0x8c is an `int` with type tag `__c`. Corresponding BTF looks as follows: [1] STRUCT 'echo' ... 'c' type_id=8 bits_offset=128 [4] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED [8] TYPE_TAG '__c' type_id=4 This commit adds support for DW_TAG_LLVM_annotation "btf:type_tag" attached to the following entities: - base types; - arrays; - pointers; - structs - unions; - enums; - typedefs. To allow backwards compatibility and void additional invocation options, implementation acts in a following way: - both `btf_type_tag` and `btf:type_tag` could be present in the debug info; - if `btf:type_tag` are present in the debug info, `btf_type_tag` annotations are ignored. Code changes could be summarized as follows: - add `enum type_tag_kind` with the following values: - TYPE_TAG_SELF for `btf:type_tag` - TYPE_TAG_POINTEE for `btf_type_tag`; - add field `struct dwarf_cu::effective_type_tag_kind` to decide which type tag kind should be used for CU; - change `dwarf_cu::type_tags` records format to convey tag kind; - add calls to add_btf_type_tag() / add_child_btf_type_tags() for die__create_new_*** functions corresponding to types listed above; - change dwarf_cu__recode_type_tags() to recode TYPE_TAG_SELF type tags *before* main recode phase, so `struct dwarf_cu::hash_types` changes would be visible during main phase. See also: [1] Mailing list discussion regarding `btf:type_tag` Various approaches are discussed, Solution acmel#2 is accepted https://lore.kernel.org/bpf/87r0w9jjoq.fsf@oracle.com/ Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
eddyz87
added a commit
to eddyz87/dwarves
that referenced
this pull request
May 23, 2023
In recent discussion in BPF mailing list ([1]) participants agreed to add a new DWARF representation for "btf_type_tag" annotations. The agreed representation of void pointers uses unspecified types. For example, consider the following C code: struct alpha { void __attribute__((btf_type_tag("__alpha_a"))) *a; } g; And corresponding DWARF: 0x29: DW_TAG_structure_type DW_AT_name ("alpha") 0x2e: DW_TAG_member DW_AT_name ("a") DW_AT_type (0x38 "void *") 0x38: DW_TAG_pointer_type DW_AT_type (0x41 "void") 0x41: DW_TAG_unspecified_type DW_AT_name ("void") 0x43: DW_TAG_LLVM_annotation DW_AT_name ("btf:type_tag") DW_AT_const_value ("__alpha_a") This is a preparatory patch for new type tags representation support, specifically it adds `struct unspecified_type` and a new `cu` field `struct cu::unspecified_types`. These would be used in a subsequent patch to recode type tags attached to DW_TAG_unspecified_type as in the example above. [1] Mailing list discussion regarding `btf:type_tag` Various approaches are discussed, Solution acmel#2 is accepted https://lore.kernel.org/bpf/87r0w9jjoq.fsf@oracle.com/ Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
eddyz87
added a commit
to eddyz87/dwarves
that referenced
this pull request
May 23, 2023
Currently BTF type tags could only be associated with "pointee" types. (Types pointed to by some pointer). This is an artifact of type tags encoding in DWARF. For example, for the following C code: int __attribute__((type_tag("tag"))) *p; Clang produces the following DWARF: 0x51: DW_TAG_pointer_type DW_AT_type (0x4d "int") 0x56: DW_TAG_LLVM_annotation DW_AT_name ("btf_type_tag") DW_AT_const_value ("tag") The assumption is that such DW_TAG_LLVM_annotation entries are only attached to DW_TAG_pointer_type entries and apply to the pointee type (0x4d "int" in this case). This is handled by dwarf_loader using a special pointer sub-type: `struct btf_type_tag_ptr_type`, which adds a list of type tags to a regular pointer and has additional processing on the recode phase. However, recent discussion [1] agreed to introduce a new kind of type tags encoding in DWARF, allowing to associate such tags with any types, not only pointee types. As a preparation step to handle such encoding this commit removes `struct btf_type_tag_ptr_type`, instead information about a set of type tags associated with a pointer is stored in a new `struct dwarf_cu` field: struct dwarf_cu { ... struct type_tags_table type_tags; ... } Creation of `struct btf_type_tag_ptr_type` is delayed until all CU members are scanned. To avoid second scan the `type_tags` field is used to accumulate information necessary for type tag creation. For each DIE with type tag children this information includes: - struct tag corresponding to this DIE - list of type tag values attached to DIE Which means that each record varies in size. To accommodate this treat `struct dwarf_cu::type_tags` as a stream of records with the following format: ... parent-pointer tag-value* NULL ... ^ ^ ^ | | '----- terminator struct tag* char* This information is used on the recode phase to establish correct `struct tag::type` links. Delayed creation of type tag objects would be exploited in the follow-up patch. [1] Mailing list discussion regarding `btf:type_tag` Various approaches are discussed, Solution acmel#2 is accepted https://lore.kernel.org/bpf/87r0w9jjoq.fsf@oracle.com/ Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
eddyz87
added a commit
to eddyz87/dwarves
that referenced
this pull request
May 23, 2023
"btf:type_tag" is an DW_TAG_LLVM_annotation object that encodes btf_type_tag attributes in DWARF. Contrary to existing "btf_type_tag" it allows to associate such attributes with non-pointer types. When "btf:type_tag" is attached to a type it applies to this type. For example, the following C code: struct echo { int __attribute__((btf_type_tag("__c"))) c; } Produces the following DWARF: 0x29: DW_TAG_structure_type DW_AT_name ("echo") 0x40: DW_TAG_member DW_AT_name ("c") DW_AT_type (0x8c "int") 0x8c: DW_TAG_base_type DW_AT_name ("int") DW_AT_encoding (DW_ATE_signed) DW_AT_byte_size (0x04) 0x90: DW_TAG_LLVM_annotation DW_AT_name ("btf:type_tag") DW_AT_const_value ("__c") Meaning that type 0x8c is an `int` with type tag `__c`. Corresponding BTF looks as follows: [1] STRUCT 'echo' ... 'c' type_id=8 bits_offset=128 [4] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED [8] TYPE_TAG '__c' type_id=4 This commit adds support for DW_TAG_LLVM_annotation "btf:type_tag" attached to the following entities: - base types; - arrays; - pointers; - structs - unions; - enums; - typedefs. To allow backwards compatibility and void additional invocation options, implementation acts in a following way: - both `btf_type_tag` and `btf:type_tag` could be present in the debug info; - if `btf:type_tag` are present in the debug info, `btf_type_tag` annotations are ignored. Code changes could be summarized as follows: - add `enum type_tag_kind` with the following values: - TYPE_TAG_SELF for `btf:type_tag` - TYPE_TAG_POINTEE for `btf_type_tag`; - add field `struct dwarf_cu::effective_type_tag_kind` to decide which type tag kind should be used for CU; - change `dwarf_cu::type_tags` records format to convey tag kind; - add calls to add_btf_type_tag() / add_child_btf_type_tags() for die__create_new_*** functions corresponding to types listed above; - change dwarf_cu__recode_type_tags() to recode TYPE_TAG_SELF type tags *before* main recode phase, so `struct dwarf_cu::hash_types` changes would be visible during main phase. See also: [1] Mailing list discussion regarding `btf:type_tag` Various approaches are discussed, Solution acmel#2 is accepted https://lore.kernel.org/bpf/87r0w9jjoq.fsf@oracle.com/ Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
eddyz87
added a commit
to eddyz87/dwarves
that referenced
this pull request
May 23, 2023
"btf:type_tag" is an DW_TAG_LLVM_annotation object that encodes btf_type_tag attributes in DWARF. Contrary to existing "btf_type_tag" it allows to associate such attributes with non-pointer types. When "btf:type_tag" is attached to a type it applies to this type. For example, the following C code: struct echo { int __attribute__((btf_type_tag("__c"))) c; } Produces the following DWARF: 0x29: DW_TAG_structure_type DW_AT_name ("echo") 0x40: DW_TAG_member DW_AT_name ("c") DW_AT_type (0x8c "int") 0x8c: DW_TAG_base_type DW_AT_name ("int") DW_AT_encoding (DW_ATE_signed) DW_AT_byte_size (0x04) 0x90: DW_TAG_LLVM_annotation DW_AT_name ("btf:type_tag") DW_AT_const_value ("__c") Meaning that type 0x8c is an `int` with type tag `__c`. Corresponding BTF looks as follows: [1] STRUCT 'echo' ... 'c' type_id=8 bits_offset=128 [4] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED [8] TYPE_TAG '__c' type_id=4 This commit adds support for DW_TAG_LLVM_annotation "btf:type_tag" attached to the following entities: - base types; - arrays; - pointers; - structs - unions; - enums; - typedefs. To allow backwards compatibility and avoid additional invocation options, implementation acts in a following way: - both `btf_type_tag` and `btf:type_tag` could be present in the debug info; - if `btf:type_tag` annotations are present in the debug info, `btf_type_tag` annotations are ignored. Code changes could be summarized as follows: - add `enum type_tag_kind` with the following values: - TYPE_TAG_SELF for `btf:type_tag` - TYPE_TAG_POINTEE for `btf_type_tag`; - add field `struct dwarf_cu::effective_type_tag_kind` to decide which type tag kind should be used for CU; - change `dwarf_cu::type_tags` records format to convey tag kind; - add calls to add_btf_type_tag() / add_child_btf_type_tags() for die__create_new_*** functions corresponding to types listed above; - change dwarf_cu__recode_type_tags() to recode TYPE_TAG_SELF type tags *before* main recode phase, so `struct dwarf_cu::hash_types` changes would be visible during main phase. See also: [1] Mailing list discussion regarding `btf:type_tag` Various approaches are discussed, Solution acmel#2 is accepted https://lore.kernel.org/bpf/87r0w9jjoq.fsf@oracle.com/ Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
eddyz87
added a commit
to eddyz87/dwarves
that referenced
this pull request
Nov 16, 2023
In recent discussion in BPF mailing list ([1]) participants agreed to add a new DWARF representation for "btf_type_tag" annotations. The agreed representation of void pointers uses unspecified types. For example, consider the following C code: struct alpha { void __attribute__((btf_type_tag("__alpha_a"))) *a; } g; And corresponding DWARF: 0x29: DW_TAG_structure_type DW_AT_name ("alpha") 0x2e: DW_TAG_member DW_AT_name ("a") DW_AT_type (0x38 "void *") 0x38: DW_TAG_pointer_type DW_AT_type (0x41 "void") 0x41: DW_TAG_unspecified_type DW_AT_name ("void") 0x43: DW_TAG_LLVM_annotation DW_AT_name ("btf:type_tag") DW_AT_const_value ("__alpha_a") This is a preparatory patch for new type tags representation support, specifically it adds `struct unspecified_type` and a new `cu` field `struct cu::unspecified_types`. These would be used in a subsequent patch to recode type tags attached to DW_TAG_unspecified_type as in the example above. [1] Mailing list discussion regarding `btf:type_tag` Various approaches are discussed, Solution acmel#2 is accepted https://lore.kernel.org/bpf/87r0w9jjoq.fsf@oracle.com/ Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
eddyz87
added a commit
to eddyz87/dwarves
that referenced
this pull request
Nov 16, 2023
Currently BTF type tags could only be associated with "pointee" types. (Types pointed to by some pointer). This is an artifact of type tags encoding in DWARF. For example, for the following C code: int __attribute__((type_tag("tag"))) *p; Clang produces the following DWARF: 0x51: DW_TAG_pointer_type DW_AT_type (0x4d "int") 0x56: DW_TAG_LLVM_annotation DW_AT_name ("btf_type_tag") DW_AT_const_value ("tag") The assumption is that such DW_TAG_LLVM_annotation entries are only attached to DW_TAG_pointer_type entries and apply to the pointee type (0x4d "int" in this case). This is handled by dwarf_loader using a special pointer sub-type: `struct btf_type_tag_ptr_type`, which adds a list of type tags to a regular pointer and has additional processing on the recode phase. However, recent discussion [1] agreed to introduce a new kind of type tags encoding in DWARF, allowing to associate such tags with any types, not only pointee types. As a preparation step to handle such encoding this commit removes `struct btf_type_tag_ptr_type`, instead information about a set of type tags associated with a pointer is stored in a new `struct dwarf_cu` field: struct dwarf_cu { ... struct type_tags_table type_tags; ... } Creation of `struct btf_type_tag_ptr_type` is delayed until all CU members are scanned. To avoid second scan the `type_tags` field is used to accumulate information necessary for type tag creation. For each DIE with type tag children this information includes: - struct tag corresponding to this DIE - list of type tag values attached to DIE Which means that each record varies in size. To accommodate this treat `struct dwarf_cu::type_tags` as a stream of records with the following format: ... parent-pointer tag-value* NULL ... ^ ^ ^ | | '----- terminator struct tag* char* This information is used on the recode phase to establish correct `struct tag::type` links. Delayed creation of type tag objects would be exploited in the follow-up patch. [1] Mailing list discussion regarding `btf:type_tag` Various approaches are discussed, Solution acmel#2 is accepted https://lore.kernel.org/bpf/87r0w9jjoq.fsf@oracle.com/ Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
eddyz87
added a commit
to eddyz87/dwarves
that referenced
this pull request
Nov 16, 2023
"btf:type_tag" is an DW_TAG_LLVM_annotation object that encodes btf_type_tag attributes in DWARF. Contrary to existing "btf_type_tag" it allows to associate such attributes with non-pointer types. When "btf:type_tag" is attached to a type it applies to this type. For example, the following C code: struct echo { int __attribute__((btf_type_tag("__c"))) c; } Produces the following DWARF: 0x29: DW_TAG_structure_type DW_AT_name ("echo") 0x40: DW_TAG_member DW_AT_name ("c") DW_AT_type (0x8c "int") 0x8c: DW_TAG_base_type DW_AT_name ("int") DW_AT_encoding (DW_ATE_signed) DW_AT_byte_size (0x04) 0x90: DW_TAG_LLVM_annotation DW_AT_name ("btf:type_tag") DW_AT_const_value ("__c") Meaning that type 0x8c is an `int` with type tag `__c`. Corresponding BTF looks as follows: [1] STRUCT 'echo' ... 'c' type_id=8 bits_offset=128 [4] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED [8] TYPE_TAG '__c' type_id=4 This commit adds support for DW_TAG_LLVM_annotation "btf:type_tag" attached to the following entities: - base types; - arrays; - pointers; - structs - unions; - enums; - typedefs. To allow backwards compatibility and avoid additional invocation options, implementation acts in a following way: - both `btf_type_tag` and `btf:type_tag` could be present in the debug info; - if `btf:type_tag` annotations are present in the debug info, `btf_type_tag` annotations are ignored. Code changes could be summarized as follows: - add `enum type_tag_kind` with the following values: - TYPE_TAG_SELF for `btf:type_tag` - TYPE_TAG_POINTEE for `btf_type_tag`; - add field `struct dwarf_cu::effective_type_tag_kind` to decide which type tag kind should be used for CU; - change `dwarf_cu::type_tags` records format to convey tag kind; - add calls to add_btf_type_tag() / add_child_btf_type_tags() for die__create_new_*** functions corresponding to types listed above; - change dwarf_cu__recode_type_tags() to recode TYPE_TAG_SELF type tags *before* main recode phase, so `struct dwarf_cu::hash_types` changes would be visible during main phase. See also: [1] Mailing list discussion regarding `btf:type_tag` Various approaches are discussed, Solution acmel#2 is accepted https://lore.kernel.org/bpf/87r0w9jjoq.fsf@oracle.com/ Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
acmel
added a commit
that referenced
this pull request
Feb 27, 2024
Since ff7bd70 ("core: Allow sizing the loader hash table") dwarf__load_files(), called by cus__load_files() needs a non-NULL conf_load argument, add one to avoid: Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7f4b1ed in dwarf__load_file (cus=0x4052a0, conf=0x0, filename=0x7fffffffe4c3 "bla") at /home/acme/git/pahole/dwarf_loader.c:3626 3626 if (conf->max_hashtable_bits != 0) { (gdb) bt #0 0x00007ffff7f4b1ed in dwarf__load_file (cus=0x4052a0, conf=0x0, filename=0x7fffffffe4c3 "bla") at /home/acme/git/pahole/dwarf_loader.c:3626 #1 0x00007ffff7f310f5 in cus__load_file (cus=0x4052a0, conf=0x0, filename=0x7fffffffe4c3 "bla") at /home/acme/git/pahole/dwarves.c:2074 #2 0x00007ffff7f31ca1 in cus__load_files (cus=0x4052a0, conf=0x0, filenames=0x7fffffffe1c0) at /home/acme/git/pahole/dwarves.c:2577 #3 0x000000000040177a in main (argc=2, argv=0x7fffffffe1b8) at /home/acme/git/pahole/syscse.c:159 (gdb) Fixes: ff7bd70 ("core: Allow sizing the loader hash table") Reported-by: J B <jb.1234abcd@gmail.com> Link: https://lore.kernel.org/dwarves/CAJXMFhFbv5MccigKvmQt9MhYwKv2iyigEG3Bhs64BZ=PMWc0WQ@mail.gmail.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
acmel
added a commit
that referenced
this pull request
Jun 18, 2024
In cu__new() zalloc() is used defensively, and that helped catch this problem where we assume that a cu us in the cus list of cu instances, but that is not the case when we use cus__merge_and_process_cu(), for instance when loading files created by clang with LTO, as reported by Peter Jung and narrowed down by Nathan Chancellor. If we use INIT_LIST_HEAD() in cu__new() to initialize cu->node, which is what we do with other lists and nodes there, then the unconditional removal using list_del_init() will be a no-op and removing something not on the cus list of cu instances will not cause problems, just keep an unconsistent cus->nr_entries field. So lets just have this fix in first, keeping Nathan's Tested-by and then do the a bit more involved fix of either adding that cu to the cus list or checking at removal time if it is there. Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7f1e13e in __list_del (prev=0x0, next=0x0) at /home/acme/git/pahole/list.h:106 106 next->prev = prev; (gdb) bt #0 0x00007ffff7f1e13e in __list_del (prev=0x0, next=0x0) at /home/acme/git/pahole/list.h:106 #1 0x00007ffff7f1e176 in list_del_init (entry=0x417980) at /home/acme/git/pahole/list.h:165 #2 0x00007ffff7f1f8f9 in __cus__remove (cus=0x4142a0, cu=0x417980) at /home/acme/git/pahole/dwarves.c:527 #3 0x00007ffff7f1f92b in cus__remove (cus=0x4142a0, cu=0x417980) at /home/acme/git/pahole/dwarves.c:533 #4 0x00007ffff7f3d01c in cus__finalize (cus=0x4142a0, cu=0x417980, conf=0x4133c0 <conf_load>, thr_data=0x0) at /home/acme/git/pahole/dwarf_loader.c:3040 #5 0x00007ffff7f3e05c in cus__merge_and_process_cu (cus=0x4142a0, conf=0x4133c0 <conf_load>, mod=0x415cf0, dw=0x416110, elf=0x414380, filename=0x7fffffffe3f7 "cast_common.ko", build_id=0x416680 "\265D\371U\213\373u|\037\250\242\032\271\365⒜]y\023", build_id_len=20, type_dcu=0x0) at /home/acme/git/pahole/dwarf_loader.c:3482 #6 0x00007ffff7f3e218 in cus__load_module (cus=0x4142a0, conf=0x4133c0 <conf_load>, mod=0x415cf0, dw=0x416110, elf=0x414380, filename=0x7fffffffe3f7 "cast_common.ko") at /home/acme/git/pahole/dwarf_loader.c:3521 #7 0x00007ffff7f3e396 in cus__process_dwflmod (dwflmod=0x415cf0, userdata=0x415d00, name=0x415ea0 "cast_common.ko", base=65536, arg=0x7fffffffde40) at /home/acme/git/pahole/dwarf_loader.c:3581 #8 0x00007ffff7eb4609 in dwfl_getmodules (dwfl=0x414300, callback=0x7ffff7f3e2ec <cus__process_dwflmod>, arg=0x7fffffffde40, offset=0) at ../libdwfl/dwfl_getmodules.c:86 #9 0x00007ffff7f3e4c5 in cus__process_file (cus=0x4142a0, conf=0x4133c0 <conf_load>, fd=3, filename=0x7fffffffe3f7 "cast_common.ko") at /home/acme/git/pahole/dwarf_loader.c:3647 #10 0x00007ffff7f3e5cd in dwarf__load_file (cus=0x4142a0, conf=0x4133c0 <conf_load>, filename=0x7fffffffe3f7 "cast_common.ko") at /home/acme/git/pahole/dwarf_loader.c:3684 #11 0x00007ffff7f232df in cus__load_file (cus=0x4142a0, conf=0x4133c0 <conf_load>, filename=0x7fffffffe3f7 "cast_common.ko") at /home/acme/git/pahole/dwarves.c:2134 #12 0x00007ffff7f23e8b in cus__load_files (cus=0x4142a0, conf=0x4133c0 <conf_load>, filenames=0x7fffffffe0f0) at /home/acme/git/pahole/dwarves.c:2637 #13 0x000000000040aec0 in main (argc=2, argv=0x7fffffffe0e8) at /home/acme/git/pahole/pahole.c:3805 (gdb) fr 1 #1 0x00007ffff7f1e176 in list_del_init (entry=0x417980) at /home/acme/git/pahole/list.h:165 165 __list_del(entry->prev, entry->next); (gdb) p entry $1 = (struct list_head *) 0x417980 (gdb) p entry->next $2 = (struct list_head *) 0x0 (gdb) p entry->prev $3 = (struct list_head *) 0x0 Closes: #53 Closes: https://gitlab.archlinux.org/archlinux/packaging/packages/pahole/-/issues/1 Tested-by: Nathan Chancellor <nathan@kernel.org> Link: https://lore.kernel.org/all/20240617210810.GA1877676@thelio-3990X Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Before this patch, running pahole on an executable compiled
with -gdwarf-4 gave:
DW_AT_<0x3c>=0x19
0x19 is DW_FORM_flag_present.
Also, DW_FORM_flag takes an argument.
Changing attr_numeric to call dwarf_formflag fixes both problems.