Pass configuration from ELFFile to DWARFInfo via a DwarfConfig object.
authorEli Bendersky <eliben@gmail.com>
Fri, 9 Dec 2011 09:07:04 +0000 (11:07 +0200)
committerEli Bendersky <eliben@gmail.com>
Fri, 9 Dec 2011 09:07:04 +0000 (11:07 +0200)
Also change the way ELFFile exposes the machine architecture gathered from the header

elftools/dwarf/dwarfinfo.py
elftools/elf/descriptions.py
elftools/elf/elffile.py
elftools/elf/relocation.py

index 2201dd2d48352e26e72fe8064b6683f26971f607..e0c9fd053b993de0189095e8b4070b3111070cf9 100644 (file)
@@ -25,7 +25,21 @@ from .lineprogram import LineProgram
 # size: the size of the section's data, in bytes
 #
 DebugSectionDescriptor = namedtuple('DebugSectionDescriptor', 
-        'stream name global_offset size')
+    'stream name global_offset size')
+
+
+# Some configuration parameters for the DWARF reader. This exists to allow
+# DWARFInfo to be independent from any specific file format/container.
+#
+# little_endian:
+#   boolean flag specifying whether the data in the file is little endian.
+#
+# machine_arch:
+#   Machine architecture as a string. For example 'x86' or 'x64'
+#               
+#
+DwarfConfig = namedtuple('DwarfConfig',
+    'little_endian machine_arch')
 
 
 class DWARFInfo(object):
@@ -33,35 +47,28 @@ class DWARFInfo(object):
         various parts of the debug infromation.
     """
     def __init__(self,
-            elffile,
+            config,
             debug_info_sec,
             debug_abbrev_sec,
             debug_str_sec,
             debug_line_sec):
-        """ elffile:
-                ELFFile reference. Note that the whole DWARF processing code is
-                decoupled from the container file. This ELFFile object is just
-                used to obtain some attributes of the data, such as endianness.
-                If desired, DWARFInfo can be created without an actual ELFFile,
-                by passing a "mock" object that only provides the required
-                attributes.
+        """ config:
+                A DwarfConfig object
 
             debug_*_sec:
                 DebugSectionDescriptor for a section
         """
-        self.elffile = elffile
+        self.config = config
         self.debug_info_sec = debug_info_sec
         self.debug_abbrev_sec = debug_abbrev_sec
         self.debug_str_sec = debug_str_sec
         self.debug_line_sec = debug_line_sec
-        
-        self.little_endian = self.elffile.little_endian
 
         # This is the DWARFStructs the context uses, so it doesn't depend on 
         # DWARF format and address_size (these are determined per CU) - set them
         # to default values.
         self.structs = DWARFStructs(
-            little_endian=self.little_endian,
+            little_endian=self.config.little_endian,
             dwarf_format=32,
             address_size=4)
         
@@ -147,7 +154,7 @@ class DWARFInfo(object):
             # object for this CU.
             #
             cu_structs = DWARFStructs(
-                little_endian=self.little_endian,
+                little_endian=self.config.little_endian,
                 dwarf_format=dwarf_format,
                 address_size=4)
             
@@ -155,7 +162,7 @@ class DWARFInfo(object):
                 cu_structs.Dwarf_CU_header, self.debug_info_sec.stream, offset)
             if cu_header['address_size'] == 8:
                 cu_structs = DWARFStructs(
-                    little_endian=self.little_endian,
+                    little_endian=self.config.little_endian,
                     dwarf_format=dwarf_format,
                      address_size=8)
             
index b7e87abf0efc1445c2eb575de29f24d46fbc2699..fa630de90420e0dd649931ae13577e69efd4f65d 100644 (file)
@@ -69,9 +69,10 @@ def describe_symbol_shndx(x):
     return _DESCR_ST_SHNDX.get(x, '%3s' % x)
 
 def describe_reloc_type(x, elffile):
-    if elffile.architecture_is_x86():
+    arch = elffile.get_machine_arch()
+    if arch == 'x86':
         return _DESCR_RELOC_TYPE_i386.get(x, _unknown)
-    elif elffile.architecture_is_x64():
+    elif arch == 'x64':
         return _DESCR_RELOC_TYPE_x64.get(x, _unknown)
     else:
         return 'unrecognized: %-7x' % (x & 0xFFFFFFFF)
index 065c06d35abdc24d07aa84526bf85a75121bb3a5..0e3530d8febf3e734c154e89d5b04d9def8716b5 100644 (file)
@@ -16,7 +16,7 @@ from .sections import (
 from .relocation import RelocationSection, RelocationHandler
 from .segments import Segment, InterpSegment
 from .enums import ENUM_RELOC_TYPE_i386, ENUM_RELOC_TYPE_x64
-from ..dwarf.dwarfinfo import DWARFInfo, DebugSectionDescriptor
+from ..dwarf.dwarfinfo import DWARFInfo, DebugSectionDescriptor, DwarfConfig
 
 
 class ELFFile(object):
@@ -133,17 +133,21 @@ class ELFFile(object):
                     relocate_dwarf_sections)
         
         return DWARFInfo(
-                elffile=self,
+                config=DwarfConfig(
+                    little_endian=self.little_endian,
+                    machine_arch=self.get_machine_arch()),
                 debug_info_sec=debug_sections['.debug_info'],
                 debug_abbrev_sec=debug_sections['.debug_abbrev'],
                 debug_str_sec=debug_sections['.debug_str'],
                 debug_line_sec=debug_sections['.debug_line'])                
-            
-    def architecture_is_x86(self):
-        return self['e_machine'] in ('EM_386', 'EM_486')
 
-    def architecture_is_x64(self):
-        return self['e_machine'] == 'EM_X86_64'
+    def get_machine_arch(self):
+        if self['e_machine'] == 'EM_X86_64':
+            return 'x64'
+        elif self['e_machine'] in ('EM_386', 'EM_486'):
+            return 'x86'
+        else:
+            return '<unknown>'
         
     #-------------------------------- PRIVATE --------------------------------#
     
index b00c72d82e2e51f57794566c913e0255866549d0..cc9003229e3cfd8869b0893ffa3356e69f6341c1 100644 (file)
@@ -135,12 +135,12 @@ class RelocationHandler(object):
         reloc_type = reloc['r_info_type']
         recipe = None
 
-        if self.elffile.architecture_is_x86():
+        if self.elffile.get_machine_arch() == 'x86':
             if reloc.is_RELA():
                 raise ELFRelocationError(
                     'Unexpected RELA relocation for x86: %s' % reloc)
             recipe = self._RELOCATION_RECIPES_X86.get(reloc_type, None)
-        elif self.elffile.architecture_is_x64():
+        elif self.elffile.get_machine_arch() == 'x64':
             if not reloc.is_RELA():
                 raise ELFRelocationError(
                     'Unexpected REL relocation for x64: %s' % reloc)