summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorMark Wielaard <[email protected]>2018-05-20 23:30:01 +0200
committerMark Wielaard <[email protected]>2018-05-25 15:07:58 +0200
commit6e3d2521a2b5a3b436901f52cfb9785887a7c961 (patch)
tree649d9c157ac680e9f99b61df772e429883602bf5 /tests
parent184fd30d1a453dc165ffc187b22dec6d196522ad (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/ChangeLog14
-rw-r--r--tests/Makefile.am2
-rw-r--r--tests/addrx_constx-4.dwo.bz2bin0 -> 809 bytes
-rw-r--r--tests/addrx_constx-5.dwo.bz2bin0 -> 824 bytes
-rwxr-xr-xtests/run-all-dwarf-ranges.sh24
-rwxr-xr-xtests/run-varlocs.sh208
-rwxr-xr-xtests/testfile-addrx_constx-4.bz2bin0 -> 2851 bytes
-rwxr-xr-xtests/testfile-addrx_constx-5.bz2bin0 -> 2847 bytes
-rw-r--r--tests/varlocs.c65
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
new file mode 100644
index 00000000..f0bae1cd
--- /dev/null
+++ b/tests/addrx_constx-4.dwo.bz2
Binary files differ
diff --git a/tests/addrx_constx-5.dwo.bz2 b/tests/addrx_constx-5.dwo.bz2
new file mode 100644
index 00000000..a5f4b1a6
--- /dev/null
+++ b/tests/addrx_constx-5.dwo.bz2
Binary files differ
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
new file mode 100755
index 00000000..cf10fbb1
--- /dev/null
+++ b/tests/testfile-addrx_constx-4.bz2
Binary files differ
diff --git a/tests/testfile-addrx_constx-5.bz2 b/tests/testfile-addrx_constx-5.bz2
new file mode 100755
index 00000000..eb2a1f17
--- /dev/null
+++ b/tests/testfile-addrx_constx-5.bz2
Binary files differ
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));
}