diff options
-rw-r--r-- | src/ChangeLog | 7 | ||||
-rw-r--r-- | src/readelf.c | 103 | ||||
-rw-r--r-- | tests/ChangeLog | 9 | ||||
-rw-r--r-- | tests/Makefile.am | 7 | ||||
-rwxr-xr-x | tests/run-readelf-discr.sh | 337 | ||||
-rw-r--r-- | tests/testfile-rng.debug.bz2 | bin | 0 -> 1286 bytes | |||
-rw-r--r-- | tests/testfile-urng.debug.bz2 | bin | 0 -> 1178 bytes |
7 files changed, 453 insertions, 10 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 0c817f41..580eea9b 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,10 @@ +2019-05-10 Mark Wielaard <mark@klomp.org> + + * readelf.c (struct attrcb_args): Rename die to dies. + (attr_callback): Get current current die using dies[level]. + Handle DW_AT_discr_list as block, not as constant. + (print_debug_units): pass dies, not dies[level] as args. + 2019-05-09 Mark Wielaard <mark@klomp.org> * readelf.c (cleanup_list): New function. diff --git a/src/readelf.c b/src/readelf.c index 4c20c38e..062168bb 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -6944,7 +6944,7 @@ struct attrcb_args { Dwfl_Module *dwflmod; Dwarf *dbg; - Dwarf_Die *die; + Dwarf_Die *dies; int level; bool silent; bool is_split; @@ -6960,7 +6960,7 @@ attr_callback (Dwarf_Attribute *attrp, void *arg) { struct attrcb_args *cbargs = (struct attrcb_args *) arg; const int level = cbargs->level; - Dwarf_Die *die = cbargs->die; + Dwarf_Die *die = &cbargs->dies[level]; bool is_split = cbargs->is_split; unsigned int attr = dwarf_whatattr (attrp); @@ -7304,9 +7304,6 @@ attr_callback (Dwarf_Attribute *attrp, void *arg) case DW_AT_ordering: valuestr = dwarf_ordering_name (num); break; - case DW_AT_discr_list: - valuestr = dwarf_discr_list_name (num); - break; case DW_AT_decl_file: case DW_AT_call_file: { @@ -7361,7 +7358,7 @@ attr_callback (Dwarf_Attribute *attrp, void *arg) /* When highpc is in constant form it is relative to lowpc. In that case also show the address. */ Dwarf_Addr highpc; - if (attr == DW_AT_high_pc && dwarf_highpc (cbargs->die, &highpc) == 0) + if (attr == DW_AT_high_pc && dwarf_highpc (die, &highpc) == 0) { printf (" %*s%-20s (%s) %" PRIuMAX " (", (int) (level * 2), "", dwarf_attr_name (attr), @@ -7383,7 +7380,7 @@ attr_callback (Dwarf_Attribute *attrp, void *arg) bool is_signed; int bytes = 0; if (attr == DW_AT_const_value) - die_type_sign_bytes (cbargs->die, &is_signed, &bytes); + die_type_sign_bytes (die, &is_signed, &bytes); else is_signed = (form == DW_FORM_sdata || form == DW_FORM_implicit_const); @@ -7538,6 +7535,96 @@ attr_callback (Dwarf_Attribute *attrp, void *arg) else print_block (block.length, block.data); break; + + case DW_AT_discr_list: + if (block.length == 0) + puts ("<default>"); + else if (form != DW_FORM_data16) + { + const unsigned char *readp = block.data; + const unsigned char *readendp = readp + block.length; + + /* See if we are dealing with a signed or unsigned + values. If the parent of this variant DIE is a + variant_part then it will either have a discriminant + which points to the member which type is the + discriminant type. Or the variant_part itself has a + type representing the discriminant. */ + bool is_signed = false; + if (level > 0) + { + Dwarf_Die *parent = &cbargs->dies[level - 1]; + if (dwarf_tag (die) == DW_TAG_variant + && dwarf_tag (parent) == DW_TAG_variant_part) + { + Dwarf_Die member; + Dwarf_Attribute discr_attr; + int bytes; + if (dwarf_formref_die (dwarf_attr (parent, + DW_AT_discr, + &discr_attr), + &member) != NULL) + die_type_sign_bytes (&member, &is_signed, &bytes); + else + die_type_sign_bytes (parent, &is_signed, &bytes); + } + } + while (readp < readendp) + { + int d = (int) *readp++; + printf ("%s ", dwarf_discr_list_name (d)); + if (readp >= readendp) + goto attrval_out; + + Dwarf_Word val; + Dwarf_Sword sval; + if (d == DW_DSC_label) + { + if (is_signed) + { + get_sleb128 (sval, readp, readendp); + printf ("%" PRId64 "", sval); + } + else + { + get_uleb128 (val, readp, readendp); + printf ("%" PRIu64 "", val); + } + } + else if (d == DW_DSC_range) + { + if (is_signed) + { + get_sleb128 (sval, readp, readendp); + printf ("%" PRId64 "..", sval); + if (readp >= readendp) + goto attrval_out; + get_sleb128 (sval, readp, readendp); + printf ("%" PRId64 "", sval); + } + else + { + get_uleb128 (val, readp, readendp); + printf ("%" PRIu64 "..", val); + if (readp >= readendp) + goto attrval_out; + get_uleb128 (val, readp, readendp); + printf ("%" PRIu64 "", val); + } + } + else + { + print_block (readendp - readp, readp); + break; + } + if (readp < readendp) + printf (", "); + } + putchar ('\n'); + } + else + print_block (block.length, block.data); + break; } break; @@ -7738,7 +7825,7 @@ print_debug_units (Dwfl_Module *dwflmod, /* Print the attribute values. */ args.level = level; - args.die = &dies[level]; + args.dies = dies; (void) dwarf_getattrs (&dies[level], attr_callback, &args, 0); /* Make room for the next level's DIE. */ diff --git a/tests/ChangeLog b/tests/ChangeLog index 49392f1f..15ac64f5 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,12 @@ +2019-05-10 Mark Wielaard <mark@klomp.org> + + * Makefile.am (TESTS): Add run-readelf-discr.sh. + (EXTRA_DIST): Likewise and add testfile-rng.debug.bz2 and + testfile-urng.debug.bz2. + * run-readelf-discr.sh: New test. + * testfile-rng.debug.bz2: New test file. + * testfile-urng.debug.bz2: Likewise. + 2019-04-30 Mark Wielaard <mark@klomp.org> * xlate_notes.c: New file. diff --git a/tests/Makefile.am b/tests/Makefile.am index 498c1db2..80900e42 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -159,7 +159,8 @@ TESTS = run-arextract.sh run-arsymtest.sh run-ar.sh newfile test-nlist \ run-next-cfi.sh run-next-cfi-self.sh \ run-copyadd-sections.sh run-copymany-sections.sh \ run-typeiter-many.sh run-strip-test-many.sh \ - run-strip-version.sh run-xlate-note.sh + run-strip-version.sh run-xlate-note.sh \ + run-readelf-discr.sh if !BIARCH export ELFUTILS_DISABLE_BIARCH = 1 @@ -424,7 +425,9 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \ testfile-debug-rel-ppc64-z.o.bz2 \ testfile-debug-rel-ppc64.o.bz2 \ run-strip-version.sh testfile-version.bz2 \ - run-xlate-note.sh + run-xlate-note.sh \ + run-readelf-discr.sh \ + testfile-rng.debug.bz2 testfile-urng.debug.bz2 if USE_VALGRIND valgrind_cmd='valgrind -q --leak-check=full --error-exitcode=1' diff --git a/tests/run-readelf-discr.sh b/tests/run-readelf-discr.sh new file mode 100755 index 00000000..dc84d827 --- /dev/null +++ b/tests/run-readelf-discr.sh @@ -0,0 +1,337 @@ +#! /bin/sh +# Copyright (C) 2019 Red Hat, Inc. +# This file is part of elfutils. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# elfutils is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +. $srcdir/test-subr.sh + +# = rng.ads = +# package Rng is +# +# type Rec (I : Integer) is record +# case I is +# when Positive => +# case I is +# when 1..15 | 17 | 23 => +# null; +# when others => +# J : Integer; +# end case; +# when -52..-1 => +# Q: Integer; +# when -64 => +# R: Boolean; +# when others => +# null; +# end case; +# end record; +# +# R : Rec (1); +# +# end Rng; + +# = urng.ads = +# +# package Urng is +# +# type Unsigned is mod 65536; +# type Rec (U : Unsigned) is record +# case U is +# when 17 | 23 | 32768..65535 => +# null; +# when 256 => +# B: Boolean; +# when others => +# I : Integer; +# end case; +# end record; +# +# R : Rec (1); +# +# end Urng; + +# gcc -c -g -fgnat-encodings=minimal -gstrict-dwarf rng.ads +# eu-strip -g -f rng.debug rng.o +# gcc -c -g -fgnat-encodings=minimal -gstrict-dwarf urng.ads +# eu-strip -g -f urng.debug urng.o + +testfiles testfile-rng.debug testfile-urng.debug + +testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=info testfile-rng.debug testfile-urng.debug <<EOF + +testfile-rng.debug: + + +DWARF section [ 5] '.debug_info' at offset 0x40: + [Offset] + Compilation unit at offset 0: + Version: 4, Abbreviation section offset: 0, Address size: 8, Offset size: 4 + [ b] compile_unit abbrev: 1 + producer (strp) "GNU Ada 9.1.1 20190503 (Red Hat 9.1.1-1) -g -fgnat-encodings=minimal -gstrict-dwarf -mtune=generic -march=x86-64" + language (data1) Ada95 (13) + name (strp) "rng.ads" + comp_dir (strp) "/home/mark" + low_pc (addr) 000000000000000000 + high_pc (data8) 2016 (0x00000000000007e0) + stmt_list (sec_offset) 0 + [ 2d] structure_type abbrev: 2 + name (strp) "rng__rec" + byte_size (exprloc) + [ 0] push_object_address + [ 1] deref_size 4 + [ 3] call4 [ c6] + [ 8] plus_uconst 7 + [10] const1s -4 + [12] and + decl_file (data1) rng.ads (1) + decl_line (data1) 3 + decl_column (data1) 9 + sibling (ref4) [ ab] + [ 47] member abbrev: 3 + name (string) "i" + decl_file (data1) rng.ads (1) + decl_line (data1) 3 + decl_column (data1) 14 + type (ref4) [ fe] + data_member_location (data1) 0 + [ 52] variant_part abbrev: 4 + discr (ref4) [ 47] + [ 57] variant abbrev: 5 + discr_list (block1) range 1..2147483647 + sibling (ref4) [ 81] + [ 64] variant_part abbrev: 4 + discr (ref4) [ 47] + [ 69] variant abbrev: 6 + discr_list (block1) range 1..15, label 17, label 23 + [ 72] variant abbrev: 7 + [ 73] member abbrev: 3 + name (string) "j" + decl_file (data1) rng.ads (1) + decl_line (data1) 10 + decl_column (data1) 19 + type (ref4) [ fe] + data_member_location (data1) 4 + [ 81] variant abbrev: 5 + discr_list (block1) range -52..-1 + sibling (ref4) [ 96] + [ 8a] member abbrev: 3 + name (string) "q" + decl_file (data1) rng.ads (1) + decl_line (data1) 13 + decl_column (data1) 13 + type (ref4) [ fe] + data_member_location (data1) 4 + [ 96] variant abbrev: 8 + discr_value (sdata) -64 + sibling (ref4) [ a8] + [ 9c] member abbrev: 3 + name (string) "r" + decl_file (data1) rng.ads (1) + decl_line (data1) 15 + decl_column (data1) 13 + type (ref4) [ 105] + data_member_location (data1) 4 + [ a8] variant abbrev: 9 + [ ab] dwarf_procedure abbrev: 10 + location (exprloc) + [ 0] dup + [ 1] lit0 + [ 2] gt + [ 3] over + [ 4] lit15 + [ 5] le + [ 6] and + [ 7] over + [ 8] lit17 + [ 9] eq + [10] or + [11] over + [12] lit23 + [13] eq + [14] or + [15] bra 22 + [18] lit4 + [19] skip 23 + [22] lit0 + [23] swap + [24] drop + [ c6] dwarf_procedure abbrev: 10 + location (exprloc) + [ 0] dup + [ 1] lit0 + [ 2] gt + [ 3] bra 36 + [ 6] dup + [ 7] const1s -52 + [ 9] lt + [10] over + [11] lit0 + [12] ge + [13] or + [14] bra 21 + [17] lit4 + [18] skip 33 + [21] dup + [22] const1s -64 + [24] eq + [25] bra 32 + [28] lit0 + [29] skip 33 + [32] lit4 + [33] skip 52 + [36] dup + [37] call4 [ ab] + [42] plus_uconst 3 + [44] const1s -4 + [46] and + [47] plus_uconst 3 + [49] const1s -4 + [51] and + [52] swap + [53] drop + [ fe] base_type abbrev: 11 + byte_size (data1) 4 + encoding (data1) signed (5) + name (strp) "integer" + artificial (flag_present) yes + [ 105] base_type abbrev: 12 + byte_size (data1) 1 + encoding (data1) boolean (2) + name (strp) "boolean" + [ 10c] variable abbrev: 13 + name (strp) "rng__r" + decl_file (data1) rng.ads (1) + decl_line (data1) 21 + decl_column (data1) 4 + type (ref4) [ 2d] + external (flag_present) yes + location (exprloc) + [ 0] addr 0x7e4 + [ 122] subprogram abbrev: 14 + external (flag_present) yes + name (strp) "rng___elabs" + artificial (flag_present) yes + low_pc (addr) 0x0000000000000734 + high_pc (data8) 22 (0x000000000000074a) + frame_base (exprloc) + [ 0] call_frame_cfa + +testfile-urng.debug: + + +DWARF section [ 5] '.debug_info' at offset 0x40: + [Offset] + Compilation unit at offset 0: + Version: 4, Abbreviation section offset: 0, Address size: 8, Offset size: 4 + [ b] compile_unit abbrev: 1 + producer (strp) "GNU Ada 9.1.1 20190503 (Red Hat 9.1.1-1) -g -fgnat-encodings=minimal -gstrict-dwarf -mtune=generic -march=x86-64" + language (data1) Ada95 (13) + name (strp) "urng.ads" + comp_dir (strp) "/home/mark" + low_pc (addr) 000000000000000000 + high_pc (data8) 977 (0x00000000000003d1) + stmt_list (sec_offset) 0 + [ 2d] base_type abbrev: 2 + byte_size (data1) 2 + encoding (data1) unsigned (7) + name (strp) "urng__unsigned" + [ 34] structure_type abbrev: 3 + name (strp) "urng__rec" + byte_size (exprloc) + [ 0] push_object_address + [ 1] deref_size 2 + [ 3] call4 [ 8d] + [ 8] plus_uconst 7 + [10] const1s -4 + [12] and + decl_file (data1) urng.ads (1) + decl_line (data1) 4 + decl_column (data1) 9 + sibling (ref4) [ 8d] + [ 4e] member abbrev: 4 + name (string) "u" + decl_file (data1) urng.ads (1) + decl_line (data1) 4 + decl_column (data1) 14 + type (ref4) [ 2d] + data_member_location (data1) 0 + [ 59] variant_part abbrev: 5 + discr (ref4) [ 4e] + [ 5e] variant abbrev: 6 + discr_list (block1) label 17, label 23, range 32768..65535 + [ 6b] variant abbrev: 7 + discr_value (udata) 256 + sibling (ref4) [ 7e] + [ 72] member abbrev: 4 + name (string) "b" + decl_file (data1) urng.ads (1) + decl_line (data1) 9 + decl_column (data1) 13 + type (ref4) [ a4] + data_member_location (data1) 4 + [ 7e] variant abbrev: 8 + [ 7f] member abbrev: 4 + name (string) "i" + decl_file (data1) urng.ads (1) + decl_line (data1) 11 + decl_column (data1) 13 + type (ref4) [ ab] + data_member_location (data1) 4 + [ 8d] dwarf_procedure abbrev: 9 + location (exprloc) + [ 0] dup + [ 1] lit17 + [ 2] ne + [ 3] over + [ 4] lit23 + [ 5] ne + [ 6] and + [ 7] over + [ 8] lit0 + [ 9] ge + [10] and + [11] bra 18 + [14] lit0 + [15] skip 19 + [18] lit4 + [19] swap + [20] drop + [ a4] base_type abbrev: 2 + byte_size (data1) 1 + encoding (data1) boolean (2) + name (strp) "boolean" + [ ab] base_type abbrev: 10 + byte_size (data1) 4 + encoding (data1) signed (5) + name (strp) "integer" + artificial (flag_present) yes + [ b2] variable abbrev: 11 + name (strp) "urng__r" + decl_file (data1) urng.ads (1) + decl_line (data1) 15 + decl_column (data1) 4 + type (ref4) [ 34] + external (flag_present) yes + location (exprloc) + [ 0] addr 0x3d8 + [ c8] subprogram abbrev: 12 + external (flag_present) yes + name (strp) "urng___elabs" + artificial (flag_present) yes + low_pc (addr) 0x0000000000000386 + high_pc (data8) 22 (0x000000000000039c) + frame_base (exprloc) + [ 0] call_frame_cfa +EOF diff --git a/tests/testfile-rng.debug.bz2 b/tests/testfile-rng.debug.bz2 Binary files differnew file mode 100644 index 00000000..58c1b76b --- /dev/null +++ b/tests/testfile-rng.debug.bz2 diff --git a/tests/testfile-urng.debug.bz2 b/tests/testfile-urng.debug.bz2 Binary files differnew file mode 100644 index 00000000..4697f364 --- /dev/null +++ b/tests/testfile-urng.debug.bz2 |