)
# d_tag
-ENUM_D_TAG = dict(
+ENUM_D_TAG_COMMON = dict(
DT_NULL=0,
DT_NEEDED=1,
DT_PLTRELSZ=2,
DT_PREINIT_ARRAYSZ=33,
DT_NUM=34,
DT_LOOS=0x6000000d,
- DT_SUNW_AUXILIARY=0x6000000d,
- DT_SUNW_RTLDINF=0x6000000e,
- DT_SUNW_FILTER=0x6000000f,
- DT_SUNW_CAP=0x60000010,
- DT_SUNW_SYMTAB=0x60000011,
- DT_SUNW_SYMSZ=0x60000012,
- DT_SUNW_ENCODING=0x60000013,
- DT_SUNW_SORTENT=0x60000013,
- DT_SUNW_SYMSORT=0x60000014,
- DT_SUNW_SYMSORTSZ=0x60000015,
- DT_SUNW_TLSSORT=0x60000016,
- DT_SUNW_TLSSORTSZ=0x60000017,
- DT_SUNW_CAPINFO=0x60000018,
- DT_SUNW_STRPAD=0x60000019,
- DT_SUNW_CAPCHAIN=0x6000001a,
- DT_SUNW_LDMACH=0x6000001b,
- DT_SUNW_CAPCHAINENT=0x6000001d,
- DT_SUNW_CAPCHAINSZ=0x6000001f,
DT_HIOS=0x6ffff000,
DT_LOPROC=0x70000000,
DT_HIPROC=0x7fffffff,
DT_VERDEFNUM=0x6ffffffd,
DT_VERNEED=0x6ffffffe,
DT_VERNEEDNUM=0x6fffffff,
+ DT_AUXILIARY=0x7ffffffd,
+ DT_FILTER=0x7fffffff,
+ _default_=Pass,
+)
+
+# Above are the dynamic tags which are valid always.
+# Below are the dynamic tags which are only valid in certain contexts.
+
+ENUM_D_TAG_SOLARIS = dict(
+ DT_SUNW_AUXILIARY=0x6000000d,
+ DT_SUNW_RTLDINF=0x6000000e,
+ DT_SUNW_FILTER=0x6000000f,
+ DT_SUNW_CAP=0x60000010,
+ DT_SUNW_SYMTAB=0x60000011,
+ DT_SUNW_SYMSZ=0x60000012,
+ DT_SUNW_ENCODING=0x60000013,
+ DT_SUNW_SORTENT=0x60000013,
+ DT_SUNW_SYMSORT=0x60000014,
+ DT_SUNW_SYMSORTSZ=0x60000015,
+ DT_SUNW_TLSSORT=0x60000016,
+ DT_SUNW_TLSSORTSZ=0x60000017,
+ DT_SUNW_CAPINFO=0x60000018,
+ DT_SUNW_STRPAD=0x60000019,
+ DT_SUNW_CAPCHAIN=0x6000001a,
+ DT_SUNW_LDMACH=0x6000001b,
+ DT_SUNW_CAPCHAINENT=0x6000001d,
+ DT_SUNW_CAPCHAINSZ=0x6000001f,
+)
+
+ENUM_D_TAG_MIPS = dict(
DT_MIPS_RLD_VERSION=0x70000001,
DT_MIPS_TIME_STAMP=0x70000002,
DT_MIPS_ICHECKSUM=0x70000003,
DT_MIPS_HIPAGENO=0x70000014,
DT_MIPS_RLD_MAP=0x70000016,
DT_MIPS_RLD_MAP_REL=0x70000035,
- DT_AUXILIARY=0x7ffffffd,
- DT_FILTER=0x7fffffff,
- _default_=Pass,
)
+# Here is the mapping from e_machine enum to the extra dynamic tags which it
+# validates. Solaris is missing from this list because its inclusion is not
+# controlled by e_machine but rather e_ident[EI_OSABI].
+# TODO: add the rest of the machine-specific dynamic tags, not just mips and
+# solaris
+
+ENUMMAP_EXTRA_D_TAG_MACHINE = dict(
+ EM_MIPS=ENUM_D_TAG_MIPS,
+ EM_MIPS_RS3_LE=ENUM_D_TAG_MIPS,
+)
+
+# Here is the full combined mapping from tag name to value
+
+ENUM_D_TAG = dict(ENUM_D_TAG_COMMON)
+ENUM_D_TAG.update(ENUM_D_TAG_SOLARIS)
+for k in ENUMMAP_EXTRA_D_TAG_MACHINE:
+ ENUM_D_TAG.update(ENUMMAP_EXTRA_D_TAG_MACHINE[k])
+
ENUM_RELOC_TYPE_MIPS = dict(
R_MIPS_NONE=0,
R_MIPS_16=1,
self._create_leb128()
self._create_ntbs()
- def create_advanced_structs(self, e_type=None, e_machine=None):
+ def create_advanced_structs(self, e_type=None, e_machine=None, e_ident_osabi=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_chdr()
self._create_sym()
self._create_rel()
- self._create_dyn()
+ self._create_dyn(e_machine, e_ident_osabi)
self._create_sunw_syminfo()
self._create_gnu_verneed()
self._create_gnu_verdef()
self.Elf_sxword('r_addend'),
)
- def _create_dyn(self):
+ def _create_dyn(self, e_machine=None, e_ident_osabi=None):
+ d_tag_dict = dict(ENUM_D_TAG_COMMON)
+ if e_machine in ENUMMAP_EXTRA_D_TAG_MACHINE:
+ d_tag_dict.update(ENUMMAP_EXTRA_D_TAG_MACHINE[e_machine])
+ elif e_ident_osabi == 'ELFOSABI_SOLARIS':
+ d_tag_dict.update(ENUM_D_TAG_SOLARIS)
+
self.Elf_Dyn = Struct('Elf_Dyn',
- Enum(self.Elf_sxword('d_tag'), **ENUM_D_TAG),
+ Enum(self.Elf_sxword('d_tag'), **d_tag_dict),
self.Elf_xword('d_val'),
Value('d_ptr', lambda ctx: ctx['d_val']),
)
exp = [b'', b'__libc_start_main', b'__gmon_start__', b'abort']
self.assertEqual(symbol_names, exp)
+ def test_sunw_tags(self):
+ def extract_sunw(filename):
+ with open(filename, 'rb') as f:
+ elf = ELFFile(f)
+ dyn = elf.get_section_by_name('.dynamic')
+
+ seen = set()
+ for tag in dyn.iter_tags():
+ if type(tag.entry.d_tag) is str and \
+ tag.entry.d_tag.startswith("DT_SUNW"):
+ seen.add(tag.entry.d_tag)
+
+ return seen
+
+ f1 = extract_sunw(os.path.join('test', 'testfiles_for_unittests',
+ 'exe_solaris32_cc.sparc.elf'))
+ f2 = extract_sunw(os.path.join('test', 'testfiles_for_unittests',
+ 'android_dyntags.elf'))
+ self.assertEqual(f1, {'DT_SUNW_STRPAD', 'DT_SUNW_LDMACH'})
+ self.assertEqual(f2, set())
if __name__ == '__main__':
unittest.main()