Bug 28012

Summary: readelf --debug-dump=Ranges doesn't handle concatenated .debug_rnglists sections
Product: binutils Reporter: Simon Marchi <simark>
Component: binutilsAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal CC: simon.marchi
Priority: P2    
Version: unspecified   
Target Milestone: ---   
Host: Target:
Build: Last reconfirmed:
Attachments: ELF file containing .debug_rnglists

Description Simon Marchi 2021-06-25 15:55:52 UTC
See attached libstdc++.so.6.0.29, taken from:

https://mirror.f4st.host/archlinux/core/os/x86_64/gcc-libs-11.1.0-1-x86_64.pkg.tar.zst

(the link may be broken when the package gets upgraded, but it doesn't really matter, the attached file should be enough)

It's compiled with gcc, contains DWARF5, and contains a .debug_rnglists section.  The .debug_rnglists section is made by concatenating the .debug_rnglists contributions from all .o files, so it's made of multiple range list tables, one after the other (each range list table is described in section 7.28 of DWARF5).

It looks like readelf tries to read the whole section as one table or something, because after having displayed the entries of the first table, it shows a bunch of:

$ ~/build/binutils-gdb/binutils/readelf --debug-dump=Ranges libstdc++.so.6.0.29 |& less
    ...
    000004d8 00000000000a3580 00000000000a359b 
    000004e2 00000000000a35a0 00000000000a35b3 
    000004ec <End of list>
readelf: Warning: Corrupt offset (0x000004f9) in range entry 72
readelf: Warning: Corrupt offset (0x000004f9) in range entry 73
readelf: Warning: Corrupt offset (0x00000509) in range entry 74
    ...

I tried to debug display_debug_ranges, in binutils/dwarf.c, but I don't really understand what's happening.  The code uses num_debug_info_entries, I'm not sure where that is coming from.  But I don't see why it would be needed to deal with debug info entries here, I think it should be possible to parse and dump .debug_rnglists by just walking the section by itself until the end.
Comment 1 Simon Marchi 2021-06-25 15:56:19 UTC
Created attachment 13512 [details]
ELF file containing .debug_rnglists
Comment 2 Alan Modra 2024-02-27 00:52:00 UTC
Apparently fixed with current binutils.

    000004e2 00000000000a35a0 00000000000a35b3 
    000004ec <End of list>
 Table at Offset: 0x4ed:
  Length:          0x7c
  DWARF version:   5
  Address size:    8
  Segment size:    0
  Offset entries:  0
    Offset   Begin    End
    000004f9 00000000000a35d4 (base address)
    00000502 00000000000a35d4 00000000000a35d7
Comment 3 Simon Marchi 2024-02-27 03:10:12 UTC
Cool, thanks!  I had to bisect to know which commit fixed it, it's this one:

e7f024765a48fba4452535a5fc006a7e858730fd is the first new commit
commit e7f024765a48fba4452535a5fc006a7e858730fd
Author: Alan Modra <amodra@gmail.com>
Date:   Sun Oct 17 17:34:46 2021 +1030

    PR28459, readelf issues bogus warning
    
    I'd missed the fact that the .debug_rnglists dump doesn't exactly
    display the contents of the section.  Instead readelf rummages through
    .debug_info looking for DW_AT_ranges entries, then displays the
    entries in .debug_rnglists pointed at, sorted.  A simpler dump of the
    actual section contents might be more useful and robust, but it was
    likely done that way to detect overlap and holes.
    
    Anyway, the headers in .debug_rnglists besides the first are ignored,
    and limiting to the unit length of the first header fails if there is
    more than one unit.
    
            PR 28459
            * dwarf.c (display_debug_ranges): Don't constrain data to length
            in header.

 binutils/dwarf.c | 1 -
 1 file changed, 1 deletion(-)