Always indirect branch to __libc_start_main via GOT

Since __libc_start_main in libc.so is called very early, lazy binding
isn't relevant.  Always call __libc_start_main with indirect branch via
GOT to avoid extra branch to PLT slot.  In case of static executable,
ld in binutils 2.26 or above can convert indirect branch into direct
branch:

0000000000400a80 <_start>:
  400a80:       31 ed                   xor    %ebp,%ebp
  400a82:       49 89 d1                mov    %rdx,%r9
  400a85:       5e                      pop    %rsi
  400a86:       48 89 e2                mov    %rsp,%rdx
  400a89:       48 83 e4 f0             and    $0xfffffffffffffff0,%rsp
  400a8d:       50                      push   %rax
  400a8e:       54                      push   %rsp
  400a8f:       49 c7 c0 20 1b 40 00    mov    $0x401b20,%r8
  400a96:       48 c7 c1 90 1a 40 00    mov    $0x401a90,%rcx
  400a9d:       48 c7 c7 c0 03 40 00    mov    $0x4003c0,%rdi
  400aa4:       67 e8 96 09 00 00       addr32 callq 401440 <__libc_start_main>
  400aaa:       f4                      hlt

	* sysdeps/x86_64/start.S (_start): Always indirect branch to
	__libc_start_main via GOT.
This commit is contained in:
H.J. Lu 2016-06-09 04:43:16 -07:00
parent 75437079e4
commit ac187dc4ab
2 changed files with 13 additions and 9 deletions

View File

@ -1,3 +1,8 @@
2016-06-09 H.J. Lu <hongjiu.lu@intel.com>
* sysdeps/x86_64/start.S (_start): Always indirect branch to
__libc_start_main via GOT.
2016-06-09 H.J. Lu <hongjiu.lu@intel.com>
* sysdeps/x86_64/memcopy.h: New file.

View File

@ -102,23 +102,22 @@ ENTRY (_start)
mov __libc_csu_init@GOTPCREL(%rip), %RCX_LP
mov main@GOTPCREL(%rip), %RDI_LP
/* Call the user's main function, and exit with its value.
But let the libc call main. Since __libc_start_main is
called very early, lazy binding isn't relevant here. Use
indirect branch via GOT to avoid extra branch to PLT slot. */
call *__libc_start_main@GOTPCREL(%rip)
#else
/* Pass address of our own entry points to .fini and .init. */
mov $__libc_csu_fini, %R8_LP
mov $__libc_csu_init, %RCX_LP
mov $main, %RDI_LP
#endif
/* Call the user's main function, and exit with its value.
But let the libc call main. */
call __libc_start_main
#endif
But let the libc call main. Since __libc_start_main in
libc.so is called very early, lazy binding isn't relevant
here. Use indirect branch via GOT to avoid extra branch
to PLT slot. In case of static executable, ld in binutils
2.26 or above can convert indirect branch into direct
branch. */
call *__libc_start_main@GOTPCREL(%rip)
hlt /* Crash if somehow `exit' does return. */
END (_start)