Initial s390x relocation support (#515)
authorStefan Schulze Frielinghaus <stefansf@linux.ibm.com>
Mon, 30 Oct 2023 12:34:14 +0000 (13:34 +0100)
committerGitHub <noreply@github.com>
Mon, 30 Oct 2023 12:34:14 +0000 (05:34 -0700)
elftools/elf/descriptions.py
elftools/elf/elffile.py
elftools/elf/enums.py
elftools/elf/relocation.py
test/testfiles_for_readelf/s390x-relocs.c [new file with mode: 0644]
test/testfiles_for_readelf/s390x-relocs.o.elf [new file with mode: 0644]

index 8458461a5857d1bd1ee98054f7ade314b8262339..f86f4a14c9a2a5e725a2430bff89ab498f1ca10d 100644 (file)
@@ -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)
 
index f9fc0b35544ed26806c52289ac75f88b9e9f12de..446d970510aea4105d695c3e4de9a140e6a267b2 100644 (file)
@@ -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',
index 24c2fd0b76e362ac530e9b23f94a95bae758c5cf..fba39376d0a8b964d6cf276cbf5ca0a8277740a7 100644 (file)
@@ -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,
index ebd399ec3b290548e94544454fb0bf5de2e8e5fd..5aa55247c74cefec500aee16fe5489cd6fab42fe 100644 (file)
@@ -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 (file)
index 0000000..6a6483c
--- /dev/null
@@ -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 (file)
index 0000000..972edf7
Binary files /dev/null and b/test/testfiles_for_readelf/s390x-relocs.o.elf differ