bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug ld/20453] New: MIPS LA25 stub not bypassed in direct PIC-to-PIC jum


From: address@hidden
Subject: [Bug ld/20453] New: MIPS LA25 stub not bypassed in direct PIC-to-PIC jumps with incrementally linked code
Date: Tue, 09 Aug 2016 14:19:23 +0000

https://sourceware.org/bugzilla/show_bug.cgi?id=20453

            Bug ID: 20453
           Summary: MIPS LA25 stub not bypassed in direct PIC-to-PIC jumps
                    with incrementally linked code
           Product: binutils
           Version: 2.28 (HEAD)
            Status: UNCONFIRMED
          Severity: minor
          Priority: P2
         Component: ld
          Assignee: unassigned at sourceware dot org
          Reporter: address@hidden
  Target Milestone: ---
            Target: mips-*-*

We have a special case in `mips_elf_relocation_needs_la25_stub' for
direct jumps (and branches) between PIC functions which causes the LA25
stub to be bypassed under the principle that any need for $25 to be set
up correctly shall be handled by code's originator:

/* We specifically ignore branches and jumps from EF_PIC objects,
   where the onus is on the compiler or programmer to perform any
   necessary initialization of $25.  Sometimes such initialization
   is unnecessary; for example, -mno-shared functions do not use
   the incoming value of $25, and may therefore be called directly.  */

This works by checking the EF_MIPS_PIC flag of the incoming object file
where the relocation associated with the jump comes from.  This flag
however is cleared for the outcoming object file in an incremental link
which involves an incoming non-PIC object as well.

Consequently when such an incrementally linked object file is used in the
final link in place of the individual original object files the LA25 stub
is not bypassed anymore where it would otherwise be, leading to different
code produced from identical original objects and to a small run-time
performance loss from the extraneous instructions executed.  Additionally
in the case where all direct jumps are PIC-to-PIC an LA25 stub would have
not been produced if an incremental link wasn't done on the way, so the
issue may cause a slight code size increase as well.

This can be reproduced with these sources and steps:

$ cat la25a.s
        .abicalls

        .global f1
        .ent    f1
f1:
        .set    noreorder
        .cpload $25
        .set    reorder
        .option pic0
        jal     f2
        .option pic2
        jr      $31
        .end    f1

        .global f2
        .ent    f2
f2:
        jr      $31
        .end    f2
$ cat la25b.s
        .abicalls
        .option pic0

        .global __start
        .ent    __start
__start:
        jal     f1
        jal     f2
        .end    __start
$ as -32 -EB -o la25a.o la25a.s
$ as -32 -EB -o la25b.o la25b.s
$ ld -melf32btsmip -o la25 la25a.o la25b.o
$ ld -melf32btsmip -r -o la25-r.o la25a.o la25b.o
$ ld -melf32btsmip -o la25-r la25-r.o
$ objdump -d la25

la25:     file format elf32-tradbigmips


Disassembly of section .text:

004000d0 <.pic.f2>:
  4000d0:       3c190040        lui     t9,0x40
  4000d4:       08100043        j       40010c <f2>
  4000d8:       2739010c        addiu   t9,t9,268
        ...

004000e8 <.pic.f1>:
  4000e8:       3c190040        lui     t9,0x40
  4000ec:       273900f0        addiu   t9,t9,240

004000f0 <f1>:
  4000f0:       3c1c0002        lui     gp,0x2
  4000f4:       279c8030        addiu   gp,gp,-32720
  4000f8:       0399e021        addu    gp,gp,t9
  4000fc:       0c100043        jal     40010c <f2>
  400100:       00000000        nop
  400104:       03e00008        jr      ra
  400108:       00000000        nop

0040010c <f2>:
  40010c:       03e00008        jr      ra
  400110:       00000000        nop
        ...

00400120 <__start>:
  400120:       0c10003a        jal     4000e8 <.pic.f1>
  400124:       00000000        nop
  400128:       0c100034        jal     4000d0 <.pic.f2>
  40012c:       00000000        nop
$ objdump -d la25-r

la25-r:     file format elf32-tradbigmips


Disassembly of section .text:

004000d0 <.pic.f2>:
  4000d0:       3c190040        lui     t9,0x40
  4000d4:       08100043        j       40010c <f2>
  4000d8:       2739010c        addiu   t9,t9,268
        ...

004000e8 <.pic.f1>:
  4000e8:       3c190040        lui     t9,0x40
  4000ec:       273900f0        addiu   t9,t9,240

004000f0 <f1>:
  4000f0:       3c1c0002        lui     gp,0x2
  4000f4:       279c8030        addiu   gp,gp,-32720
  4000f8:       0399e021        addu    gp,gp,t9
  4000fc:       0c100034        jal     4000d0 <.pic.f2>
  400100:       00000000        nop
  400104:       03e00008        jr      ra
  400108:       00000000        nop

0040010c <f2>:
  40010c:       03e00008        jr      ra
  400110:       00000000        nop
        ...

00400120 <__start>:
  400120:       0c10003a        jal     4000e8 <.pic.f1>
  400124:       00000000        nop
  400128:       0c100034        jal     4000d0 <.pic.f2>
  40012c:       00000000        nop
$ diff -u la25 la25-r
--- la25.dump   2016-08-09 13:45:33.435771000 +0100
+++ la25-r.dump 2016-08-09 13:45:40.734859000 +0100
@@ -1,5 +1,5 @@

-la25:     file format elf32-tradbigmips
+la25-r:     file format elf32-tradbigmips


 Disassembly of section .text:
@@ -18,7 +18,7 @@
   4000f0:      3c1c0002        lui     gp,0x2
   4000f4:      279c8030        addiu   gp,gp,-32720
   4000f8:      0399e021        addu    gp,gp,t9
-  4000fc:      0c100043        jal     40010c <f2>
+  4000fc:      0c100034        jal     4000d0 <.pic.f2>
   400100:      00000000        nop
   400104:      03e00008        jr      ra
   400108:      00000000        nop
$ 

A potential way to fix this is to check for the STO_MIPS_PIC flag on the
function symbol spanning the area containing the offending relocation,
e.g. `f1' (vs `__start') in the example case above:

$ readelf -s la25-r.o

Symbol table '.symtab' contains 12 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 00000000     0 SECTION LOCAL  DEFAULT    1 
     2: 00000000     0 SECTION LOCAL  DEFAULT    2 
     3: 00000000     0 SECTION LOCAL  DEFAULT    3 
     4: 00000000     0 SECTION LOCAL  DEFAULT    5 
     5: 00000000     0 SECTION LOCAL  DEFAULT    6 
     6: 00000000     0 SECTION LOCAL  DEFAULT    7 
     7: 00000000     0 SECTION LOCAL  DEFAULT    9 
     8: 00000000     0 OBJECT  GLOBAL DEFAULT  UND _gp_disp
     9: 00000030    16 FUNC    GLOBAL DEFAULT    3 __start
    10: 0000001c     8 FUNC    GLOBAL DEFAULT [MIPS PIC]     3 f2
    11: 00000000    28 FUNC    GLOBAL DEFAULT [MIPS PIC]     3 f1
$ 

This however might require scanning the symbol table every time such a
problematic relocation is encountered and consequently be computationally
too complex, or require setting up additional data structures to avoid
this complexity and therefore take too much processing time elsewhere
and/or memory to be justified for such a corner case.

Marking as minor as this is a missed optimisation only and not a code
correctness issue.

-- 
You are receiving this mail because:
You are on the CC list for the bug.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]