From patchwork Mon May 6 04:45:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hau Hsu X-Patchwork-Id: 89513 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 C325D3858C98 for ; Mon, 6 May 2024 04:46:10 +0000 (GMT) X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from mail-pl1-x632.google.com (mail-pl1-x632.google.com [IPv6:2607:f8b0:4864:20::632]) by sourceware.org (Postfix) with ESMTPS id 2FD2F3858D1E for ; Mon, 6 May 2024 04:45:36 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 2FD2F3858D1E Authentication-Results: sourceware.org; dmarc=pass (p=reject dis=none) header.from=sifive.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=sifive.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 2FD2F3858D1E Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::632 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1714970737; cv=none; b=bfz4x3/O/CFGTZCiNrWyJIogp8JkKdDnj8QTJ9Yy+cHr1XffuOhQgFABdY3RzvqwKq7WsvxMxmJsILUNzNnjnA1ryRGskGFPSnM3w1IbbpKHLSeQQOF80qXhtZMwQ9DUh345uB/J0KkwEISycxN76KaXSiwBgyPRwfwmFlsBhTs= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1714970737; c=relaxed/simple; bh=chKkHEfUdkShlmPmkKliPhLd9k9cTUbOja7G/5yQ0dY=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=FYEVbYDA3vRQtVmZ8IgRM394+TIDG3CTbrToZ2gXEdrIXDacB+YqYOAo8Mk4eukn174bwEddKsbWkkP+ggFUWQCmMfiGpZO0r7WpZCxvS1bwhfkgRBAODZ9oXczGDlRI0a+0DtE7D4c2tkc6lS1HJb1FXhaMynV/r8q4vUGmOtA= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pl1-x632.google.com with SMTP id d9443c01a7336-1edfc57ac0cso4041095ad.3 for ; Sun, 05 May 2024 21:45:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1714970734; x=1715575534; darn=sourceware.org; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:from:to:cc:subject:date:message-id:reply-to; bh=KFdIGhBkb536R1DHpdVlXxEoy9Z1hrQzR0F8HHdBnbE=; b=GhotsEHUf3jVJkq4y10O//iMbSQu5FdZeFjdPkzC0MTptsybv0e1e4kIual2hLdThk aiev+Mn7nT4oOIbM9F/vGVb7qFmDWTp8zU5C8D5vmtaNWf9NMVx5ZBXK3FWyPCSqFTY8 3kyz+ugjg4jL/3gaMlLjdoPfWcEXiT8PNPBBcIkP31mOLMW+b4zE9MdqRNAWADyfOhUz sTeWU8O7wBVdmsSQD4UA4ghOZ58vTdfg60KgmElxg/QqeXHmEuh8lUJTYYN436ALHR7l 18+EwqEQbgsZdNmWXc22p2gXHA4bdwmerwQfHe4cJthdFy5Sk/yDsBo1SjD+NpYCxMJv VmMw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714970734; x=1715575534; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=KFdIGhBkb536R1DHpdVlXxEoy9Z1hrQzR0F8HHdBnbE=; b=avNa377j4Bs/5xdyuptyxLsyIK2jnf0kI9HizfuK4wp28wpcXk/4eh3b6mkJaFyt9L YNZBTgbaqRVMrnn0ZvsTO3CKh67qiML/pvqTRBVM66Y73LiziHVLckKLWhtDCpTXXsr6 q6O8Y9MkkQJEIxF/7DGgYUiM4zpPMD8dOcrCyU+VqnoV9GQ5A06QYJuwBdOInvVGWST6 ZFy2VVgY0dP6iU5Ei9Ti/gY2MG+qvcD4IzpxDbXtiJD4DlgG+G6JhOBt1imHFvrHD8Q1 +vgprsEWKUGg8XML+s8GTbEu/jT4ZVNNkj7N+81SFu0lZhmEt66S+QJtYr8dZWWsesvj 4itA== X-Gm-Message-State: AOJu0YzDD2fzXdNHEbnpM39Amxd+q3FWA/ienP9JgSqzpoDhEy78EcLQ OUQ0buYX3kTNoFrQyKh3N0SGT5xSvZaDBqIbdK3HUUs624x6D5ZUt/B98w+sL1/qlTvueceh2Fb KHNbhjoPUWXxLVp68yGGZt+yu9ull4mJzQOyXixesVaZJ0c5/bhg42iJVVdjjLNLC8rShF7EDrX nr8WdVXemM68wkwrpzvsSTPcxTI4xQmxOHIbG0 X-Google-Smtp-Source: AGHT+IEa0Otm7XFCDilOX0FLkmTOROTUJn1aH3mDaOiF4ysdrfSq/0wnfsLC4t4Ts9MOTOacFexlnQ== X-Received: by 2002:a17:902:7288:b0:1e3:e1e8:bb5 with SMTP id d8-20020a170902728800b001e3e1e80bb5mr8191229pll.28.1714970733894; Sun, 05 May 2024 21:45:33 -0700 (PDT) Received: from sw05.internal.sifive.com ([4.53.31.132]) by smtp.gmail.com with ESMTPSA id s11-20020a170902ea0b00b001e3e081d07esm7304810plg.179.2024.05.05.21.45.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 05 May 2024 21:45:33 -0700 (PDT) From: Hau Hsu To: binutils@sourceware.org, kito.cheng@gmail.com, hau.hsu@sifive.com Subject: [PATCH 1/2] riscv: Add POINTER_LOCAL_IFUNC_P/PLT_LOCAL_IFUNC_P Date: Mon, 6 May 2024 12:45:19 +0800 Message-Id: <20240506044520.2780464-1-hau.hsu@sifive.com> X-Mailer: git-send-email 2.37.1 MIME-Version: 1.0 X-Spam-Status: No, score=-12.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: binutils@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: binutils-bounces+patchwork=sourceware.org@sourceware.org Add POINTER_LOCAL_IFUNC_P which returns TRUE for pointer reference to local IFUNC symbol. Add PLT_LOCAL_IFUNC_P which returns TRUE for PLT reference to local IFUNC symbol. Copied from x86 commit: cf1070f1a1ca1f8be1cd88aa6ece55a25e6a887b --- bfd/elfnn-riscv.c | 11 ++--------- bfd/elfxx-riscv.h | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c index 95abf2d10e2..3a30b7a4bd9 100644 --- a/bfd/elfnn-riscv.c +++ b/bfd/elfnn-riscv.c @@ -2373,9 +2373,7 @@ riscv_elf_relocate_section (bfd *output_bfd, outrel.r_offset += input_section->output_section->vma + input_section->output_offset; - if (h->dynindx == -1 - || h->forced_local - || bfd_link_executable (info)) + if (POINTER_LOCAL_IFUNC_P (info, h)) { info->callbacks->minfo (_("Local IFUNC function `%s' in %pB\n"), @@ -3272,12 +3270,7 @@ riscv_elf_finish_dynamic_symbol (bfd *output_bfd, bfd_put_NN (output_bfd, sec_addr (plt), loc); rela.r_offset = got_address; - - if (h->dynindx == -1 - || ((bfd_link_executable (info) - || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT) - && h->def_regular - && h->type == STT_GNU_IFUNC)) + if (PLT_LOCAL_IFUNC_P (info, h)) { info->callbacks->minfo (_("Local IFUNC function `%s' in %pB\n"), h->root.root.string, diff --git a/bfd/elfxx-riscv.h b/bfd/elfxx-riscv.h index 49be71746b9..9efac27864c 100644 --- a/bfd/elfxx-riscv.h +++ b/bfd/elfxx-riscv.h @@ -27,6 +27,20 @@ #define RISCV_UNKNOWN_VERSION -1 +/* TRUE if this is a pointer reference to a local IFUNC. */ +#define POINTER_LOCAL_IFUNC_P(INFO, H) \ + ((H)->dynindx == -1 \ + || (H)->forced_local \ + || bfd_link_executable (INFO)) + +/* TRUE if this is a PLT reference to a local IFUNC. */ +#define PLT_LOCAL_IFUNC_P(INFO, H) \ + ((H)->dynindx == -1 \ + || ((bfd_link_executable (INFO) \ + || ELF_ST_VISIBILITY ((H)->other) != STV_DEFAULT) \ + && (H)->def_regular \ + && (H)->type == STT_GNU_IFUNC)) + struct riscv_elf_params { /* Whether to relax code sequences to GP-relative addressing. */ From patchwork Mon May 6 04:45:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hau Hsu X-Patchwork-Id: 89514 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 75F50384AB51 for ; Mon, 6 May 2024 04:46:22 +0000 (GMT) X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from mail-pl1-x633.google.com (mail-pl1-x633.google.com [IPv6:2607:f8b0:4864:20::633]) by sourceware.org (Postfix) with ESMTPS id 410173858D38 for ; Mon, 6 May 2024 04:45:45 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 410173858D38 Authentication-Results: sourceware.org; dmarc=pass (p=reject dis=none) header.from=sifive.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=sifive.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 410173858D38 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::633 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1714970748; cv=none; b=QaP61aDORvEp1fg625gpTSbk2alNPvcnNThksnhcQXbnLMcga7hlf9CCVVYF/QqUA6jEKz4hk4xTpfg2E2JaL7WQe/4kGEJx0/hxAfZLu+WVMQ+1WhE0Hr68KAQzWObKtfWrMFkoy2/NxgMFaNgT3FAUuNrQ1i3CVE7uAzem3wA= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1714970748; c=relaxed/simple; bh=fNjkHJQkZM5mdxQrp/qpzFsKzhv67OnjEt2LNpII11w=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=Z0ymu9uw/NRENzUAL9gTE19tnuZ0KavnZARozBTJeqjYWfYK4Vu2XQz5x6i0XEe4hZZ5dIzd0zHZuxwBT/FdCeF0d6keqEufyNexyImaKKXVCweDw9kGfd9RxXgZAcuiTghm0O6SMeCsCmHte/IbWSKYDV/Me8lhNpgLC3H86rs= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pl1-x633.google.com with SMTP id d9443c01a7336-1eab16dcfd8so9327715ad.0 for ; Sun, 05 May 2024 21:45:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1714970744; x=1715575544; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=Nm6OMSlaCCfLCClAABJuu2rZnRcW6xA5yvZ0jWYk5VQ=; b=ldkPQBQeYk7NoEBkoOr8LDiEtOe9etawzvIduUOvS7oxL63athtRdfSGWB1ji8pv/v i/EScqVbtUg8qay6cTXEUKmkS94wu2bhdRLwkRs6NvcOmZQqyPTPTZyRcudX0Prd2cF2 DyOWMO2/+KxLzwYvOTpKzAx89D7RuebkZMo+a+cBNPw7wpRfNDKaWK64V9K79LqQtyKa Td4jj9utiTDS6qe+u5liTij9rh6OOVET5UCgcPhXprDhPHyjAzuwzVaFT2VbGg2K3tPV ieIXXyyocWacdrFUeOnT7vDWEuPWMNW98U31r598OQleeKvRzxrasJ/8wfGhK8jpXwHj wPOw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714970744; x=1715575544; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Nm6OMSlaCCfLCClAABJuu2rZnRcW6xA5yvZ0jWYk5VQ=; b=sgnZgwNsmdrp9FMv/eO13eKhscBUUpNP9dQ2frtkkn0qLRanGAqbI3L4jROrwBBbuK jZJNkpz3QM0c6uvj0uffkR6xcCIzdMMZ9+v8Gowp43KRkjREZmx1fTINwPJf0gwWrd6B S+LCisHs1OUkb1Iun7N0+pEeXsY7mBXgRWy3/Dla+yBoP+S/p15M7QKKBWQkw+bf38xm sAeSYNfI/6w3AH2vvElO5mqWyJV9Lwf0sPZYxtV894mOMq5eKufweJDMUYq3Z/2FmgOx NqxwI1LB6LgZ/gtyOXFzrlywqo8wUR6d66bYqcr7bZxJ5+8zBZDreS1qapg4nc6arlVd JRdw== X-Gm-Message-State: AOJu0Yxv0YpEdxqKlmTeBKInUiPpIOxG5XGhrqu3cmh00/pf0vUhyXi9 GfCg7avJ65fRs6kBXSMb3zIeM7/BBviCrWwHQMGPeHLXAJ0ewyP1+JcF+ZANw4J3HRfP8a9VLiv 8l/5+Y170tt2B5FUflU3lVGD0NA+amUZxbtNBLiNHx3hBCihivH9RNH9w+QKfsY5YHwU8xikuJJ bjE8tmpTn2GDtp2uVnYWB/+612tRihki7P5Oz5pXs= X-Google-Smtp-Source: AGHT+IEU+IyUdcjhjYCdiCbzVVn/dH+YCH7JL7cmyfuBqcsXvsRS+U32PeJd4agLct39TX6P507a2g== X-Received: by 2002:a17:902:e84d:b0:1eb:a636:ecab with SMTP id t13-20020a170902e84d00b001eba636ecabmr9804846plg.34.1714970743276; Sun, 05 May 2024 21:45:43 -0700 (PDT) Received: from sw05.internal.sifive.com ([4.53.31.132]) by smtp.gmail.com with ESMTPSA id s11-20020a170902ea0b00b001e3e081d07esm7304810plg.179.2024.05.05.21.45.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 05 May 2024 21:45:42 -0700 (PDT) From: Hau Hsu To: binutils@sourceware.org, kito.cheng@gmail.com, hau.hsu@sifive.com Subject: [PATCH 2/2] riscv: Fix R_RISCV_IRELATIVE overwrite and order issues Date: Mon, 6 May 2024 12:45:20 +0800 Message-Id: <20240506044520.2780464-2-hau.hsu@sifive.com> X-Mailer: git-send-email 2.37.1 In-Reply-To: <20240506044520.2780464-1-hau.hsu@sifive.com> References: <20240506044520.2780464-1-hau.hsu@sifive.com> MIME-Version: 1.0 X-Spam-Status: No, score=-11.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_STOCKGEN, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: binutils@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: binutils-bounces+patchwork=sourceware.org@sourceware.org This commit resolved two issues: 1. When an ifunc is referenced by a pointer, the relocation of the pointer in .rela.plt would be overwritten by normal ifunc call. 2. R_RISCV_IRELATIVE should come last. See https://sourceware.org/bugzilla/show_bug.cgi?id=13302 This patch fixes above issues with the implementation similar to x86. That is, by adding two variables to record the next relocation index for R_RISCV_IRELATIVE and R_RISCV_JUMP_SLOT. A previous commit partially fixed the overwrite issue: https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=51a8a7c2e3cc0730831963651a55d23d1fae624d Details below: There are three ways to access a local (non-preemptible) ifunc: (1) Through PLT + GOT, i.e. use normal function call. (2) Through GOT, i.e. use a local function pointer. (3) Through a global function pointer. For (1) and (2), a R_RISCV_IRELATIVE is created for GOT entry. For (3), a R_RISCV_IRELATIVE is created for the global pointer. The relocations overwrite issue is that, the R_RISCV_IRELATIVE created for (1) overwrite the relocations for (2) and (3). The previous commit partially fixed the overwrite issue for (2), but not for (3). --- bfd/elfnn-riscv.c | 65 +++++++++---------- ld/testsuite/ld-riscv-elf/ifunc-macro.s | 19 ++++++ .../ifunc-plt-got-overwrite-02-exe.rd | 4 ++ .../ifunc-plt-got-overwrite-02-pic.rd | 11 ++++ .../ifunc-plt-got-overwrite-02-pie.rd | 7 ++ .../ld-riscv-elf/ifunc-plt-got-overwrite-02.d | 16 +++++ .../ld-riscv-elf/ifunc-plt-got-overwrite-02.s | 34 ++++++++++ ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp | 7 ++ ld/testsuite/ld-riscv-elf/variant_cc-now.d | 4 +- ld/testsuite/ld-riscv-elf/variant_cc-shared.d | 4 +- 10 files changed, 132 insertions(+), 39 deletions(-) create mode 100644 ld/testsuite/ld-riscv-elf/ifunc-macro.s create mode 100644 ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite-02-exe.rd create mode 100644 ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite-02-pic.rd create mode 100644 ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite-02-pie.rd create mode 100644 ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite-02.d create mode 100644 ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite-02.s diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c index 3a30b7a4bd9..d9243648d24 100644 --- a/bfd/elfnn-riscv.c +++ b/bfd/elfnn-riscv.c @@ -224,8 +224,12 @@ struct riscv_elf_link_hash_table htab_t loc_hash_table; void * loc_hash_memory; - /* The index of the last unused .rel.iplt slot. */ - bfd_vma last_iplt_index; + /* The index of the next R_RISCV_JUMP_SLOT entry in .rela.plt. */ + bfd_vma next_jump_slot_index; + + /* R_RISCV_IRELATIVE entry in .rela.plt comes last. + Use this to record the index of the next R_RISCV_IRELATIVE entry. */ + bfd_vma next_irelative_index; /* The data segment phase, don't relax the section when it is exp_seg_relro_adjust. */ @@ -1273,6 +1277,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) /* We also need to make an entry in the .rela.plt section. */ htab->elf.srelplt->size += sizeof (ElfNN_External_Rela); + htab->elf.srelplt->reloc_count ++; /* If this symbol is not defined in a regular file, and we are not generating a shared library, then set the symbol to this @@ -1622,10 +1627,14 @@ riscv_elf_late_size_sections (bfd *output_bfd, struct bfd_link_info *info) local ifunc symbols. */ htab_traverse (htab->loc_hash_table, allocate_local_ifunc_dynrelocs, info); - /* Used to resolve the dynamic relocs overwite problems when - generating static executable. */ - if (htab->elf.irelplt) - htab->last_iplt_index = htab->elf.irelplt->reloc_count - 1; + + htab->next_jump_slot_index = 0; + + if (htab->elf.srelplt) + htab->next_irelative_index = htab->elf.srelplt->reloc_count - 1; + else if (htab->elf.irelplt) + htab->next_irelative_index = htab->elf.irelplt->reloc_count - 1; + if (htab->elf.sgotplt) { @@ -3201,15 +3210,14 @@ riscv_elf_finish_dynamic_symbol (bfd *output_bfd, if (h->plt.offset != (bfd_vma) -1) { - /* We've decided to create a PLT entry for this symbol. */ + /* We've decided to create a PLT entry for this symbol. + Add a PLT entry, a GOT entry and a relocation entry. */ bfd_byte *loc; bfd_vma i, header_address, plt_idx, got_offset, got_address; uint32_t plt_entry[PLT_ENTRY_INSNS]; Elf_Internal_Rela rela; asection *plt, *gotplt, *relplt; - /* When building a static executable, use .iplt, .igot.plt and - .rela.iplt sections for STT_GNU_IFUNC symbols. */ if (htab->elf.splt != NULL) { plt = htab->elf.splt; @@ -3218,6 +3226,8 @@ riscv_elf_finish_dynamic_symbol (bfd *output_bfd, } else { + /* When building a static executable, use .iplt, .igot.plt and + .rela.iplt sections for STT_GNU_IFUNC symbols. */ plt = htab->elf.iplt; gotplt = htab->elf.igotplt; relplt = htab->elf.irelplt; @@ -3238,7 +3248,8 @@ riscv_elf_finish_dynamic_symbol (bfd *output_bfd, header_address = sec_addr (plt); /* Calculate the index of the entry and the offset of .got.plt entry. - For static executables, we don't reserve anything. */ + The index of .got.plt is the same as .plt (exclude the header entries), + since this section is dedicated for plt. */ if (plt == htab->elf.splt) { plt_idx = (h->plt.offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE; @@ -3246,6 +3257,7 @@ riscv_elf_finish_dynamic_symbol (bfd *output_bfd, } else { + /* For static executables, we don't need to reserve the header entry. */ plt_idx = h->plt.offset / PLT_ENTRY_SIZE; got_offset = plt_idx * GOT_ENTRY_SIZE; } @@ -3269,6 +3281,7 @@ riscv_elf_finish_dynamic_symbol (bfd *output_bfd, loc = gotplt->contents + (got_address - sec_addr (gotplt)); bfd_put_NN (output_bfd, sec_addr (plt), loc); + /* Fill in the relocation entry. */ rela.r_offset = got_address; if (PLT_LOCAL_IFUNC_P (info, h)) { @@ -3283,17 +3296,20 @@ riscv_elf_finish_dynamic_symbol (bfd *output_bfd, rela.r_addend = h->root.u.def.value + sec->output_section->vma + sec->output_offset; + bfd_vma rela_idx = htab->next_irelative_index--; + loc = relplt->contents + rela_idx * sizeof (ElfNN_External_Rela); + bed->s->swap_reloca_out (output_bfd, &rela, loc); } else { /* Fill in the entry in the .rela.plt section. */ rela.r_info = ELFNN_R_INFO (h->dynindx, R_RISCV_JUMP_SLOT); rela.r_addend = 0; + bfd_vma rela_idx = htab->next_jump_slot_index++; + loc = relplt->contents + rela_idx * sizeof (ElfNN_External_Rela); + bed->s->swap_reloca_out (output_bfd, &rela, loc); } - loc = relplt->contents + plt_idx * sizeof (ElfNN_External_Rela); - bed->s->swap_reloca_out (output_bfd, &rela, loc); - if (!h->def_regular) { /* Mark the symbol as undefined, rather than as defined in @@ -3315,7 +3331,6 @@ riscv_elf_finish_dynamic_symbol (bfd *output_bfd, asection *sgot; asection *srela; Elf_Internal_Rela rela; - bool use_elf_append_rela = true; /* This symbol has an entry in the GOT. Set it up. */ @@ -3338,10 +3353,6 @@ riscv_elf_finish_dynamic_symbol (bfd *output_bfd, /* Use .rela.iplt section to store .got relocations in static executable. */ srela = htab->elf.irelplt; - - /* Do not use riscv_elf_append_rela to add dynamic - relocs. */ - use_elf_append_rela = false; } if (SYMBOL_REFERENCES_LOCAL (info, h)) @@ -3417,23 +3428,7 @@ riscv_elf_finish_dynamic_symbol (bfd *output_bfd, bfd_put_NN (output_bfd, 0, sgot->contents + (h->got.offset & ~(bfd_vma) 1)); - if (use_elf_append_rela) - riscv_elf_append_rela (output_bfd, srela, &rela); - else - { - /* Use riscv_elf_append_rela to add the dynamic relocs into - .rela.iplt may cause the overwrite problems. Since we insert - the relocs for PLT didn't handle the reloc_index of .rela.iplt, - but the riscv_elf_append_rela adds the relocs to the place - that are calculated from the reloc_index (in seqential). - - One solution is that add these dynamic relocs (GOT IFUNC) - from the last of .rela.iplt section. */ - bfd_vma iplt_idx = htab->last_iplt_index--; - bfd_byte *loc = srela->contents - + iplt_idx * sizeof (ElfNN_External_Rela); - bed->s->swap_reloca_out (output_bfd, &rela, loc); - } + riscv_elf_append_rela (output_bfd, srela, &rela); } if (h->needs_copy) diff --git a/ld/testsuite/ld-riscv-elf/ifunc-macro.s b/ld/testsuite/ld-riscv-elf/ifunc-macro.s new file mode 100644 index 00000000000..88935a55814 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-macro.s @@ -0,0 +1,19 @@ +/* Define macros to handle similar behaviors for rv32/rv64. + Assumes macro "__64_bit__" defined for rv64. + The macro is specifically defined for ifunc tests in ld-riscv-elf.exp. */ + +.macro PTR_DATA name +.ifdef __64_bit__ + .quad \name +.else + .long \name +.endif +.endm + +.macro LOAD rd, rs, offset +.ifdef __64_bit__ + ld \rd, \offset (\rs) +.else + lw \rd, \offset (\rs) +.endif +.endm diff --git a/ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite-02-exe.rd b/ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite-02-exe.rd new file mode 100644 index 00000000000..0de47a4009f --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite-02-exe.rd @@ -0,0 +1,4 @@ +Relocation section '.rela.plt' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_IRELATIVE[ ]+[0-9a-f]* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_IRELATIVE[ ]+[0-9a-f]* diff --git a/ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite-02-pic.rd b/ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite-02-pic.rd new file mode 100644 index 00000000000..d7ecd4a4a69 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite-02-pic.rd @@ -0,0 +1,11 @@ +Relocation section '.rela.got' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_(32|64)[ ]+foo1\(\)[ ]+foo1 \+ 0 +#... +Relocation section '.rela.ifunc' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_(32|64)[ ]+foo2\(\)[ ]+foo2 \+ 0 +#... +Relocation section '.rela.plt' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_JUMP_SLOT[ ]+foo1\(\)[ ]+foo1 \+ 0 diff --git a/ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite-02-pie.rd b/ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite-02-pie.rd new file mode 100644 index 00000000000..532cbf8a86a --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite-02-pie.rd @@ -0,0 +1,7 @@ +Relocation section '.rela.ifunc' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_IRELATIVE[ ]+[0-9a-f]* + +Relocation section '.rela.plt' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_IRELATIVE[ ]+[0-9a-f]* diff --git a/ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite-02.d b/ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite-02.d new file mode 100644 index 00000000000..3e33ac619d4 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite-02.d @@ -0,0 +1,16 @@ +#... +Disassembly of section .plt: +#... +0+[0-9a-f]+ <(\*ABS\*\+0x[0-9a-f]+@plt|foo@plt|.plt)>: +#... +Disassembly of section .text: +#... +0+[0-9a-f]+ : +.*:[ ]+[0-9a-f]+[ ]+ret + +0+[0-9a-f]+ <_start>: +.*:[ ]+[0-9a-f]+[ ]+auipc[ ]+.* +.*:[ ]+[0-9a-f]+[ ]+(lw|ld)[ ]+.*<(.*)> +.*:[ ]+[0-9a-f]+[ ]+auipc[ ]+.* +.*:[ ]+[0-9a-f]+[ ]+jalr[ ]+.*<(.*plt.*)> +.*:[ ]+[0-9a-f]+[ ]+ret diff --git a/ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite-02.s b/ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite-02.s new file mode 100644 index 00000000000..ff6d171591c --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite-02.s @@ -0,0 +1,34 @@ +/* There are 2 ifuncs: foo1 and foo2. + foo1 is accessed by a function call. + foo2 is referenced by a global pointer (foo2_addr). */ + .include "ifunc-macro.s" + .globl foo2_addr + .section .data + .type foo2_addr, @object +foo2_addr: + PTR_DATA foo2 + + .text + .type foo_resolver, @function +foo_resolver: + ret + .size foo_resolver, .-foo_resolver + + .globl foo1 + .type foo1, %gnu_indirect_function + .set foo1, foo_resolver + + .globl foo2 + .type foo2, %gnu_indirect_function + .set foo2, foo_resolver + + .globl _start + .type _start, @function +_start: +.L1: + auipc x1, %got_pcrel_hi (foo1) + LOAD x1, x1, %pcrel_lo (.L1) + call foo1 + + ret + .size _start, .-_start diff --git a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp index a1dd0e5e37e..10011445683 100644 --- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp +++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp @@ -284,6 +284,13 @@ if [istarget "riscv*-*-*"] { run_dump_test_ifunc "ifunc-plt-got-overwrite" rv64 pie run_dump_test_ifunc "ifunc-plt-got-overwrite" rv64 pic + run_dump_test_ifunc "ifunc-plt-got-overwrite-02" rv32 exe + run_dump_test_ifunc "ifunc-plt-got-overwrite-02" rv32 pie + run_dump_test_ifunc "ifunc-plt-got-overwrite-02" rv32 pic + run_dump_test_ifunc "ifunc-plt-got-overwrite-02" rv64 exe + run_dump_test_ifunc "ifunc-plt-got-overwrite-02" rv64 pie + run_dump_test_ifunc "ifunc-plt-got-overwrite-02" rv64 pic + # TODO: Make the following tests work under RV32. if [istarget "riscv32-*-*"] { return diff --git a/ld/testsuite/ld-riscv-elf/variant_cc-now.d b/ld/testsuite/ld-riscv-elf/variant_cc-now.d index 9453554a159..3ed5ab3cae0 100644 --- a/ld/testsuite/ld-riscv-elf/variant_cc-now.d +++ b/ld/testsuite/ld-riscv-elf/variant_cc-now.d @@ -7,11 +7,11 @@ Relocation section '.rela.plt' at .* #... [0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_JUMP_SLOT[ ]+0+0000[ ]+nocc_global_default_undef \+ 0 [0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_JUMP_SLOT[ ]+0+0000[ ]+cc_global_default_undef \+ 0 +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_JUMP_SLOT[ ]+cc_global_default_ifunc\(\)[ ]+cc_global_default_ifunc \+ 0 +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_JUMP_SLOT[ ]+nocc_global_default_ifunc\(\)[ ]+nocc_global_default_ifunc \+ 0 [0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_JUMP_SLOT[ ]+0+8000[ ]+cc_global_default_def \+ 0 [0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_JUMP_SLOT[ ]+0+8000[ ]+nocc_global_default_def \+ 0 -[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_JUMP_SLOT[ ]+cc_global_default_ifunc\(\)[ ]+cc_global_default_ifunc \+ 0 [0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_IRELATIVE[ ]+8000 -[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_JUMP_SLOT[ ]+nocc_global_default_ifunc\(\)[ ]+nocc_global_default_ifunc \+ 0 [0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_IRELATIVE[ ]+8000 [0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_IRELATIVE[ ]+8050 [0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_IRELATIVE[ ]+8050 diff --git a/ld/testsuite/ld-riscv-elf/variant_cc-shared.d b/ld/testsuite/ld-riscv-elf/variant_cc-shared.d index ffb69a392f2..6b73cf1de20 100644 --- a/ld/testsuite/ld-riscv-elf/variant_cc-shared.d +++ b/ld/testsuite/ld-riscv-elf/variant_cc-shared.d @@ -7,11 +7,11 @@ Relocation section '.rela.plt' at .* #... [0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_JUMP_SLOT[ ]+0+0000[ ]+nocc_global_default_undef \+ 0 [0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_JUMP_SLOT[ ]+0+0000[ ]+cc_global_default_undef \+ 0 +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_JUMP_SLOT[ ]+cc_global_default_ifunc\(\)[ ]+cc_global_default_ifunc \+ 0 +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_JUMP_SLOT[ ]+nocc_global_default_ifunc\(\)[ ]+nocc_global_default_ifunc \+ 0 [0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_JUMP_SLOT[ ]+0+8000[ ]+cc_global_default_def \+ 0 [0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_JUMP_SLOT[ ]+0+8000[ ]+nocc_global_default_def \+ 0 -[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_JUMP_SLOT[ ]+cc_global_default_ifunc\(\)[ ]+cc_global_default_ifunc \+ 0 [0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_IRELATIVE[ ]+8000 -[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_JUMP_SLOT[ ]+nocc_global_default_ifunc\(\)[ ]+nocc_global_default_ifunc \+ 0 [0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_IRELATIVE[ ]+8000 [0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_IRELATIVE[ ]+8050 [0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_IRELATIVE[ ]+8050