partial support for parsing relocation sections
authorEli Bendersky <eliben@gmail.com>
Mon, 19 Sep 2011 03:51:52 +0000 (06:51 +0300)
committerEli Bendersky <eliben@gmail.com>
Mon, 19 Sep 2011 03:51:52 +0000 (06:51 +0300)
elftools/elf/elffile.py
elftools/elf/sections.py
elftools/elf/structs.py
tests/run_tests.py

index 2999cc1e412cc7a63410c96770caf739f4ec39ee..2c00fb5839662cb76581b85e7cb2292152c1901b 100644 (file)
@@ -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)
 
index f9dd149f01d91d463dbb780e944f1314a3816756..1655ea90186a9530bb16f705f9f336cfec66256b 100644 (file)
@@ -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.
index ae084d28ddf7f76e93fedc777a6b072b8171fe34..8105206a93d115d1af6ed2d4f6f05f7f0e1a36b4 100644 (file)
@@ -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']
index ccc459eb0641cf5d0fcbb3435040e30e848da1fb..24f40152814d6fede53bc75e9e6fd7736b18b8c0 100755 (executable)
@@ -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)