From patchwork Fri Feb 19 11:59:26 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Renlin Li X-Patchwork-Id: 10921 Received: (qmail 86569 invoked by alias); 19 Feb 2016 11:59:31 -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 86557 invoked by uid 89); 19 Feb 2016 11:59:30 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.9 required=5.0 tests=BAYES_00, KAM_LAZY_DOMAIN_SECURITY, RP_MATCHES_RCVD autolearn=no version=3.3.2 spammy=_DYNAMIC, _dynamic, mcmodel, sk:_global X-HELO: foss.arm.com To: libc-alpha@sourceware.org Cc: Marcus Shawcroft , Szabolcs.Nagy@arm.com From: Renlin Li Subject: [GLIBC][AARCH64] Rewrite elf_machine_dynamic using inline assembly Message-ID: <56C7039E.6000702@foss.arm.com> Date: Fri, 19 Feb 2016 11:59:26 +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 is a small improvement to use inline assembly instead of high-level C code to get the address of _DYNAMIC. Fixed PC-relative addressing inline assembly code is used here. It provides +/-1MB PC-relative addressing capability. I have checked that, in ld.so, the distance between .text section and .got section is within 1MB. The whole image without debug section is less than 130kiB, which is far less than the addressing capability. So direct PC relative addressing should be adequate and safe here. Originally, two instructions are generated from previous C code. Now only one instruction is needed. Tiny memory model: adr Rn _GLOBAL_OFFSET_TABLE_ ldr Rn [Rn] Small memory model: adrp Rn _GLOBAL_OFFSET_TABLE_ ldr Rn [Rn, imm] Another benefit is that, it's guaranteed that, no runtime relocation is generated for this function. For example, if glibc is compiled using -mcmodel=large, the original C code will generate the following absolute addressing code which cannot be resolved at this early stage. It will cause segment fault. ldr x0, .L0 .L0: _GLOBAL_TABLE_OFFSET_ aarch64-none-linux-gnu is tested without any issues. Is Okay to commit? Regards, Renlin Li ChangeLog: 2016-02-19 Renlin Li * sysdeps/aarch64/dl-machine.h (elf_machine_dynamic): Use PC-relative instruction to get the value of _DYNAMIC. diff --git a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h index 217e179..7b66457 100644 --- a/sysdeps/aarch64/dl-machine.h +++ b/sysdeps/aarch64/dl-machine.h @@ -33,12 +33,21 @@ elf_machine_matches_host (const ElfW(Ehdr) *ehdr) } /* Return the link-time address of _DYNAMIC. Conveniently, this is the - first element of the GOT. */ + first element of the GOT. + + PC-relative addressing is used here despite the memory model. + The offset from the address of this instruction is in the range +/- 1MB, + which should be enough. + + This also ensures no run-time relocation is generated by compiler. */ + static inline ElfW(Addr) __attribute__ ((unused)) elf_machine_dynamic (void) { - extern const ElfW(Addr) _GLOBAL_OFFSET_TABLE_[] attribute_hidden; - return _GLOBAL_OFFSET_TABLE_[0]; + ElfW(Addr) dynamic; + + asm ("ldr %0, _GLOBAL_OFFSET_TABLE_\n" : "=r" (dynamic)); + return dynamic; } /* Return the run-time load address of the shared object. */