# Eli Bendersky (eliben@gmail.com)
# This code is in the public domain
#-------------------------------------------------------------------------------
-from .enums import ENUM_E_VERSION
+from .enums import ENUM_E_VERSION, ENUM_RELOC_TYPE_i386, ENUM_RELOC_TYPE_x64
from .constants import P_FLAGS, SH_FLAGS
def describe_ei_class(x):
- return _DESCR_EI_CLASS.get(x, _unknown())
+ return _DESCR_EI_CLASS.get(x, _unknown)
def describe_ei_data(x):
- return _DESCR_EI_DATA.get(x, _unknown())
+ return _DESCR_EI_DATA.get(x, _unknown)
def describe_ei_version(x):
s = '%d' % ENUM_E_VERSION[x]
return s
def describe_ei_osabi(x):
- return _DESCR_EI_OSABI.get(x, _unknown())
+ return _DESCR_EI_OSABI.get(x, _unknown)
def describe_e_type(x):
- return _DESCR_E_TYPE.get(x, _unknown())
+ return _DESCR_E_TYPE.get(x, _unknown)
def describe_e_machine(x):
- return _DESCR_E_MACHINE.get(x, _unknown())
+ return _DESCR_E_MACHINE.get(x, _unknown)
def describe_e_version_numeric(x):
return '0x%x' % ENUM_E_VERSION[x]
def describe_p_type(x):
- return _DESCR_P_TYPE.get(x, _unknown())
+ return _DESCR_P_TYPE.get(x, _unknown)
def describe_p_flags(x):
s = ''
return s
def describe_sh_type(x):
- return _DESCR_SH_TYPE.get(x, _unknown())
+ return _DESCR_SH_TYPE.get(x, _unknown)
def describe_sh_flags(x):
s = ''
return s
def describe_symbol_type(x):
- return _DESCR_ST_INFO_TYPE.get(x, _unknown())
+ return _DESCR_ST_INFO_TYPE.get(x, _unknown)
def describe_symbol_bind(x):
- return _DESCR_ST_INFO_BIND.get(x, _unknown())
+ return _DESCR_ST_INFO_BIND.get(x, _unknown)
def describe_symbol_visibility(x):
- return _DESCR_ST_VISIBILITY.get(x, _unknown())
+ return _DESCR_ST_VISIBILITY.get(x, _unknown)
def describe_symbol_shndx(x):
return _DESCR_ST_SHNDX.get(x, '%3s' % x)
+def describe_reloc_type(x, e_machine):
+ if e_machine in ('EM_386', 'EM_486'):
+ return _DESCR_RELOC_TYPE_i386.get(x, _unknown)
+ elif e_machine in ('EM_X86_64', 'EM_L10M'):
+ return _DESCR_RELOC_TYPE_x64.get(x, _unknown)
+ else:
+ return 'unrecognized: %-7x' % (x & 0xFFFFFFFF)
+
#-------------------------------------------------------------------------------
-def _unknown():
- return '<unknown>'
+_unknown = '<unknown>'
_DESCR_EI_CLASS = dict(
SHN_COMMON='COM',
)
+_DESCR_RELOC_TYPE_i386 = dict(
+ (v, k) for k, v in ENUM_RELOC_TYPE_i386.iteritems())
+
+_DESCR_RELOC_TYPE_x64 = dict(
+ (v, k) for k, v in ENUM_RELOC_TYPE_x64.iteritems())
+
EM_386=3,
EM_68K=4,
EM_88K=5,
+ EM_486=6,
EM_860=7,
EM_MIPS=8,
EM_S370=9,
EM_IA_64=50,
EM_X86_64=62,
EM_AVR=83,
+ EM_L10M=180,
_default_=Pass,
)
_default_=Pass,
)
+ENUM_RELOC_TYPE_i386 = dict(
+ R_386_NONE=0,
+ R_386_32=1,
+ R_386_PC32=2,
+ R_386_GOT32=3,
+ R_386_PLT32=4,
+ R_386_COPY=5,
+ R_386_GLOB_DAT=6,
+ R_386_JUMP_SLOT=7,
+ R_386_RELATIVE=8,
+ R_386_GOTOFF=9,
+ R_386_GOTPC=10,
+ R_386_32PLT=11,
+ R_386_TLS_TPOFF=14,
+ R_386_TLS_IE=15,
+ R_386_TLS_GOTIE=16,
+ R_386_TLS_LE=17,
+ R_386_TLS_GD=18,
+ R_386_TLS_LDM=19,
+ R_386_16=20,
+ R_386_PC16=21,
+ R_386_8=22,
+ R_386_PC8=23,
+ R_386_TLS_GD_32=24,
+ R_386_TLS_GD_PUSH=25,
+ R_386_TLS_GD_CALL=26,
+ R_386_TLS_GD_POP=27,
+ R_386_TLS_LDM_32=28,
+ R_386_TLS_LDM_PUSH=29,
+ R_386_TLS_LDM_CALL=30,
+ R_386_TLS_LDM_POP=31,
+ R_386_TLS_LDO_32=32,
+ R_386_TLS_IE_32=33,
+ R_386_TLS_LE_32=34,
+ R_386_TLS_DTPMOD32=35,
+ R_386_TLS_DTPOFF32=36,
+ R_386_TLS_TPOFF32=37,
+ R_386_TLS_GOTDESC=39,
+ R_386_TLS_DESC_CALL=40,
+ R_386_TLS_DESC=41,
+ R_386_IRELATIVE=42,
+ R_386_USED_BY_INTEL_200=200,
+ R_386_GNU_VTINHERIT=250,
+ R_386_GNU_VTENTRY=251,
+ _default_=Pass,
+)
+
+ENUM_RELOC_TYPE_x64 = dict(
+ R_X86_64_NONE=0,
+ R_X86_64_64=1,
+ R_X86_64_PC32=2,
+ R_X86_64_GOT32=3,
+ R_X86_64_PLT32=4,
+ R_X86_64_COPY=5,
+ R_X86_64_GLOB_DAT=6,
+ R_X86_64_JUMP_SLOT=7,
+ R_X86_64_RELATIVE=8,
+ R_X86_64_GOTPCREL=9,
+ R_X86_64_32=10,
+ R_X86_64_32S=11,
+ R_X86_64_16=12,
+ R_X86_64_PC16=13,
+ R_X86_64_8=14,
+ R_X86_64_PC8=15,
+ R_X86_64_DTPMOD64=16,
+ R_X86_64_DTPOFF64=17,
+ R_X86_64_TPOFF64=18,
+ R_X86_64_TLSGD=19,
+ R_X86_64_TLSLD=20,
+ R_X86_64_DTPOFF32=21,
+ R_X86_64_GOTTPOFF=22,
+ R_X86_64_TPOFF32=23,
+ R_X86_64_PC64=24,
+ R_X86_64_GOTOFF64=25,
+ R_X86_64_GOTPC32=26,
+ R_X86_64_GOT64=27,
+ R_X86_64_GOTPCREL64=28,
+ R_X86_64_GOTPC64=29,
+ R_X86_64_GOTPLT64=30,
+ R_X86_64_PLTOFF64=31,
+ R_X86_64_GOTPC32_TLSDESC=34,
+ R_X86_64_TLSDESC_CALL=35,
+ R_X86_64_TLSDESC=36,
+ R_X86_64_IRELATIVE=37,
+ R_X86_64_GNU_VTINHERIT=250,
+ R_X86_64_GNU_VTENTRY=251,
+ _default_=Pass,
+)
+
self.header['sh_entsize'] == expected_size,
'Expected sh_entsize of SHT_REL section to be %s' % expected_size)
+ def is_RELA(self):
+ """ Is this a RELA relocation section? If not, it's REL.
+ """
+ return self.header['sh_type'] == 'SHT_RELA'
+
def num_relocations(self):
""" Number of relocations in the section
"""
def __init__(self, entry):
self.entry = entry
+ def is_RELA(self):
+ """ Is this a RELA relocation? If not, it's REL.
+ """
+ return 'r_addend' in self.entry
+
def __getitem__(self, name):
""" Dict-like access to entries
"""
describe_e_version_numeric, describe_p_type, describe_p_flags,
describe_sh_type, describe_sh_flags,
describe_symbol_type, describe_symbol_bind, describe_symbol_visibility,
- describe_symbol_shndx,
+ describe_symbol_shndx, describe_reloc_type,
)
section.name,
self._format_hex(section['sh_offset']),
section.num_relocations()))
+ if section.is_RELA():
+ self._emitline(" Offset Info Type Sym. Value Sym. Name + Addend")
+ else:
+ self._emitline(" Offset Info Type Sym.Value Sym. Name")
+
+ # The symbol table section pointed to in sh_link
+ symtable = self.elffile.get_section(section['sh_link'])
+
for rel in section.iter_relocations():
- self._emitline('%s %s' % (
- self._format_hex(rel['r_offset'], fullhex=True, lead0x=False),
- self._format_hex(rel['r_info'], fullhex=True, lead0x=False)))
- #print rel, rel.entry
+ hexwidth = 8 if self.elffile.elfclass == 32 else 12
+ symbol = symtable.get_symbol(rel['r_info_sym'])
+ self._emit('%s %s %-17.17s %s %s%s' % (
+ self._format_hex(rel['r_offset'],
+ fieldsize=hexwidth, lead0x=False),
+ self._format_hex(rel['r_info'],
+ fieldsize=hexwidth, lead0x=False),
+ describe_reloc_type(
+ rel['r_info_type'], self.elffile['e_machine']),
+ self._format_hex(
+ symbol['st_value'],
+ fullhex=True, lead0x=False),
+ ' ' if self.elffile.elfclass == 32 else '',
+ symbol.name,
+ ))
+
+ if section.is_RELA():
+ self._emit(' %s %x' % (
+ '+' if rel['r_addend'] >= 0 else '-',
+ abs(rel['r_addend'])))
+ self._emitline()
if not has_relocation_sections:
self._emitline('\nThere are no relocations in this file.')
"""
success = True
testlog.info("Running test on file '%s'" % filename)
- for option in ['-e', '-s', '-x.text', '-p.shstrtab']:
+ for option in ['-e', '-s', '-r', '-x.text', '-p.shstrtab']:
testlog.info("..option='%s'" % option)
# stdouts will be a 2-element list: output of readelf and output
# of scripts/readelf.py