From 6351610cfaece0e59d1e0a47a038170638f9a8b8 Mon Sep 17 00:00:00 2001 From: Stefan Schulze Frielinghaus Date: Mon, 30 Oct 2023 13:34:14 +0100 Subject: [PATCH] Initial s390x relocation support (#515) --- elftools/elf/descriptions.py | 7 +- elftools/elf/elffile.py | 2 +- elftools/elf/enums.py | 63 ++++++++++++++++++ elftools/elf/relocation.py | 14 +++- test/testfiles_for_readelf/s390x-relocs.c | 16 +++++ test/testfiles_for_readelf/s390x-relocs.o.elf | Bin 0 -> 3168 bytes 6 files changed, 99 insertions(+), 3 deletions(-) create mode 100644 test/testfiles_for_readelf/s390x-relocs.c create mode 100644 test/testfiles_for_readelf/s390x-relocs.o.elf diff --git a/elftools/elf/descriptions.py b/elftools/elf/descriptions.py index 8458461..f86f4a1 100644 --- a/elftools/elf/descriptions.py +++ b/elftools/elf/descriptions.py @@ -11,7 +11,8 @@ from .enums import ( ENUM_RELOC_TYPE_i386, ENUM_RELOC_TYPE_x64, ENUM_RELOC_TYPE_ARM, ENUM_RELOC_TYPE_AARCH64, ENUM_RELOC_TYPE_PPC64, ENUM_RELOC_TYPE_MIPS, ENUM_ATTR_TAG_ARM, ENUM_ATTR_TAG_RISCV, - ENUM_RELOC_TYPE_LOONGARCH, ENUM_DT_FLAGS, ENUM_DT_FLAGS_1) + ENUM_RELOC_TYPE_S390X, ENUM_RELOC_TYPE_LOONGARCH, ENUM_DT_FLAGS, + ENUM_DT_FLAGS_1) from .constants import ( P_FLAGS, RH_FLAGS, SH_FLAGS, SUNW_SYMINFO_FLAGS, VER_FLAGS) from ..common.utils import bytes2hex @@ -150,6 +151,8 @@ def describe_reloc_type(x, elffile): return _DESCR_RELOC_TYPE_AARCH64.get(x, _unknown) elif arch == '64-bit PowerPC': return _DESCR_RELOC_TYPE_PPC64.get(x, _unknown) + elif arch == 'IBM S/390': + return _DESCR_RELOC_TYPE_S390X.get(x, _unknown) elif arch == 'MIPS': return _DESCR_RELOC_TYPE_MIPS.get(x, _unknown) elif arch == 'LoongArch': @@ -396,6 +399,7 @@ _DESCR_E_MACHINE = dict( EM_860='Intel 80860', EM_MIPS='MIPS R3000', EM_S370='IBM System/370', + EM_S390='IBM S/390', EM_MIPS_RS4_BE='MIPS 4000 big-endian', EM_IA_64='Intel IA-64', EM_X86_64='Advanced Micro Devices X86-64', @@ -691,6 +695,7 @@ _DESCR_RELOC_TYPE_x64 = _reverse_dict(ENUM_RELOC_TYPE_x64) _DESCR_RELOC_TYPE_ARM = _reverse_dict(ENUM_RELOC_TYPE_ARM) _DESCR_RELOC_TYPE_AARCH64 = _reverse_dict(ENUM_RELOC_TYPE_AARCH64) _DESCR_RELOC_TYPE_PPC64 = _reverse_dict(ENUM_RELOC_TYPE_PPC64) +_DESCR_RELOC_TYPE_S390X = _reverse_dict(ENUM_RELOC_TYPE_S390X) _DESCR_RELOC_TYPE_MIPS = _reverse_dict(ENUM_RELOC_TYPE_MIPS) _DESCR_RELOC_TYPE_LOONGARCH = _reverse_dict(ENUM_RELOC_TYPE_LOONGARCH) diff --git a/elftools/elf/elffile.py b/elftools/elf/elffile.py index f9fc0b3..446d970 100644 --- a/elftools/elf/elffile.py +++ b/elftools/elf/elffile.py @@ -365,7 +365,7 @@ class ELFFile(object): 'EM_960' : 'Intel 80960', 'EM_PPC' : 'PowerPC', 'EM_PPC64' : '64-bit PowerPC', - 'EM_S390' : 'IBM System/390', + 'EM_S390' : 'IBM S/390', 'EM_SPU' : 'IBM SPU/SPC', 'EM_V800' : 'NEC V800', 'EM_FR20' : 'Fujitsu FR20', diff --git a/elftools/elf/enums.py b/elftools/elf/enums.py index 24c2fd0..fba3937 100644 --- a/elftools/elf/enums.py +++ b/elftools/elf/enums.py @@ -934,6 +934,69 @@ ENUM_RELOC_TYPE_LOONGARCH = dict( _default_=Pass, ) +ENUM_RELOC_TYPE_S390X = dict( + R_390_NONE=0, + R_390_8=1, + R_390_12=2, + R_390_16=3, + R_390_32=4, + R_390_PC32=5, + R_390_GOT12=6, + R_390_GOT32=7, + R_390_PLT32=8, + R_390_COPY=9, + R_390_GLOB_DAT=10, + R_390_JMP_SLOT=11, + R_390_RELATIVE=12, + R_390_GOTOFF32=13, + R_390_GOTPC=14, + R_390_GOT16=15, + R_390_PC16=16, + R_390_PC16DBL=17, + R_390_PLT16DBL=18, + R_390_PC32DBL=19, + R_390_PLT32DBL=20, + R_390_GOTPCDBL=21, + R_390_64=22, + R_390_PC64=23, + R_390_GOT64=24, + R_390_PLT64=25, + R_390_GOTENT=26, + R_390_GOTOFF16=27, + R_390_GOTOFF64=28, + R_390_GOTPLT12=29, + R_390_GOTPLT16=30, + R_390_GOTPLT32=31, + R_390_GOTPLT64=32, + R_390_GOTPLTENT=33, + R_390_PLTOFF16=34, + R_390_PLTOFF32=35, + R_390_PLTOFF64=36, + R_390_TLS_LOAD=37, + R_390_TLS_GDCALL=38, + R_390_TLS_LDCALL=39, + R_390_TLS_GD64=41, + R_390_TLS_GOTIE12=42, + R_390_TLS_GOTIE64=44, + R_390_TLS_LDM64=46, + R_390_TLS_IE64=48, + R_390_TLS_IEENT=49, + R_390_TLS_LE64=51, + R_390_TLS_LDO64=53, + R_390_TLS_DTPMOD=54, + R_390_TLS_DTPOFF=55, + R_390_TLS_TPOFF=56, + R_390_20=57, + R_390_GOT20=58, + R_390_GOTPLT20=59, + R_390_TLS_GOTIE20=60, + R_390_IRELATIVE=61, + R_390_PC12DBL=62, + R_390_PLT12DBL=63, + R_390_PC24DBL=64, + R_390_PLT24DBL=65, +) + # Sunw Syminfo Bound To special values ENUM_SUNW_SYMINFO_BOUNDTO = dict( SYMINFO_BT_SELF=0xffff, diff --git a/elftools/elf/relocation.py b/elftools/elf/relocation.py index ebd399e..5aa5524 100644 --- a/elftools/elf/relocation.py +++ b/elftools/elf/relocation.py @@ -14,7 +14,8 @@ from .sections import Section from .enums import ( ENUM_RELOC_TYPE_i386, ENUM_RELOC_TYPE_x64, ENUM_RELOC_TYPE_MIPS, ENUM_RELOC_TYPE_ARM, ENUM_RELOC_TYPE_AARCH64, ENUM_RELOC_TYPE_PPC64, - ENUM_RELOC_TYPE_BPF, ENUM_RELOC_TYPE_LOONGARCH, ENUM_D_TAG) + ENUM_RELOC_TYPE_S390X, ENUM_RELOC_TYPE_BPF, ENUM_RELOC_TYPE_LOONGARCH, + ENUM_D_TAG) from ..construct import Container @@ -278,6 +279,8 @@ class RelocationHandler(object): recipe = self._RELOCATION_RECIPES_AARCH64.get(reloc_type, None) elif self.elffile.get_machine_arch() == '64-bit PowerPC': recipe = self._RELOCATION_RECIPES_PPC64.get(reloc_type, None) + elif self.elffile.get_machine_arch() == 'IBM S/390': + recipe = self._RELOCATION_RECIPES_S390X.get(reloc_type, None) elif self.elffile.get_machine_arch() == 'Linux BPF - in-kernel virtual machine': recipe = self._RELOCATION_RECIPES_EBPF.get(reloc_type, None) elif self.elffile.get_machine_arch() == 'LoongArch': @@ -491,4 +494,13 @@ class RelocationHandler(object): calc_func=_reloc_calc_sym_plus_addend_pcrel), } + _RELOCATION_RECIPES_S390X = { + ENUM_RELOC_TYPE_S390X['R_390_32']: _RELOCATION_RECIPE_TYPE( + bytesize=4, has_addend=True, calc_func=_reloc_calc_sym_plus_addend), + ENUM_RELOC_TYPE_S390X['R_390_PC32']: _RELOCATION_RECIPE_TYPE( + bytesize=4, has_addend=True, calc_func=_reloc_calc_sym_plus_addend_pcrel), + ENUM_RELOC_TYPE_S390X['R_390_64']: _RELOCATION_RECIPE_TYPE( + bytesize=8, has_addend=True, calc_func=_reloc_calc_sym_plus_addend), + } + diff --git a/test/testfiles_for_readelf/s390x-relocs.c b/test/testfiles_for_readelf/s390x-relocs.c new file mode 100644 index 0000000..6a6483c --- /dev/null +++ b/test/testfiles_for_readelf/s390x-relocs.c @@ -0,0 +1,16 @@ +/* This source was compiled for s390x. + gcc -c -o s390x-relocs.o.elf s390x-relocs.c -g +*/ + +extern struct { + int i, j; +} data; + +extern int bar (void); + +int +foo (int a) +{ + data.i += a; + data.j -= bar(); +} diff --git a/test/testfiles_for_readelf/s390x-relocs.o.elf b/test/testfiles_for_readelf/s390x-relocs.o.elf new file mode 100644 index 0000000000000000000000000000000000000000..972edf7158064e61bb0764dad261a3638e84c4a9 GIT binary patch literal 3168 zcmbtWO>7%g5Pomh>vgiR>%a^TP-+*&Tl5sAMG5*KcWQ!hoF5E5bL`Az)1wj~53y`7nFe%`!! zKlU5XJ-@1HoShJ74}h!yCl(OQ>q5)R?<7mzJG{TePXBuUcV`3xu7-@dxu{!7BT-efgt2VX7CusYWR5s zKLe%N>x~}sY!_alcUt*&uL|7zZ)S3Y^Kx5q0;p;?;ZkzFuF?291trp{B*no8y zDwX-?F&Atik^aFiuS0@3%(XPbFU>?3t+mue3#uFEXA&t(PfRDq`GlE#5Xwn$%UZH7 zS&J4=!IDlh%X-?4}bIEw!9}GR;`jVasVqD%>ASucZ()9o`FK>ipDeV2T-7 zg798TX;Yno&v%+6+NCZ5WznG!_#(qboZsdnNaTott;&oSZ#3J2#)3 z&E@Q~n_k(z;s(-?SvY5B8o^G}dulJY0HWJ2RY9Bw@dE052-ulzmaVoLUe*u1ire%n z*|K-Tt7l)i>D4Pit5x^2f#(O}Q>oQGzfftl3vJIWgPoP#z-8?6%F2>`7V0|pFNzW^ z5T8l>^1V&QcN2Vi?9>4^4d^_KhlPZ_UVVGyo!GnPd(roe)x!|eJ_0b(2Lb@NxCLPw;CN~J2=IXi3UIsw$;hV1dU+=&S*M+sAT_s!>&K;h2 z6EHQ;XEJC9_@F#kJD#y{9^8sS{@AxcxGnMSd3F4ojleB3#}C>aUL^@$E7u9U-GDh_ zE1jb6Ge@9hueh^as5L7sunE~M7Tey99<$qao7-M*NWIqdCPL%J*O5FF-uih51yX`9D@ckX8R2=u}U>*U$Jw>PNtF z{dB&lUR?h(Fw}gY67gjzeME@ls{b{>R9$i9KS^a)0Z~-_H$Wd!e{@U6VLaAPbrZ+> zYcSM&pb}}6w?K&Gs(%?U^2_)7Mcp zuhV(TQlRAIkNhnqKIEp)g#c119`$_~q~qJ9kbY4rR}>IMT0hF4!Wh=S19SkQ{?R*5 z@rdKxp?NU`Nxvl+