From dcc349f0456146734acf505a526b5a3e0e2b46de Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Fri, 9 Dec 2011 11:07:04 +0200 Subject: [PATCH] Pass configuration from ELFFile to DWARFInfo via a DwarfConfig object. Also change the way ELFFile exposes the machine architecture gathered from the header --- elftools/dwarf/dwarfinfo.py | 37 +++++++++++++++++++++--------------- elftools/elf/descriptions.py | 5 +++-- elftools/elf/elffile.py | 18 +++++++++++------- elftools/elf/relocation.py | 4 ++-- 4 files changed, 38 insertions(+), 26 deletions(-) diff --git a/elftools/dwarf/dwarfinfo.py b/elftools/dwarf/dwarfinfo.py index 2201dd2..e0c9fd0 100644 --- a/elftools/dwarf/dwarfinfo.py +++ b/elftools/dwarf/dwarfinfo.py @@ -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) diff --git a/elftools/elf/descriptions.py b/elftools/elf/descriptions.py index b7e87ab..fa630de 100644 --- a/elftools/elf/descriptions.py +++ b/elftools/elf/descriptions.py @@ -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) diff --git a/elftools/elf/elffile.py b/elftools/elf/elffile.py index 065c06d..0e3530d 100644 --- a/elftools/elf/elffile.py +++ b/elftools/elf/elffile.py @@ -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 '' #-------------------------------- PRIVATE --------------------------------# diff --git a/elftools/elf/relocation.py b/elftools/elf/relocation.py index b00c72d..cc90032 100644 --- a/elftools/elf/relocation.py +++ b/elftools/elf/relocation.py @@ -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) -- 2.30.2