summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ChangeLog7
-rw-r--r--src/readelf.c103
-rw-r--r--tests/ChangeLog9
-rw-r--r--tests/Makefile.am7
-rwxr-xr-xtests/run-readelf-discr.sh337
-rw-r--r--tests/testfile-rng.debug.bz2bin0 -> 1286 bytes
-rw-r--r--tests/testfile-urng.debug.bz2bin0 -> 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
new file mode 100644
index 00000000..58c1b76b
--- /dev/null
+++ b/tests/testfile-rng.debug.bz2
Binary files differ
diff --git a/tests/testfile-urng.debug.bz2 b/tests/testfile-urng.debug.bz2
new file mode 100644
index 00000000..4697f364
--- /dev/null
+++ b/tests/testfile-urng.debug.bz2
Binary files differ