From patchwork Fri Nov 4 09:42:23 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Renlin Li X-Patchwork-Id: 80795 Delivered-To: patch@linaro.org Received: by 10.140.97.247 with SMTP id m110csp1057053qge; Fri, 4 Nov 2016 02:42:48 -0700 (PDT) X-Received: by 10.99.55.66 with SMTP id g2mr20510284pgn.65.1478252568391; Fri, 04 Nov 2016 02:42:48 -0700 (PDT) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id qd6si12806163pac.134.2016.11.04.02.42.48 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 04 Nov 2016 02:42:48 -0700 (PDT) Received-SPF: pass (google.com: domain of libc-alpha-return-74386-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org; spf=pass (google.com: domain of libc-alpha-return-74386-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-74386-patch=linaro.org@sourceware.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:message-id:date :mime-version:content-type; q=dns; s=default; b=Xoqrl87sygZdlL+P umHZv+MGCQy/lFXzcVqVM6+Zd3MT7CirH6B2pm869TUz7z5SruY2ow0GMaxxqTRN jh50x7RIeD8c4qpTdVodrOimW/AQKYBfjcTvonMe3elJMHlhYWWZY7yyZ4aYNmBk HKRmFC1FHODeee9SMqR16uBchqs= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:message-id:date :mime-version:content-type; s=default; bh=lihOylVGNr9bVJrZnxOlR9 kcEdY=; b=bqBW4JAuQqu5mltwcKjFj0p8Wvi/PMjJi/eLR5Y9gDrpmvf23/nSvD /jAfsTIwj6XI21E2dlkjWadYbNPBNbodjpBceaISlR9CtI1KjbF1tZGC43wYRRkl ImRaxQ2C8p1XasgNrUJ4C8BzJZOwHoy9JswYcaNWIGfIV+5AC7fGg= Received: (qmail 107005 invoked by alias); 4 Nov 2016 09:42:38 -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 106986 invoked by uid 89); 4 Nov 2016 09:42:37 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.2 required=5.0 tests=BAYES_00, KAM_LAZY_DOMAIN_SECURITY, RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=GOT, 4925, lp64 X-HELO: foss.arm.com From: Renlin Li To: libc-alpha@sourceware.org Cc: Marcus Shawcroft , Richard Earnshaw Subject: [GLIBC][AARCH64]Rewrite elf_machine_load_address using _DYNAMIC symbol Message-ID: <581C57FF.2090901@foss.arm.com> Date: Fri, 4 Nov 2016 09:42:23 +0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 Hi all, This patch rewrites aarch64 elf_machine_load_address to use special _DYNAMIC symbol instead of _dl_start. The static address of _DYNAMIC symbol is stored in the first GOT entry. Here is the change which makes this solution work. https://sourceware.org/ml/binutils/2013-06/msg00248.html i386, x86_64 targets use the same method to do this as well. The original implementation relies on a trick that R_AARCH64_ABS32 relocation being resolved at link time and the static address fits in the 32bits. However, in LP64, normally, the address is defined to be 64 bit. Additionally, the original inline assembly is not optimized. It uses 4 instructions including a jump. Optimally, the new implementation here is just two instructions: ldr %1, _GLOBAL_OFFSET_TABLE_ adr %2, _DYNAMIC The size of ld.so is around 130K, so it's save to use ldr, adr to get the address. The address range for those two instruction is +/-1MB. And by the way, this method is ILP32 safe as well. aarch64 linux toolchain regression test OK. OK to commit? Regards, Renlin Li ChangeLog: 2016-11-04 Renlin Li * sysdeps/aarch64/dl-machine.h (elf_machine_load_address): Use _DYNAMIC symbol to calculate load address. diff --git a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h index 217e179..b2f6618 100644 --- a/sysdeps/aarch64/dl-machine.h +++ b/sysdeps/aarch64/dl-machine.h @@ -49,25 +49,19 @@ elf_machine_load_address (void) /* To figure out the load address we use the definition that for any symbol: dynamic_addr(symbol) = static_addr(symbol) + load_addr - The choice of symbol is arbitrary. The static address we obtain - by constructing a non GOT reference to the symbol, the dynamic - address of the symbol we compute using adrp/add to compute the - symbol's address relative to the PC. - This depends on 32bit relocations being resolved at link time - and that the static address fits in the 32bits. */ - - ElfW(Addr) static_addr; - ElfW(Addr) dynamic_addr; + _DYNAMIC symbol is used here as its static address is stored in + the special unrelocated first GOT entry. */ + ElfW(Addr) static_addr, dynamic_addr; asm (" \n" -" adrp %1, _dl_start; \n" -" add %1, %1, #:lo12:_dl_start \n" -" ldr %w0, 1f \n" -" b 2f \n" -"1: \n" -" .word _dl_start \n" -"2: \n" - : "=r" (static_addr), "=r" (dynamic_addr)); + "adr %0, _DYNAMIC \n" +#ifdef __LP64__ + "ldr %1, _GLOBAL_OFFSET_TABLE_ \n" +#else + "ldr %w1, _GLOBAL_OFFSET_TABLE_ \n" +#endif + : "=r" (dynamic_addr), "=r" (static_addr)); + return dynamic_addr - static_addr; }