From e8fb03087513f6b7446855b59eb52eb0afbcf27d Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Tue, 10 Nov 2020 14:44:56 +0100 Subject: [PATCH] readelf: Fix output of rnglists section Noticed this when examining the debug info in the following gdb test case binutils-gdb/gdb/testsuite/gdb.cp/step-and-next-inline.cc: $ gcc -g -gdwarf-5 -O2 step-and-next-inline.cc $ readelf --debug-dump=Ranges a.out Contents of the .debug_rnglists section: Offset Begin End 0000000c 0000000000401160 00000000004011ca 00000016 0000000000401060 0000000000401065 00000020 00000021 0000000000401165 (base address) 0000002a 0000000000401165 0000000000401165 (start == end) 0000002d 0000000000401169 0000000000401173 00000030 00000000008021c5 00000000008021ca <== wrong 0000003a 0000003b 0000000000401160 00000000004011ca 00000045 0000000000401060 0000000000401065 0000004f 0000000000401070 0000000000401085 00000059 It turns out that the .s file contans this: .LLRL2: .byte 0x5 .quad .LBB8 .byte 0x4 .uleb128 .LBB8-.LBB8 .uleb128 .LBE8-.LBB8 .byte 0x4 .uleb128 .LBB12-.LBB8 .uleb128 .LBE12-.LBB8 .byte 0x7 .quad .LBB17 .uleb128 .LBE17-.LBB17 .byte 0 So 0x7 = DW_RLE_start_length is wrong decoded and got the base address added unexpectedly. while 0x4 = DW_RLE_offset_pair is the only entry that needs to add the base address. BTW: gdb does it right, see: commit d0ce17d8537 ("gdb: fix issues with handling DWARF v5 rnglists & .dwo files."). 2020-11-10 Bernd Edlinger * dwarf.c (display_debug_rnglists_list): Only DW_RLE_offset_pair needs the base address added. --- binutils/dwarf.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/binutils/dwarf.c b/binutils/dwarf.c index 5807744..0722518 100644 --- a/binutils/dwarf.c +++ b/binutils/dwarf.c @@ -7516,8 +7516,15 @@ display_debug_rnglists_list (unsigned char *start, unsigned char *finish, if (rlet == DW_RLE_base_address) continue; - print_dwarf_vma (begin + base_address, pointer_size); - print_dwarf_vma (end + base_address, pointer_size); + /* Only DW_RLE_offset_pair needs the base address added. */ + if (rlet == DW_RLE_offset_pair) + { + begin += base_address; + end += base_address; + } + + print_dwarf_vma (begin, pointer_size); + print_dwarf_vma (end, pointer_size); if (begin == end) fputs (_("(start == end)"), stdout); -- 1.9.1