From patchwork Thu Jun 9 00:37:58 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Lu, Hongjiu" X-Patchwork-Id: 12896 Received: (qmail 112658 invoked by alias); 9 Jun 2016 00:38:03 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 112648 invoked by uid 89); 9 Jun 2016 00:38:02 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.3 required=5.0 tests=AWL, BAYES_00, KAM_LAZY_DOMAIN_SECURITY, NO_DNS_FOR_FROM, RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=sk:$0xffff, R8_LP, r8_lp, our X-HELO: mga04.intel.com X-ExtLoop1: 1 Date: Wed, 8 Jun 2016 17:37:58 -0700 From: "H.J. Lu" To: GNU C Library Subject: [PATCH] Always indirect branch to __libc_start_main via GOT Message-ID: <20160609003757.GA19143@intel.com> Reply-To: "H.J. Lu" MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.6.1 (2016-04-27) 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 Tested on x86-64. OK for master? H.J. --- * sysdeps/x86_64/start.S (_start): Always indirect branch to __libc_start_main via GOT. --- sysdeps/x86_64/start.S | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/sysdeps/x86_64/start.S b/sysdeps/x86_64/start.S index 2369b69..f1b961f 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)