[S390] module function call optimization
authorMartin Schwidefsky <schwidefsky@de.ibm.com>
Thu, 26 Mar 2009 14:24:36 +0000 (15:24 +0100)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Thu, 26 Mar 2009 14:24:24 +0000 (15:24 +0100)
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>
arch/s390/kernel/module.c

index 59b4e79..eed4a00 100644 (file)
@@ -310,15 +310,20 @@ apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab,
                        info->plt_initialized = 1;
                }
                if (r_type == R_390_PLTOFF16 ||
-                   r_type == R_390_PLTOFF32
-                   || r_type == R_390_PLTOFF64
-                       )
+                   r_type == R_390_PLTOFF32 ||
+                   r_type == R_390_PLTOFF64)
                        val = me->arch.plt_offset - me->arch.got_offset +
                                info->plt_offset + rela->r_addend;
-               else
-                       val =  (Elf_Addr) me->module_core +
-                               me->arch.plt_offset + info->plt_offset + 
-                               rela->r_addend - loc;
+               else {
+                       if (!((r_type == R_390_PLT16DBL &&
+                              val - loc + 0xffffUL < 0x1ffffeUL) ||
+                             (r_type == R_390_PLT32DBL &&
+                              val - loc + 0xffffffffULL < 0x1fffffffeULL)))
+                               val = (Elf_Addr) me->module_core +
+                                       me->arch.plt_offset +
+                                       info->plt_offset;
+                       val += rela->r_addend - loc;
+               }
                if (r_type == R_390_PLT16DBL)
                        *(unsigned short *) loc = val >> 1;
                else if (r_type == R_390_PLTOFF16)