# 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)
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
)
# 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,
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,
# 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,
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,
""" 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()
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'),
)
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'),