+ def _dump_debug_ranges(self):
+ # TODO: GNU readelf format doesn't need entry_length?
+ di = self._dwarfinfo
+ range_lists = di.range_lists()
+ if not range_lists: # No ranges section - readelf outputs nothing
+ return
+
+ ver5 = range_lists.version >= 5
+ range_lists = list(range_lists.iter_range_lists())
+ if len(range_lists) == 0:
+ # Present but empty locations section - readelf outputs a message
+ self._emitline("\nSection '%s' has no debugging data." % (di.debug_rnglists_sec or di.debug_ranges_sec).name)
+ return
+
+ # In order to determine the base address of the range
+ # We need to know the corresponding CU.
+ cu_map = {die.attributes['DW_AT_ranges'].value : cu # Range list offset => CU
+ for cu in di.iter_CUs()
+ for die in cu.iter_DIEs()
+ if 'DW_AT_ranges' in die.attributes}
+
+ addr_size = di.config.default_address_size # In bytes, 4 or 8
+ addr_width = addr_size * 2 # In hex digits, 8 or 16
+ line_template = " %%08x %%0%dx %%0%dx %%s" % (addr_width, addr_width)
+ base_template = " %%08x %%0%dx (base address)" % (addr_width)
+
+ self._emitline('Contents of the %s section:\n' % (di.debug_rnglists_sec or di.debug_ranges_sec).name)
+ self._emitline(' Offset Begin End')
+
+ for range_list in range_lists:
+ # Weird discrepancy in binutils: for DWARFv5 it outputs entry offset,
+ # for DWARF<=4 list offset.
+ first = range_list[0]
+ base_ip = _get_cu_base(cu_map[first.entry_offset])
+ for entry in range_list:
+ if isinstance(entry, RangeEntry):
+ postfix = ' (start == end)' if entry.begin_offset == entry.end_offset else ''
+ self._emitline(line_template % (
+ entry.entry_offset if ver5 else first.entry_offset,
+ (0 if entry.is_absolute else base_ip) + entry.begin_offset,
+ (0 if entry.is_absolute else base_ip) + entry.end_offset,
+ postfix))
+ elif isinstance(entry, elftools.dwarf.ranges.BaseAddressEntry):
+ base_ip = entry.base_address
+ self._emitline(base_template % (
+ entry.entry_offset if ver5 else first.entry_offset,
+ entry.base_address))
+ else:
+ raise NotImplementedError("Unknown object in a range list")
+ last = range_list[-1]
+ self._emitline(' %08x <End of list>' % (last.entry_offset + last.entry_length if ver5 else first.entry_offset))
+