diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2009-03-26 10:24:36 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2009-03-26 10:24:24 -0400 |
commit | 504665a91498f43d220b7d0942281067283a35f7 (patch) | |
tree | 5399477888501a58fe33f088fe335d342d46ade4 /arch/s390/kernel/module.c | |
parent | e13ed9b2704487e98d9241282765869fbd9a2dda (diff) |
[S390] module function call optimization
Avoid the detour over the PLT if the branch target of a function call
in a module is in the range of the bras (16-bit) or brasl (32-bit)
instruction. The PLT is still generated but it is unused.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel/module.c')
-rw-r--r-- | arch/s390/kernel/module.c | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c index 59b4e796680a..eed4a00cb676 100644 --- a/arch/s390/kernel/module.c +++ b/arch/s390/kernel/module.c | |||
@@ -310,15 +310,20 @@ apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab, | |||
310 | info->plt_initialized = 1; | 310 | info->plt_initialized = 1; |
311 | } | 311 | } |
312 | if (r_type == R_390_PLTOFF16 || | 312 | if (r_type == R_390_PLTOFF16 || |
313 | r_type == R_390_PLTOFF32 | 313 | r_type == R_390_PLTOFF32 || |
314 | || r_type == R_390_PLTOFF64 | 314 | r_type == R_390_PLTOFF64) |
315 | ) | ||
316 | val = me->arch.plt_offset - me->arch.got_offset + | 315 | val = me->arch.plt_offset - me->arch.got_offset + |
317 | info->plt_offset + rela->r_addend; | 316 | info->plt_offset + rela->r_addend; |
318 | else | 317 | else { |
319 | val = (Elf_Addr) me->module_core + | 318 | if (!((r_type == R_390_PLT16DBL && |
320 | me->arch.plt_offset + info->plt_offset + | 319 | val - loc + 0xffffUL < 0x1ffffeUL) || |
321 | rela->r_addend - loc; | 320 | (r_type == R_390_PLT32DBL && |
321 | val - loc + 0xffffffffULL < 0x1fffffffeULL))) | ||
322 | val = (Elf_Addr) me->module_core + | ||
323 | me->arch.plt_offset + | ||
324 | info->plt_offset; | ||
325 | val += rela->r_addend - loc; | ||
326 | } | ||
322 | if (r_type == R_390_PLT16DBL) | 327 | if (r_type == R_390_PLT16DBL) |
323 | *(unsigned short *) loc = val >> 1; | 328 | *(unsigned short *) loc = val >> 1; |
324 | else if (r_type == R_390_PLTOFF16) | 329 | else if (r_type == R_390_PLTOFF16) |