about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--sysdeps/x86_64/start.S17
2 files changed, 13 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index 9c417f2321..f72f22e2df 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 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.
 	* sysdeps/x86_64/wordcopy.c: Likewise.
 
diff --git a/sysdeps/x86_64/start.S b/sysdeps/x86_64/start.S
index 2369b69ec3..f1b961f5ba 100644
--- a/sysdeps/x86_64/start.S
+++ b/sysdeps/x86_64/start.S
@@ -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)