summaryrefslogtreecommitdiff
path: root/arch/s390/kernel
diff options
context:
space:
mode:
authorSumanth Korikkar <sumanthk@linux.ibm.com>2023-06-05 09:55:27 +0200
committerAlexander Gordeev <agordeev@linux.ibm.com>2023-06-20 19:55:00 +0200
commit11458e2b3ffa0e3798f392695d7aec210ac14efd (patch)
tree983c41783fab7afd5c0e6c32ee8a7d45131dc265 /arch/s390/kernel
parent2e3d8d71e285fcf39eb30dbb17a58baa90649867 (diff)
s390/module: fix rela calculation for R_390_GOTENT
During module load, module layout allocation occurs by initially allowing the architecture to frob the sections. This is performed via module_frob_arch_sections(). However, the size of each module memory types like text,data,rodata etc are updated correctly only after layout_sections(). After calculation of required module memory sizes for each types, move_module() is responsible for allocating the module memory for each type from modules vaddr range. Considering the sequence above, module_frob_arch_sections() updates the module mod_arch_specific got_offset before module memory text type size is fully updated in layout_sections(). Hence mod_arch_specific got_offset points to currently zero. As per s390 ABI, R_390_GOTENT : (G + O + A - P) >> 1 where G=me->mem[MOD_TEXT].base+me->arch.got_offset O=info->got_offset A=rela->r_addend P=loc fix R_390_GOTENT calculation in apply_rela(). Note: currently this doesn't break anything because me->arch.got_offset is zero. However, reordering of functions in the future could break it. Signed-off-by: Sumanth Korikkar <sumanthk@linux.ibm.com> Acked-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
Diffstat (limited to 'arch/s390/kernel')
-rw-r--r--arch/s390/kernel/module.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c
index f1b35dcdf3eb..42215f9404af 100644
--- a/arch/s390/kernel/module.c
+++ b/arch/s390/kernel/module.c
@@ -352,7 +352,8 @@ static int apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab,
rc = apply_rela_bits(loc, val, 0, 64, 0, write);
else if (r_type == R_390_GOTENT ||
r_type == R_390_GOTPLTENT) {
- val += (Elf_Addr) me->mem[MOD_TEXT].base - loc;
+ val += (Elf_Addr)me->mem[MOD_TEXT].base +
+ me->arch.got_offset - loc;
rc = apply_rela_bits(loc, val, 1, 32, 1, write);
}
break;