Skip to content

Commit

Permalink
Initial s390x relocation support (#515)
Browse files Browse the repository at this point in the history
  • Loading branch information
stefan-sf-ibm authored Oct 30, 2023
1 parent d9ea5f1 commit 6351610
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 3 deletions.
7 changes: 6 additions & 1 deletion elftools/elf/descriptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
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
Expand Down Expand Up @@ -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':
Expand Down Expand Up @@ -396,6 +399,7 @@ def describe_note_gnu_properties(properties):
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',
Expand Down Expand Up @@ -691,6 +695,7 @@ def _reverse_dict(d, low_priority=()):
_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)

Expand Down
2 changes: 1 addition & 1 deletion elftools/elf/elffile.py
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ def get_machine_arch(self):
'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',
Expand Down
63 changes: 63 additions & 0 deletions elftools/elf/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -934,6 +934,69 @@
_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,
Expand Down
14 changes: 13 additions & 1 deletion elftools/elf/relocation.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
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


Expand Down Expand Up @@ -278,6 +279,8 @@ def _do_apply_relocation(self, stream, reloc, symtab):
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':
Expand Down Expand Up @@ -491,4 +494,13 @@ def _bpf_64_32_reloc_calc_sym_plus_addend(value, sym_value, offset, addend=0):
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),
}


16 changes: 16 additions & 0 deletions test/testfiles_for_readelf/s390x-relocs.c
Original file line number Diff line number Diff line change
@@ -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();
}
Binary file added test/testfiles_for_readelf/s390x-relocs.o.elf
Binary file not shown.

0 comments on commit 6351610

Please sign in to comment.