e_machine-dependent p_type parsing;
authorEli Bendersky <eliben@gmail.com>
Mon, 15 Jan 2018 22:31:31 +0000 (14:31 -0800)
committerEli Bendersky <eliben@gmail.com>
Mon, 15 Jan 2018 22:31:31 +0000 (14:31 -0800)
This should address #71 and #121, hopefully

elftools/elf/descriptions.py
elftools/elf/enums.py
elftools/elf/structs.py

index d197c1400468438f25c5294847e295387f1d8dc4..79c7d603c203e50b7a9ca548d3fd9d333033495e 100644 (file)
@@ -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
 
index d8b6e1d775cff698b6d80a7076fc97e0ed7910b5..48ef99aee0f905baf1e0d1f6d87061c5864aa7f5 100644 (file)
@@ -268,6 +268,11 @@ ENUM_E_MACHINE = dict(
 )
 
 # 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 @@ ENUM_SH_TYPE_BASE = dict(
     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 @@ ENUM_ELFCOMPRESS_TYPE = dict(
 
 # 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 @@ ENUM_P_TYPE = dict(
     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,
index 62c27f00638efd8ecb96335f8fbe7c4140e1b4ab..28624547d5f065d284d79b8ee8074f1a479dcd47 100644 (file)
@@ -76,7 +76,7 @@ class ELFStructs(object):
         """ 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 @@ class ELFStructs(object):
     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 @@ class ELFStructs(object):
             )
         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'),