From 84066b23aceee0393696c1311f5b147ef4335972 Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Tue, 20 Sep 2011 06:48:52 +0300 Subject: [PATCH] some more work towards relocations --- elftools/elf/sections.py | 39 +++++++++++++++++++++++++++++++++++++++ scripts/readelf.py | 24 +++++++++++++++++++++++- 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/elftools/elf/sections.py b/elftools/elf/sections.py index 1655ea9..59c85b7 100644 --- a/elftools/elf/sections.py +++ b/elftools/elf/sections.py @@ -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] + + diff --git a/scripts/readelf.py b/scripts/readelf.py index 4554ab0..eb2c550 100755 --- a/scripts/readelf.py +++ b/scripts/readelf.py @@ -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='', help='Dump the contents of section 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: -- 2.30.2