From 73716604dcd617f77ea39f20b32189ca6dc395e5 Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Mon, 15 Jan 2018 14:31:31 -0800 Subject: [PATCH] e_machine-dependent p_type parsing; This should address #71 and #121, hopefully --- elftools/elf/descriptions.py | 6 +++--- elftools/elf/enums.py | 42 +++++++++++++++++++++++++++--------- elftools/elf/structs.py | 16 ++++++++++---- 3 files changed, 47 insertions(+), 17 deletions(-) diff --git a/elftools/elf/descriptions.py b/elftools/elf/descriptions.py index d197c140..79c7d603 100644 --- a/elftools/elf/descriptions.py +++ b/elftools/elf/descriptions.py @@ -7,7 +7,7 @@ # This code is in the public domain #------------------------------------------------------------------------------- from .enums import ( - ENUM_D_TAG, ENUM_E_VERSION, ENUM_P_TYPE, ENUM_SH_TYPE_BASE, + ENUM_D_TAG, ENUM_E_VERSION, ENUM_P_TYPE_BASE, ENUM_SH_TYPE_BASE, ENUM_RELOC_TYPE_i386, ENUM_RELOC_TYPE_x64, ENUM_RELOC_TYPE_ARM, ENUM_RELOC_TYPE_AARCH64, ENUM_RELOC_TYPE_MIPS, ENUM_ATTR_TAG_ARM) @@ -49,8 +49,8 @@ def describe_e_version_numeric(x): def describe_p_type(x): if x in _DESCR_P_TYPE: return _DESCR_P_TYPE.get(x) - elif x >= ENUM_P_TYPE['PT_LOOS'] and x <= ENUM_P_TYPE['PT_HIOS']: - return 'LOOS+%lx' % (x - ENUM_P_TYPE['PT_LOOS']) + elif x >= ENUM_P_TYPE_BASE['PT_LOOS'] and x <= ENUM_P_TYPE_BASE['PT_HIOS']: + return 'LOOS+%lx' % (x - ENUM_P_TYPE_BASE['PT_LOOS']) else: return _unknown diff --git a/elftools/elf/enums.py b/elftools/elf/enums.py index d8b6e1d7..48ef99ae 100644 --- a/elftools/elf/enums.py +++ b/elftools/elf/enums.py @@ -268,6 +268,11 @@ ) # sh_type in the section header +# +# This is the "base" dict that doesn't hold processor-specific values; from it +# we later create per-processor dicts that use the LOPROC...HIPROC range to +# define processor-specific values. The proper dict should be used based on the +# machine the ELF header refers to. ENUM_SH_TYPE_BASE = dict( SHT_NULL=0, SHT_PROGBITS=1, @@ -295,8 +300,8 @@ SHT_GNU_verneed=0x6ffffffe, # also SHT_SUNW_verneed SHT_GNU_versym=0x6fffffff, # also SHT_SUNW_versym, SHT_HIOS - # These are commented out because they carry no semantic meaning in themselves and - # may be overridden by target-specific enums. + # These are commented out because they carry no semantic meaning in + # themselves and may be overridden by target-specific enums. #SHT_LOPROC=0x70000000, #SHT_HIPROC=0x7fffffff, @@ -369,7 +374,9 @@ # p_type in the program header # some values scavenged from the ELF headers in binutils-2.21 -ENUM_P_TYPE = dict( +# +# Using the same base + per-processor augmentation technique as in sh_type. +ENUM_P_TYPE_BASE = dict( PT_NULL=0, PT_LOAD=1, PT_DYNAMIC=2, @@ -380,19 +387,34 @@ PT_TLS=7, PT_LOOS=0x60000000, PT_HIOS=0x6fffffff, - PT_LOPROC=0x70000000, - PT_HIPROC=0x7fffffff, + + # These are commented out because they carry no semantic meaning in + # themselves and may be overridden by target-specific enums. + #PT_LOPROC=0x70000000, + #PT_HIPROC=0x7fffffff, + PT_GNU_EH_FRAME=0x6474e550, PT_GNU_STACK=0x6474e551, PT_GNU_RELRO=0x6474e552, - PT_ARM_ARCHEXT=0x70000000, - PT_ARM_EXIDX=0x70000001, - PT_AARCH64_ARCHEXT=0x70000000, - PT_AARCH64_UNWIND=0x70000001, - PT_MIPS_ABIFLAGS=0x70000003, _default_=Pass, ) +ENUM_P_TYPE_ARM = merge_dicts( + ENUM_P_TYPE_BASE, + dict( + PT_ARM_ARCHEXT=0x70000000, + PT_ARM_EXIDX=0x70000001)) + +ENUM_P_TYPE_AARCH64 = merge_dicts( + ENUM_P_TYPE_BASE, + dict( + PT_AARCH64_ARCHEXT=0x70000000, + PT_AARCH64_UNWIND=0x70000001)) + +ENUM_P_TYPE_MIPS = merge_dicts( + ENUM_P_TYPE_BASE, + dict(PT_MIPS_ABIFLAGS=0x70000003)) + # st_info bindings in the symbol header ENUM_ST_INFO_BIND = dict( STB_LOCAL=0, diff --git a/elftools/elf/structs.py b/elftools/elf/structs.py index 62c27f00..28624547 100644 --- a/elftools/elf/structs.py +++ b/elftools/elf/structs.py @@ -76,7 +76,7 @@ def create_advanced_structs(self, e_type=None, e_machine=None): """ Create all ELF structs except the ehdr. They may possibly depend on provided e_type and/or e_machine parsed from ehdr. """ - self._create_phdr() + self._create_phdr(e_machine) self._create_shdr(e_machine) self._create_chdr() self._create_sym() @@ -125,10 +125,18 @@ def _create_leb128(self): def _create_ntbs(self): self.Elf_ntbs = CString - def _create_phdr(self): + def _create_phdr(self, e_machine=None): + p_type_dict = ENUM_P_TYPE_BASE + if e_machine == 'EM_ARM': + p_type_dict = ENUM_P_TYPE_ARM + elif e_machine == 'EM_AARCH64': + p_type_dict = ENUM_P_TYPE_AARCH64 + elif e_machine == 'EM_MIPS': + p_type_dict = ENUM_P_TYPE_MIPS + if self.elfclass == 32: self.Elf_Phdr = Struct('Elf_Phdr', - Enum(self.Elf_word('p_type'), **ENUM_P_TYPE), + Enum(self.Elf_word('p_type'), **p_type_dict), self.Elf_offset('p_offset'), self.Elf_addr('p_vaddr'), self.Elf_addr('p_paddr'), @@ -139,7 +147,7 @@ def _create_phdr(self): ) else: # 64 self.Elf_Phdr = Struct('Elf_Phdr', - Enum(self.Elf_word('p_type'), **ENUM_P_TYPE), + Enum(self.Elf_word('p_type'), **p_type_dict), self.Elf_word('p_flags'), self.Elf_offset('p_offset'), self.Elf_addr('p_vaddr'),