def _reloc_calc_sym_plus_addend_pcrel(value, sym_value, offset, addend=0):
return sym_value + addend - offset
+ def _arm_reloc_calc_sym_plus_value_pcrel(value, sym_value, offset, addend=0):
+ return sym_value / 4 + value - offset / 4
+
_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),
+ ENUM_RELOC_TYPE_ARM['R_ARM_CALL']: _RELOCATION_RECIPE_TYPE(
+ bytesize=4, has_addend=False,
+ calc_func=_arm_reloc_calc_sym_plus_value_pcrel),
}
# https://dmz-portal.mips.com/wiki/MIPS_relocation_types
--- /dev/null
+#!/usr/bin/env python
+#-------------------------------------------------------------------------------
+# test/run_arm_reloc_call_test.py
+#
+# Test 'R_ARM_CALL' relocation type support.
+# Compare the '.text' section data of ELF file that relocated by elftools
+# and ELF file that relocated by linker.
+#
+# Dmitry Koltunov (koltunov@ispras.ru)
+#-------------------------------------------------------------------------------
+from os.path import (
+ join,
+ dirname
+)
+from sys import (
+ exit
+)
+
+from elftools.common.py3compat import (
+ BytesIO
+)
+from elftools.elf.elffile import (
+ ELFFile
+)
+from elftools.elf.relocation import (
+ RelocationHandler
+)
+
+
+def do_relocation(rel_elf):
+ data = rel_elf.get_section_by_name('.text').data()
+ rh = RelocationHandler(rel_elf)
+
+ stream = BytesIO()
+ stream.write(data)
+
+ rel = rel_elf.get_section_by_name('.rel.text')
+ rh.apply_section_relocations(stream, rel)
+
+ stream.seek(0)
+ data = stream.readlines()
+
+ return data
+
+
+def main():
+ test_dir = join(dirname(__file__) or '.', 'testfiles_for_unittests')
+ with open(join(test_dir, 'reloc_simple_arm_llvm.o'), 'rb') as rel_f, \
+ open(join(test_dir, 'simple_arm_llvm.elf'), 'rb') as f:
+ rel_elf = ELFFile(rel_f)
+ elf = ELFFile(f)
+
+ # Comparison of '.text' section data
+ if do_relocation(rel_elf).pop() != elf.get_section_by_name('.text').data():
+ print 'FAIL'
+ return 1
+ print 'OK'
+ return 0
+
+
+if __name__ == '__main__':
+ exit(main())
--- /dev/null
+/* Generated by compiling with any LLVM version and
+** with any GNU Arm Embedded Toolchain version.
+** LLVM 3.8.0/5.0.0 and GNU Arm Embedded Toolchain 2.26 is fine.
+**
+** clang -O0 --target=arm-none-eabi -emit-llvm -c simple.c -o simple.bc
+** llc -O0 -march=arm -filetype=obj simple.bc -o reloc_simple_arm_llvm.o
+** arm-none-eabi-ld -e main reloc_simple_arm_llvm.o -o simple_arm_llvm.elf
+**
+** reloc_simple_arm_llvm.o is ELF file that needs call relocation.
+**
+** simple_arm_llvm.elf is a relocated ELF file.
+*/
+
+int add(int a, int b) {
+ return a + b;
+}
+
+int sub(int a, int b) {
+ return a - b;
+}
+
+int mul(int a, int b) {
+ return a * b;
+}
+
+void triple(int a, int b) {
+ add(a, b);
+ sub(a, b);
+ mul(a, b);
+}
+
+int main(void) {
+ int a = 0xABCD, b = 0x1234;
+
+ add(a, b);
+ sub(a, b);
+ mul(a, b);
+ triple(a, b);
+
+ return 0;
+}