From: Eli Bendersky Date: Mon, 19 Sep 2011 03:51:52 +0000 (+0300) Subject: partial support for parsing relocation sections X-Git-Tag: v0.10~111 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f29751e0cbd9d07908a17e98902d396b1900ab55;p=pyelftools.git partial support for parsing relocation sections --- diff --git a/elftools/elf/elffile.py b/elftools/elf/elffile.py index 2999cc1..2c00fb5 100644 --- a/elftools/elf/elffile.py +++ b/elftools/elf/elffile.py @@ -11,7 +11,8 @@ from ..common.utils import struct_parse, elf_assert from ..construct import ConstructError from .structs import ELFStructs from .sections import ( - Section, StringTableSection, SymbolTableSection, NullSection) + Section, StringTableSection, SymbolTableSection, NullSection, + RelocationSection) from .segments import Segment, InterpSegment @@ -158,6 +159,9 @@ class ELFFile(object): return NullSection(section_header, name, self.stream) elif sectype in ('SHT_SYMTAB', 'SHT_DYNSYM'): 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) else: return Section(section_header, name, self.stream) diff --git a/elftools/elf/sections.py b/elftools/elf/sections.py index f9dd149..1655ea9 100644 --- a/elftools/elf/sections.py +++ b/elftools/elf/sections.py @@ -104,6 +104,22 @@ class SymbolTableSection(Section): yield self.get_symbol(i) +class RelocationSection(Section): + def __init__(self, header, name, stream, elfstructs): + super(RelocationSection, self).__init__(header, name, stream) + self.elfstructs = elfstructs + if self.header['sh_type'] == 'SHT_REL': + expected_size = self.elfstructs.Elf_Rel.sizeof() + elif self.header['sh_type'] == 'SHT_RELA': + expected_size = self.elfstructs.Elf_Rela.sizeof() + else: + elf_assert(False, 'Unknown relocation type section') + + elf_assert( + self.header['sh_entsize'] == expected_size, + 'Expected sh_entsize of SHT_REL section to be %s' % expected_size) + + class Symbol(object): """ Symbol object - representing a single symbol entry from a symbol table section. diff --git a/elftools/elf/structs.py b/elftools/elf/structs.py index ae084d2..8105206 100644 --- a/elftools/elf/structs.py +++ b/elftools/elf/structs.py @@ -35,6 +35,9 @@ class ELFStructs(object): Elf_Sym: Symbol table entry + + Elf_Rel, Elf_Rela: + Entries in relocation sections """ def __init__(self, little_endian=True, elfclass=32): assert elfclass == 32 or elfclass == 64 @@ -66,6 +69,7 @@ class ELFStructs(object): self._create_phdr() self._create_shdr() self._create_sym() + self._create_rel() def _create_ehdr(self): self.Elf_Ehdr = Struct('Elf_Ehdr', @@ -105,7 +109,7 @@ class ELFStructs(object): self.Elf_word('p_flags'), self.Elf_word('p_align'), ) - else: + else: # 64 self.Elf_Phdr = Struct('Elf_Phdr', Enum(self.Elf_word('p_type'), **ENUM_P_TYPE), self.Elf_word('p_flags'), @@ -131,6 +135,29 @@ class ELFStructs(object): self.Elf_xword('sh_entsize'), ) + def _create_rel(self): + # r_info is hierarchical. To access the type, use + # container['r_info']['type'] + if self.elfclass == 32: + r_info_struct = BitStruct('r_info', + BitField('sym', 24), + BitField('type', 8)) + else: # 64 + r_info_struct = BitStruct('r_info', + BitField('sym', 32), + Padding(24), + BitField('type', 8)) + + self.Elf_Rel = Struct('Elf_Rel', + self.Elf_addr('r_offset'), + r_info_struct, + ) + self.Elf_Rela = Struct('Elf_Rela', + self.Elf_addr('r_offset'), + r_info_struct, + self.Elf_sxword('r_addend'), + ) + def _create_sym(self): # st_info is hierarchical. To access the type, use # container['st_info']['type'] diff --git a/tests/run_tests.py b/tests/run_tests.py index ccc459e..24f4015 100755 --- a/tests/run_tests.py +++ b/tests/run_tests.py @@ -61,7 +61,7 @@ def run_test_on_file(filename): rc, stdout = run_exe(exe_path, args) if rc != 0: testlog.error("@@ aborting - '%s' returned '%s'" % (exe_path, rc)) - break + return False stdouts.append(stdout) testlog.info('....comparing output...') success, errmsg = compare_output(*stdouts)