--- /dev/null
+#-------------------------------------------------------------------------------
+# elftools: dwarf/dwarfrelocationmanager.py
+#
+# DWARFRelocationManager - handles relocations of DWARF data
+#
+# Eli Bendersky (eliben@gmail.com)
+# This code is in the public domain
+#-------------------------------------------------------------------------------
+
+from ..elf.sections import RelocationSection
+
+
+class DWARFRelocationManager(object):
+ """ Manages relocations for some DWARF section
+ """
+ def __init__(self, elffile, section_name):
+ """
+ """
+ self.elffile = elffile
+ self.section_name = section_name
+ self._section = self.elffile.get_section_by_name(section_name)
+
+ # _relocs maps an offset in the section to a Relocation object
+ # _reloc_section is the relocation section object
+ # ... both are loaded by _load_relocations
+ self._relocs = {}
+ self._reloc_section = None
+ self._load_relocations()
+
+ # _symtable: symbol table section attached to the relocation section
+ self._symtable = self.elffile.get_section(
+ self._reloc_section['sh_link'])
+
+ def has_relocation(self, offset):
+ """ Does the given offset have a relocation registered for it?
+ The offset is relative to its section.
+ """
+ return offset in self._relocs
+
+ def apply_relocation(self, offset):
+ """ Apply the relocation registered for the given offset. Return the
+ relocated value.
+ """
+ reloc = self._relocs[offset]
+
+ def _load_relocations(self):
+ # Currently assume that only a single relocation section will exist
+ # for our section, and that it's either a .rel or a .rela
+ reloc_section_names = (
+ '.rel' + self.section_name,
+ '.rela' + self.section_name)
+ for section in self.elffile.iter_sections():
+ if ( isinstance(section, RelocationSection) and
+ section.name in reloc_section_names):
+ self._reloc_section = section
+ for reloc in self._reloc_section.iter_relocations():
+ self._relocs[reloc['r_offset']] = reloc
+ break
+
return self._make_symbol_table_section(section_header, name)
elif sectype in ('SHT_REL', 'SHT_RELA'):
return RelocationSection(
- section_header, name, self.stream, self.structs)
+ section_header, name, self.stream, self)
else:
return Section(section_header, name, self.stream)
strtab_section = self.get_section(linked_strtab_index)
return SymbolTableSection(
section_header, name, self.stream,
- elfstructs=self.structs,
+ elffile=self,
stringtable=strtab_section)
def _get_segment_header(self, n):
--- /dev/null
+#-------------------------------------------------------------------------------
+# elftools: elf/relocation.py
+#
+# ELF relocations
+#
+# Eli Bendersky (eliben@gmail.com)
+# This code is in the public domain
+#-------------------------------------------------------------------------------
+
+class Relocation(object):
+ """ Relocation object - representing a single relocation entry. Allows
+ dictionary-like access to the entry's fields.
+
+ Can be either a REL or RELA relocation.
+ """
+ def __init__(self, entry, elffile):
+ self.entry = entry
+ self.elffile = elffile
+
+ def is_RELA(self):
+ """ Is this a RELA relocation? If not, it's REL.
+ """
+ return 'r_addend' in self.entry
+
+ def __getitem__(self, name):
+ """ Dict-like access to entries
+ """
+ return self.entry[name]
+
+ def __repr__(self):
+ return '<Relocation (%s): %s>' % (
+ 'RELA' if self.is_RELA() else 'REL',
+ self.entry)
+
+ def __str__(self):
+ return self.__repr__()
+
#-------------------------------------------------------------------------------
from ..construct import CString
from ..common.utils import struct_parse, elf_assert
+from .relocation import Relocation
class Section(object):
""" ELF symbol table section. Has an associated StringTableSection that's
passed in the constructor.
"""
- def __init__(self, header, name, stream, elfstructs, stringtable):
+ def __init__(self, header, name, stream, elffile, stringtable):
super(SymbolTableSection, self).__init__(header, name, stream)
- self.elfstructs = elfstructs
+ self.elffile = elffile
+ self.elfstructs = self.elffile.structs
self.stringtable = stringtable
elf_assert(self['sh_entsize'] > 0,
'Expected entry size of section %s to be > 0' % name)
class RelocationSection(Section):
- def __init__(self, header, name, stream, elfstructs):
+ def __init__(self, header, name, stream, elffile):
super(RelocationSection, self).__init__(header, name, stream)
- self.elfstructs = elfstructs
+ self.elffile = elffile
+ self.elfstructs = self.elffile.structs
if self.header['sh_type'] == 'SHT_REL':
expected_size = self.elfstructs.Elf_Rel.sizeof()
self.entry_struct = self.elfstructs.Elf_Rel
self.entry_struct,
self.stream,
stream_pos=entry_offset)
- return Relocation(entry)
+ return Relocation(entry, self.elffile)
def iter_relocations(self):
""" Yield all the relocations in the section
return self.entry[name]
-class Relocation(object):
- """ Relocation object - representing a single relocation entry. Allows
- dictionary-like access to the entry's fields.
-
- Can be either a REL or RELA relocation.
- """
- def __init__(self, entry):
- self.entry = entry
-
- def is_RELA(self):
- """ Is this a RELA relocation? If not, it's REL.
- """
- return 'r_addend' in self.entry
-
- def __getitem__(self, name):
- """ Dict-like access to entries
- """
- return self.entry[name]
-
- def __repr__(self):
- return '<Relocation (%s): %s>' % (
- 'RELA' if self.is_RELA() else 'REL',
- self.entry)
-
- def __str__(self):
- return self.__repr__()
-
#print topdie
dinfo_sec = efile.get_section_by_name('.debug_info')
-relman = DWARFRelocationManager(efile, dinfo_sec.name, dinfo_sec['sh_offset'])
+relman = DWARFRelocationManager(efile, dinfo_sec.name)
print relman._reloc_section.name, relman._reloc_section['sh_offset']
pprint.pprint(relman._relocs)