RFC: Add R_X86_64_INDBR_GOTPCREL and R_386_INDBR_GOT32

H.J. Lu hongjiu.lu@intel.com
Wed Jul 1 22:59:00 GMT 2015


To avoid indirect branch to locally defined functions, I am proposing to
add a new relocation, R_X86_64_INDBR_GOTPCREL, to x86-64 psABI: 

1. When branching to an external function, foo, toolchain generates 
        call/jmp *foo@GOTPCREL(%rip) 
   with R_X86_64_INDBR_GOTPCREL relocation, instead of 
        call/jmp foo[@PLT] 
2. When function foo is locally defined, linker converts 
        call/jmp *foo@GOTPCREL(%rip) 
   to 
        nop call/jmp foo 
3. Otherwise, linker treats R_X86_64_INDBR_GOTPCREL the same way as 
   R_X86_64_GOTPCREL. 

For i386 psABI, we add R_386_INDBR_GOT32: 

1. When branching to an external function, foo, in non-PIC mode, 
    toolchain generates 
        call/jmp *foo@GOT 
   with R_386_INDBR_GOT32 relocation, instead of 
        call/jmp foo 
   and in PIC mode 
        call/jmp *foo@GOT(%reg) 
   with R_386_INDBR_GOT32 relocation and REG holds the address 
   of GOT, instead of 
        call/jmp foo@PLT 
2. When function foo is locally defined, linker converts 
        call/jmp *foo@GOT[(%reg)] 
   to 
        nop call/jmp foo 
3. Otherwise, 
   a. In PIC mode, linker treats R_386_INDBR_GOT32 the same way as 
      R_386_GOT32 and "call/jmp *foo@GOT" is unsupported. 
   b. In no-PIC mode, linker computes its relocation value as relocation 
      value of R_386_GOT32 plus the address of GOT and converts 
        call/jmp *foo@GOT(%reg) 
      to 
        call/jmp *foo@GOT 
      if needed. 

This new relocation effectively turns off lazy binding on function, foo. 

For i386, compiler is free to choose any register to hold the address of 
GOT and there is no need to make EBX a fixed register when branching to 
an external function in PIC mode. 

With this new relocation, only a one-byte NOP prefix overhead is added 
when function, foo, which compiler determines is external, turns out to 
be local at link-time, because of -Bsymbolic or a definition in another 
input object file which compiler has no knowledge of. 

The new -fno-plt GCC option can use R_X86_64_INDBR_GOTPCREL and 
R_386_INDBR_GOT32 relocations if linker supports them to avoid indirect 
branch to internal functions. 

For x86-64 GCC, it is implemented in assembler and linker.  Assembler
should generate R_X86_64_INDBR_GOTPCREL relocation, instead of 
R_X86_64_GOTPCREL relocation for “call/jmp *foo@GOTPCREL(%rip)” 

For i386 GCC, most is implemented in assembler and linker.  Assembler
should generate R_386_INDBR_GOT32 relocation, instead of R_386_GOT32
relocation, for “call/jmp *foo@GOT(%reg)”.  GCC also needs to modify
to generate “call/jmp *foo@GOT” in non-PIC mode. 


H.J.



More information about the Binutils mailing list