diff options
author | Sumanth Korikkar <sumanthk@linux.ibm.com> | 2023-06-05 09:55:27 +0200 |
---|---|---|
committer | Alexander Gordeev <agordeev@linux.ibm.com> | 2023-06-20 19:55:00 +0200 |
commit | 11458e2b3ffa0e3798f392695d7aec210ac14efd (patch) | |
tree | 983c41783fab7afd5c0e6c32ee8a7d45131dc265 /arch/s390/kernel | |
parent | 2e3d8d71e285fcf39eb30dbb17a58baa90649867 (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.c | 3 |
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; |