From a70ccd3e163d2ee04bed68212654f8843b90300d Mon Sep 17 00:00:00 2001 From: Pierre-Marie de Rodat Date: Tue, 10 Mar 2020 14:12:11 +0100 Subject: [PATCH] callframe.py: fix DW_EH_PE_absptr decoding (#295) * Handle type2/type3 relocation fields for ELF64 MIPS binaries * dwarf/callframe.py: fix field read using the DW_EH_PE_absptr encoding This encoding represents target addresses, so it is the virtual address space determines its size, not the DWARF format. Fixes #288 --- elftools/dwarf/callframe.py | 4 +- elftools/elf/structs.py | 66 ++++++++++++++----- scripts/readelf.py | 66 +++++++++++-------- test/testfiles_for_readelf/angr-eh_frame.elf | Bin 0 -> 69216 bytes 4 files changed, 88 insertions(+), 48 deletions(-) create mode 100644 test/testfiles_for_readelf/angr-eh_frame.elf diff --git a/elftools/dwarf/callframe.py b/elftools/dwarf/callframe.py index 46116ca..101c2d6 100644 --- a/elftools/dwarf/callframe.py +++ b/elftools/dwarf/callframe.py @@ -375,9 +375,7 @@ class CallFrameInfo(object): """ return { DW_EH_encoding_flags['DW_EH_PE_absptr']: - entry_structs.Dwarf_uint32 - if entry_structs.dwarf_format == 32 else - entry_structs.Dwarf_uint64, + entry_structs.Dwarf_target_addr, DW_EH_encoding_flags['DW_EH_PE_uleb128']: entry_structs.Dwarf_uleb128, DW_EH_encoding_flags['DW_EH_PE_udata2']: diff --git a/elftools/elf/structs.py b/elftools/elf/structs.py index 67ff1f5..6fc05da 100644 --- a/elftools/elf/structs.py +++ b/elftools/elf/structs.py @@ -215,31 +215,61 @@ class ELFStructs(object): self.Elf_Chdr = Struct('Elf_Chdr', *fields) def _create_rel(self): - # r_info is also taken apart into r_info_sym and r_info_type. - # This is done in Value to avoid endianity issues while parsing. + r_info = self.Elf_xword('r_info') + + # r_info is also taken apart into r_info_sym and r_info_type, plus + # r_info_type2 and r_info_type3 on ELF64 MIPS. This is done in Value + # to avoid endianity issues while parsing. if self.elfclass == 32: - r_info_sym = Value('r_info_sym', - lambda ctx: (ctx['r_info'] >> 8) & 0xFFFFFF) - r_info_type = Value('r_info_type', - lambda ctx: ctx['r_info'] & 0xFF) - else: # 64 - r_info_sym = Value('r_info_sym', - lambda ctx: (ctx['r_info'] >> 32) & 0xFFFFFFFF) - r_info_type = Value('r_info_type', - lambda ctx: ctx['r_info'] & 0xFFFFFFFF) + fields = [Value('r_info_sym', + lambda ctx: (ctx['r_info'] >> 8) & 0xFFFFFF), + Value('r_info_type', + lambda ctx: ctx['r_info'] & 0xFF)] + elif self.e_machine == 'EM_MIPS': # ELF64 MIPS + # The r_info field in MIPS ELF64 binaries (called r_raw_info, here) + # isn't a 64-bit field, but rather two 32-bit fields (the symbol + # index, then three bytes for relocation types). See the + # specification: + # + # Note that the specification describes the fields more directly, + # but here we stick to the general "r_info" field to be compatible + # with other architectures and simplify testing. + + def compute_r_info(ctx): + raw = ctx['r_raw_info'] + return (((raw & 0xffffffff) << 32) + | ((raw >> 56) & 0xff) + | ((raw >> 40) & 0xff00) + | ((raw >> 24) & 0xff0000) + | ((raw >> 8) & 0xff000000)) + + r_info = self.Elf_xword('r_raw_info') + fields = [ + Value('r_info', compute_r_info), + Value('r_info_sym', + lambda ctx: (ctx['r_info'] >> 32) & 0xFFFFFFFF), + Value('r_info_type3', + lambda ctx: (ctx['r_info'] >> 16) & 0xFF), + Value('r_info_type2', + lambda ctx: (ctx['r_info'] >> 8) & 0xFF), + Value('r_info_type', + lambda ctx: ctx['r_info'] & 0xFF) + ] + else: # Other 64 ELFs + fields = [Value('r_info_sym', + lambda ctx: (ctx['r_info'] >> 32) & 0xFFFFFFFF), + Value('r_info_type', + lambda ctx: ctx['r_info'] & 0xFFFFFFFF)] self.Elf_Rel = Struct('Elf_Rel', self.Elf_addr('r_offset'), - self.Elf_xword('r_info'), - r_info_sym, - r_info_type, + r_info, + *fields ) self.Elf_Rela = Struct('Elf_Rela', self.Elf_addr('r_offset'), - self.Elf_xword('r_info'), - r_info_sym, - r_info_type, - self.Elf_sxword('r_addend'), + r_info, + *(fields + [self.Elf_sxword('r_addend')]) ) def _create_dyn(self): diff --git a/scripts/readelf.py b/scripts/readelf.py index 2ff229a..46955db 100755 --- a/scripts/readelf.py +++ b/scripts/readelf.py @@ -517,35 +517,47 @@ class ReadElf(object): addend = self._format_hex(rel['r_addend'], lead0x=False) self._emit(' %s %s' % (' ' * fieldsize, addend)) self._emitline() - continue - symbol = symtable.get_symbol(rel['r_info_sym']) - # Some symbols have zero 'st_name', so instead what's used is - # the name of the section they point at. Truncate symbol names - # (excluding version info) to 22 chars, similarly to readelf. - if symbol['st_name'] == 0: - symsec = self.elffile.get_section(symbol['st_shndx']) - symbol_name = symsec.name - version = '' else: - symbol_name = symbol.name - version = self._symbol_version(rel['r_info_sym']) - version = (version['name'] - if version and version['name'] else '') - symbol_name = '%.22s' % symbol_name - if version: - symbol_name += '@' + version - - self._emit(' %s %s' % ( - self._format_hex( - symbol['st_value'], - fullhex=True, lead0x=False), - symbol_name)) - if section.is_RELA(): - self._emit(' %s %x' % ( - '+' if rel['r_addend'] >= 0 else '-', - abs(rel['r_addend']))) - self._emitline() + symbol = symtable.get_symbol(rel['r_info_sym']) + # Some symbols have zero 'st_name', so instead what's used + # is the name of the section they point at. Truncate symbol + # names (excluding version info) to 22 chars, similarly to + # readelf. + if symbol['st_name'] == 0: + symsec = self.elffile.get_section(symbol['st_shndx']) + symbol_name = symsec.name + version = '' + else: + symbol_name = symbol.name + version = self._symbol_version(rel['r_info_sym']) + version = (version['name'] + if version and version['name'] else '') + symbol_name = '%.22s' % symbol_name + if version: + symbol_name += '@' + version + + self._emit(' %s %s' % ( + self._format_hex( + symbol['st_value'], + fullhex=True, lead0x=False), + symbol_name)) + if section.is_RELA(): + self._emit(' %s %x' % ( + '+' if rel['r_addend'] >= 0 else '-', + abs(rel['r_addend']))) + self._emitline() + + # Emit the two additional relocation types for ELF64 MIPS + # binaries. + if (self.elffile.elfclass == 64 and + self.elffile['e_machine'] == 'EM_MIPS'): + for i in (2, 3): + rtype = rel['r_info_type%s' % i] + self._emit(' Type%s: %s' % ( + i, + describe_reloc_type(rtype, self.elffile))) + self._emitline() if not has_relocation_sections: self._emitline('\nThere are no relocations in this file.') diff --git a/test/testfiles_for_readelf/angr-eh_frame.elf b/test/testfiles_for_readelf/angr-eh_frame.elf new file mode 100644 index 0000000000000000000000000000000000000000..f6514ad05a9ff6494f2301c032f8119494a6e7d3 GIT binary patch literal 69216 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
8hz_J`Z~Q(L-=jv_-gMJg z?Djr?zhB3G(&sT$9=y_bL%{D(Z_)PNpC{h=6A_QI;`#GiT Y`Tbm5yt>@h>}&O2Q}%~F2A(GU56u7j`Tzg` literal 0 HcmV?d00001 -- 2.30.2