eliben / pyelftools

Parsing ELF and DWARF in Python
Other
1.99k stars 508 forks source link

[BUG] [DWARF] Missing Compile Units #311

Open SjRNMzU opened 4 years ago

SjRNMzU commented 4 years ago

I'm using the latest git version of pyelftools with python 3.8.

pyelftools misses CUs that objdump can display when dumping DWARF info from MUSL libc.

The ELF64 binary I'm analyzing can be found here.

If I iterate through all the CUs using dwarf_info.iter_CUs() pyelftools misses all CUs from offset 0x66c71 and above.

Trying to specify the CU explicitly returns:

In [3]: dwarf_info.get_CU_at(0x66c71)                      
---------------------------------------------------------------------------
DWARFError                                Traceback (most recent call last)
~/abc/src/classes/dwarf.py in <module>
----> 1 dwarf_info.get_CU_at(0x66c71)

/usr/local/lib/python3.8/dist-packages/pyelftools-0.26-py3.8.egg/elftools/dwarf/dwarfinfo.py in get_CU_at(self, offset)
    191             self.has_debug_info,
    192             'CU lookup but no debug info section')
--> 193         dwarf_assert(
    194             0 <= offset < self.debug_info_sec.size,
    195             "offset %s beyond .debug_info size" % offset)

/usr/local/lib/python3.8/dist-packages/pyelftools-0.26-py3.8.egg/elftools/common/utils.py in dwarf_assert(cond, msg)
     81     """ Assert that cond is True, otherwise raise DWARFError(msg)
     82     """
---> 83     _assert_with_exception(cond, msg, DWARFError)
     84 
     85 

/usr/local/lib/python3.8/dist-packages/pyelftools-0.26-py3.8.egg/elftools/common/utils.py in _assert_with_exception(cond, msg, exception_type)
    112 def _assert_with_exception(cond, msg, exception_type):
    113     if not cond:
--> 114         raise exception_type(msg)

DWARFError: offset 420977 beyond .debug_info size

Dumping DWARF info with objdump --dwarf produces the following excert:

...
<1><66c70>: Abbrev Number: 0
  Compilation Unit @ offset 0x66c71:
   Length:        0x33d (32-bit)
   Version:       4
   Abbrev Offset: 0x272a1
   Pointer Size:  8
 <0><66c7c>: Abbrev Number: 1 (DW_TAG_compile_unit)
    <66c7d>   DW_AT_producer    : (indirect string, offset: 0x243): GNU C99 7.3.0 -mtune=generic -march=x86-64 -g -g -O2 -std=c99 -ffreestanding -fexcess-precision=standard -frounding-math -fno-unwind-tables -fno-asynchronous-unwind-tables -ffunction-sections -fdata-sections -fstack-protector-strong -fPIC
    <66c81>   DW_AT_language    : 12    (ANSI C99)
    <66c82>   DW_AT_name        : (indirect string, offset: 0x6f1d): src/network/connect.c
    <66c86>   DW_AT_comp_dir    : .
    <66c88>   DW_AT_ranges      : 0xa100
    <66c8c>   DW_AT_low_pc      : 0x0
    <66c94>   DW_AT_stmt_list   : 0x1e256
 <1><66c98>: Abbrev Number: 2 (DW_TAG_typedef)
...
mdmillerii commented 4 years ago

The error says the requested offset is beyond the size of the .debug_info section. Please compare the section headers parsed by pyelftools with readelf. (The server for your linked binary is unresponsive to my fetch request).

sevaa commented 4 years ago

I can't retrieve the binary, either. transfer.sh probably has an expiration mechanism in place. @SjRNMzU, would you mind either attaching to the issue, or uploading to a more permanent storage? Dropbox is quite popular.

SjRNMzU commented 4 years ago

@sevaa @mdmillerii I think it was this file.

sevaa commented 4 months ago

@SjRNMzU This should be addressed. Is it still an issue?