From f52f66634d1f9419239ce80ce455fea43ecc6aa7 Mon Sep 17 00:00:00 2001 From: Dmitry Koltunov Date: Wed, 5 Sep 2018 15:25:28 +0300 Subject: [PATCH] Call relocation for ARM V3 (#194) * Add support for 'R_ARM_CALL' relocation type * Add test script and test files to verify support for 'R_ARM_CALL' Signed-off-by: Koltunov Dmitry --- elftools/elf/relocation.py | 6 ++ test/run_arm_reloc_call_test.py | 62 ++++++++++++++++++ .../reloc_simple_arm_llvm.o | Bin 0 -> 1488 bytes test/testfiles_for_unittests/simple.c | 41 ++++++++++++ .../simple_arm_llvm.elf | Bin 0 -> 34272 bytes 5 files changed, 109 insertions(+) create mode 100755 test/run_arm_reloc_call_test.py create mode 100644 test/testfiles_for_unittests/reloc_simple_arm_llvm.o create mode 100644 test/testfiles_for_unittests/simple.c create mode 100755 test/testfiles_for_unittests/simple_arm_llvm.elf diff --git a/elftools/elf/relocation.py b/elftools/elf/relocation.py index 6f2c4b4..59b6750 100644 --- a/elftools/elf/relocation.py +++ b/elftools/elf/relocation.py @@ -219,10 +219,16 @@ class RelocationHandler(object): 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 diff --git a/test/run_arm_reloc_call_test.py b/test/run_arm_reloc_call_test.py new file mode 100755 index 0000000..261949d --- /dev/null +++ b/test/run_arm_reloc_call_test.py @@ -0,0 +1,62 @@ +#!/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()) diff --git a/test/testfiles_for_unittests/reloc_simple_arm_llvm.o b/test/testfiles_for_unittests/reloc_simple_arm_llvm.o new file mode 100644 index 0000000000000000000000000000000000000000..a1bfbaa893443246d3da536c7f6685252c51827b GIT binary patch literal 1488 zcmb7Ezi-n}5Wd&CC6ItjRYYm4VgZ5_sgCo*Ns1U+@vB42075Jbb!?|Z3tN17p+35{LzMMEEYTOBx{rCp~}neRsLL_nw`nw-#>;At*3G zQTok@=A=$!DAj=|oj_FHT{;ko+a%3xMyTP11hY!ZbrQ`nPe0yyDCl&~jbuAlApR|!0%K*Rh3 z^#)|O*{g^8b@1>m_Pp@!Gw-RlACcSQULR$*^=5Lj#XTG6-If^NY(?OAdrx?BU(G=8 zpCQouX9#quua1nfKQbHcitkYKaoNY0K1v97?$|6E+1X^)Or~|y)HN%W&u0w7GP7nTJ5BR(jBVIPu0Y}n+#3m1 zo26k95~t|27?DQB8F6-SOq>(r15?8n#O2=C7x_dFJJ0SzqVH{|hZ7APVT0iJeTC0& z1Uw1kGu!rg7PySX-vr0m=iDHF5k8-F6^rBVfs^=-J~196`o=g+bQ3jMf5ZsgVTAsI zF@z-8)j=Y58D$^Gd{lfSwPqL9`Fl&Myt-j;-Fg`(UQ-80Hf~Mzv^@VOdl!l;El+)mL+*)}5MTFm99>FBvLt_n*x| zCbn>BA3!z^ng2e5k78l_gk$I!pRvn=Z{5G6?pYiUM4*Lwd@ro=jdC8J+YlChUVRQ^ z+XIOLgIf>kaf{x1+o;ERtZ`0IZyY}72Alr@@)|raj`6zgW1znZ8u|j~uwBGLt7?bf Y!Fh>*0E4_D{N56KAX|Psm`?`(1@iAQlK=n! literal 0 HcmV?d00001 diff --git a/test/testfiles_for_unittests/simple.c b/test/testfiles_for_unittests/simple.c new file mode 100644 index 0000000..4ea1c67 --- /dev/null +++ b/test/testfiles_for_unittests/simple.c @@ -0,0 +1,41 @@ +/* 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; +} diff --git a/test/testfiles_for_unittests/simple_arm_llvm.elf b/test/testfiles_for_unittests/simple_arm_llvm.elf new file mode 100755 index 0000000000000000000000000000000000000000..f1cfbb8d6593d38281a49dc2cb8e2ccacb42ed8e GIT binary patch literal 34272 zcmeIw&u`mg7zgm@P27^vAiN5+A4S8U0h<8FY2qe>3lkdbupU4hkT|4{?Q{`I8YS*j zPD{33BXQukNxn>~gpiOpaX{i90QJC$Q?tkth!g+7!t>a%aH9&rf!p_$UcY{RP6#+G2A3#5m+$nJaNt z(MM6>ooHADtGw!`6_A4f1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa z0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV= z5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SNrh0{YSR6J>-`vchSRCQ(73L`8bU z>!V1~=vXr*5m}Q+KbkzbG%rp6x&OWY)c>U_9v3N`E&z|ACOg?*t?=yKhOM2!XIj^&Q z_G~*(=XVu<18&FZ?HYId!LYs8Gi=i`E#u1VAn3nSDs?({y5`*{ik6)lIKfwyJ); zQg?qjS8@@mC|FKCkQCe_^Tq2FJ3W#f#M6vsL#BIg8r!sdS95962omzNFhlYenl`bWtOlfP9m zER~E`c;R&a9S8>BMIq| yah7NHYyI>A(T%v0T+%*SvtRj$_uJv*Gn|)m%K3DjXLx4!JHAhJz`1m!`~3yEO<^Md literal 0 HcmV?d00001 -- 2.30.2