From: Frederik Sdun Date: Mon, 16 Jul 2018 13:22:55 +0000 (+0200) Subject: Handle ARM relocations (#121) X-Git-Tag: v0.25~3 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ab76d5ca08c676fd861aa4f49fa63d89024b72ff;p=pyelftools.git Handle ARM relocations (#121) * relocation: handle ARM binaries * relocation: handle R_ARM_ABS32 for ARM machines * testfiles: add reloc_arm_gcc.o.elf Generated on Ubuntu 14.04 using: arm-linux-gnueabi-gcc-4.7 -c -g -o reloc_armhf_gcc.o.elf hello.c * testfiles: add reloc_armhf_gcc.o.elf Generated on Ubuntu 14.04 using: arm-linux-gnueabihf-gcc-4.7 -c -g -o reloc_armhf_gcc.o.elf hello.c * readelf: print soft-float abi for ARM if EF_ARM_ABI_FLOAT_SOFT in flags * readelf: print hard-float abi for ARM if EF_ARM_ABI_FLOAT_HARD in flags * readelf: print BE8 info for armeb binaries * testfiles: add simple_armhf_gcc.o.elf Generated on Ubuntu 14.04 using: arm-linux-gnueabihf-gcc-4.7 -g -o simple_armhf_gcc.o.elf hello.c * elf: remove unwind from dicts and set ARM_EXIDX description * testfiles: add reloc_armsf_gcc.o.elf as soft float testcase taken from binutils 2.30 * testfiles: add reloc_armeb_gcc.o.elf as arm big endian testcase taken from binutils 2.30 testcase arm-be8 * readelf: print endian info LE8 if flag was set in header flags --- diff --git a/elftools/elf/descriptions.py b/elftools/elf/descriptions.py index b76238a..022b074 100644 --- a/elftools/elf/descriptions.py +++ b/elftools/elf/descriptions.py @@ -319,7 +319,7 @@ _DESCR_SH_TYPE = dict( SHT_GNU_verneed='VERNEED', SHT_GNU_versym='VERSYM', SHT_GNU_LIBLIST='GNU_LIBLIST', - SHT_ARM_EXIDX='EXIDX', # binutils calls this EXIDX, not ARM_EXIDX + SHT_ARM_EXIDX='ARM_EXIDX', SHT_ARM_PREEMPTMAP='ARM_PREEMPTMAP', SHT_ARM_ATTRIBUTES='ARM_ATTRIBUTES', SHT_ARM_DEBUGOVERLAY='ARM_DEBUGOVERLAY', diff --git a/elftools/elf/relocation.py b/elftools/elf/relocation.py index 633bbf5..6f2c4b4 100644 --- a/elftools/elf/relocation.py +++ b/elftools/elf/relocation.py @@ -12,7 +12,7 @@ from ..common.exceptions import ELFRelocationError from ..common.utils import elf_assert, struct_parse from .sections import Section from .enums import ( - ENUM_RELOC_TYPE_i386, ENUM_RELOC_TYPE_x64, ENUM_RELOC_TYPE_MIPS) + ENUM_RELOC_TYPE_i386, ENUM_RELOC_TYPE_x64, ENUM_RELOC_TYPE_MIPS, ENUM_RELOC_TYPE_ARM) class Relocation(object): @@ -151,6 +151,11 @@ class RelocationHandler(object): raise ELFRelocationError( 'Unexpected RELA relocation for MIPS: %s' % reloc) recipe = self._RELOCATION_RECIPES_MIPS.get(reloc_type, None) + elif self.elffile.get_machine_arch() == 'ARM': + if reloc.is_RELA(): + raise ELFRelocationError( + 'Unexpected RELA relocation for ARM: %s' % reloc) + recipe = self._RELOCATION_RECIPES_ARM.get(reloc_type, None) if recipe is None: raise ELFRelocationError( @@ -214,6 +219,12 @@ class RelocationHandler(object): def _reloc_calc_sym_plus_addend_pcrel(value, sym_value, offset, addend=0): return sym_value + addend - offset + _RELOCATION_RECIPES_ARM = { + ENUM_RELOC_TYPE_ARM['R_ARM_ABS32']: _RELOCATION_RECIPE_TYPE( + bytesize=4, has_addend=False, + calc_func=_reloc_calc_sym_plus_value), + } + # https://dmz-portal.mips.com/wiki/MIPS_relocation_types _RELOCATION_RECIPES_MIPS = { ENUM_RELOC_TYPE_MIPS['R_MIPS_NONE']: _RELOCATION_RECIPE_TYPE( @@ -247,3 +258,5 @@ class RelocationHandler(object): ENUM_RELOC_TYPE_x64['R_X86_64_32S']: _RELOCATION_RECIPE_TYPE( bytesize=4, has_addend=True, calc_func=_reloc_calc_sym_plus_addend), } + + diff --git a/scripts/readelf.py b/scripts/readelf.py index d65c385..8535119 100755 --- a/scripts/readelf.py +++ b/scripts/readelf.py @@ -131,8 +131,19 @@ class ReadElf(object): flags &= ~E_FLAGS.EF_ARM_RELEXEC if eabi == E_FLAGS.EF_ARM_EABI_VER5: + EF_ARM_KNOWN_FLAGS = E_FLAGS.EF_ARM_ABI_FLOAT_SOFT|E_FLAGS.EF_ARM_ABI_FLOAT_HARD|E_FLAGS.EF_ARM_LE8|E_FLAGS.EF_ARM_BE8 description += ', Version5 EABI' - if flags: + if flags & E_FLAGS.EF_ARM_ABI_FLOAT_SOFT: + description += ", soft-float ABI" + elif flags & E_FLAGS.EF_ARM_ABI_FLOAT_HARD: + description += ", hard-float ABI" + + if flags & E_FLAGS.EF_ARM_BE8: + description += ", BE8" + elif flags & E_FLAGS.EF_ARM_LE8: + description += ", LE8" + + if flags & ~EF_ARM_KNOWN_FLAGS: description += ', ' else: description += ', ' diff --git a/test/testfiles_for_readelf/reloc_arm_gcc.o.elf b/test/testfiles_for_readelf/reloc_arm_gcc.o.elf new file mode 100644 index 0000000..4d8e4e9 Binary files /dev/null and b/test/testfiles_for_readelf/reloc_arm_gcc.o.elf differ diff --git a/test/testfiles_for_readelf/reloc_armhf_gcc.o.elf b/test/testfiles_for_readelf/reloc_armhf_gcc.o.elf new file mode 100644 index 0000000..320aea3 Binary files /dev/null and b/test/testfiles_for_readelf/reloc_armhf_gcc.o.elf differ diff --git a/test/testfiles_for_readelf/reloc_armsf_gcc.o.elf b/test/testfiles_for_readelf/reloc_armsf_gcc.o.elf new file mode 100755 index 0000000..04c3849 Binary files /dev/null and b/test/testfiles_for_readelf/reloc_armsf_gcc.o.elf differ diff --git a/test/testfiles_for_readelf/simple_armeb_gcc.o.elf b/test/testfiles_for_readelf/simple_armeb_gcc.o.elf new file mode 100755 index 0000000..bd0c38b Binary files /dev/null and b/test/testfiles_for_readelf/simple_armeb_gcc.o.elf differ diff --git a/test/testfiles_for_readelf/simple_armhf_gcc.o.elf b/test/testfiles_for_readelf/simple_armhf_gcc.o.elf new file mode 100644 index 0000000..a5a0233 Binary files /dev/null and b/test/testfiles_for_readelf/simple_armhf_gcc.o.elf differ