From patchwork Fri Aug 6 18:44:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fangrui Song X-Patchwork-Id: 44598 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A1BA039A8401 for ; Fri, 6 Aug 2021 18:44:32 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A1BA039A8401 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1628275472; bh=ocWnIlfSvM4eCuSWj6Uex9UkD5eikZZMv6yWPUb50w0=; h=Date:Subject:To:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=c7Yr9k6n3EDLy0IRfqdBjj8prZOr0FbB4VZSKWVVK/OTcaxPaL4+L7JigVqCmpu6D J0D1k9ZZ4HG4EX6XWmA6acCUuNmsSTax5dw5Cf3JP5eGeKpenkhESjT6OQzpySXVN2 hA72qO+Px3VgaEzGlbc0d679zws86nQq79m76KdU= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by sourceware.org (Postfix) with ESMTPS id 62202386185D for ; Fri, 6 Aug 2021 18:44:10 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 62202386185D Received: by mail-yb1-xb49.google.com with SMTP id j21-20020a25d2150000b029057ac4b4e78fso10265697ybg.4 for ; Fri, 06 Aug 2021 11:44:10 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:message-id:mime-version:subject:from:to:cc; bh=ocWnIlfSvM4eCuSWj6Uex9UkD5eikZZMv6yWPUb50w0=; b=rbkan9gwGbEnp9Wutzz9I+3wYi6ZjBiFQay6L4WswWgG1fv+PaA1YruCeQCS2PjBSP 6ZEC48HOea4wVWrHNCtBaPGKCEBj1mK67N/CGVrhd8Zgj6oFocWNJ/r1TzOOOZOPLW46 jSSnCZGDfGRN9vRX+iQHH3RlElZkdnkuUohhaL2XmoxM9igBS0gAzTNKfVMlDllsWBch GQzW2a3qIKLT5Nqb7PgcdXTeeH7dNrYB91SexqPj0zeRJcMljdxWAlm7iEoj5EfX1gBd 6roiFwurwkPNwvX/hOWm0TlMzAZolOGaLd//QrwdOUll6+mZKLVbr323ZtIypG7z3qHb YZdQ== X-Gm-Message-State: AOAM532DWmE7k18An24hK52ShGzZmw0RZ5rnfiJBXVopjkwrKJUk/liZ 4Fa+vrpzyyJfa5AQee/uw27KPrgZ9Zdkb5MtOGNWlPrrtlo4hGzGgFy6ETyLS3RIe/r6f6Hswc2 E8QuhrbqyxSZRN9gKfS4Tb8pUT57NmFJ+iCYQqK/iGd5rKXQknpJpogyHRrWxYq7SeXJD X-Google-Smtp-Source: ABdhPJwLVV4gpq3fvBO0UuWcfXYbMNgc+o9rHwm5hMbXVj4yzZqQNlJxaDB1FFj2evutozzhKUaOUzxpNQw0 X-Received: from maskray1.svl.corp.google.com ([2620:15c:2ce:200:6d69:ec51:238e:4db2]) (user=maskray job=sendgmr) by 2002:a25:1546:: with SMTP id 67mr15099239ybv.331.1628275449855; Fri, 06 Aug 2021 11:44:09 -0700 (PDT) Date: Fri, 6 Aug 2021 11:44:06 -0700 Message-Id: <20210806184406.3192584-1-maskray@google.com> Mime-Version: 1.0 Subject: [PATCH] aarch64: Make elf_machine_{load_address, dynamic} robust [BZ #28203] To: libc-alpha@sourceware.org, Adhemerval Zanella , Szabolcs Nagy X-Spam-Status: No, score=-20.0 required=5.0 tests=BAYES_00, DKIMWL_WL_MED, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Fangrui Song via Libc-alpha From: Fangrui Song Reply-To: Fangrui Song Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" The AArch64 ABI is largely platform agnostic and does not specify _GLOBAL_OFFSET_TABLE_[0] ([1]). glibc ld.so turns out to be probably the only user of _GLOBAL_OFFSET_TABLE_[0] and GNU ld defines the value to the link-time address _DYNAMIC. [2] In 2012, __ehdr_start was implemented in GNU ld and gold. Using adrp+addr to access __ehdr_start/_DYNAMIC gives us a robust way to get the load address and the link-time address of _DYNAMIC. With https://sourceware.org/pipermail/libc-alpha/2021-August/129864.html, this patch, and disabling traditional TLSGD tests (neither Clang nor LLD's aarch64 port supports), LLD linked glibc has the same number of `make check` failures. With this, I think https://github.com/ARM-software/abi-aa/pull/57 doesn't need to specify _GLOBAL_OFFSET_TABLE_[0]. musl, FreeBSD, and NetBSD don't use _GLOBAL_OFFSET_TABLE_[0]. A bonus with the new asm approach: we drop reliance on compiler generating PC-relative relocations to get the runtime address. [1]: From a psABI maintainer, https://bugs.llvm.org/show_bug.cgi?id=49672#c2 [2]: LLD's aarch64 port does not set _GLOBAL_OFFSET_TABLE_[0] to the link-time address _DYNAMIC. LLD is widely used on aarch64 Android and ChromeOS devices. Software just works without the need for _GLOBAL_OFFSET_TABLE_[0]. --- sysdeps/aarch64/dl-machine.h | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h index d29d827ab3..bf251d2972 100644 --- a/sysdeps/aarch64/dl-machine.h +++ b/sysdeps/aarch64/dl-machine.h @@ -37,28 +37,26 @@ elf_machine_matches_host (const ElfW(Ehdr) *ehdr) return ehdr->e_machine == EM_AARCH64; } -/* Return the link-time address of _DYNAMIC. Conveniently, this is the - first element of the GOT. */ -static inline ElfW(Addr) __attribute__ ((unused)) -elf_machine_dynamic (void) -{ - extern const ElfW(Addr) _GLOBAL_OFFSET_TABLE_[] attribute_hidden; - return _GLOBAL_OFFSET_TABLE_[0]; -} - /* Return the run-time load address of the shared object. */ static inline ElfW(Addr) __attribute__ ((unused)) 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 + ElfW(Addr) addr; + asm ("adrp %0, __ehdr_start\n\t" + "add %0, %0, :lo12:__ehdr_start" : "=r"(addr)); + return addr; +} - _DYNAMIC sysmbol is used here as its link-time address stored in - the special unrelocated first GOT entry. */ +/* Return the link-time address of _DYNAMIC. */ - extern ElfW(Dyn) _DYNAMIC[] attribute_hidden; - return (ElfW(Addr)) &_DYNAMIC - elf_machine_dynamic (); +static inline ElfW(Addr) __attribute__ ((unused)) +elf_machine_dynamic (void) +{ + ElfW(Addr) addr; + asm ("adrp %0, _DYNAMIC\n\t" + "add %0, %0, :lo12:_DYNAMIC" : "=r"(addr)); + return addr - elf_machine_load_address (); } /* Set up the loaded object described by L so its unrelocated PLT