some more work towards relocations
authorEli Bendersky <eliben@gmail.com>
Tue, 20 Sep 2011 03:48:52 +0000 (06:48 +0300)
committerEli Bendersky <eliben@gmail.com>
Tue, 20 Sep 2011 03:48:52 +0000 (06:48 +0300)
elftools/elf/sections.py
scripts/readelf.py

index 1655ea90186a9530bb16f705f9f336cfec66256b..59c85b79b363a16b17861a623046af2dc27a88a7 100644 (file)
@@ -110,8 +110,10 @@ class RelocationSection(Section):
         self.elfstructs = elfstructs
         if self.header['sh_type'] == 'SHT_REL':
             expected_size = self.elfstructs.Elf_Rel.sizeof()
+            self.entry_struct = self.elfstructs.Elf_Rel
         elif self.header['sh_type'] == 'SHT_RELA':
             expected_size = self.elfstructs.Elf_Rela.sizeof()
+            self.entry_struct = self.elfstructs.Elf_Rela
         else:
             elf_assert(False, 'Unknown relocation type section')
 
@@ -119,6 +121,27 @@ class RelocationSection(Section):
             self.header['sh_entsize'] == expected_size,
             'Expected sh_entsize of SHT_REL section to be %s' % expected_size)
 
+    def num_relocations(self):
+        """ Number of relocations in the section
+        """
+        return self['sh_size'] // self['sh_entsize']
+        
+    def get_relocation(self, n):
+        """ Get the relocation at index #n from the section (Relocation object)
+        """
+        entry_offset = self['sh_offset'] + n * self['sh_entsize']
+        entry = struct_parse(
+            self.entry_struct,
+            self.stream,
+            stream_pos=entry_offset)
+        return Relocation(entry)
+
+    def iter_relocations(self):
+        """ Yield all the relocations in the section
+        """
+        for i in range(self.num_relocations()):
+            yield self.get_relocation(i)
+
 
 class Symbol(object):
     """ Symbol object - representing a single symbol entry from a symbol table
@@ -136,3 +159,19 @@ class Symbol(object):
         """
         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 __getitem__(self, name):
+        """ Dict-like access to entries
+        """
+        return self.entry[name]
+
+
index 4554ab0988300c5bf43f6dddef65d83299f381ec..eb2c55037590a1eb694139b78b6fe0fba4822a8c 100755 (executable)
@@ -24,7 +24,7 @@ from elftools import __version__
 from elftools.common.exceptions import ELFError
 from elftools.elf.elffile import ELFFile
 from elftools.elf.segments import InterpSegment
-from elftools.elf.sections import SymbolTableSection
+from elftools.elf.sections import SymbolTableSection, RelocationSection
 from elftools.elf.descriptions import (
     describe_ei_class, describe_ei_data, describe_ei_version,
     describe_ei_osabi, describe_e_type, describe_e_machine,
@@ -266,6 +266,23 @@ class ReadElf(object):
                     describe_symbol_shndx(symbol['st_shndx']),
                     symbol.name))
         
+    def display_relocations(self):
+        """ Display the relocations contained in the file
+        """
+        has_relocation_sections = False
+        for section in self.elffile.iter_sections():
+            if not isinstance(section, RelocationSection):
+                continue
+
+            has_relocation_sections = True
+            self._emitline("\nRelocation section '%s' at offset %s contains %s entries:" % (
+                1, 2, 3))
+            for rel in section.iter_relocations():
+                print rel, rel.entry
+
+        if not has_relocation_sections:
+            self._emitline('\nThere are no relocations in this file.')
+        
     def display_hex_dump(self, section_spec):
         """ Display a hex dump of a section. section_spec is either a section
             number or a name.
@@ -428,6 +445,9 @@ def main():
     optparser.add_option('-s', '--symbols', '--syms',
             action='store_true', dest='show_symbols',
             help='Display the symbol table')
+    optparser.add_option('-r', '--relocs',
+            action='store_true', dest='show_relocs',
+            help='Display the relocations (if present)')
     optparser.add_option('-x', '--hex-dump',
             action='store', dest='show_hex_dump', metavar='<number|name>',
             help='Dump the contents of section <number|name> as bytes')
@@ -461,6 +481,8 @@ def main():
                         show_heading=not do_file_header)
             if options.show_symbols:
                 readelf.display_symbol_tables()
+            if options.show_relocs:
+                readelf.display_relocations()
             if options.show_hex_dump:
                 readelf.display_hex_dump(options.show_hex_dump)
             if options.show_string_dump: