From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from EUR05-DB8-obe.outbound.protection.outlook.com (mail-db8eur05on2052.outbound.protection.outlook.com [40.107.20.52]) by sourceware.org (Postfix) with ESMTPS id 7C4AC3858D38 for ; Tue, 21 Mar 2023 14:29:04 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 7C4AC3858D38 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=arm.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector2-armh-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=degnb3q789zhRfPzC9AG4bsO+DNT0l/CBNrUFGZa3/k=; b=WJoEoOSurvsLGSC4yE09kP+pt4TaFUlllJIRe59/RmNRtzeaSvKzSvqyS+wnvVjdXAbaVLL8QlknGNViwVvMtquFSiGqWP0jfofUmhO3PWY6IoVGLs+E7cqrhK+wRp3PNs6ceZ3bhNGObmyYrxCLEDaCmmADXhp5M2tDP0dQvBc= Received: from DUZPR01CA0006.eurprd01.prod.exchangelabs.com (2603:10a6:10:3c3::13) by AS8PR08MB6005.eurprd08.prod.outlook.com (2603:10a6:20b:298::23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6178.37; Tue, 21 Mar 2023 14:28:52 +0000 Received: from DBAEUR03FT019.eop-EUR03.prod.protection.outlook.com (2603:10a6:10:3c3:cafe::53) by DUZPR01CA0006.outlook.office365.com (2603:10a6:10:3c3::13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6178.37 via Frontend Transport; Tue, 21 Mar 2023 14:28:51 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 63.35.35.123) smtp.mailfrom=arm.com; dkim=pass (signature was verified) header.d=armh.onmicrosoft.com;dmarc=pass action=none header.from=arm.com; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 63.35.35.123 as permitted sender) receiver=protection.outlook.com; client-ip=63.35.35.123; helo=64aa7808-outbound-1.mta.getcheckrecipient.com; pr=C Received: from 64aa7808-outbound-1.mta.getcheckrecipient.com (63.35.35.123) by DBAEUR03FT019.mail.protection.outlook.com (100.127.142.129) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6222.16 via Frontend Transport; Tue, 21 Mar 2023 14:28:51 +0000 Received: ("Tessian outbound b29c0599cbc9:v135"); Tue, 21 Mar 2023 14:28:51 +0000 X-CheckRecipientChecked: true X-CR-MTA-CID: b68da5abfd8bc556 X-CR-MTA-TID: 64aa7808 Received: from fe21d1daadcd.1 by 64aa7808-outbound-1.mta.getcheckrecipient.com id 41993FA9-FC82-4031-AAEA-2CD7A4127A16.1; Tue, 21 Mar 2023 14:28:45 +0000 Received: from EUR03-AM7-obe.outbound.protection.outlook.com by 64aa7808-outbound-1.mta.getcheckrecipient.com with ESMTPS id fe21d1daadcd.1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384); Tue, 21 Mar 2023 14:28:45 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=b2822F3qy9sT/txMQsfh0+MAeBQIAMDEZCqUtu1qCevrhKjVaBDgiC5Z2dcayWi5JsB/a/nmK0F+alxq5OO2Z499pHmTJyO0q5DAZdwCuC4mZYxDt4NoKDwYNFlCs44TPer89OyrXzdSXdtv/p3niS+0ipOgJYU+cdysccx3OoeFGSLSeKMyW2cWXDru0YB7+4t5vGEpOrUdJW/tjScR0wpG3Q4anytyXke2RXerpODLWZhDqG+KvkQ1nYbcXidJnQP65QwV+5QwEZDMBUR6MV6NCHVAFGgj6jJnESe3LzNF3Zo3gI2kdauE6ji4s6dBwNeS7YrIIsWP5C3lXk5JwQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=degnb3q789zhRfPzC9AG4bsO+DNT0l/CBNrUFGZa3/k=; b=icTSRLzblx6h1CdLzKK8ijNB75+rAliS/t+Lm0/tYwX31/Ef6G/fli47BMSpvhXU1R0M7hNw6ttrwVI540sQ9refIAegpBwvnDuWnEvv3YjsrfqAvCAnE9PvvgIV8/RtQf+nykitcT0X4j872eLrfpN0SO69THqZss65z9Bso2z3nTGfDXCuJ2fbcnc1v1VPN6opHPeiJW+/iSCmZRp2xzA66FxFyJbtM4VbIZFUZuIR5qrvbHICzZ1VDE+2rsUl8IEqX6anIHXV6xohg6Np04CatbkSzYoLLoAgluX50P8z2edK7ffiFGqdcRjUYwEm89WH/Q5qljs1tJHXjoYUaQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 40.67.248.234) smtp.rcpttodomain=sourceware.org smtp.mailfrom=arm.com; dmarc=pass (p=none sp=none pct=100) action=none header.from=arm.com; dkim=none (message not signed); arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector2-armh-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=degnb3q789zhRfPzC9AG4bsO+DNT0l/CBNrUFGZa3/k=; b=WJoEoOSurvsLGSC4yE09kP+pt4TaFUlllJIRe59/RmNRtzeaSvKzSvqyS+wnvVjdXAbaVLL8QlknGNViwVvMtquFSiGqWP0jfofUmhO3PWY6IoVGLs+E7cqrhK+wRp3PNs6ceZ3bhNGObmyYrxCLEDaCmmADXhp5M2tDP0dQvBc= Received: from AM6PR04CA0010.eurprd04.prod.outlook.com (2603:10a6:20b:92::23) by AS8PR08MB8038.eurprd08.prod.outlook.com (2603:10a6:20b:548::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6178.37; Tue, 21 Mar 2023 14:28:40 +0000 Received: from AM7EUR03FT046.eop-EUR03.prod.protection.outlook.com (2603:10a6:20b:92:cafe::d4) by AM6PR04CA0010.outlook.office365.com (2603:10a6:20b:92::23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6178.37 via Frontend Transport; Tue, 21 Mar 2023 14:28:40 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 40.67.248.234) smtp.mailfrom=arm.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=arm.com; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 40.67.248.234 as permitted sender) receiver=protection.outlook.com; client-ip=40.67.248.234; helo=nebula.arm.com; pr=C Received: from nebula.arm.com (40.67.248.234) by AM7EUR03FT046.mail.protection.outlook.com (100.127.140.78) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.6222.17 via Frontend Transport; Tue, 21 Mar 2023 14:28:40 +0000 Received: from AZ-NEU-EX03.Arm.com (10.251.24.31) by AZ-NEU-EX04.Arm.com (10.251.24.32) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.17; Tue, 21 Mar 2023 14:28:39 +0000 Received: from armchair.cambridge.arm.com (10.2.80.71) by mail.arm.com (10.251.24.31) with Microsoft SMTP Server id 15.1.2507.17 via Frontend Transport; Tue, 21 Mar 2023 14:28:39 +0000 From: Szabolcs Nagy To: Subject: [PATCH 1/3] bfd: aarch64: Refactor stub sizing code Date: Tue, 21 Mar 2023 14:28:39 +0000 Message-ID: <20230321142839.672428-1-szabolcs.nagy@arm.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-EOPAttributedMessage: 1 X-MS-TrafficTypeDiagnostic: AM7EUR03FT046:EE_|AS8PR08MB8038:EE_|DBAEUR03FT019:EE_|AS8PR08MB6005:EE_ X-MS-Office365-Filtering-Correlation-Id: b41e11cd-9bbe-4903-6345-08db2a1897d6 x-checkrecipientrouted: true NoDisclaimer: true X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Untrusted: BCL:0; X-Microsoft-Antispam-Message-Info-Original: WIatlXhEuHEK3seeh72wBXYdn46SBtAmIXYgMWUE850WTW1ntBkPRRTDr2abzt5d7eVFifd5tpkIi2h7TLSriiq7h0HS3sZDjYQLUH5b2vRHVV1XgaBUqDw6W0WMVQX3f8uWvxqbqn0KXB3+6BWPnNg8wQTj7QN3I846os1Qwa8evwgK/oiB2dFQm8StJCsxkephAtvqusxw2LM8OGNMbJq4AxboWLKWaiyl+75e46ChnSIZYA+RZPttu2dSgDtwV8u1XRgy69QUKW9p+wPDvzv2OtPYVK6a0xo3WJyOkDODdMmPSt03K7hOJjdFujSzfAubhKDCpow1aUvZLiUh/IT4y56Drk2FDK6yk8lAd7/5ubmFhg3P/+K9CtWgQvbCts9eWiLYGz/XC7AK9knSrrWdGmACsCKH5u+re/9dcad1O0z8RBcIa4M4E6YCI3BpAHHu6tHNGidf5kyf6ipPiCfa4XdKwOguvk6mj9lfuGZrNW/gdJXEO2ddu8fOYfDbLg3g8adupEhrBJpUAtpkYelcqYpwNDwTv2lFsxFt0vZkQpCR4IgbFSJ2G/wcF/2pZzVWnNGSAJbl1aLRlLUsw9x3TfPB//43XPXm3mNtaWL0+JZByqNVgr4eG/dgaSwgoNn0uFkSMjMfP8CyTxRNoF3jxjwd0yuwXLXxaeHC5+wq5Gc78CGUF7L/xpA68hhXC22wfCV+5V0+D34EsN044gFeoAnLre1aBJ21BOFeZHY= X-Forefront-Antispam-Report-Untrusted: CIP:40.67.248.234;CTRY:IE;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:nebula.arm.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230025)(4636009)(396003)(39860400002)(346002)(136003)(376002)(451199018)(36840700001)(46966006)(40470700004)(30864003)(2616005)(44832011)(5660300002)(8936002)(186003)(40480700001)(36860700001)(356005)(86362001)(36756003)(82310400005)(81166007)(82740400003)(40460700003)(336012)(2906002)(426003)(47076005)(83380400001)(316002)(7696005)(6916009)(8676002)(70206006)(70586007)(478600001)(1076003)(26005)(41300700001)(36900700001);DIR:OUT;SFP:1101; X-MS-Exchange-Transport-CrossTenantHeadersStamped: AS8PR08MB8038 X-MS-Exchange-Transport-CrossTenantHeadersStripped: DBAEUR03FT019.eop-EUR03.prod.protection.outlook.com X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id-Prvs: ec6a7984-f094-4022-34cc-08db2a18910f X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: hnwvXc+i4/fLn3cvemGyRdtawN4tbpx/8j9SDc4aKOpu3UNG5TT6uWORr/4a0euKrTMiJ1hNmDLVYBdKSBCekO6sw2dMkwVvv31A6UZCOs4uFp4cMbXJprwHgT0B4O9dtmPHlKaOnku/wKipV9s9Y2CHki0REDpUIM2fnC/w+bnJcgheKllggIJwdLy5aKNFNxyQcW2jDlnZQzGsFO8iAunrapRnKPYPO93+o2X7dUufM0npfxb3lnj99KTNhFFcirW9+9aGYf04K2f4um/a6/IJz/gk1jOjFwtuM6c/ZU2+r8SmgVJgB3ekX2c4aPi4Vd8PtZ95eMtD2068zfTNcRL2Yb12dVn2dFJi729H490M5M8UDs7ZhwjtG1EijMY1nFZ3E27KyN2AKslHKCw6DsFjyD/fnkD83JJA0gna+Ae2OmiPXIlNVZg1m1SQn6BfBhJOmK00i5nCtL4AzoQ3eXIJetDW7XCXBkp+8wppSOnF3EoWlR+PLIcixV1w7/OxqAL4zX7OZNB1q+Agc6TI1U8ULcve2ShYLUDq4EfMIyWokyEggAJtX5BVmnAaRE9snRH2JrW9jiJcEIMpC85S4Jxm7TasbQct936MDCV9UyGBuIQV/BLmOfrxsv3UM36WYAs74NEbDsJirHs435+sFGOaDY5IPCzcG/EucB9x7NQRw61C0AVhNEphoMx8vA6OXcwZCSp58E2PZzxPgtdGkg== X-Forefront-Antispam-Report: CIP:63.35.35.123;CTRY:IE;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:64aa7808-outbound-1.mta.getcheckrecipient.com;PTR:ec2-63-35-35-123.eu-west-1.compute.amazonaws.com;CAT:NONE;SFS:(13230025)(4636009)(346002)(396003)(39860400002)(376002)(136003)(451199018)(46966006)(40470700004)(36840700001)(7696005)(2616005)(47076005)(426003)(186003)(83380400001)(478600001)(336012)(316002)(26005)(70586007)(6916009)(70206006)(8676002)(1076003)(36860700001)(44832011)(41300700001)(5660300002)(30864003)(8936002)(82740400003)(40460700003)(81166007)(2906002)(40480700001)(36756003)(86362001)(82310400005);DIR:OUT;SFP:1101; X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Mar 2023 14:28:51.7892 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: b41e11cd-9bbe-4903-6345-08db2a1897d6 X-MS-Exchange-CrossTenant-Id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=f34e5979-57d9-4aaa-ad4d-b122a662184d;Ip=[63.35.35.123];Helo=[64aa7808-outbound-1.mta.getcheckrecipient.com] X-MS-Exchange-CrossTenant-AuthSource: DBAEUR03FT019.eop-EUR03.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: AS8PR08MB6005 X-Spam-Status: No, score=-11.6 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,FORGED_SPF_HELO,GIT_PATCH_0,KAM_DMARC_NONE,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,RCVD_IN_VALIDITY_RPBL,SPF_HELO_PASS,SPF_NONE,TXREP,UNPARSEABLE_RELAY autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: elfNN_aarch64_size_stubs has grown big, so factor out the call stub related code before adding new logic there. --- bfd/elfnn-aarch64.c | 552 ++++++++++++++++++++++---------------------- 1 file changed, 279 insertions(+), 273 deletions(-) diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c index bf8f913a66d..f858d10c596 100644 --- a/bfd/elfnn-aarch64.c +++ b/bfd/elfnn-aarch64.c @@ -4265,12 +4265,285 @@ _bfd_aarch64_erratum_843419_scan (bfd *input_bfd, asection *section, } -/* Determine and set the size of the stub section for a final link. +/* Add stub entries for calls. The basic idea here is to examine all the relocations looking for PC-relative calls to a target that is unreachable with a "bl" instruction. */ +static bool +_bfd_aarch64_add_call_stub_entries (bool *stub_changed, bfd *output_bfd, + struct bfd_link_info *info) +{ + struct elf_aarch64_link_hash_table *htab = elf_aarch64_hash_table (info); + bfd *input_bfd; + + for (input_bfd = info->input_bfds; input_bfd != NULL; + input_bfd = input_bfd->link.next) + { + Elf_Internal_Shdr *symtab_hdr; + asection *section; + Elf_Internal_Sym *local_syms = NULL; + + if (!is_aarch64_elf (input_bfd) + || (input_bfd->flags & BFD_LINKER_CREATED) != 0) + continue; + + /* We'll need the symbol table in a second. */ + symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; + if (symtab_hdr->sh_info == 0) + continue; + + /* Walk over each section attached to the input bfd. */ + for (section = input_bfd->sections; + section != NULL; section = section->next) + { + Elf_Internal_Rela *internal_relocs, *irelaend, *irela; + + /* If there aren't any relocs, then there's nothing more to do. */ + if ((section->flags & SEC_RELOC) == 0 + || section->reloc_count == 0 + || (section->flags & SEC_CODE) == 0) + continue; + + /* If this section is a link-once section that will be + discarded, then don't create any stubs. */ + if (section->output_section == NULL + || section->output_section->owner != output_bfd) + continue; + + /* Get the relocs. */ + internal_relocs + = _bfd_elf_link_read_relocs (input_bfd, section, NULL, + NULL, info->keep_memory); + if (internal_relocs == NULL) + goto error_ret_free_local; + + /* Now examine each relocation. */ + irela = internal_relocs; + irelaend = irela + section->reloc_count; + for (; irela < irelaend; irela++) + { + unsigned int r_type, r_indx; + enum elf_aarch64_stub_type stub_type; + struct elf_aarch64_stub_hash_entry *stub_entry; + asection *sym_sec; + bfd_vma sym_value; + bfd_vma destination; + struct elf_aarch64_link_hash_entry *hash; + const char *sym_name; + char *stub_name; + const asection *id_sec; + unsigned char st_type; + bfd_size_type len; + + r_type = ELFNN_R_TYPE (irela->r_info); + r_indx = ELFNN_R_SYM (irela->r_info); + + if (r_type >= (unsigned int) R_AARCH64_end) + { + bfd_set_error (bfd_error_bad_value); + error_ret_free_internal: + if (elf_section_data (section)->relocs == NULL) + free (internal_relocs); + goto error_ret_free_local; + } + + /* Only look for stubs on unconditional branch and + branch and link instructions. */ + if (r_type != (unsigned int) AARCH64_R (CALL26) + && r_type != (unsigned int) AARCH64_R (JUMP26)) + continue; + + /* Now determine the call target, its name, value, + section. */ + sym_sec = NULL; + sym_value = 0; + destination = 0; + hash = NULL; + sym_name = NULL; + if (r_indx < symtab_hdr->sh_info) + { + /* It's a local symbol. */ + Elf_Internal_Sym *sym; + Elf_Internal_Shdr *hdr; + + if (local_syms == NULL) + { + local_syms + = (Elf_Internal_Sym *) symtab_hdr->contents; + if (local_syms == NULL) + local_syms + = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, + symtab_hdr->sh_info, 0, + NULL, NULL, NULL); + if (local_syms == NULL) + goto error_ret_free_internal; + } + + sym = local_syms + r_indx; + hdr = elf_elfsections (input_bfd)[sym->st_shndx]; + sym_sec = hdr->bfd_section; + if (!sym_sec) + /* This is an undefined symbol. It can never + be resolved. */ + continue; + + if (ELF_ST_TYPE (sym->st_info) != STT_SECTION) + sym_value = sym->st_value; + destination = (sym_value + irela->r_addend + + sym_sec->output_offset + + sym_sec->output_section->vma); + st_type = ELF_ST_TYPE (sym->st_info); + sym_name + = bfd_elf_string_from_elf_section (input_bfd, + symtab_hdr->sh_link, + sym->st_name); + } + else + { + int e_indx; + + e_indx = r_indx - symtab_hdr->sh_info; + hash = ((struct elf_aarch64_link_hash_entry *) + elf_sym_hashes (input_bfd)[e_indx]); + + while (hash->root.root.type == bfd_link_hash_indirect + || hash->root.root.type == bfd_link_hash_warning) + hash = ((struct elf_aarch64_link_hash_entry *) + hash->root.root.u.i.link); + + if (hash->root.root.type == bfd_link_hash_defined + || hash->root.root.type == bfd_link_hash_defweak) + { + struct elf_aarch64_link_hash_table *globals = + elf_aarch64_hash_table (info); + sym_sec = hash->root.root.u.def.section; + sym_value = hash->root.root.u.def.value; + /* For a destination in a shared library, + use the PLT stub as target address to + decide whether a branch stub is + needed. */ + if (globals->root.splt != NULL && hash != NULL + && hash->root.plt.offset != (bfd_vma) - 1) + { + sym_sec = globals->root.splt; + sym_value = hash->root.plt.offset; + if (sym_sec->output_section != NULL) + destination = (sym_value + + sym_sec->output_offset + + sym_sec->output_section->vma); + } + else if (sym_sec->output_section != NULL) + destination = (sym_value + irela->r_addend + + sym_sec->output_offset + + sym_sec->output_section->vma); + } + else if (hash->root.root.type == bfd_link_hash_undefined + || (hash->root.root.type + == bfd_link_hash_undefweak)) + { + /* For a shared library, use the PLT stub as + target address to decide whether a long + branch stub is needed. + For absolute code, they cannot be handled. */ + struct elf_aarch64_link_hash_table *globals = + elf_aarch64_hash_table (info); + + if (globals->root.splt != NULL && hash != NULL + && hash->root.plt.offset != (bfd_vma) - 1) + { + sym_sec = globals->root.splt; + sym_value = hash->root.plt.offset; + if (sym_sec->output_section != NULL) + destination = (sym_value + + sym_sec->output_offset + + sym_sec->output_section->vma); + } + else + continue; + } + else + { + bfd_set_error (bfd_error_bad_value); + goto error_ret_free_internal; + } + st_type = ELF_ST_TYPE (hash->root.type); + sym_name = hash->root.root.root.string; + } + + /* Determine what (if any) linker stub is needed. */ + stub_type = aarch64_type_of_stub (section, irela, sym_sec, + st_type, destination); + if (stub_type == aarch64_stub_none) + continue; + + /* Support for grouping stub sections. */ + id_sec = htab->stub_group[section->id].link_sec; + + /* Get the name of this stub. */ + stub_name = elfNN_aarch64_stub_name (id_sec, sym_sec, hash, + irela); + if (!stub_name) + goto error_ret_free_internal; + + stub_entry = + aarch64_stub_hash_lookup (&htab->stub_hash_table, + stub_name, false, false); + if (stub_entry != NULL) + { + /* The proper stub has already been created. */ + free (stub_name); + + /* Always update this stub's target since it may have + changed after layout. */ + stub_entry->target_value = sym_value + irela->r_addend; + continue; + } + + stub_entry = _bfd_aarch64_add_stub_entry_in_group + (stub_name, section, htab); + if (stub_entry == NULL) + { + free (stub_name); + goto error_ret_free_internal; + } + + stub_entry->target_value = sym_value + irela->r_addend; + stub_entry->target_section = sym_sec; + stub_entry->stub_type = stub_type; + stub_entry->h = hash; + stub_entry->st_type = st_type; + + if (sym_name == NULL) + sym_name = "unnamed"; + len = sizeof (STUB_ENTRY_NAME) + strlen (sym_name); + stub_entry->output_name = bfd_alloc (htab->stub_bfd, len); + if (stub_entry->output_name == NULL) + { + free (stub_name); + goto error_ret_free_internal; + } + + snprintf (stub_entry->output_name, len, STUB_ENTRY_NAME, + sym_name); + + *stub_changed = true; + } + + /* We're done with the internal relocs, free them. */ + if (elf_section_data (section)->relocs == NULL) + free (internal_relocs); + } + } + return true; + error_ret_free_local: + return false; +} + + +/* Determine and set the size of the stub section for a final link. */ + bool elfNN_aarch64_size_stubs (bfd *output_bfd, bfd *stub_bfd, @@ -4282,7 +4555,6 @@ elfNN_aarch64_size_stubs (bfd *output_bfd, { bfd_size_type stub_group_size; bool stubs_always_before_branch; - bool stub_changed = false; struct elf_aarch64_link_hash_table *htab = elf_aarch64_hash_table (info); unsigned int num_erratum_835769_fixes = 0; @@ -4357,285 +4629,19 @@ elfNN_aarch64_size_stubs (bfd *output_bfd, (*htab->layout_sections_again) (); } - while (1) + for (;;) { - bfd *input_bfd; - - for (input_bfd = info->input_bfds; - input_bfd != NULL; input_bfd = input_bfd->link.next) - { - Elf_Internal_Shdr *symtab_hdr; - asection *section; - Elf_Internal_Sym *local_syms = NULL; - - if (!is_aarch64_elf (input_bfd) - || (input_bfd->flags & BFD_LINKER_CREATED) != 0) - continue; - - /* We'll need the symbol table in a second. */ - symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; - if (symtab_hdr->sh_info == 0) - continue; - - /* Walk over each section attached to the input bfd. */ - for (section = input_bfd->sections; - section != NULL; section = section->next) - { - Elf_Internal_Rela *internal_relocs, *irelaend, *irela; - - /* If there aren't any relocs, then there's nothing more - to do. */ - if ((section->flags & SEC_RELOC) == 0 - || section->reloc_count == 0 - || (section->flags & SEC_CODE) == 0) - continue; - - /* If this section is a link-once section that will be - discarded, then don't create any stubs. */ - if (section->output_section == NULL - || section->output_section->owner != output_bfd) - continue; - - /* Get the relocs. */ - internal_relocs - = _bfd_elf_link_read_relocs (input_bfd, section, NULL, - NULL, info->keep_memory); - if (internal_relocs == NULL) - goto error_ret_free_local; - - /* Now examine each relocation. */ - irela = internal_relocs; - irelaend = irela + section->reloc_count; - for (; irela < irelaend; irela++) - { - unsigned int r_type, r_indx; - enum elf_aarch64_stub_type stub_type; - struct elf_aarch64_stub_hash_entry *stub_entry; - asection *sym_sec; - bfd_vma sym_value; - bfd_vma destination; - struct elf_aarch64_link_hash_entry *hash; - const char *sym_name; - char *stub_name; - const asection *id_sec; - unsigned char st_type; - bfd_size_type len; - - r_type = ELFNN_R_TYPE (irela->r_info); - r_indx = ELFNN_R_SYM (irela->r_info); - - if (r_type >= (unsigned int) R_AARCH64_end) - { - bfd_set_error (bfd_error_bad_value); - error_ret_free_internal: - if (elf_section_data (section)->relocs == NULL) - free (internal_relocs); - goto error_ret_free_local; - } - - /* Only look for stubs on unconditional branch and - branch and link instructions. */ - if (r_type != (unsigned int) AARCH64_R (CALL26) - && r_type != (unsigned int) AARCH64_R (JUMP26)) - continue; - - /* Now determine the call target, its name, value, - section. */ - sym_sec = NULL; - sym_value = 0; - destination = 0; - hash = NULL; - sym_name = NULL; - if (r_indx < symtab_hdr->sh_info) - { - /* It's a local symbol. */ - Elf_Internal_Sym *sym; - Elf_Internal_Shdr *hdr; - - if (local_syms == NULL) - { - local_syms - = (Elf_Internal_Sym *) symtab_hdr->contents; - if (local_syms == NULL) - local_syms - = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, - symtab_hdr->sh_info, 0, - NULL, NULL, NULL); - if (local_syms == NULL) - goto error_ret_free_internal; - } - - sym = local_syms + r_indx; - hdr = elf_elfsections (input_bfd)[sym->st_shndx]; - sym_sec = hdr->bfd_section; - if (!sym_sec) - /* This is an undefined symbol. It can never - be resolved. */ - continue; - - if (ELF_ST_TYPE (sym->st_info) != STT_SECTION) - sym_value = sym->st_value; - destination = (sym_value + irela->r_addend - + sym_sec->output_offset - + sym_sec->output_section->vma); - st_type = ELF_ST_TYPE (sym->st_info); - sym_name - = bfd_elf_string_from_elf_section (input_bfd, - symtab_hdr->sh_link, - sym->st_name); - } - else - { - int e_indx; + bool stub_changed = false; - e_indx = r_indx - symtab_hdr->sh_info; - hash = ((struct elf_aarch64_link_hash_entry *) - elf_sym_hashes (input_bfd)[e_indx]); - - while (hash->root.root.type == bfd_link_hash_indirect - || hash->root.root.type == bfd_link_hash_warning) - hash = ((struct elf_aarch64_link_hash_entry *) - hash->root.root.u.i.link); - - if (hash->root.root.type == bfd_link_hash_defined - || hash->root.root.type == bfd_link_hash_defweak) - { - struct elf_aarch64_link_hash_table *globals = - elf_aarch64_hash_table (info); - sym_sec = hash->root.root.u.def.section; - sym_value = hash->root.root.u.def.value; - /* For a destination in a shared library, - use the PLT stub as target address to - decide whether a branch stub is - needed. */ - if (globals->root.splt != NULL && hash != NULL - && hash->root.plt.offset != (bfd_vma) - 1) - { - sym_sec = globals->root.splt; - sym_value = hash->root.plt.offset; - if (sym_sec->output_section != NULL) - destination = (sym_value - + sym_sec->output_offset - + - sym_sec->output_section->vma); - } - else if (sym_sec->output_section != NULL) - destination = (sym_value + irela->r_addend - + sym_sec->output_offset - + sym_sec->output_section->vma); - } - else if (hash->root.root.type == bfd_link_hash_undefined - || (hash->root.root.type - == bfd_link_hash_undefweak)) - { - /* For a shared library, use the PLT stub as - target address to decide whether a long - branch stub is needed. - For absolute code, they cannot be handled. */ - struct elf_aarch64_link_hash_table *globals = - elf_aarch64_hash_table (info); - - if (globals->root.splt != NULL && hash != NULL - && hash->root.plt.offset != (bfd_vma) - 1) - { - sym_sec = globals->root.splt; - sym_value = hash->root.plt.offset; - if (sym_sec->output_section != NULL) - destination = (sym_value - + sym_sec->output_offset - + - sym_sec->output_section->vma); - } - else - continue; - } - else - { - bfd_set_error (bfd_error_bad_value); - goto error_ret_free_internal; - } - st_type = ELF_ST_TYPE (hash->root.type); - sym_name = hash->root.root.root.string; - } - - /* Determine what (if any) linker stub is needed. */ - stub_type = aarch64_type_of_stub (section, irela, sym_sec, - st_type, destination); - if (stub_type == aarch64_stub_none) - continue; - - /* Support for grouping stub sections. */ - id_sec = htab->stub_group[section->id].link_sec; - - /* Get the name of this stub. */ - stub_name = elfNN_aarch64_stub_name (id_sec, sym_sec, hash, - irela); - if (!stub_name) - goto error_ret_free_internal; - - stub_entry = - aarch64_stub_hash_lookup (&htab->stub_hash_table, - stub_name, false, false); - if (stub_entry != NULL) - { - /* The proper stub has already been created. */ - free (stub_name); - /* Always update this stub's target since it may have - changed after layout. */ - stub_entry->target_value = sym_value + irela->r_addend; - continue; - } - - stub_entry = _bfd_aarch64_add_stub_entry_in_group - (stub_name, section, htab); - if (stub_entry == NULL) - { - free (stub_name); - goto error_ret_free_internal; - } - - stub_entry->target_value = sym_value + irela->r_addend; - stub_entry->target_section = sym_sec; - stub_entry->stub_type = stub_type; - stub_entry->h = hash; - stub_entry->st_type = st_type; - - if (sym_name == NULL) - sym_name = "unnamed"; - len = sizeof (STUB_ENTRY_NAME) + strlen (sym_name); - stub_entry->output_name = bfd_alloc (htab->stub_bfd, len); - if (stub_entry->output_name == NULL) - { - free (stub_name); - goto error_ret_free_internal; - } - - snprintf (stub_entry->output_name, len, STUB_ENTRY_NAME, - sym_name); - - stub_changed = true; - } - - /* We're done with the internal relocs, free them. */ - if (elf_section_data (section)->relocs == NULL) - free (internal_relocs); - } - } + if (!_bfd_aarch64_add_call_stub_entries (&stub_changed, output_bfd, info)) + return false; if (!stub_changed) - break; + return true; _bfd_aarch64_resize_stubs (htab); - - /* Ask the linker to do its stuff. */ (*htab->layout_sections_again) (); - stub_changed = false; } - - return true; - - error_ret_free_local: - return false; } /* Build all the stubs associated with the current output file. The -- 2.25.1