diff options
| author | Mark Wielaard <[email protected]> | 2018-05-20 23:30:01 +0200 |
|---|---|---|
| committer | Mark Wielaard <[email protected]> | 2018-05-25 15:07:58 +0200 |
| commit | 6e3d2521a2b5a3b436901f52cfb9785887a7c961 (patch) | |
| tree | 649d9c157ac680e9f99b61df772e429883602bf5 /tests | |
| parent | 184fd30d1a453dc165ffc187b22dec6d196522ad (diff) | |
libdw: Support DW_OP_addrx/constx and split DWARF addrx/constx support.
DW_OP_addrx/constx and GNU DebugFission DW_OP_GNU_addr/const_index take
as argument an index into the .debug_addr section for the associated CU.
This index gets resolved through dwarf_getlocation_attr. A new fake addr
CU is created per Dwarf for use with this new attribute. For split DWARF
files, the IDX_debug_addr gets replaced with the skeleton section and the
addr base is resolved immediately when constructing the split DWARF CU.
Move __libdw_cu_addr_base to libdwP.h to share with eu-readelf. Also
make it possible to resolve addrx[1234]/GNU_addr_index also as constant
indexes to (also) show when displaying these attributes in eu-readelf.
A new varlocs tests is added to test the resolving for both the DWARF4
and DWARF5 DW_OP variants. And now that addrx forms are resolved in
split DWARF files add the new DIEs with "single ranges" (those DIEs that
have a lowpc/highpc attribute pair) to run-all-dwarf-ranges.sh.
Signed-off-by: Mark Wielaard <[email protected]>
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/ChangeLog | 14 | ||||
| -rw-r--r-- | tests/Makefile.am | 2 | ||||
| -rw-r--r-- | tests/addrx_constx-4.dwo.bz2 | bin | 0 -> 809 bytes | |||
| -rw-r--r-- | tests/addrx_constx-5.dwo.bz2 | bin | 0 -> 824 bytes | |||
| -rwxr-xr-x | tests/run-all-dwarf-ranges.sh | 24 | ||||
| -rwxr-xr-x | tests/run-varlocs.sh | 208 | ||||
| -rwxr-xr-x | tests/testfile-addrx_constx-4.bz2 | bin | 0 -> 2851 bytes | |||
| -rwxr-xr-x | tests/testfile-addrx_constx-5.bz2 | bin | 0 -> 2847 bytes | |||
| -rw-r--r-- | tests/varlocs.c | 65 |
9 files changed, 299 insertions, 14 deletions
diff --git a/tests/ChangeLog b/tests/ChangeLog index a93b0e98..2f92cc2f 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,17 @@ +2018-05-21 Mark Wielaard <[email protected]> + + * addrx_constx-4.dwo.bz2: New testfile. + * addrx_constx-5.dwo.bz2: Likewise. + * testfile-addrx_constx-4.bz2: Likewise. + * testfile-addrx_constx-5.bz2: Likewise + * Makefile.am (EXTRA_DIST): Add addrx_constx-5.dwo.bz2 + testfile-addrx_constx-4\ .bz2 testfile-addrx_constx-5.bz2. + * run-varlocs.sh: Add addrx_constx tests for DWARF4 and DWARF5. + * varlocx.c (print_expr): Handle DW_OP_GNU_addr_index, + DW_OP_addrx, DW_OP_GNU_const_index and DW_OP_constx. + (main): Handle split DWARF. + * run-all-dwarf-ranges.sh: Add new ranges for addrx low/highpc. + 2018-05-20 Mark Wielaard <[email protected]> * unit-info.c: New test. diff --git a/tests/Makefile.am b/tests/Makefile.am index 9beae140..4b13be27 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -305,6 +305,8 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \ testfile_entry_value.c testfile_entry_value.bz2 \ testfile_implicit_value.c testfile_implicit_value.bz2 \ testfile_aarch64_core.bz2 testfile_i686_core.bz2 \ + addrx_constx-4.dwo.bz2 addrx_constx-5.dwo.bz2 \ + testfile-addrx_constx-4.bz2 testfile-addrx_constx-5.bz2 \ run-funcretval.sh funcretval_test.c funcretval_test_aarch64.bz2 \ run-backtrace-data.sh run-backtrace-dwarf.sh cleanup-13.c \ run-backtrace-native.sh run-backtrace-native-biarch.sh \ diff --git a/tests/addrx_constx-4.dwo.bz2 b/tests/addrx_constx-4.dwo.bz2 Binary files differnew file mode 100644 index 00000000..f0bae1cd --- /dev/null +++ b/tests/addrx_constx-4.dwo.bz2 diff --git a/tests/addrx_constx-5.dwo.bz2 b/tests/addrx_constx-5.dwo.bz2 Binary files differnew file mode 100644 index 00000000..a5f4b1a6 --- /dev/null +++ b/tests/addrx_constx-5.dwo.bz2 diff --git a/tests/run-all-dwarf-ranges.sh b/tests/run-all-dwarf-ranges.sh index ba5528d2..ad5e634f 100755 --- a/tests/run-all-dwarf-ranges.sh +++ b/tests/run-all-dwarf-ranges.sh @@ -33,9 +33,30 @@ die: hello.c (11) 4004e0..4004ff 4003e0..4003f7 +die: no_say (2e) + 4004f0..4004ff + +die: main (2e) + 4003e0..4003f7 + +die: subject (1d) + 4003e3..4003ef + +die: subject (2e) + 4004e0..4004f0 + die: world.c (11) 400500..400567 +die: no_main (2e) + 400550..400567 + +die: no_subject (1d) + 400553..40055f + +die: say (2e) + 400500..400540 + die: happy (1d) 40051c..400526 400530..400534 @@ -45,6 +66,9 @@ die: sad (1d) 40051c..400526 400535..40053f +die: no_subject (2e) + 400540..400550 + EOF exit 0 diff --git a/tests/run-varlocs.sh b/tests/run-varlocs.sh index 9c4b313e..2781fef4 100755 --- a/tests/run-varlocs.sh +++ b/tests/run-varlocs.sh @@ -125,4 +125,212 @@ module 'testfile_implicit_pointer' EOF +# DW_OP_addrx and DW_OP_constx testcases. +# +# int i, j, k; +# __thread int l, m, n; +# +# int main () +# { +# int r1 = i + j + k; +# int r2 = l + m + n; +# int res = r1 + r2; +# +# return res; +# } +# +# gcc -O2 -gdwarf-5 -gsplit-dwarf -o addrx_constx-5.o -c addrx_constx.c +# gcc -O2 -gdwarf-5 -gsplit-dwarf -o testfile-addrx_constx-5 addrx_constx-5.o +# gcc -O2 -gdwarf-4 -gsplit-dwarf -o addrx_constx-4.o -c addrx_constx.c +# gcc -O2 -gdwarf-4 -gsplit-dwarf -o testfile-addrx_constx-4 addrx_constx-4.o + +testfiles testfile-addrx_constx-5 addrx_constx-5.dwo +testrun_compare ${abs_top_builddir}/tests/varlocs --exprlocs -e testfile-addrx_constx-5 <<\EOF +module 'testfile-addrx_constx-5' +[14] CU 'addrx_constx.c' + producer (strx) + language (data1) + name (strx) + comp_dir (strx) + [19] variable "i" + name (string) + decl_file (implicit_const) + decl_line (data1) + decl_column (data1) + type (ref4) + external (flag_present) + location (exprloc) {addr: 0x404038} + [25] base_type "int" + byte_size (data1) + encoding (data1) + name (string) + [2c] variable "j" + name (string) + decl_file (implicit_const) + decl_line (data1) + decl_column (data1) + type (ref4) + external (flag_present) + location (exprloc) {addr: 0x404034} + [38] variable "k" + name (string) + decl_file (implicit_const) + decl_line (data1) + decl_column (data1) + type (ref4) + external (flag_present) + location (exprloc) {addr: 0x40403c} + [44] variable "l" + name (string) + decl_file (implicit_const) + decl_line (data1) + decl_column (data1) + type (ref4) + external (flag_present) + location (exprloc) {const: 0x403e10, form_tls_address} + [51] variable "m" + name (string) + decl_file (implicit_const) + decl_line (data1) + decl_column (data1) + type (ref4) + external (flag_present) + location (exprloc) {const: 0x403e0c, form_tls_address} + [5e] variable "n" + name (string) + decl_file (implicit_const) + decl_line (data1) + decl_column (data1) + type (ref4) + external (flag_present) + location (exprloc) {const: 0x403e08, form_tls_address} + [6b] subprogram "main" + external (flag_present) + name (strx) + decl_file (data1) + decl_line (data1) + decl_column (data1) + type (ref4) + low_pc (addrx) + high_pc (data8) + frame_base (exprloc) {call_frame_cfa {bregx(7,8)}} + call_all_calls (flag_present) + [7f] variable "r1" + name (string) + decl_file (implicit_const) + decl_line (data1) + decl_column (implicit_const) + type (ref4) + location (exprloc) {addr: 0x404038, deref_size(4), addr: 0x404034, deref_size(4), plus, addr: 0x40403c, deref_size(4), plus, stack_value} + [98] variable "r2" + name (string) + decl_file (implicit_const) + decl_line (data1) + decl_column (implicit_const) + type (ref4) + location (exprloc) {form_tls_address, const: 0x403e10, deref_size(4), form_tls_address, const: 0x403e0c, deref_size(4), plus, form_tls_address, const: 0x403e08, deref_size(4), plus, stack_value} + [b4] variable "res" + name (string) + decl_file (implicit_const) + decl_line (data1) + decl_column (implicit_const) + type (ref4) + location (exprloc) {addr: 0x404038, deref_size(4), form_tls_address, const: 0x403e08, deref_size(4), plus, form_tls_address, const: 0x403e0c, deref_size(4), plus, form_tls_address, const: 0x403e10, deref_size(4), plus, addr: 0x404034, deref_size(4), plus, addr: 0x40403c, deref_size(4), plus, stack_value} +EOF + +testfiles testfile-addrx_constx-4 addrx_constx-4.dwo +testrun_compare ${abs_top_builddir}/tests/varlocs --exprlocs -e testfile-addrx_constx-4 <<\EOF +module 'testfile-addrx_constx-4' +[b] CU 'addrx_constx.c' + producer (GNU_str_index) + language (data1) + name (GNU_str_index) + comp_dir (GNU_str_index) + GNU_dwo_id (data8) + [18] variable "i" + name (string) + decl_file (data1) + decl_line (data1) + decl_column (data1) + type (ref4) + external (flag_present) + location (exprloc) {addr: 0x404038} + [25] base_type "int" + byte_size (data1) + encoding (data1) + name (string) + [2c] variable "j" + name (string) + decl_file (data1) + decl_line (data1) + decl_column (data1) + type (ref4) + external (flag_present) + location (exprloc) {addr: 0x404034} + [39] variable "k" + name (string) + decl_file (data1) + decl_line (data1) + decl_column (data1) + type (ref4) + external (flag_present) + location (exprloc) {addr: 0x40403c} + [46] variable "l" + name (string) + decl_file (data1) + decl_line (data1) + decl_column (data1) + type (ref4) + external (flag_present) + location (exprloc) {const: 0x403e10, GNU_push_tls_address} + [54] variable "m" + name (string) + decl_file (data1) + decl_line (data1) + decl_column (data1) + type (ref4) + external (flag_present) + location (exprloc) {const: 0x403e0c, GNU_push_tls_address} + [62] variable "n" + name (string) + decl_file (data1) + decl_line (data1) + decl_column (data1) + type (ref4) + external (flag_present) + location (exprloc) {const: 0x403e08, GNU_push_tls_address} + [70] subprogram "main" + external (flag_present) + name (GNU_str_index) + decl_file (data1) + decl_line (data1) + decl_column (data1) + type (ref4) + low_pc (GNU_addr_index) + high_pc (data8) + frame_base (exprloc) {call_frame_cfa {bregx(7,8)}} + GNU_all_call_sites (flag_present) + [84] variable "r1" + name (string) + decl_file (data1) + decl_line (data1) + decl_column (data1) + type (ref4) + location (exprloc) {addr: 0x404038, deref_size(4), addr: 0x404034, deref_size(4), plus, addr: 0x40403c, deref_size(4), plus, stack_value} + [9f] variable "r2" + name (string) + decl_file (data1) + decl_line (data1) + decl_column (data1) + type (ref4) + location (exprloc) {GNU_push_tls_address, const: 0x403e10, deref_size(4), GNU_push_tls_address, const: 0x403e0c, deref_size(4), plus, GNU_push_tls_address, const: 0x403e08, deref_size(4), plus, stack_value} + [bd] variable "res" + name (string) + decl_file (data1) + decl_line (data1) + decl_column (data1) + type (ref4) + location (exprloc) {addr: 0x404038, deref_size(4), GNU_push_tls_address, const: 0x403e08, deref_size(4), plus, GNU_push_tls_address, const: 0x403e0c, deref_size(4), plus, GNU_push_tls_address, const: 0x403e10, deref_size(4), plus, addr: 0x404034, deref_size(4), plus, addr: 0x40403c, deref_size(4), plus, stack_value} +EOF + exit 0 diff --git a/tests/testfile-addrx_constx-4.bz2 b/tests/testfile-addrx_constx-4.bz2 Binary files differnew file mode 100755 index 00000000..cf10fbb1 --- /dev/null +++ b/tests/testfile-addrx_constx-4.bz2 diff --git a/tests/testfile-addrx_constx-5.bz2 b/tests/testfile-addrx_constx-5.bz2 Binary files differnew file mode 100755 index 00000000..eb2a1f17 --- /dev/null +++ b/tests/testfile-addrx_constx-5.bz2 diff --git a/tests/varlocs.c b/tests/varlocs.c index b2ceda2e..859068d6 100644 --- a/tests/varlocs.c +++ b/tests/varlocs.c @@ -652,6 +652,42 @@ print_expr (Dwarf_Attribute *attr, Dwarf_Op *expr, Dwarf_Addr addr) } break; + case DW_OP_GNU_addr_index: + case DW_OP_addrx: + /* Address from the .debug_addr section (indexed based on CU). */ + { + Dwarf_Attribute addr_attr; + if (dwarf_getlocation_attr (attr, expr, &addr_attr) != 0) + error (EXIT_FAILURE, 0, "dwarf_getlocation_attr for addr: %s", + dwarf_errmsg (-1)); + + Dwarf_Addr address; + if (dwarf_formaddr (&addr_attr, &address) != 0) + error (EXIT_FAILURE, 0, "dwarf_formaddr address failed: %s", + dwarf_errmsg (-1)); + + printf ("addr: 0x%" PRIx64, address); + } + break; + + case DW_OP_GNU_const_index: + case DW_OP_constx: + /* Constant from the .debug_addr section (indexed based on CU). */ + { + Dwarf_Attribute addr_attr; + if (dwarf_getlocation_attr (attr, expr, &addr_attr) != 0) + error (EXIT_FAILURE, 0, "dwarf_getlocation_attr for addr: %s", + dwarf_errmsg (-1)); + + Dwarf_Word constant; + if (dwarf_formudata (&addr_attr, &constant) != 0) + error (EXIT_FAILURE, 0, "dwarf_formudata constant failed: %s", + dwarf_errmsg (-1)); + + printf ("const: 0x%" PRIx64, constant); + } + break; + default: error (EXIT_FAILURE, 0, "unhandled opcode: DW_OP_%s (0x%x)", opname, atom); @@ -1019,9 +1055,18 @@ main (int argc, char *argv[]) /* Only walk actual compile units (not partial units) that contain code if we are only interested in the function variable locations. */ + Dwarf_Die cudie; + Dwarf_Die subdie; + uint8_t unit_type; + if (dwarf_cu_info (cu->cu, NULL, &unit_type, &cudie, &subdie, + NULL, NULL, NULL) != 0) + error (EXIT_FAILURE, 0, "dwarf_cu_info: %s", dwarf_errmsg (-1)); + if (unit_type == DW_UT_skeleton) + cudie = subdie; + Dwarf_Addr cubase; - if (dwarf_tag (cu) == DW_TAG_compile_unit - && (exprlocs || dwarf_lowpc (cu, &cubase) == 0)) + if (dwarf_tag (&cudie) == DW_TAG_compile_unit + && (exprlocs || dwarf_lowpc (&cudie, &cubase) == 0)) { found_cu = true; @@ -1043,7 +1088,7 @@ main (int argc, char *argv[]) ? modname : basename (mainfile)); printf ("module '%s'\n", name); - print_die (cu, "CU", 0); + print_die (&cudie, "CU", 0); Dwarf_Addr elfbias; Elf *elf = dwfl_module_getelf (mod, &elfbias); @@ -1060,18 +1105,10 @@ main (int argc, char *argv[]) GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (elf, &ehdr_mem); is_ET_REL = ehdr->e_type == ET_REL; - // Get the actual CU DIE and walk all all DIEs (or just the - // functions) inside it. - Dwarf_Die cudie; - uint8_t offsize; - uint8_t addrsize; - if (dwarf_diecu (cu, &cudie, &addrsize, &offsize) == NULL) - error (EXIT_FAILURE, 0, "dwarf_diecu %s", dwarf_errmsg (-1)); - if (exprlocs) { Dwarf_Addr entrypc; - if (dwarf_entrypc (cu, &entrypc) != 0) + if (dwarf_entrypc (&cudie, &entrypc) != 0) entrypc = 0; /* XXX - Passing true for has_frame_base is not really true. @@ -1079,9 +1116,9 @@ main (int argc, char *argv[]) attributes. Technically we should check that the DIE (types) are referenced from variables that are defined in a context (function) that has a frame base. */ - handle_die (cu, 0, true /* Should be false */, entrypc); + handle_die (&cudie, 0, true /* Should be false */, entrypc); } - else if (dwarf_getfuncs (cu, handle_function, NULL, 0) != 0) + else if (dwarf_getfuncs (&cudie, handle_function, NULL, 0) != 0) error (EXIT_FAILURE, 0, "dwarf_getfuncs %s", dwarf_errmsg (-1)); } |
