From patchwork Tue Sep 1 02:33:08 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matt Turner X-Patchwork-Id: 142570 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 0070A4BA79A1 for ; Tue, 1 Sep 2026 02:34:28 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0070A4BA79A1 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=L4iDgDul X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from mail-yw1-x112b.google.com (mail-yw1-x112b.google.com [IPv6:2607:f8b0:4864:20::112b]) by sourceware.org (Postfix) with ESMTPS id 6D03B4BA23EB for ; Tue, 1 Sep 2026 02:33:24 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 6D03B4BA23EB Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 6D03B4BA23EB Authentication-Results: sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::112b ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1788230004; cv=none; b=d4ha5Z/W/3wpAWCUxGqaADee/H9Bgrxkppngk8gEQNTkzBPFLnvXdpQDInDGTz44V8X2p7Onr9vqo5NbtrYB6noDTZQzCW9scTRAQ9SRdTvG9AHkwdqw31Vtjda6HPQJCcLO6fk42F2tZxchk0uhoJbe0lNhHPsyMye/yxMH8wA= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1788230004; c=relaxed/simple; bh=4uwKW6oISFCkA+iUuiLE1X1X/IlHhTYwkw2N6LwQJ2E=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=XfAXED4O1Wie3ECYEPnmCJAsGh4F1+OhJ5jQwFXUTo4X0CPxM7ni481fx8cTO7kzZsgofcRq6cqjI5/G2nccF9E72HQK3lv2IR5hVPDKlzoe8JygbC38xI+9jc2k5SoV8uegCaSVpDTYIn81KdX8QCKNItbyK4uiZPwcermQ9VM= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=L4iDgDul DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6D03B4BA23EB Received: by mail-yw1-x112b.google.com with SMTP id 00721157ae682-8200b55dc47so40422007b3.3 for ; Mon, 31 Aug 2026 19:33:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788230004; x=1788834804; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=c49xvp6JYqq2Vm8oWKJh81pcIRZiVhEFuJezJBbnPGo=; b=L4iDgDulA5CH1qHB/nEn9bQXHvJPjrOfDqqbzxvWOhiVE49jQGhtCTtI5Fki/dB8+N U19sGFWhGYw3oOoi7AC/fC0EV5uWMU4JR3FuaNTTYWXzZLqSB0HMHYhM4RbsgpiS0Dg2 jd3gDlCFwzE66mE2/8/otXFKewvwqmiDbDZOWWSQXX6FhiU4wcRDBenPhwFwQ18VfDKE mGNPtewk0EJ5qB/MVW15P/gCWfnZ4iHHYqJqoyhmHMReTSocIca6rG99m7WqIH+RaTDT HJ1C7XV3MkoJlpn/37tJpyryhJ3p2JAuQUluUB3eDCM+CS8n6smziBA3Em5u36L79DQF dJpg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788230004; x=1788834804; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=c49xvp6JYqq2Vm8oWKJh81pcIRZiVhEFuJezJBbnPGo=; b=R5qCU+D+9eGYMp3TTJkQTMh4XQiWD4LwzOyHWvrsmkCCzPSRaPMg0Q9yvmGnEFi6hj Uw4DcZaXTPmLaZHIIR2ziXTCHJB1BhRxkJMC02Eg9C6zRo4lKugbjhvFdy6GMQptbehy CtQe3hEX6AoQMoCeD1UREmzLmdMfUnvnGUTJAA60Ryg3yZbpimez7/xIs+kI+QhjGszk yQHQRHDrTRyTYwaZSYatagWXPOr882OQKmACSBNF/Gs8s6F0Hou83N7h0UWlQo85slBf OdTIs7rHr2ASGRvnRmnTY0u1Kjc3y0b6RL5I3QPjaEbviME2Dtma6uhATJ9JUuQ72eX5 hH/w== X-Gm-Message-State: AFuF++m5svBqbZJtaH0ZfsrTjCkI3LuU1BDOJAhQvoWSY5NuHVECV78B HJ8uo7ZoZJ4mGHAFw+HREijaA3Ni4O728MgUSQ17qVESruAKdwpheW3FKnCPxA== X-Gm-Gg: AYBFou2vj2uPH3fNz3lTkJ4L/8KylrZ508xZF7TINuwu2SCZGChdqBXKGCzE8YrgaoC 5d5ABe3rC4vp515cVVShHJCOGfkwIqXv7+zi5QJyFb2VbCTS2n4dOTgib7tyURSVUKQWnEfFbxZ 63BOrZapFJH8UlwusVx4VeXPOkp6gRhmmkFsYFxIXUuZaTSkIHPjb1MC1/jcxavPQE+1f3f5+VS SWAhnZIPNV7uHwJWpYaFTFmkCNPW+OGLhpSJpGhfdwrG0s8PzczqB6t13pu+74CFAmCr+RCY+Pg cNgwgONxDBJsnESA6c3qlk8DrTm5XU3eq3wjkLoUpD+wvLiIfcVeU9CgVEPuxnUHD46isVollrc Sju5Iera+y1baKXd7xs4Sm0xpmC2iw29mzDMmKDDzbkA2YY7V429CL9jTGr0QdMZjfVVpsKOu+8 D7VCuLSymklNmtImkRnAxS1KORw8a8UlbK/Csir7ENQZpA4aiE93oP7F1pMG3mD4/8U9Crp91NE fe7J0rzzVTbzwBgVSu1/3vN5uWZZnuh+IL+8zRqfcWP9s83UBg= X-Received: by 2002:a05:690c:6608:b0:861:2228:a4d3 with SMTP id 00721157ae682-8612228af79mr56764897b3.19.1788230003473; Mon, 31 Aug 2026 19:33:23 -0700 (PDT) Received: from localhost (107-220-129-194.lightspeed.chrlnc.sbcglobal.net. [107.220.129.194]) by smtp.gmail.com with ESMTPSA id 00721157ae682-85e5ed19446sm64861357b3.14.2026.08.31.19.33.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Aug 2026 19:33:21 -0700 (PDT) From: Matt Turner To: binutils@sourceware.org Cc: Magnus Lindholm , Alan Modra , Matt Turner Subject: [PATCH 01/11] alpha: initialize every field of a new got entry Date: Mon, 31 Aug 2026 22:33:08 -0400 Message-ID: <20260901023318.3503991-2-mattst88@gmail.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260901023318.3503991-1-mattst88@gmail.com> References: <20260901023318.3503991-1-mattst88@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-11.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on 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 get_got_entry allocates a got entry with bfd_alloc and then assigns the fields one by one, but never assigns flags. elf64_alpha_merge_gots reads it, so two got subsections that merge OR uninitialized memory into the surviving entry. A literal always has flags assigned by check_relocs before then, from its LITUSEs or from the fallback that marks it as an address use, but an entry created for a TLS relocation has no such assignment. elf64_alpha_relax_tls_get_addr allocates one the same way when it switches a general dynamic sequence to initial exec and the object has no GOTTPREL entry yet. That one leaves both flags and plt_offset uninitialized, and a stray plt_offset is not a value the rest of the code expects to see. Allocate both with bfd_zalloc and assign only the fields whose initial value is not zero. A new field then needs no assignment at either site, rather than one that is easy to forget at the second. Found with valgrind. --- bfd/elf64-alpha.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git ./bfd/elf64-alpha.c ./bfd/elf64-alpha.c index 8b8a97a4b05..4fc1a542704 100644 --- ./bfd/elf64-alpha.c +++ ./bfd/elf64-alpha.c @@ -1718,7 +1718,7 @@ get_got_entry (bfd *abfd, struct alpha_elf_link_hash_entry *h, size_t amt; amt = sizeof (struct alpha_elf_got_entry); - gotent = (struct alpha_elf_got_entry *) bfd_alloc (abfd, amt); + gotent = (struct alpha_elf_got_entry *) bfd_zalloc (abfd, amt); if (!gotent) return NULL; @@ -1728,8 +1728,6 @@ get_got_entry (bfd *abfd, struct alpha_elf_link_hash_entry *h, gotent->plt_offset = -1; gotent->use_count = 1; gotent->reloc_type = r_type; - gotent->reloc_done = 0; - gotent->reloc_xlated = 0; gotent->next = *slot; *slot = gotent; @@ -3655,7 +3653,7 @@ elf64_alpha_relax_tls_get_addr (struct alpha_relax_info *info, bfd_vma symval, else { tprel_gotent = (struct alpha_elf_got_entry *) - bfd_alloc (info->abfd, sizeof (struct alpha_elf_got_entry)); + bfd_zalloc (info->abfd, sizeof (struct alpha_elf_got_entry)); if (!tprel_gotent) return false; @@ -3665,8 +3663,7 @@ elf64_alpha_relax_tls_get_addr (struct alpha_relax_info *info, bfd_vma symval, tprel_gotent->gotobj = info->gotobj; tprel_gotent->addend = irel->r_addend; tprel_gotent->got_offset = -1; - tprel_gotent->reloc_done = 0; - tprel_gotent->reloc_xlated = 0; + tprel_gotent->plt_offset = -1; } tprel_gotent->use_count = 1; From patchwork Tue Sep 1 02:33:09 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matt Turner X-Patchwork-Id: 142569 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 312AB4BA798E for ; Tue, 1 Sep 2026 02:34:22 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 312AB4BA798E Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=JGB8iTKb X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from mail-yw1-x1134.google.com (mail-yw1-x1134.google.com [IPv6:2607:f8b0:4864:20::1134]) by sourceware.org (Postfix) with ESMTPS id A465B4BA23ED for ; Tue, 1 Sep 2026 02:33:25 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A465B4BA23ED Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org A465B4BA23ED Authentication-Results: sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::1134 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1788230005; cv=none; b=XFwQjLN30kaROI5Bn5AEUTdrgz7bNPo2BNiQVMy2wiCQYhEtEZUq66AEFpxYEq6WahW/Th0Sri6PmIOdGPT+tVOgsj7w5StvLrr41IH/4EEE0TeSYojOT0z5SqzeHSoYBXtPltFB49uEAhGpWjM28BpWyD/20LzhMaJwmSFE1jM= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1788230005; c=relaxed/simple; bh=A4mZB7kplfwZ69GzNshJBc9I1OB2+pr+Ufe4H6T4/AE=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=vKZBDuHTdasfmd1sF42b3ptOk0zYWl4bOcHjk9TTucS/z3AmsVUVfcIjj4+1Jg+s2yq7YAnC4N2pTQ2KydjG18BAKxYGxBsRM9hGmzt7YRSxZc8oshUAyKEoNwM6mJbzOIp7vj4CkPNIhObF/HqYxCYsfDTav1q3E8LPspvIM9c= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=JGB8iTKb DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A465B4BA23ED Received: by mail-yw1-x1134.google.com with SMTP id 00721157ae682-81f36179d72so49437597b3.2 for ; Mon, 31 Aug 2026 19:33:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788230005; x=1788834805; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=R21kZVLV9T+nCC3J25pz9Pi11OAlQ2wyKnI3bgL46DM=; b=JGB8iTKb7XwwmzzerzGR0LuBcaPnBtf+5a5PzjVzmKD2u+h88fGF6aioRboJtJ8HSX pUiUNe4M47cECUvJfHWYa6xK3gVRZacuhJ3qYstkz6GX+w83mIhjcZco/Nr4w097yAqP nA++GT0Bg+hHi7V9pbCxJqwZRL9OspWZXpwJ9tZIPCP2zhlmRm67RlEuw8r3k1ScdNCG Y+vZ4yI0ynOd1z24rjj44LZo7HBsNHp5vlxb4DH1tvSxpHFk5GCOFw724kDddrhY247E qfYrxo8RChtB4aSrI7jyx4yHvRoPtmdjdNNsiiU629mzHbFuhTvtIu/8ET6yeYoFoSlC 0yvQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788230005; x=1788834805; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=R21kZVLV9T+nCC3J25pz9Pi11OAlQ2wyKnI3bgL46DM=; b=JoN6PpAuAzeuV73PWZhAZmlk7+x8yqK1f/6cHSq5y4Go3cvVewxIz6+oTwuJxqqb+S FWUyg/y8CCIUHdm3rnsm4Gp2KZ97g6fYYJnxX8pPlgXwvYiXUH367t1TKlNvtN6FCgBV +45+091BS2I26pThHgKYGAUBEHE8FxW/cPKWdk0a7rYk+17CfXxLrnSgShELLqKHECwX TpG9Nig5QFB44X1uh74m0lHogz3fSd+wUT1KrGWz3q9pC//zyCvivynY16DCb9SjRnfV NpJ5JY3CAdEzOg5FrVJlNX6fDR2Pw/49ituplFRn5zY74QE5wIsiMS8jH20kH7d6B/Gp d0LQ== X-Gm-Message-State: AFuF++mW2pc8233RgFwq4PcmwnvPAjjxYeJOS+bZ6ACZmzrI79FGncRB PcmIGFgVFQb7NY9O8QxDphLkukM6XKHP8QUEXmTjUfQeP6P7wHo0iPCjZssUMg== X-Gm-Gg: AYBFou3tjDp+5PLAqjI0UHTIbv5PPdKEfr6X9/QN9nEKwyusPUg6Q1Q4WiRIeWS8mP2 iXF80D5XLxX0Wn8a+BR6Ehv92jUrf757KioqdI7EELAGW3w6sgW80lTqy119pUOmX6xITWPmD/5 hE0PEY+NY317Mc3ceM9HUTMrkSIAAoO7PAoomIVGWx9H3dk8qCxO80r2IEpjG666BSiE869RxHa Tht1XTb0dJcI2GXIGvJJmLwAIUWp6LOSG6VVhPrS2h+BzN34uLydKaCqcThfeZVl7MO1/L8zN1S I18Bsi8SILAILpSTH1kG+S4AlYfktJZjKVKtiQTjJ4u6c+OwTmwd93Z/ETg1Y8GLcQ3A8lx08oZ KphCOUibh6J2/V8+t+XFVIxJzNGeC8SwhZtBrD5hsvTFnIRGfFue+lCdU0uvaCtnYpApAy01Hjy 6YbCcwGN8PQrNIX5Op9hQFV/zKgk0RaPq6k4wpVT1ou71WzOID5G17tZnQoQJt5YUogIyf/9y6y oI06QYWmbOWOk47tJkt+Mu/sKc4oMDZuKEvnJuc X-Received: by 2002:a05:690c:dd3:b0:80d:f376:5ba9 with SMTP id 00721157ae682-85d6c7e2969mr107972277b3.24.1788230004978; Mon, 31 Aug 2026 19:33:24 -0700 (PDT) Received: from localhost (107-220-129-194.lightspeed.chrlnc.sbcglobal.net. [107.220.129.194]) by smtp.gmail.com with ESMTPSA id 00721157ae682-85e66cad342sm66012937b3.40.2026.08.31.19.33.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Aug 2026 19:33:24 -0700 (PDT) From: Matt Turner To: binutils@sourceware.org Cc: Magnus Lindholm , Alan Modra , Matt Turner Subject: [PATCH 02/11] alpha: set DF_TEXTREL rather than DT_TEXTREL in info->flags Date: Mon, 31 Aug 2026 22:33:09 -0400 Message-ID: <20260901023318.3503991-3-mattst88@gmail.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260901023318.3503991-1-mattst88@gmail.com> References: <20260901023318.3503991-1-mattst88@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-11.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on 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 elf64_alpha_calc_dynrel_sizes ORs DT_TEXTREL (22) into info->flags where it means DF_TEXTREL (4). The value happens to include the DF_TEXTREL bit, so DT_TEXTREL still appeared, but DT_FLAGS also gained DF_SYMBOLIC and DF_STATIC_TLS: a shared library with a text relocation against a global symbol was treated by the dynamic linker as if linked with -Bsymbolic, and dlopen of it could fail for lack of static TLS. The stray DF_STATIC_TLS also fed back into the link: elf64_alpha_relax_sec reads info->flags to decide that a general dynamic TLS reference may as well be relaxed to initial exec, so such a library was relaxed differently too. Present since commit fcfbdf319ee in 2001, which introduced both this and the correct DF_TEXTREL a few lines above it. --- bfd/elf64-alpha.c | 2 +- ld/testsuite/ld-alpha/textrel.d | 9 +++++++++ ld/testsuite/ld-alpha/textrel.s | 13 +++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 ld/testsuite/ld-alpha/textrel.d create mode 100644 ld/testsuite/ld-alpha/textrel.s diff --git ./bfd/elf64-alpha.c ./bfd/elf64-alpha.c index 4fc1a542704..a97acdc41de 100644 --- ./bfd/elf64-alpha.c +++ ./bfd/elf64-alpha.c @@ -2667,7 +2667,7 @@ elf64_alpha_calc_dynrel_sizes (struct alpha_elf_link_hash_entry *h, entries * sizeof (Elf64_External_Rela) * relent->count; if ((sec->flags & SEC_READONLY) != 0) { - info->flags |= DT_TEXTREL; + info->flags |= DF_TEXTREL; info->callbacks->minfo (_("%pB: dynamic relocation against `%pT' in " "read-only section `%pA'\n"), diff --git ./ld/testsuite/ld-alpha/textrel.d ./ld/testsuite/ld-alpha/textrel.d new file mode 100644 index 00000000000..e319ab203d3 --- /dev/null +++ ./ld/testsuite/ld-alpha/textrel.d @@ -0,0 +1,9 @@ +#source: textrel.s +#ld: -shared -melf64alpha -z notext +#readelf: -d + +# Only DT_TEXTREL, with no DT_FLAGS carrying the SYMBOLIC and STATIC_TLS +# bits of the value of DT_TEXTREL. +#... + +0x0+16 +\(TEXTREL\) +0x0 + +0x0+0 +\(NULL\) +0x0 diff --git ./ld/testsuite/ld-alpha/textrel.s ./ld/testsuite/ld-alpha/textrel.s new file mode 100644 index 00000000000..bbd0675363d --- /dev/null +++ ./ld/testsuite/ld-alpha/textrel.s @@ -0,0 +1,13 @@ + .text + .globl _start +_start: + ret + + .data + .globl var +var: + .quad 0 + + # A dynamic relocation against a global symbol in a read-only section. + .section .rodata,"a",@progbits + .quad var From patchwork Tue Sep 1 02:33:10 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matt Turner X-Patchwork-Id: 142572 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 01F2E4BA9020 for ; Tue, 1 Sep 2026 02:36:18 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 01F2E4BA9020 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=AME+LqCc X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from mail-yw1-x1136.google.com (mail-yw1-x1136.google.com [IPv6:2607:f8b0:4864:20::1136]) by sourceware.org (Postfix) with ESMTPS id 7A18C4BA7995 for ; Tue, 1 Sep 2026 02:33:27 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 7A18C4BA7995 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 7A18C4BA7995 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::1136 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1788230007; cv=none; b=eLD+YxN07nw1Zba2GY1blDyITHJ8dNdZVd5R/vok8klSDePcw4h6/LJLiXxPeEVPR4pEgkV3S3zqQaHk5tdSqucbwgqOaPId0MFr/PfF3f38aJ6nHda03dMeMUK0fdhnHOZeCH+/e5HJVUW72w1Aw30onIpXOfbvTKAnU8IHgoE= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1788230007; c=relaxed/simple; bh=UNbL3tYBh8qWtNERXxX1rsSNgh7NswKfWAnfe7DmHuM=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=ojOAyaWU7BndrZEpVRCKVM5STyEdqqnNQhk36FV7CP6Wdbfs3zFbK9vzmL3c9S2wYK31AGfhsrgf9BCdHdr+OWOPcr2YvAI03tK08AvQmIfusIF/EVe+ooE3u1buW3UuG7oNYMmEb645Vhk0KCp4NJGlZq0RojKixSd6ygQT9hk= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=AME+LqCc DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7A18C4BA7995 Received: by mail-yw1-x1136.google.com with SMTP id 00721157ae682-836c8bde2dcso42111387b3.0 for ; Mon, 31 Aug 2026 19:33:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788230007; x=1788834807; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=jgS9qvhOkM+OETDeAOIr2+3kAYXxHuwdJLulROdIzLI=; b=AME+LqCcgkBXBsrzMdVyftXxq+zwDreSqJ/nu37P2GR8wlLHAtcWDfq0MMKPcDIbG+ QJtNLe+uR5bSKwkCzCrW2B8sX1D3mLByWq7jqgzgw90f9Uac6T89gekv6qw+tNBxkW45 +fnulhU0o7GU6Io9Ir+vHN8CS18gVlv3iWXVMq9s0uz2Z1U75lRrbJODHwiUfmsfEURi rJHpasoYbReAdbkYMeaJCnvsmlHaCaOanRHk6KHZb+O0kpEDGFmCnnZnXfWjZs43Y8Mk b0u0Lnk4D0si/ltwiaMYwNOt8H/tGcjQ9yR8voMrmHwDeGcBYxTv+ZMJ2RzUkDQVvxq7 kMtw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788230007; x=1788834807; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=jgS9qvhOkM+OETDeAOIr2+3kAYXxHuwdJLulROdIzLI=; b=WrgWfmNVSA0ucXks+SAz4sZPR+fdS5pgcEly6uCzw5URLLF6TvjCCo1KVo1LPpW57k Sx8FCrnm5JhjOCHf0tBgyuhmYjfKagLV7pkMsuaQ3F2YUtLu5BZOC9plnx4ibFtO84Yg PdMFpkTnb882AGhX2QD7TaQcj83xSO8Lut9rm3HahhlVHJO0oJwRQ7vBXzUePBINOZMG niKauDXwvSyeT3K6P3ibijeqztUuGN/OUzMO23C7FBErj47qyD9IXBBXKif5E1k7XRSB c4J5PjQtKNxXEcUFSQnjSKYpWoYtGz7jx0x7tUK04eGWDmoUGH+qs7aRilX0o5QHfy+0 1NVw== X-Gm-Message-State: AFuF++kvnbfTGaI8ZAMPfdJdd2t+WlrxfynTpjccu0zyZ7LTVB7zCmBo JMrhTzRz2LPtI0jzSlucrCLPJD7UJTSyjJ5l3VDe3NMPHVXAiMLMONVRTLddIQ== X-Gm-Gg: AYBFou0hotifI6+Z9iOtgb3HYyUADi4jeG2HEBhB8wVAtpKkLcecYbeFStPjnza7BY9 +wp6yDjjbJEKHxyTOoL8Hpe0jihDMxaV7jCfXQdlmdciVx1N/qMGunxMXTkNAWCMzB4u0PI2LUZ DXeI8n3seLe9KVUnX6gb7ggZTazI4tsHH79LF9tSt08VxFoIM+CZfi6FSeULJnqW7rZ29XeSaCd 8NYZRpe/MJhbPYBv/jwCJxgTiIimo11kfAPv+EJMfcGcNXvf8UqrikBzALhyqc1u9WPbiblF7C5 tdbV2Fapb+GOqR8L7uI4FcgrE3W/EVYFMxayCfejWjsdjPls6Ec76AdZam+VZiVGy6haJ0v21qC zavfitL5lPthYGyl6I+r8nsIPN4QeB/RrPnSfMcor1iRWmvqXXAjPypBi5uSSrv2LtWFqB3qnOA u/mpJWHX74O4Sx4HhGBv112PlQ5hYmpaC0am6p2ICWJqNQTn3pWPzqKcrzEU5v1qdPKqBCHmSRk FzNnd3sSNUAy8NRNoc3luknvxLzftwGf7bHTCIw X-Received: by 2002:a05:690c:4513:b0:80f:d844:779c with SMTP id 00721157ae682-85d6b275a86mr127974667b3.22.1788230006682; Mon, 31 Aug 2026 19:33:26 -0700 (PDT) Received: from localhost (107-220-129-194.lightspeed.chrlnc.sbcglobal.net. [107.220.129.194]) by smtp.gmail.com with ESMTPSA id 00721157ae682-8646265eb15sm37946067b3.25.2026.08.31.19.33.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Aug 2026 19:33:25 -0700 (PDT) From: Matt Turner To: binutils@sourceware.org Cc: Magnus Lindholm , Alan Modra , Matt Turner Subject: [PATCH 03/11] alpha: allocate R_ALPHA_IRELATIVE Date: Mon, 31 Aug 2026 22:33:10 -0400 Message-ID: <20260901023318.3503991-4-mattst88@gmail.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260901023318.3503991-1-mattst88@gmail.com> References: <20260901023318.3503991-1-mattst88@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-11.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on 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 R_ALPHA_IRELATIVE is the dynamic relocation that runs an IFUNC's resolver and stores the address it returns, applied by the dynamic linker or, in a static executable, by libc's startup code. Alpha had no number for it. Take 42, the first free number after R_ALPHA_TPREL16. The number is being claimed here and in the matching glibc submission; nothing else uses it, and no dynamic linker implements the relocation yet. glibc's elf/elf.h carries its own copy of these definitions, so the two have to be kept in sync. This adds only the number, the howto, the entry in the BFD reloc map that every other target with an IRELATIVE has, and the reloc class. The linker support that produces the relocation follows. --- bfd/elf64-alpha.c | 19 +++++++++++++++++++ include/elf/alpha.h | 2 ++ 2 files changed, 21 insertions(+) diff --git ./bfd/elf64-alpha.c ./bfd/elf64-alpha.c index a97acdc41de..86a59ba0937 100644 --- ./bfd/elf64-alpha.c +++ ./bfd/elf64-alpha.c @@ -1020,6 +1020,22 @@ static reloc_howto_type elf64_alpha_howto_table[] = 0xffff, /* src_mask */ 0xffff, /* dst_mask */ false), /* pcrel_offset */ + + /* A dynamic relocation to set a 64-bit field to the value returned by + the resolver whose address is the addend. */ + HOWTO (R_ALPHA_IRELATIVE, + 0, + 0, + 0, + false, + 0, + complain_overflow_dont, + bfd_elf_generic_reloc, + "IRELATIVE", + false, + 0, + 0, + true), }; /* A mapping from BFD reloc types to Alpha ELF reloc types. */ @@ -1062,6 +1078,7 @@ static const struct elf_reloc_map elf64_alpha_reloc_map[] = {BFD_RELOC_ALPHA_TPREL_HI16, R_ALPHA_TPRELHI}, {BFD_RELOC_ALPHA_TPREL_LO16, R_ALPHA_TPRELLO}, {BFD_RELOC_ALPHA_TPREL16, R_ALPHA_TPREL16}, + {BFD_RELOC_IRELATIVE, R_ALPHA_IRELATIVE}, }; /* Given a BFD reloc type, return a HOWTO structure. */ @@ -5310,6 +5327,8 @@ elf64_alpha_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED, return reloc_class_plt; case R_ALPHA_COPY: return reloc_class_copy; + case R_ALPHA_IRELATIVE: + return reloc_class_ifunc; default: return reloc_class_normal; } diff --git ./include/elf/alpha.h ./include/elf/alpha.h index 9b7b4cfe16a..f7a0f040508 100644 --- ./include/elf/alpha.h +++ ./include/elf/alpha.h @@ -118,6 +118,8 @@ START_RELOC_NUMBERS (elf_alpha_reloc_type) RELOC_NUMBER (R_ALPHA_TPRELLO, 40) RELOC_NUMBER (R_ALPHA_TPREL16, 41) + RELOC_NUMBER (R_ALPHA_IRELATIVE, 42) + END_RELOC_NUMBERS (R_ALPHA_max) #define LITUSE_ALPHA_ADDR 0 From patchwork Tue Sep 1 02:33:11 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matt Turner X-Patchwork-Id: 142568 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id DE1004BA79A0 for ; Tue, 1 Sep 2026 02:34:12 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org DE1004BA79A0 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=fOMMcYXO X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from mail-yw1-x112e.google.com (mail-yw1-x112e.google.com [IPv6:2607:f8b0:4864:20::112e]) by sourceware.org (Postfix) with ESMTPS id 2D84B4BA23F1 for ; Tue, 1 Sep 2026 02:33:29 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 2D84B4BA23F1 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 2D84B4BA23F1 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::112e ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1788230009; cv=none; b=CnAKbdBcYeOKWgKt2bnBkjMCfQ+AX2E/T1cm7lqcyYJzJtcqR6xxTL6cc0R+4sUvhccv4YQzI4PC5cb0Qv5y1sgwVwbZzIeKiDYiZKnIvCxi4bKtzuq0+c2sPmpAhn8YKQu8E6XpkmRkeoqOgzUQHULDmmNlVFY/Juy28yDZbAU= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1788230009; c=relaxed/simple; bh=g5Of06l7+KRZrE9DVlFD/+N0SHnro1KdyexJ2A23xKU=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=ff06X0b4g6x1HHvAn0kFKhD4iZXx3ELkH6LnWzKd9KEB7AirKvAW/ZJd5Mc0eHgKQEVlvqRptFb+StXQj1jKrFm4+lKM7iwUPPVd+4g+gaanx9Hh/pfH/nlGeZQ2PWCwg7XQ7Ww9/YWGW+TMkbp9YvT/r9Q/CyfDMr3eOTxAJJk= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=fOMMcYXO DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2D84B4BA23F1 Received: by mail-yw1-x112e.google.com with SMTP id 00721157ae682-85a50f6a7f7so48790647b3.2 for ; Mon, 31 Aug 2026 19:33:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788230008; x=1788834808; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=394z9cMQ/EwJmwTepXME4fxl6b386UYKCKTXGCwPBrU=; b=fOMMcYXORLquHyj1x0YPdeq4Qjp8/xHcSWYmnI9bTmLSLd/OEg00vL6utUd0Lecme5 COKKFk8Un8ULUq9LiFXDbqOTjC7hS6hjC+N65EhJhOjeXiAWxJLMZi69NBdC406cT/lB ksB68l+io+jyufH4UGlEZcRgT4kHXroagIodDDByfPXyymFaAY5culnqWHYLNqUwxtod nEW62j4+2E0qlYy90gjm84Tl2Oe25JijYqsLMhEpvU7IrDQ1NAbf5Jxc1OeFAhNFpNCx KfiOfuRvJuoOq2ZjvfMHIW1R4zzUfPgX/X0+l4Bt8RyTJk6Rkbjf63hLfI6O0inWXeC2 tehQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788230008; x=1788834808; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=394z9cMQ/EwJmwTepXME4fxl6b386UYKCKTXGCwPBrU=; b=bSq2xQDoNovWFXq3PKJShBkmv0OeiBFDdfYCpZ6VrpJI/JpxQ1u2xS823uP8dlCEaj BQYkt62Hr3EdalOvuxI5rIYt8UlmTMuFzr6WfvK5k8UePvt/MbA1s3+BxFJiVSo38b9r 5Ce7hwDyDbIvNYDB6PiJXgFCxkJeFRsP0s5mroGr6879dLtOnecb2g/brNrNgiMhVWtb aFXjdxspOQh5li/dUPggybTkvKT9VlrIByZLk133XM8E8RHSwlAVkNRynniULDZKug6H Tv0QBWOLGF4BGL0hEsurhOHgVXeDm6WiiaXvc9q3G0W+jyEWZYPw9cIHu8obeGQETJoK MGCQ== X-Gm-Message-State: AFuF++mqDCL91KrEIwygWglGyWYkRRfYO6drCJiyCR/LnQQb/O4a0Zn6 2jLh0xROYTHqL7oopPXGJX6BCXS5jKreO1T+dQno1aY0Su9jBkC5dkh1uafnlg== X-Gm-Gg: AYBFou0RZIp8pM+GceoLrCOsKCd0Iq/XvnOyeWBj9cpKbWsZI577TYNXE5KyZ3PLj2r uiCEhiK/6lbMBcAhWHR9zjEkvhaUVsKHNzfwBje1UC0/yLDzQrSJI+r2ConEnJfwNQa8JXi+6pM h+dnE75r0T6MvcYdzpRSTAZiNohjC3ARrBvWGcBzvj+ncRrwc4/UpkVDx1evUmIWQoXHElsjVNw Ds+D9gwlaO8ZvHsFXJogQrNeFCsSsOjL49Tnkf1jJB+81k7NsVPHYDn1/YZNrjdHVGfehUOJS0Y 7tXJy5HsOKbJAJeOOVn3kLiaRlIgJMU9kk9FfkzL4FEx5N1VjfojKZD9mC5psLEMy9GnEs3Mg3P tojWyWwNIra1NcZufcGxf7ys4HFTM8HlHInNOb7eZ4sCGKf+LMtP6ZbURY3I7Ra0kQZ661dxTk7 E6m40ntzB5fwu7U9Q8miCZEqxh4G/Qy9CZxph7pUYqoqow5+W711LBpOhmP5dHaLV5k9ZF4w8qm Prss0rIZ1VYuJDMYwtqTUb5A/5Ur/ZBbZqk+duv X-Received: by 2002:a05:690c:c50f:b0:80c:8d09:3880 with SMTP id 00721157ae682-85fd251ac5fmr94076957b3.15.1788230008443; Mon, 31 Aug 2026 19:33:28 -0700 (PDT) Received: from localhost (107-220-129-194.lightspeed.chrlnc.sbcglobal.net. [107.220.129.194]) by smtp.gmail.com with ESMTPSA id 00721157ae682-85e5ed1b3b8sm66367767b3.16.2026.08.31.19.33.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Aug 2026 19:33:27 -0700 (PDT) From: Matt Turner To: binutils@sourceware.org Cc: Magnus Lindholm , Alan Modra , Matt Turner Subject: [PATCH 04/11] alpha: factor out elf64_alpha_sym_name Date: Mon, 31 Aug 2026 22:33:11 -0400 Message-ID: <20260901023318.3503991-5-mattst88@gmail.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260901023318.3503991-1-mattst88@gmail.com> References: <20260901023318.3503991-1-mattst88@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-11.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on 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 relocate_section spells out how to name the symbol a relocation refers to, which is one thing for a global symbol and another for a local one. Later diagnostics need the same, so give it a name. The open-coded version is replaced by bfd_elf_sym_name, which every other backend uses here. It names a section symbol by its section rather than by an empty string, and a symbol whose name cannot be read comes out empty rather than as "". --- bfd/elf64-alpha.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git ./bfd/elf64-alpha.c ./bfd/elf64-alpha.c index 86a59ba0937..fef3c0127aa 100644 --- ./bfd/elf64-alpha.c +++ ./bfd/elf64-alpha.c @@ -4104,6 +4104,20 @@ elf64_alpha_relocate_section_r (struct bfd_link_info *info ATTRIBUTE_UNUSED, return ret_val; } +/* The name of the symbol a relocation refers to, for diagnostics. H + describes the symbol when it is global and SYM when it is local. */ + +static const char * +elf64_alpha_sym_name (bfd *abfd, Elf_Internal_Shdr *symtab_hdr, + struct alpha_elf_link_hash_entry *h, + Elf_Internal_Sym *sym, asection *sec) +{ + if (h != NULL) + return h->root.root.root.string; + + return bfd_elf_sym_name (abfd, symtab_hdr, sym, sec); +} + /* Relocate an Alpha ELF section. */ static int @@ -4443,17 +4457,8 @@ elf64_alpha_relocate_section (struct bfd_link_info *info, value += 8; break; default: - if (h != NULL) - name = h->root.root.root.string; - else - { - name = (bfd_elf_string_from_elf_section - (input_bfd, symtab_hdr->sh_link, sym->st_name)); - if (name == NULL) - name = _(""); - else if (name[0] == 0) - name = bfd_section_name (sec); - } + name = elf64_alpha_sym_name (input_bfd, symtab_hdr, h, sym, + sec); _bfd_error_handler /* xgettext:c-format */ (_("%pB: !samegp reloc against symbol without .prologue: %s"), From patchwork Tue Sep 1 02:33:12 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matt Turner X-Patchwork-Id: 142574 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id B1A734BA23EE for ; Tue, 1 Sep 2026 02:36:33 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B1A734BA23EE Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=RkCNZnMi X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from mail-yx1-xb12a.google.com (mail-yx1-xb12a.google.com [IPv6:2607:f8b0:4864:20::b12a]) by sourceware.org (Postfix) with ESMTPS id 49C1B4BA7994 for ; Tue, 1 Sep 2026 02:33:31 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 49C1B4BA7994 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 49C1B4BA7994 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::b12a ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1788230011; cv=none; b=yCTwrCI3EfH1FsSohrn6KlV+lygo3WTs+mTTtd6/rjUDT2ZGk91iOE9Uowu/EnvGrgv4jiFNTkQGWNj+O1pL0Ft5nSiTyd1h+WkAlKHefihMF3curLCIUQCI+towwASl5VxkcR3LwppdNJyNpEADBKRoepEaMW5pdFyPCw6HUtQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1788230011; c=relaxed/simple; bh=aDSyR/1CTutPguv/DBSptzGhVNNe2RLRInvbc2sqhBs=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=DCxGhnFizoW6znBxTnyYpV/qAALj3tEKRjdKrKiCvR9L4hK4NFOhxecltIkosZzboyjT4ixPJU7/JBaefzsy/anQqAg96VwXcPCN7zJ/E12YXl7UTuSnHyWxUkNCVwyXQK4RJxNFCUS/AodjjChC6O6+Z7AHGuWFbi+drng28NE= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=RkCNZnMi DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 49C1B4BA7994 Received: by mail-yx1-xb12a.google.com with SMTP id 956f58d0204a3-66c70cff944so613781d50.0 for ; Mon, 31 Aug 2026 19:33:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788230010; x=1788834810; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=x8n6nncTQCVbgmoLNBoqWeZBlr9XY6Fh3VffhGa4wlI=; b=RkCNZnMia7WNnW7jl14Nm7UguyFEl0iS2r6YV54T4jGThDTkSDnlURZYrjKHuidrQc I/rPhC40f8lOpL+GU6PT73Pbk2kuNNmmgVEdSkCkZPypPkX4AUJbialqd5FqtLQeKoCX ddJL2rOYuPyeQymcuAfdCEdkWFdwCyKwt7xl4xnHWJZAZFP89NAGaeRMKoEnZDkGvvkN tqnx2qVoKGdJQydqEWI4ldt3sMRfGfqXL9P4GVdt6jJvBQXlcPVf45tMo5v7mxNqvgDE nTVzit23mAOPf3WaSLkP4E8e7IjCg5D0jgPEOJGEbNRPPekWGf50xD6nQZFN3iQl1yGe M4lg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788230010; x=1788834810; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=x8n6nncTQCVbgmoLNBoqWeZBlr9XY6Fh3VffhGa4wlI=; b=scqy/o8tdLhYel69Vmr3EdubzgIQEDaKyUfU4OlY/uTG1C78/pA3qWUd2fGLR6YUC7 hPAOGpYY7H8jyAJtTT0E4gVbvYByTpXA4+pcElAlumlHiF+Y7xz8By0iYspjePa6s28B DRGAPKFZUMZntTCWKPMvsAaf6tzsXiPdb/ew6LRTdbiYLb18PghCQGfb0329L+3Zf7OT xanMTvDSXZcVolMvYBZItima8Ym94+8mikKMh4y0Yl26dHDYuHRIoeMluDxHAzA7oLFo PGM2kwSTnjPFBywWhc01vhh/y3Mfsr1bXTSvsuTOv+mkADiU4TpBxBbuiTfXC5iRd3Ds 6LDw== X-Gm-Message-State: AFuF++lghuSBlNSQLxEVaQly1R61eXXrX782o4NlTMVkhIhqmvU/EYl+ aVlEVgeb+7fopvsAMzB0Nc/Z5j5305O6r0l4J+hZFQLtfpIUeqrMdDsAbG2Bog== X-Gm-Gg: AYBFou1zuKra7wqmVzyZQGv5GM2KfWYQWKBuegCBD5nSXAe7aMN3SC4SMLVRYNzZNI4 Up8LDU6CaweoXwQ3oa63jvdHVxZmZqcbfcjErkAZls/gkvZS47/dUCnwWJ01mAxi0EgeWAb/rvl qdhbx8bdumoyCHbx+p8qLH+1fRq0UVaFsP7fzmVDhQ10wcNMTUCCfeYaLojuWkZqvi4HY1cyqYS brAdoHrczdZkuBECUO8aZL1xdm9ICYEfobuJClPlp38Xfxf0j26wEVmwOPLoFsPLb3I2W0wlS3u VFTGLvL7dJD1hIg+S054b6Rsj6LjcZaUsjIFZwSicvftrVHPlYe8a5zRQkzq/QsZ6UTTTdxsawp ag21LbYVr4WYl83wSq0+V5B+AhcrYv35X6hGJAuIg0qwqwxtIVOq5cbvwH2vwETWckuLSKy/B2f B71DDgho1AR6Rwo6qMdt6pN6e0A3KhaHI9TRbQx7xXLL1Lw+sG/HREKcfy3orqZ+u2qamxnYeHZ xASPG4q9Vt0iNJIJlan7Mr+lmthP9teynJk/pUj4QPvHgehNTg= X-Received: by 2002:a05:690c:c057:b0:866:ba76:7eaf with SMTP id 00721157ae682-866ba76cc7fmr34234727b3.29.1788230010413; Mon, 31 Aug 2026 19:33:30 -0700 (PDT) Received: from localhost (107-220-129-194.lightspeed.chrlnc.sbcglobal.net. [107.220.129.194]) by smtp.gmail.com with ESMTPSA id 00721157ae682-862e2335134sm42798257b3.28.2026.08.31.19.33.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Aug 2026 19:33:29 -0700 (PDT) From: Matt Turner To: binutils@sourceware.org Cc: Magnus Lindholm , Alan Modra , Matt Turner Subject: [PATCH 05/11] alpha: emit R_ALPHA_IRELATIVE in PIC links Date: Mon, 31 Aug 2026 22:33:12 -0400 Message-ID: <20260901023318.3503991-6-mattst88@gmail.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260901023318.3503991-1-mattst88@gmail.com> References: <20260901023318.3503991-1-mattst88@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-11.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on 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 Alpha treats an IFUNC like an ordinary function, so a reference the linker resolves itself gets the address of the resolver rather than of the function the resolver selects. In a PIC link that is the R_ALPHA_RELATIVE written for a GOT entry or a data word whose symbol binds locally. Emit R_ALPHA_IRELATIVE in its place. Space is already reserved for the RELATIVE, in the same section, so nothing else has to change. A preemptible IFUNC is left alone: the dynamic linker resolves it, and a PLT entry and a JMP_SLOT are what it needs, as for an STT_FUNC. Relaxation leaves references to an IFUNC alone, since a direct branch or a gp-relative address would reach the resolver. Non-PIC links are handled separately; they have no reserved slot to reuse. --- bfd/elf64-alpha.c | 59 +++++++++++++++++-- ld/testsuite/ld-alpha/ifunc-global-pie.d | 9 +++ ld/testsuite/ld-alpha/ifunc-global-relax.d | 15 +++++ ld/testsuite/ld-alpha/ifunc-global-shared.d | 12 ++++ ld/testsuite/ld-alpha/ifunc-global.s | 24 ++++++++ .../ld-alpha/ifunc-local-call-shared.d | 8 +++ ld/testsuite/ld-alpha/ifunc-local-call.s | 17 ++++++ ld/testsuite/ld-alpha/ifunc-local-relax.d | 16 +++++ ld/testsuite/ld-alpha/ifunc-local-shared.d | 9 +++ ld/testsuite/ld-alpha/ifunc-local.s | 25 ++++++++ 10 files changed, 190 insertions(+), 4 deletions(-) create mode 100644 ld/testsuite/ld-alpha/ifunc-global-pie.d create mode 100644 ld/testsuite/ld-alpha/ifunc-global-relax.d create mode 100644 ld/testsuite/ld-alpha/ifunc-global-shared.d create mode 100644 ld/testsuite/ld-alpha/ifunc-global.s create mode 100644 ld/testsuite/ld-alpha/ifunc-local-call-shared.d create mode 100644 ld/testsuite/ld-alpha/ifunc-local-call.s create mode 100644 ld/testsuite/ld-alpha/ifunc-local-relax.d create mode 100644 ld/testsuite/ld-alpha/ifunc-local-shared.d create mode 100644 ld/testsuite/ld-alpha/ifunc-local.s diff --git ./bfd/elf64-alpha.c ./bfd/elf64-alpha.c index fef3c0127aa..484fe9589fb 100644 --- ./bfd/elf64-alpha.c +++ ./bfd/elf64-alpha.c @@ -1764,6 +1764,7 @@ static bool elf64_alpha_want_plt (struct alpha_elf_link_hash_entry *ah) { return ((ah->root.type == STT_FUNC + || ah->root.type == STT_GNU_IFUNC || ah->root.root.type == bfd_link_hash_undefweak || ah->root.root.type == bfd_link_hash_undefined) && (ah->flags & ALPHA_ELF_LINK_HASH_LU_PLT) != 0 @@ -1782,6 +1783,31 @@ elf64_alpha_sort_relocs_p (asection *sec) } +/* True if a relocation refers to an IFUNC defined in a regular object. H + describes the symbol when it is global and SYM when it is local. An + undefined symbol can carry the IFUNC type from a .type directive; it is + treated as an ordinary undefined function, as the generic code does when + it writes it out. */ + +static bool +elf64_alpha_ifunc_p (struct alpha_elf_link_hash_entry *h, + Elf_Internal_Sym *sym) +{ + if (h != NULL) + return h->root.type == STT_GNU_IFUNC && h->root.def_regular; + + return sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC; +} + +/* True if a relocation of type R_TYPE against an IFUNC can end up as an + R_ALPHA_IRELATIVE. */ + +static bool +elf64_alpha_ifunc_reloc_p (unsigned long r_type) +{ + return r_type == R_ALPHA_LITERAL || r_type == R_ALPHA_REFQUAD; +} + /* Handle dynamic relocations when doing an Alpha ELF link. */ static bool @@ -3822,6 +3848,12 @@ elf64_alpha_relax_section (bfd *abfd, asection *sec, isym = isymbuf + r_symndx; + /* A reference to an IFUNC has to keep going through the GOT: a + direct branch or a gp-relative address would reach the resolver + rather than the function it selects. */ + if (elf64_alpha_ifunc_p (NULL, isym)) + continue; + /* Given the symbol for a TLSLDM reloc is ignored, this also means forcing the symbol value to the tp base. */ if (r_type == R_ALPHA_TLSLDM) @@ -3865,6 +3897,10 @@ elf64_alpha_relax_section (bfd *abfd, asection *sec, || h->root.root.type == bfd_link_hash_warning) h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link; + /* A reference to an IFUNC has to keep going through the GOT. */ + if (elf64_alpha_ifunc_p (h, NULL)) + continue; + /* If the symbol is undefined, we can't do anything with it. */ if (h->root.root.type == bfd_link_hash_undefined) continue; @@ -4346,15 +4382,18 @@ elf64_alpha_relocate_section (struct bfd_link_info *info, bfd_put_64 (info->output_bfd, value, alpha_got_slot (gotent, 0)); - /* If the symbol has been forced local, output a - RELATIVE reloc, otherwise it will be handled in - finish_dynamic_symbol. */ + /* If the symbol has been forced local, output a RELATIVE + reloc, otherwise it will be handled in finish_dynamic_symbol. + An IFUNC gets an IRELATIVE instead. */ if (bfd_link_pic (info) && !dynamic_symbol_p && !undef_weak_ref) elf64_alpha_emit_dynrel (info->output_bfd, info, sgot, srelgot, gotent->got_offset, 0, - R_ALPHA_RELATIVE, value); + (elf64_alpha_ifunc_p (h, sym) + ? R_ALPHA_IRELATIVE + : R_ALPHA_RELATIVE), + value); } value = (sgot->output_section->vma @@ -4505,6 +4544,18 @@ elf64_alpha_relocate_section (struct bfd_link_info *info, dynindx = 0; dynaddend = value - dtp_base; } + else if (elf64_alpha_ifunc_reloc_p (r_type) + && bfd_link_pic (info) + && elf64_alpha_ifunc_p (h, sym) + && (input_section->flags & SEC_ALLOC)) + { + /* The RELATIVE this would otherwise get would store the + address of the resolver. Space for it is already + reserved, so the IRELATIVE takes its place. */ + dynindx = 0; + dyntype = R_ALPHA_IRELATIVE; + dynaddend = value; + } else if (bfd_link_pic (info) && r_symndx != STN_UNDEF && (input_section->flags & SEC_ALLOC) diff --git ./ld/testsuite/ld-alpha/ifunc-global-pie.d ./ld/testsuite/ld-alpha/ifunc-global-pie.d new file mode 100644 index 00000000000..c7b14f1030f --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-global-pie.d @@ -0,0 +1,9 @@ +#source: ifunc-global.s +#ld: -pie -melf64alpha +#readelf: -Wr + +Relocation section '\.rela\.dyn' .* contains 2 entries: +#... +[0-9a-f]+ +[0-9a-f]+ +R_ALPHA_IRELATIVE +[0-9a-f]+ +[0-9a-f]+ +[0-9a-f]+ +R_ALPHA_IRELATIVE +[0-9a-f]+ +#pass diff --git ./ld/testsuite/ld-alpha/ifunc-global-relax.d ./ld/testsuite/ld-alpha/ifunc-global-relax.d new file mode 100644 index 00000000000..c42f1ab73b8 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-global-relax.d @@ -0,0 +1,15 @@ +#source: ifunc-global.s +#ld: -relax -melf64alpha +#objdump: -dj.text + +# The call must keep going through the GOT; relaxing it into a bsr would +# reach the resolver rather than the function it selects. +.*: +file format elf64-alpha.* + +Disassembly of section \.text: +#... +[0-9a-f]+ <_start>: +#... + +[0-9a-f]+: [0-9a-f ]+ ldq t12,-?[0-9]+\(gp\) + +[0-9a-f]+: [0-9a-f ]+ jsr ra,\(t12\),[0-9a-f]+ <_start\+0x10> +#pass diff --git ./ld/testsuite/ld-alpha/ifunc-global-shared.d ./ld/testsuite/ld-alpha/ifunc-global-shared.d new file mode 100644 index 00000000000..55508f0b0b7 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-global-shared.d @@ -0,0 +1,12 @@ +#source: ifunc-global.s +#ld: -shared -melf64alpha +#readelf: -Wr + +Relocation section '\.rela\.dyn' .* contains 1 entry: +#... +[0-9a-f]+ +[0-9a-f]+ +R_ALPHA_REFQUAD .*global_ifunc \+ 0 +#... +Relocation section '\.rela\.plt' .* contains 1 entry: +#... +[0-9a-f]+ +[0-9a-f]+ +R_ALPHA_JMP_SLOT .*global_ifunc \+ 0 +#pass diff --git ./ld/testsuite/ld-alpha/ifunc-global.s ./ld/testsuite/ld-alpha/ifunc-global.s new file mode 100644 index 00000000000..f94806b10b1 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-global.s @@ -0,0 +1,24 @@ + .text + + # A globally visible IFUNC, both called and referenced, so that both + # its GOT entry and the data word holding its address need an + # IRELATIVE. + .globl global_ifunc + .type global_ifunc, @gnu_indirect_function +global_ifunc: + ret + + .globl _start + .ent _start +_start: + ldgp $29, 0($27) + ldq $27, global_ifunc($29) !literal!1 + jsr $26, ($27), 0 !lituse_jsr!1 + ldgp $29, 0($26) + ret + .end _start + + .data + .globl ptr +ptr: + .quad global_ifunc diff --git ./ld/testsuite/ld-alpha/ifunc-local-call-shared.d ./ld/testsuite/ld-alpha/ifunc-local-call-shared.d new file mode 100644 index 00000000000..01fb33e17bb --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-local-call-shared.d @@ -0,0 +1,8 @@ +#source: ifunc-local-call.s +#ld: -shared -melf64alpha +#readelf: -Wr + +Relocation section '\.rela\.dyn' .* contains 1 entry: +#... +[0-9a-f]+ +[0-9a-f]+ +R_ALPHA_IRELATIVE +[0-9a-f]+ +#pass diff --git ./ld/testsuite/ld-alpha/ifunc-local-call.s ./ld/testsuite/ld-alpha/ifunc-local-call.s new file mode 100644 index 00000000000..165749221bd --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-local-call.s @@ -0,0 +1,17 @@ + .text + + # An IFUNC with local binding, called but not otherwise referenced, + # so that only its GOT entry needs an IRELATIVE. + .type local_ifunc, @gnu_indirect_function +local_ifunc: + ret + + .globl _start + .ent _start +_start: + ldgp $29, 0($27) + ldq $27, local_ifunc($29) !literal!1 + jsr $26, ($27), 0 !lituse_jsr!1 + ldgp $29, 0($26) + ret + .end _start diff --git ./ld/testsuite/ld-alpha/ifunc-local-relax.d ./ld/testsuite/ld-alpha/ifunc-local-relax.d new file mode 100644 index 00000000000..88b9029c64c --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-local-relax.d @@ -0,0 +1,16 @@ +#source: ifunc-local.s +#ld: -relax -melf64alpha +#objdump: -dj.text + +# As for a global IFUNC, the call must keep going through the GOT. A local +# symbol reaches the check in elf64_alpha_relax_section by its symbol table +# entry rather than by a hash table entry. +.*: +file format elf64-alpha.* + +Disassembly of section \.text: +#... +[0-9a-f]+ <_start>: +#... + +[0-9a-f]+: [0-9a-f ]+ ldq t12,-?[0-9]+\(gp\) + +[0-9a-f]+: [0-9a-f ]+ jsr ra,\(t12\),[0-9a-f]+ <_start\+0x10> +#pass diff --git ./ld/testsuite/ld-alpha/ifunc-local-shared.d ./ld/testsuite/ld-alpha/ifunc-local-shared.d new file mode 100644 index 00000000000..c21226bf729 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-local-shared.d @@ -0,0 +1,9 @@ +#source: ifunc-local.s +#ld: -shared -melf64alpha +#readelf: -Wr + +Relocation section '\.rela\.dyn' .* contains 2 entries: +#... +[0-9a-f]+ +[0-9a-f]+ +R_ALPHA_IRELATIVE +[0-9a-f]+ +[0-9a-f]+ +[0-9a-f]+ +R_ALPHA_IRELATIVE +[0-9a-f]+ +#pass diff --git ./ld/testsuite/ld-alpha/ifunc-local.s ./ld/testsuite/ld-alpha/ifunc-local.s new file mode 100644 index 00000000000..cba6f3f2e98 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-local.s @@ -0,0 +1,25 @@ + .text + + # An IFUNC with local binding: no .globl, so it has no entry in the + # linker's hash table. It is both called and referenced, so that + # both its GOT entry and the data word holding its address need an + # IRELATIVE. The data word alone is the shape of glibc's configure + # probe for linker IFUNC support. + .type local_ifunc, @gnu_indirect_function +local_ifunc: + ret + + .globl _start + .ent _start +_start: + ldgp $29, 0($27) + ldq $27, local_ifunc($29) !literal!1 + jsr $26, ($27), 0 !lituse_jsr!1 + ldgp $29, 0($26) + ret + .end _start + + .data + .globl ptr +ptr: + .quad local_ifunc From patchwork Tue Sep 1 02:33:13 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matt Turner X-Patchwork-Id: 142575 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 545464BA900D for ; Tue, 1 Sep 2026 02:36:46 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 545464BA900D Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=ZG8Wx8pj X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from mail-yw1-x112d.google.com (mail-yw1-x112d.google.com [IPv6:2607:f8b0:4864:20::112d]) by sourceware.org (Postfix) with ESMTPS id 0CE0B4BA79BB for ; Tue, 1 Sep 2026 02:33:33 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 0CE0B4BA79BB Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 0CE0B4BA79BB Authentication-Results: sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::112d ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1788230013; cv=none; b=WYQFUUiTxVd1fMv3rC5hWlFEM9fmFf6KO6mPtXleXyACMPw3a+4xWvGy1PtfupA/ppbrQAIk/DIXA1ZNMjqgRg3KOVmuPbTCHz1nWy/HhptfeNubORcvSDFKm3clRhw/VFlhcx/e74345Gnq9qCJS7KCSIRQzC/9OuWzojSW3U8= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1788230013; c=relaxed/simple; bh=duWWS8ED4UVGD7yeyul16T9veLIOLytAUpDSIxVanOE=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=F39TM6YwbmD6ES6KTss7ILJZApthE0/Q9vwWAUmvuWKoRn3hhYEdpWM6qF7xYdoXYVcDqhlh+ORdsK4x8POOtv85NWdk1dlAFTIsnoUADvxBUrUx+BiEspH+xyPD2+E8pelbLxzwHfUxHgVTZG9fFCAgP7d74pW4bJ4K0kKc8kY= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=ZG8Wx8pj DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0CE0B4BA79BB Received: by mail-yw1-x112d.google.com with SMTP id 00721157ae682-861145fc841so27046027b3.3 for ; Mon, 31 Aug 2026 19:33:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788230012; x=1788834812; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=xfmaGPm6izxlNUqrzK4n4f+2Rr8lcBIEqr09qmenHW0=; b=ZG8Wx8pjWMR6fJGRPvNCpOZRN0B5+892Zx3qVlUG/q+FstvSRusWcpxsrz9jtSqsKD hXY+q3sG6WPo7GHRYU7TGP+oXjXSfLVu9c1/BrfOtE0v1EdO8zkza/EFXcJLYVQhhl8f O9MDIJL4pTv2dbSbe4VgN8eSHzX9OtlZxt4zQw2FqqHovbc6rGq8rPhycUpTV8nNA+Ky tc+d67bp246FQnpFl65bcdkMAryVnwunwKTWISq/jX5FgBh3SYsec4yanB+w01Cw3r/b gkH7aa1Bj7lcRUiWhtdvkg5btTw2ifXiAUmkFmu26hRzOUZ7NgNtJJFSPMhfCovBdOFZ /cFw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788230012; x=1788834812; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=xfmaGPm6izxlNUqrzK4n4f+2Rr8lcBIEqr09qmenHW0=; b=FBDQh7BUMv/KzifsxL3AnQpTAwlVICPxbwBqBCrlMaqv0sDpco6gPEkdmvBeinUbBw bXA2D5/qPjSIFqlZ7CMlLRUBoCnO+6qNEePZeO+DP4kz6LoUszI1hpi6p7bikiwHSwLh O/6QJHXc0OBqGeVPT949qU4OZaDSpYIHR+HtDxCZRWICYTF8/9AT1/Kvo4qKnsKZhKmR i0Q02DoxPiL5bo/EdAwFYUf/2HzoogNlEodtwjtLWV4GH3//p791tBaWfoyyIWVTF8Qo JANOgS5qwK8v6uHaufuxsCzsSU+EIQBAmp62YB7BRfZvo96sLmBKEprhlVESWEPJYOJc 6M7Q== X-Gm-Message-State: AFuF++n66HtyzMdhZMFdzpGNYBGJ4ugFUphnHqNzW1jupn7ho+uqYKfr v4NUCCBYj5a7rJ22xTXHdD0bzQxn1xMCWlrxYCplfoLZZYJYymfJLccgU8G8Nw== X-Gm-Gg: AYBFou1h23NEMgRh7HE2QmxbwwALjSc8odf5mowk2S/qyNb18+DYDzK0Tiqibz9unGj z0PaN43ACpT2UvHPA0UuCuqrTsh6Sq4D4QmWfoaeA9n/4dYPIneg0YTd/mROtPoOy5Z+sm7AFcT F2rmjrYbYgLLtglaN6g7wZ7pn384H1d/blZ4LiTLZ6+5a64qu20jpJOghCCx/sR2ksebVTbt7Cz Vt70o2KlELpcap2xvZVi8FcfRs/k7xc3hih8YuZVnZO8YmeCJCeI3bHEymzIngHFh0SvjCLEYmq pWb0m7yaBRbLSbp42CT90l60J5QKdqLaEWzh0zBak2DNu66KSJFABSSpCQq4q44Egsvm6APF4c6 QFfBkS9JLO+DMeQEHU0/fZ7dZYBCHthB6oitHU2WrxqSNA1f/SuvCusuEjENFlOpHIAe2zF8az8 9IMid5yX0zsHIOBMUW4lH/qHQyAqDXLppjsFJS89Wd2j4ISV3MBY64CpE9s8DbAA8aovsTY6Uvo WU0l6zYYWFjVEFb+lAZdE3pXIuZK1/Yw1VrZWty X-Received: by 2002:a05:690c:309:b0:866:e57f:58db with SMTP id 00721157ae682-868682a0d18mr26124307b3.0.1788230012189; Mon, 31 Aug 2026 19:33:32 -0700 (PDT) Received: from localhost (107-220-129-194.lightspeed.chrlnc.sbcglobal.net. [107.220.129.194]) by smtp.gmail.com with ESMTPSA id 00721157ae682-85e66f9a5d8sm65444357b3.41.2026.08.31.19.33.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Aug 2026 19:33:31 -0700 (PDT) From: Matt Turner To: binutils@sourceware.org Cc: Magnus Lindholm , Alan Modra , Matt Turner Subject: [PATCH 06/11] alpha: reject relocations that cannot refer to an IFUNC Date: Mon, 31 Aug 2026 22:33:13 -0400 Message-ID: <20260901023318.3503991-7-mattst88@gmail.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260901023318.3503991-1-mattst88@gmail.com> References: <20260901023318.3503991-1-mattst88@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-11.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on 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 A reference to an IFUNC has to go through the GOT entry or the data word that an R_ALPHA_IRELATIVE fills in with the address the resolver returns. Two kinds of relocation cannot, and nothing diagnosed either. R_ALPHA_BRADDR, R_ALPHA_BRSGP, the gp-relative relocations and the pc-relative R_ALPHA_SREL* name the symbol directly, so they reach the resolver rather than the function it selects. R_ALPHA_REFLONG names it indirectly but has only a 32-bit field, which cannot hold the address the resolver returns. Report each of these and carry on, so that one link reports them all. --- bfd/elf64-alpha.c | 31 +++++++++++++++++++ ld/testsuite/ld-alpha/ifunc-branch.d | 3 ++ ld/testsuite/ld-alpha/ifunc-branch.s | 17 ++++++++++ ld/testsuite/ld-alpha/ifunc-gprel.d | 3 ++ ld/testsuite/ld-alpha/ifunc-gprel.s | 18 +++++++++++ ld/testsuite/ld-alpha/ifunc-gprel32.d | 3 ++ ld/testsuite/ld-alpha/ifunc-gprel32.s | 17 ++++++++++ ld/testsuite/ld-alpha/ifunc-reflong-dynamic.d | 3 ++ ld/testsuite/ld-alpha/ifunc-reflong-static.d | 3 ++ ld/testsuite/ld-alpha/ifunc-reflong.s | 26 ++++++++++++++++ ld/testsuite/ld-alpha/ifunc-srel.d | 3 ++ ld/testsuite/ld-alpha/ifunc-srel.s | 19 ++++++++++++ 12 files changed, 146 insertions(+) create mode 100644 ld/testsuite/ld-alpha/ifunc-branch.d create mode 100644 ld/testsuite/ld-alpha/ifunc-branch.s create mode 100644 ld/testsuite/ld-alpha/ifunc-gprel.d create mode 100644 ld/testsuite/ld-alpha/ifunc-gprel.s create mode 100644 ld/testsuite/ld-alpha/ifunc-gprel32.d create mode 100644 ld/testsuite/ld-alpha/ifunc-gprel32.s create mode 100644 ld/testsuite/ld-alpha/ifunc-reflong-dynamic.d create mode 100644 ld/testsuite/ld-alpha/ifunc-reflong-static.d create mode 100644 ld/testsuite/ld-alpha/ifunc-reflong.s create mode 100644 ld/testsuite/ld-alpha/ifunc-srel.d create mode 100644 ld/testsuite/ld-alpha/ifunc-srel.s diff --git ./bfd/elf64-alpha.c ./bfd/elf64-alpha.c index 484fe9589fb..ebb2f0ded11 100644 --- ./bfd/elf64-alpha.c +++ ./bfd/elf64-alpha.c @@ -4349,6 +4349,37 @@ elf64_alpha_relocate_section (struct bfd_link_info *info, && gotent->addend == addend) break; + /* A reference to an IFUNC has to go through the GOT entry or the data + word that an R_ALPHA_IRELATIVE fills in with the address the + resolver returns. A relocation that names the symbol directly + reaches the resolver instead, and R_ALPHA_REFLONG has no room for + the address in the first place. */ + if (elf64_alpha_ifunc_p (h, sym) && (input_section->flags & SEC_ALLOC)) + switch (r_type) + { + case R_ALPHA_REFLONG: + case R_ALPHA_BRADDR: + case R_ALPHA_BRSGP: + case R_ALPHA_GPREL16: + case R_ALPHA_GPREL32: + case R_ALPHA_GPRELLOW: + case R_ALPHA_GPRELHIGH: + case R_ALPHA_SREL16: + case R_ALPHA_SREL32: + case R_ALPHA_SREL64: + _bfd_error_handler + /* xgettext:c-format */ + (_("%pB: %s relocation against STT_GNU_IFUNC symbol `%s' is " + "not supported"), + input_bfd, howto->name, + elf64_alpha_sym_name (input_bfd, symtab_hdr, h, sym, sec)); + ret_val = false; + continue; + + default: + break; + } + switch (r_type) { case R_ALPHA_GPDISP: diff --git ./ld/testsuite/ld-alpha/ifunc-branch.d ./ld/testsuite/ld-alpha/ifunc-branch.d new file mode 100644 index 00000000000..fb0e875b79b --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-branch.d @@ -0,0 +1,3 @@ +#source: ifunc-branch.s +#ld: -melf64alpha +#error: \A[^\n]*: BRADDR relocation against STT_GNU_IFUNC symbol `global_ifunc' is not supported\n[^\n]*: BRSGP relocation against STT_GNU_IFUNC symbol `global_ifunc' is not supported\n[^\n]*: final link failed[^\n]*\n?\Z diff --git ./ld/testsuite/ld-alpha/ifunc-branch.s ./ld/testsuite/ld-alpha/ifunc-branch.s new file mode 100644 index 00000000000..701ab520690 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-branch.s @@ -0,0 +1,17 @@ + .text + + .globl global_ifunc + .type global_ifunc, @gnu_indirect_function +global_ifunc: + ret + + # A direct branch reaches the resolver rather than the function it + # selects, so it cannot be used to call an IFUNC. + .globl _start + .ent _start +_start: + ldgp $29, 0($27) + bsr $26, global_ifunc + bsr $26, global_ifunc !samegp + ret + .end _start diff --git ./ld/testsuite/ld-alpha/ifunc-gprel.d ./ld/testsuite/ld-alpha/ifunc-gprel.d new file mode 100644 index 00000000000..26a3f8abbe7 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-gprel.d @@ -0,0 +1,3 @@ +#source: ifunc-gprel.s +#ld: -melf64alpha +#error: \A[^\n]*: GPRELHIGH relocation against STT_GNU_IFUNC symbol `global_ifunc' is not supported\n[^\n]*: GPRELLOW relocation against STT_GNU_IFUNC symbol `global_ifunc' is not supported\n[^\n]*: GPREL16 relocation against STT_GNU_IFUNC symbol `global_ifunc' is not supported\n[^\n]*: final link failed[^\n]*\n?\Z diff --git ./ld/testsuite/ld-alpha/ifunc-gprel.s ./ld/testsuite/ld-alpha/ifunc-gprel.s new file mode 100644 index 00000000000..3236bfb7346 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-gprel.s @@ -0,0 +1,18 @@ + .text + + .globl global_ifunc + .type global_ifunc, @gnu_indirect_function +global_ifunc: + ret + + # A gp-relative address is the address of the resolver rather than + # of the function it selects. + .globl _start + .ent _start +_start: + ldgp $29, 0($27) + ldah $1, global_ifunc($29) !gprelhigh + lda $1, global_ifunc($1) !gprellow + ldq $1, global_ifunc($29) !gprel + ret + .end _start diff --git ./ld/testsuite/ld-alpha/ifunc-gprel32.d ./ld/testsuite/ld-alpha/ifunc-gprel32.d new file mode 100644 index 00000000000..2e4dddbd7d9 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-gprel32.d @@ -0,0 +1,3 @@ +#source: ifunc-gprel32.s +#ld: -melf64alpha +#error: \A[^\n]*: GPREL32 relocation against STT_GNU_IFUNC symbol `global_ifunc' is not supported\n[^\n]*: final link failed[^\n]*\n?\Z diff --git ./ld/testsuite/ld-alpha/ifunc-gprel32.s ./ld/testsuite/ld-alpha/ifunc-gprel32.s new file mode 100644 index 00000000000..cdef3d47d18 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-gprel32.s @@ -0,0 +1,17 @@ + .text + + .globl global_ifunc + .type global_ifunc, @gnu_indirect_function +global_ifunc: + ret + + .globl _start + .ent _start +_start: + ret + .end _start + + # A gp-relative offset to an IFUNC is an offset to the resolver + # rather than to the function it selects. + .data + .gprel32 global_ifunc diff --git ./ld/testsuite/ld-alpha/ifunc-reflong-dynamic.d ./ld/testsuite/ld-alpha/ifunc-reflong-dynamic.d new file mode 100644 index 00000000000..2edab481e8a --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-reflong-dynamic.d @@ -0,0 +1,3 @@ +#source: ifunc-reflong.s +#ld: -melf64alpha --export-dynamic +#error: \A[^\n]*: REFLONG relocation against STT_GNU_IFUNC symbol `global_ifunc' is not supported\n[^\n]*: REFLONG relocation against STT_GNU_IFUNC symbol `local_ifunc' is not supported\n[^\n]*: final link failed[^\n]*\n?\Z diff --git ./ld/testsuite/ld-alpha/ifunc-reflong-static.d ./ld/testsuite/ld-alpha/ifunc-reflong-static.d new file mode 100644 index 00000000000..b10ad913f2c --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-reflong-static.d @@ -0,0 +1,3 @@ +#source: ifunc-reflong.s +#ld: -melf64alpha +#error: \A[^\n]*: REFLONG relocation against STT_GNU_IFUNC symbol `global_ifunc' is not supported\n[^\n]*: REFLONG relocation against STT_GNU_IFUNC symbol `local_ifunc' is not supported\n[^\n]*: final link failed[^\n]*\n?\Z diff --git ./ld/testsuite/ld-alpha/ifunc-reflong.s ./ld/testsuite/ld-alpha/ifunc-reflong.s new file mode 100644 index 00000000000..a153beb52a0 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-reflong.s @@ -0,0 +1,26 @@ + .text + + .globl global_ifunc + .type global_ifunc, @gnu_indirect_function +global_ifunc: + ret + + .type local_ifunc, @gnu_indirect_function +local_ifunc: + ret + + .globl _start + .ent _start +_start: + ret + .end _start + + # An IRELATIVE writes the 64-bit address the resolver returns, so a + # 32-bit reference to an IFUNC cannot be represented. A local symbol + # is named in the diagnostic by its symbol table entry rather than by + # a hash table entry. + .data + .globl ptr +ptr: + .long global_ifunc + .long local_ifunc diff --git ./ld/testsuite/ld-alpha/ifunc-srel.d ./ld/testsuite/ld-alpha/ifunc-srel.d new file mode 100644 index 00000000000..46034487b99 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-srel.d @@ -0,0 +1,3 @@ +#source: ifunc-srel.s +#ld: -melf64alpha +#error: \A[^\n]*: SREL16 relocation against STT_GNU_IFUNC symbol `global_ifunc' is not supported\n[^\n]*: SREL32 relocation against STT_GNU_IFUNC symbol `global_ifunc' is not supported\n[^\n]*: SREL64 relocation against STT_GNU_IFUNC symbol `global_ifunc' is not supported\n[^\n]*: final link failed[^\n]*\n?\Z diff --git ./ld/testsuite/ld-alpha/ifunc-srel.s ./ld/testsuite/ld-alpha/ifunc-srel.s new file mode 100644 index 00000000000..d0da109f471 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-srel.s @@ -0,0 +1,19 @@ + .text + + .globl global_ifunc + .type global_ifunc, @gnu_indirect_function +global_ifunc: + ret + + .globl _start + .ent _start +_start: + ret + .end _start + + # A pc-relative offset to an IFUNC is an offset to the resolver + # rather than to the function it selects. + .data + .short global_ifunc - . + .long global_ifunc - . + .quad global_ifunc - . From patchwork Tue Sep 1 02:33:14 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matt Turner X-Patchwork-Id: 142577 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id BDBF44BA7981 for ; Tue, 1 Sep 2026 02:38:00 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org BDBF44BA7981 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=rPWFUrQa X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from mail-yw1-x1132.google.com (mail-yw1-x1132.google.com [IPv6:2607:f8b0:4864:20::1132]) by sourceware.org (Postfix) with ESMTPS id 325E14BA7994 for ; Tue, 1 Sep 2026 02:33:35 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 325E14BA7994 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 325E14BA7994 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::1132 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1788230015; cv=none; b=ihat5No8WbYlagDatmxru9rE13VC1Cu0e3RMxpryIlvvBE6Y8gxJx0lcTQbB7y5GPnDsrJMKpFhTEA1A9YB2fZNwrmnUIy2PAggIM+bldY9myMXPTcKFu2V71qXkNa0m4Gu6ecOi182XVPZgXh8IFn8LLk9T9h0gQbM4BsjkADk= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1788230015; c=relaxed/simple; bh=7nzdDc+PUma8mxDXV2Krgdq5b5hhzjwhFnnmSK2Ol5k=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=VPBqy2Cb7uzWmPhmu6UpuFuH61e6MCsBsfoF4YtY7ZD5vrf5c35r26dGZxP56L9dyqhX6mlI9hPkmcUauv36AURyCnNNbIb/ckzbeh0yAPL2SkG1K+z/ebVXAOVYmfiUqErhlTUufGLHRyTe8yHphFiwNEiJaO2dZj1zlY16YIw= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=rPWFUrQa DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 325E14BA7994 Received: by mail-yw1-x1132.google.com with SMTP id 00721157ae682-85aeb506b78so56838117b3.3 for ; Mon, 31 Aug 2026 19:33:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788230014; x=1788834814; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=ZCxhxPsXjkmUOi8Z+T0dimK/4hJ92asQFUkLCJ4o5SY=; b=rPWFUrQag6QqHxwiV7jnOSbzp+gYWl3LAv4nP3LNnCjJRtDqyoIYTBoYz8DSTObyLP Zm17/NnGrBBPJh/qqh41z7SCozYdygz7wSj1CmyY4FJKlVF5R5eK1VZ9Dh3/iodCrixI 7FlxTD7xRAArujo8ewDMFcDU7moVSLZe91VdEklR5vmbtPFOrdbFWf6XRwyr+uZ6EkJX yaVppT5HAijQfjCvEO3fJRPAZ8Sc1hnWL/PX4lRyqH7ezLBTG9wKtEaxaMA1VEhf64Y3 m3om9UMg+WuOOXijjDjiGQ3OpWfcrm8Diq5LC/7dIVAROBmW3GiuQlMYSKyN9ZFlCKDl O0Rg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788230014; x=1788834814; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=ZCxhxPsXjkmUOi8Z+T0dimK/4hJ92asQFUkLCJ4o5SY=; b=AegI4V1tjSFGRe5rOb4wHuCcbUNsfSQxN1xu3VcTeSQA9znK2RjzB9JgjXPJUOD5KE ShTWZNFiXDcbWMFca1646dzOZxyemTDVVDO6VAtQmVhjnSSs6J9s/uN0bhlrSVc1utGD I5kbTHjTHGHV/FwP6TVrEowq+3sezHrJ/GbzeoMV/oiviCeotePGXJ7X3k6tBdh294La Yia76cIXRJ2eaPzp8iBAcBx6fDM6eMNkc1hhS/8JuE4cT++Hd0JONoK2hLjFuerTNpSi 67ZpBx25SeNkBFTYFry0IYOq4e41TEaeSDynJcg7OIWRMq/6dYq6/qo0amPetRE5QNdE zW6g== X-Gm-Message-State: AFuF++klWfPhOPiP+pBtbvJZDmD7kFKsnKdGRzcRxWFbG9TNfHuy/Bue ZMnrtBpB5Y1kUy6gJ6TVkMW+SQcGJfHtA+zauOSHfXNPmDOMf4AQNzH+a/ovzg== X-Gm-Gg: AYBFou1CLTV/aVD8z4sv+um7JSJflyZJIzAJex7ksx42uMuqU5hN4tw7cKrdckqovQr tFgdJkvQngOVcOI+cqvgKV4bG6APG0PoR/DsaiY6qx6ryBx89VtqQKuDGMI40WvQwdHqZ1EU723 X1zQq+h16ERIRRlEfF50Cy5rM8mpnJbWNilNCmkLBwibBl2AU3m/0/t45T8vLApFoKc+aMqn5Na U+J8xss1xrEQxgTEBFPV5+AeDwC7xqduuLPN9CL04eYS/qrMwhAjAyEK4mE28u6OKQmrkkUywbb 2+ZbB2AiDsNJTOalRkPPH2aPUSk+Uinxc/AeePXis1czfyLQNCFlvA+iufocfdwoz5QgD6rtMuQ R2LFNbhMInXubyQizg1c9D7VLKQQouzZKx0AgeBiu8J/iF8CN3AclLOKpPs5HhbOUZ8TIbMsNfx a4U/Il5+QGmleRBZ+PCE2IMb1pXA1mrZ1G243Zvk8KfBsmuMv0gBmtM8X/mxB1k1fHhDz8wRId1 AZKf1s9LbRxB8P1d4k3J6LFy93xJLY/7j3tQmVI X-Received: by 2002:a05:690c:6602:b0:858:1661:a43e with SMTP id 00721157ae682-86867ec13bdmr27610127b3.0.1788230013965; Mon, 31 Aug 2026 19:33:33 -0700 (PDT) Received: from localhost (107-220-129-194.lightspeed.chrlnc.sbcglobal.net. [107.220.129.194]) by smtp.gmail.com with ESMTPSA id 00721157ae682-85e668ce7ecsm65005457b3.34.2026.08.31.19.33.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Aug 2026 19:33:33 -0700 (PDT) From: Matt Turner To: binutils@sourceware.org Cc: Magnus Lindholm , Alan Modra , Matt Turner Subject: [PATCH 07/11] alpha: support IFUNC symbols in non-PIC links Date: Mon, 31 Aug 2026 22:33:14 -0400 Message-ID: <20260901023318.3503991-8-mattst88@gmail.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260901023318.3503991-1-mattst88@gmail.com> References: <20260901023318.3503991-1-mattst88@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-11.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, POISEN_SPAM_PILL, POISEN_SPAM_PILL_1, POISEN_SPAM_PILL_3, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on 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 A non-PIC link reserves no dynamic relocation for a reference it resolves itself, so an IFUNC reference has nothing to turn into an R_ALPHA_IRELATIVE the way a PIC link does. Put those in a new .rela.iplt instead, which the linker script places with the other dynamic relocations: ld.so applies it along with the rest of .rela.dyn, and in a static executable libc applies the range between __rela_iplt_start and __rela_iplt_end. Unlike .rela.dyn, .rela.iplt has to be sized exactly: libc applies every entry of it, so a slot reserved and then not filled in would be an R_ALPHA_NONE that its startup code chokes on. Only the input sections that make it into the output are relocated, and check_relocs runs before a linker script has had the chance to discard any of them, so the sizing runs in late_size_sections instead, over the sections that survived. It marks the got entry each surviving reference reaches, since however many references reach one it holds one address and gets one relocation, and counts the data references, which get one each. A reference whose symbol is itself defined in a discarded section reserves nothing either: the generic code reports it rather than letting relocate_section reach it. The got entries are counted again on each relaxation trip, since re-merging the GOTs can still combine two entries of a global IFUNC into one. The marks are made once: which sections survive does not change after this point, and merging two entries carries the mark over. Only the entry that survives a merge is asked for its mark, so it has to take the one the entry it absorbs made, which is not always its own: the reference that created the surviving entry may be the one a linker script discarded. A non-dynamic IFUNC gets no PLT entry, like any other function: a call goes through the GOT entry, and the IRELATIVE fills that in. A defined IFUNC then reaches finish_dynamic_symbol even when there are no dynamic sections (elf_link_output_extsym), where there is nothing left to do. A local IFUNC has to work: glibc's configure probe for linker IFUNC support is a data reference to one. Removing alpha from the skip list in ld-ifunc/ifunc.exp is left for later in the series, once the cases that cannot work are diagnosed. --- bfd/elf64-alpha.c | 346 +++++++++++++++++- ld/testsuite/ld-alpha/alpha.exp | 6 + ld/testsuite/ld-alpha/ifunc-comdat-a.s | 11 + ld/testsuite/ld-alpha/ifunc-comdat-b.s | 14 + ld/testsuite/ld-alpha/ifunc-comdat.d | 4 + ld/testsuite/ld-alpha/ifunc-discard.d | 11 + ld/testsuite/ld-alpha/ifunc-discard.ld | 4 + ld/testsuite/ld-alpha/ifunc-discard.s | 33 ++ ld/testsuite/ld-alpha/ifunc-extern.d | 14 + ld/testsuite/ld-alpha/ifunc-extern.s | 16 + ld/testsuite/ld-alpha/ifunc-gc-local.d | 8 + ld/testsuite/ld-alpha/ifunc-gc-local.s | 32 ++ ld/testsuite/ld-alpha/ifunc-gc.d | 8 + ld/testsuite/ld-alpha/ifunc-gc.s | 32 ++ ld/testsuite/ld-alpha/ifunc-global-dynamic.d | 9 + ld/testsuite/ld-alpha/ifunc-global-export.d | 12 + .../ld-alpha/ifunc-global-nocombreloc.d | 9 + ld/testsuite/ld-alpha/ifunc-global-static.d | 17 + .../ld-alpha/ifunc-local-call-static.d | 8 + ld/testsuite/ld-alpha/ifunc-local-dynamic.d | 9 + ld/testsuite/ld-alpha/ifunc-local-static.d | 17 + ld/testsuite/ld-alpha/ifunc-multi-a.s | 24 ++ ld/testsuite/ld-alpha/ifunc-multi-b.s | 16 + ld/testsuite/ld-alpha/ifunc-multi.d | 13 + ld/testsuite/ld-alpha/ifunc-none.d | 7 + ld/testsuite/ld-alpha/ifunc-none.s | 12 + ld/testsuite/ld-alpha/ifunc-relax-a.s | 32 ++ ld/testsuite/ld-alpha/ifunc-relax-b.s | 47 +++ ld/testsuite/ld-alpha/ifunc-relax-discard.d | 14 + ld/testsuite/ld-alpha/ifunc-relax-discard.s | 41 +++ ld/testsuite/ld-alpha/ifunc-relax.d | 14 + ld/testsuite/ld-alpha/ifunc-shlib.s | 9 + ld/testsuite/ld-alpha/ifunc-weak-dynamic.d | 9 + ld/testsuite/ld-alpha/ifunc-weak-static.d | 9 + .../ld-alpha/ifunc-weak-undef-dynamic.d | 5 + .../ld-alpha/ifunc-weak-undef-static.d | 5 + ld/testsuite/ld-alpha/ifunc-weak-undef.s | 22 ++ ld/testsuite/ld-alpha/ifunc-weak.s | 24 ++ 38 files changed, 911 insertions(+), 12 deletions(-) create mode 100644 ld/testsuite/ld-alpha/ifunc-comdat-a.s create mode 100644 ld/testsuite/ld-alpha/ifunc-comdat-b.s create mode 100644 ld/testsuite/ld-alpha/ifunc-comdat.d create mode 100644 ld/testsuite/ld-alpha/ifunc-discard.d create mode 100644 ld/testsuite/ld-alpha/ifunc-discard.ld create mode 100644 ld/testsuite/ld-alpha/ifunc-discard.s create mode 100644 ld/testsuite/ld-alpha/ifunc-extern.d create mode 100644 ld/testsuite/ld-alpha/ifunc-extern.s create mode 100644 ld/testsuite/ld-alpha/ifunc-gc-local.d create mode 100644 ld/testsuite/ld-alpha/ifunc-gc-local.s create mode 100644 ld/testsuite/ld-alpha/ifunc-gc.d create mode 100644 ld/testsuite/ld-alpha/ifunc-gc.s create mode 100644 ld/testsuite/ld-alpha/ifunc-global-dynamic.d create mode 100644 ld/testsuite/ld-alpha/ifunc-global-export.d create mode 100644 ld/testsuite/ld-alpha/ifunc-global-nocombreloc.d create mode 100644 ld/testsuite/ld-alpha/ifunc-global-static.d create mode 100644 ld/testsuite/ld-alpha/ifunc-local-call-static.d create mode 100644 ld/testsuite/ld-alpha/ifunc-local-dynamic.d create mode 100644 ld/testsuite/ld-alpha/ifunc-local-static.d create mode 100644 ld/testsuite/ld-alpha/ifunc-multi-a.s create mode 100644 ld/testsuite/ld-alpha/ifunc-multi-b.s create mode 100644 ld/testsuite/ld-alpha/ifunc-multi.d create mode 100644 ld/testsuite/ld-alpha/ifunc-none.d create mode 100644 ld/testsuite/ld-alpha/ifunc-none.s create mode 100644 ld/testsuite/ld-alpha/ifunc-relax-a.s create mode 100644 ld/testsuite/ld-alpha/ifunc-relax-b.s create mode 100644 ld/testsuite/ld-alpha/ifunc-relax-discard.d create mode 100644 ld/testsuite/ld-alpha/ifunc-relax-discard.s create mode 100644 ld/testsuite/ld-alpha/ifunc-relax.d create mode 100644 ld/testsuite/ld-alpha/ifunc-shlib.s create mode 100644 ld/testsuite/ld-alpha/ifunc-weak-dynamic.d create mode 100644 ld/testsuite/ld-alpha/ifunc-weak-static.d create mode 100644 ld/testsuite/ld-alpha/ifunc-weak-undef-dynamic.d create mode 100644 ld/testsuite/ld-alpha/ifunc-weak-undef-static.d create mode 100644 ld/testsuite/ld-alpha/ifunc-weak-undef.s create mode 100644 ld/testsuite/ld-alpha/ifunc-weak.s diff --git ./bfd/elf64-alpha.c ./bfd/elf64-alpha.c index ebb2f0ded11..470a6818023 100644 --- ./bfd/elf64-alpha.c +++ ./bfd/elf64-alpha.c @@ -135,6 +135,11 @@ struct alpha_elf_got_entry /* Have we adjusted this entry for SEC_MERGE? */ unsigned char reloc_xlated; + + /* Does a section that survives into the output refer to this entry? + Only such an entry is ever filled in, so only such an entry gets an + R_ALPHA_IRELATIVE reserved for it. */ + unsigned char irel_live; }; struct alpha_elf_reloc_entry @@ -196,6 +201,12 @@ struct alpha_elf_link_hash_table /* The most recent relax pass that we've seen. The GOTs should be regenerated if this doesn't match. */ int relax_trip; + + /* The part of the size of .rela.iplt that is due to data references to + an IFUNC, counted once the sections that survive into the output are + known. The rest comes from got entries and is recomputed whenever the + GOTs are. */ + bfd_size_type irelplt_data_size; }; /* Look up an entry in a Alpha ELF linker hash table. */ @@ -1808,6 +1819,260 @@ elf64_alpha_ifunc_reloc_p (unsigned long r_type) return r_type == R_ALPHA_LITERAL || r_type == R_ALPHA_REFQUAD; } +/* True if a reference to the IFUNC described by H (global) or SYM (local) + needs its R_ALPHA_IRELATIVE in .rela.iplt: the link is not PIC, so + nothing has reserved a slot for it alongside the R_ALPHA_RELATIVE it + would otherwise have had, and the symbol is not preemptible. */ + +static bool +elf64_alpha_ifunc_irelplt_p (struct alpha_elf_link_hash_entry *h, + Elf_Internal_Sym *sym, + struct bfd_link_info *info) +{ + if (!elf64_alpha_ifunc_p (h, sym) || bfd_link_pic (info)) + return false; + + return h == NULL || !alpha_elf_dynamic_symbol_p (&h->root, info); +} + +/* Create .rela.iplt. Called from check_relocs, since the section has to + exist before input sections are mapped to output sections. One that + stays empty is stripped by elf64_alpha_late_size_sections. */ + +static bool +elf64_alpha_create_irelplt (struct bfd_link_info *info) +{ + struct elf_link_hash_table *htab = elf_hash_table (info); + const struct elf_backend_data *bed; + asection *s; + + if (htab->irelplt != NULL) + return true; + + bed = get_elf_backend_data (info->output_bfd); + s = bfd_make_section_anyway_with_flags (htab->dynobj, ".rela.iplt", + (bed->dynamic_sec_flags + | SEC_READONLY)); + if (s == NULL || !bfd_set_section_alignment (s, 3)) + return false; + + htab->irelplt = s; + return true; +} + +/* Note that an R_ALPHA_IRELATIVE will be applied to SEC. A read-only one + needs the page made writable at startup, which only the dynamic linker + can do. Only a data relocation can land in such a section; the GOT is + always writable. */ + +static void +elf64_alpha_note_irelative (struct bfd_link_info *info, asection *sec) +{ + if ((sec->flags & SEC_READONLY) != 0) + { + info->flags |= DF_TEXTREL; + info->callbacks->minfo + (_("%pB: R_ALPHA_IRELATIVE in read-only section `%pA'\n"), + sec->owner, sec); + } +} + +/* Note the references to an IFUNC that need an R_ALPHA_IRELATIVE in + .rela.iplt: mark the got entries that get one and count the data + relocations that do. Only the input sections that make it into the + output are relocated, and only their references are emitted, so this runs + once the output sections are known rather than in check_relocs, which + still sees the sections a linker script goes on to discard. */ + +static bool +elf64_alpha_scan_irelative (struct bfd_link_info *info) +{ + struct alpha_elf_link_hash_table *htab = alpha_elf_hash_table (info); + bfd *abfd; + + htab->irelplt_data_size = 0; + + for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link.next) + { + Elf_Internal_Shdr *symtab_hdr; + asection *sec; + + if (!is_alpha_elf (abfd) || (abfd->flags & DYNAMIC) != 0) + continue; + + symtab_hdr = &elf_symtab_hdr (abfd); + + for (sec = abfd->sections; sec != NULL; sec = sec->next) + { + Elf_Internal_Rela *relocs, *rel, *relend; + bool noted = false; + + /* The sections elf_link_input_bfd will relocate. One a linker + script discarded and one discarded as a duplicate both have the + absolute section for their output. */ + if ((sec->flags & (SEC_ALLOC | SEC_RELOC | SEC_HAS_CONTENTS)) + != (SEC_ALLOC | SEC_RELOC | SEC_HAS_CONTENTS) + || sec->reloc_count == 0 + || sec->output_section == NULL + || bfd_is_abs_section (sec->output_section)) + continue; + + relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, + info->keep_memory); + if (relocs == NULL) + return false; + + relend = relocs + sec->reloc_count; + for (rel = relocs; rel < relend; rel++) + { + unsigned long r_type = ELF64_R_TYPE (rel->r_info); + unsigned long r_symndx = ELF64_R_SYM (rel->r_info); + struct alpha_elf_link_hash_entry *h = NULL; + Elf_Internal_Sym *isym = NULL; + struct alpha_elf_got_entry *gotent; + + if (!elf64_alpha_ifunc_reloc_p (r_type)) + continue; + + if (r_symndx < symtab_hdr->sh_info) + { + isym = bfd_sym_from_r_symndx + (&elf_hash_table (info)->sym_cache, abfd, r_symndx); + if (isym == NULL) + return false; + } + else + { + h = (alpha_elf_sym_hashes (abfd) + [r_symndx - symtab_hdr->sh_info]); + while (h->root.root.type == bfd_link_hash_indirect + || h->root.root.type == bfd_link_hash_warning) + h = ((struct alpha_elf_link_hash_entry *) + h->root.root.u.i.link); + } + + /* A symbol defined in a section the linker discarded reaches + relocate_section as an error rather than as a relocation to + emit, so nothing may be reserved for it. */ + if (h != NULL) + { + if ((h->root.root.type == bfd_link_hash_defined + || h->root.root.type == bfd_link_hash_defweak) + && discarded_section (h->root.root.u.def.section)) + continue; + } + else if (isym->st_shndx < SHN_LORESERVE + || isym->st_shndx > SHN_HIRESERVE) + { + /* An index above the reserved range is one that + bfd_sym_from_r_symndx expanded from an SHN_XINDEX + entry; elf_link_input_bfd looks that one up too. */ + asection *isec; + + isec = bfd_section_from_elf_index (abfd, isym->st_shndx); + if (isec != NULL && discarded_section (isec)) + continue; + } + + if (!elf64_alpha_ifunc_irelplt_p (h, isym, info)) + continue; + + if (r_type == R_ALPHA_REFQUAD) + { + htab->irelplt_data_size += sizeof (Elf64_External_Rela); + if (!noted) + { + elf64_alpha_note_irelative (info, sec); + noted = true; + } + continue; + } + + /* However many references reach a got entry, it holds one + address and gets one R_ALPHA_IRELATIVE. Find it the way + relocate_section will. */ + if (h != NULL) + gotent = h->got_entries; + else if (alpha_elf_tdata (abfd)->local_got_entries != NULL) + gotent = alpha_elf_tdata (abfd)->local_got_entries[r_symndx]; + else + gotent = NULL; + + for (; gotent != NULL; gotent = gotent->next) + if (gotent->gotobj == alpha_elf_tdata (abfd)->gotobj + && gotent->reloc_type == r_type + && gotent->addend == rel->r_addend) + { + gotent->irel_live = 1; + break; + } + } + + if (elf_section_data (sec)->relocs != relocs) + free (relocs); + } + } + + return true; +} + +/* Reserve space in .rela.iplt for the got entries of a global IFUNC that + elf64_alpha_scan_irelative marked. */ + +static bool +elf64_alpha_size_irelative (struct alpha_elf_link_hash_entry *h, + struct bfd_link_info *info) +{ + asection *irelplt = elf_hash_table (info)->irelplt; + struct alpha_elf_got_entry *gotent; + + for (gotent = h->got_entries; gotent != NULL; gotent = gotent->next) + if (gotent->irel_live && gotent->use_count > 0) + irelplt->size += sizeof (Elf64_External_Rela); + + return true; +} + +/* Size .rela.iplt. The data references are counted once, since nothing + later changes them; the got entries of a global IFUNC can still merge + when the GOTs are re-merged during relaxation, so the part of the size + that comes from them is recomputed alongside them. */ + +static void +elf64_alpha_size_irelplt_section (struct bfd_link_info *info) +{ + struct alpha_elf_link_hash_table *htab = alpha_elf_hash_table (info); + asection *irelplt = elf_hash_table (info)->irelplt; + bfd *i; + + if (irelplt == NULL) + return; + + irelplt->size = htab->irelplt_data_size; + alpha_elf_link_hash_traverse (htab, elf64_alpha_size_irelative, info); + + /* A local symbol has no hash entry for the traversal to reach. */ + for (i = htab->got_list; i != NULL; i = alpha_elf_tdata (i)->got_link_next) + { + bfd *j; + + for (j = i; j != NULL; j = alpha_elf_tdata (j)->in_got_link_next) + { + struct alpha_elf_got_entry **local_got_entries, *gotent; + int k, n; + + local_got_entries = alpha_elf_tdata (j)->local_got_entries; + if (local_got_entries == NULL) + continue; + + for (k = 0, n = elf_symtab_hdr (j).sh_info; k < n; ++k) + for (gotent = local_got_entries[k]; gotent; gotent = gotent->next) + if (gotent->irel_live && gotent->use_count > 0) + irelplt->size += sizeof (Elf64_External_Rela); + } + } +} + /* Handle dynamic relocations when doing an Alpha ELF link. */ static bool @@ -1844,14 +2109,29 @@ elf64_alpha_check_relocs (bfd *abfd, struct bfd_link_info *info, unsigned long r_symndx, r_type; struct alpha_elf_link_hash_entry *h; + Elf_Internal_Sym *isym; unsigned int gotent_flags; bool maybe_dynamic; unsigned int need; bfd_vma addend; r_symndx = ELF64_R_SYM (rel->r_info); + r_type = ELF64_R_TYPE (rel->r_info); + isym = NULL; if (r_symndx < symtab_hdr->sh_info) - h = NULL; + { + h = NULL; + + /* A local IFUNC needs the same treatment as a global one, but + only the symbol table says that it is one. */ + if (elf64_alpha_ifunc_reloc_p (r_type)) + { + isym = bfd_sym_from_r_symndx (&elf_hash_table (info)->sym_cache, + abfd, r_symndx); + if (isym == NULL) + return false; + } + } else { h = sym_hashes[r_symndx - symtab_hdr->sh_info]; @@ -1877,9 +2157,16 @@ elf64_alpha_check_relocs (bfd *abfd, struct bfd_link_info *info, || h->root.root.type == bfd_link_hash_defweak)) maybe_dynamic = true; + /* Whether a global IFUNC needs .rela.iplt is not settled until + sizing, so create the section for every reference that might. */ + if (elf64_alpha_ifunc_reloc_p (r_type) + && elf64_alpha_ifunc_p (h, isym) + && !bfd_link_pic (info) + && !elf64_alpha_create_irelplt (info)) + return false; + need = 0; gotent_flags = 0; - r_type = ELF64_R_TYPE (rel->r_info); addend = rel->r_addend; switch (r_type) @@ -1911,7 +2198,16 @@ elf64_alpha_check_relocs (bfd *abfd, struct bfd_link_info *info, case R_ALPHA_REFLONG: case R_ALPHA_REFQUAD: - if (bfd_link_pic (info) || maybe_dynamic) + if (r_type == R_ALPHA_REFQUAD && elf64_alpha_ifunc_p (h, isym)) + { + /* A reference that becomes an R_ALPHA_IRELATIVE in .rela.iplt + is sized later, from the sections that survive. Whether a + global one does is not settled until then, so record it + either way; a local symbol never becomes dynamic. */ + if (h != NULL || !elf64_alpha_ifunc_irelplt_p (NULL, isym, info)) + need = NEED_DYNREL; + } + else if (bfd_link_pic (info) || maybe_dynamic) need = NEED_DYNREL; break; @@ -2349,6 +2645,7 @@ elf64_alpha_merge_gots (bfd *a, bfd *b) && ae->addend == be->addend) { ae->flags |= be->flags; + ae->irel_live |= be->irel_live; ae->use_count += be->use_count; *pbe = be->next; memset (be, 0xa5, sizeof (*be)); @@ -2861,7 +3158,15 @@ elf64_alpha_late_size_sections (struct bfd_link_info *info) elf64_alpha_size_rela_got_section (info); elf64_alpha_size_plt_section (info); } - /* else we're not dynamic and by definition we don't need such things. */ + + /* The sizing above reserves nothing for a non-dynamic IFUNC, since the + dynamic linker never sees it; its relocations go in .rela.iplt. */ + if (elf_hash_table (info)->irelplt != NULL) + { + if (!elf64_alpha_scan_irelative (info)) + return false; + elf64_alpha_size_irelplt_section (info); + } /* The check_relocs and adjust_dynamic_symbol entry points have determined the sizes of the various dynamic sections. Allocate @@ -3763,6 +4068,7 @@ elf64_alpha_relax_section (bfd *abfd, asection *sec, elf64_alpha_size_plt_section (link_info); elf64_alpha_size_rela_got_section (link_info); } + elf64_alpha_size_irelplt_section (link_info); } symtab_hdr = &elf_symtab_hdr (abfd); @@ -4416,9 +4722,14 @@ elf64_alpha_relocate_section (struct bfd_link_info *info, /* If the symbol has been forced local, output a RELATIVE reloc, otherwise it will be handled in finish_dynamic_symbol. An IFUNC gets an IRELATIVE instead. */ - if (bfd_link_pic (info) - && !dynamic_symbol_p - && !undef_weak_ref) + if (elf64_alpha_ifunc_irelplt_p (h, sym, info)) + elf64_alpha_emit_dynrel (info->output_bfd, info, sgot, + elf_hash_table (info)->irelplt, + gotent->got_offset, 0, + R_ALPHA_IRELATIVE, value); + else if (bfd_link_pic (info) + && !dynamic_symbol_p + && !undef_weak_ref) elf64_alpha_emit_dynrel (info->output_bfd, info, sgot, srelgot, gotent->got_offset, 0, (elf64_alpha_ifunc_p (h, sym) @@ -4547,6 +4858,7 @@ elf64_alpha_relocate_section (struct bfd_link_info *info, { long dynindx, dyntype = r_type; bfd_vma dynaddend; + asection *srel_out = srel; /* Careful here to remember RELATIVE relocations for global variables for symbolic shared objects. */ @@ -4576,16 +4888,20 @@ elf64_alpha_relocate_section (struct bfd_link_info *info, dynaddend = value - dtp_base; } else if (elf64_alpha_ifunc_reloc_p (r_type) - && bfd_link_pic (info) && elf64_alpha_ifunc_p (h, sym) && (input_section->flags & SEC_ALLOC)) { - /* The RELATIVE this would otherwise get would store the - address of the resolver. Space for it is already - reserved, so the IRELATIVE takes its place. */ + /* In a PIC link the RELATIVE this would otherwise get would + store the address of the resolver, and space for it is + already reserved, so the IRELATIVE takes its place. A + non-PIC link reserved nothing there and puts it in + .rela.iplt instead. */ dynindx = 0; dyntype = R_ALPHA_IRELATIVE; dynaddend = value; + + if (elf64_alpha_ifunc_irelplt_p (h, sym, info)) + srel_out = elf_hash_table (info)->irelplt; } else if (bfd_link_pic (info) && r_symndx != STN_UNDEF @@ -4615,7 +4931,7 @@ elf64_alpha_relocate_section (struct bfd_link_info *info, if (input_section->flags & SEC_ALLOC) elf64_alpha_emit_dynrel (info->output_bfd, info, input_section, - srel, rel->r_offset, dynindx, + srel_out, rel->r_offset, dynindx, dyntype, dynaddend); } goto default_reloc; @@ -4850,6 +5166,12 @@ elf64_alpha_finish_dynamic_symbol (struct bfd_link_info *info, { struct alpha_elf_link_hash_entry *ah = (struct alpha_elf_link_hash_entry *)h; + /* Only a defined IFUNC gets here without dynamic sections. There is no + PLT to fill in, whatever needs_plt says, and relocate_section has + already written its GOT entries. */ + if (!elf_hash_table (info)->dynamic_sections_created) + return true; + if (h->needs_plt) { /* Fill in the .plt entry for this symbol. */ diff --git ./ld/testsuite/ld-alpha/alpha.exp ./ld/testsuite/ld-alpha/alpha.exp index af5d94e24a8..fa5862cc5eb 100644 --- ./ld/testsuite/ld-alpha/alpha.exp +++ ./ld/testsuite/ld-alpha/alpha.exp @@ -66,6 +66,8 @@ set alphatests { "" {got-realloc-a.s got-realloc-b.s} {{readelf -SW got-realloc.rd}} "got-realloc.so"} + {"IFUNC helper shared library" "-shared -melf64alpha" "" + "" {ifunc-shlib.s} {} "libalphaifunc.so"} } # Not implemented yet @@ -75,6 +77,10 @@ set alphatests { run_ld_link_tests $alphatests +# The dump tests run after the link tests above, so a .d file may name one +# of the shared libraries they leave in tmpdir. Several do: linking against +# a shared library is the only way to make a dump test produce an +# executable with dynamic sections. set test_list [lsort [glob -nocomplain $srcdir/$subdir/*.d]] foreach t $test_list { # We need to strip the ".d", but can leave the dirname. diff --git ./ld/testsuite/ld-alpha/ifunc-comdat-a.s ./ld/testsuite/ld-alpha/ifunc-comdat-a.s new file mode 100644 index 00000000000..5a71c7da3a8 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-comdat-a.s @@ -0,0 +1,11 @@ + .section .text.grp,"axG",@progbits,grp,comdat + .type kept_ifunc, @gnu_indirect_function +kept_ifunc: + ret + + .text + .globl _start + .ent _start +_start: + ret + .end _start diff --git ./ld/testsuite/ld-alpha/ifunc-comdat-b.s ./ld/testsuite/ld-alpha/ifunc-comdat-b.s new file mode 100644 index 00000000000..f612ddd4cd8 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-comdat-b.s @@ -0,0 +1,14 @@ + # This copy of the group is discarded in favour of the one in + # ifunc-comdat-a.s, taking the definition of local_ifunc with it. + .section .text.grp,"axG",@progbits,grp,comdat + .type local_ifunc, @gnu_indirect_function +local_ifunc: + ret + + # The reference survives, but nothing relocates it: the generic code + # reports it rather than letting relocate_section reach it. Nothing + # may be reserved in .rela.iplt for it either. + .data + .globl ptr +ptr: + .quad local_ifunc diff --git ./ld/testsuite/ld-alpha/ifunc-comdat.d ./ld/testsuite/ld-alpha/ifunc-comdat.d new file mode 100644 index 00000000000..752f92bba61 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-comdat.d @@ -0,0 +1,4 @@ +#source: ifunc-comdat-a.s +#source: ifunc-comdat-b.s +#ld: -melf64alpha +#error: \A`local_ifunc' referenced in section `\.data' of [^\n]*: defined in discarded section `\.text\.grp\[grp\]' of [^\n]*\n?\Z diff --git ./ld/testsuite/ld-alpha/ifunc-discard.d ./ld/testsuite/ld-alpha/ifunc-discard.d new file mode 100644 index 00000000000..86fa8d48dc4 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-discard.d @@ -0,0 +1,11 @@ +#source: ifunc-discard.s +#ld: -melf64alpha --no-warn-rwx-segments -T $srcdir/$subdir/ifunc-discard.ld +#readelf: -Wr + +# Only the reference that survives the script reserves anything. A slot +# reserved for one the script discarded would be left as an R_ALPHA_NONE, +# which libc's startup code would try to apply. +Relocation section '\.rela\.dyn' .* contains 1 entry: +#... +[0-9a-f]+ +0+2a R_ALPHA_IRELATIVE +[0-9a-f]+ +#pass diff --git ./ld/testsuite/ld-alpha/ifunc-discard.ld ./ld/testsuite/ld-alpha/ifunc-discard.ld new file mode 100644 index 00000000000..f0cc43278ba --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-discard.ld @@ -0,0 +1,4 @@ +SECTIONS +{ + /DISCARD/ : { *(.data.discard) *(.text.discard) } +} diff --git ./ld/testsuite/ld-alpha/ifunc-discard.s ./ld/testsuite/ld-alpha/ifunc-discard.s new file mode 100644 index 00000000000..005c660e8fe --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-discard.s @@ -0,0 +1,33 @@ + .text + + .globl global_ifunc + .type global_ifunc, @gnu_indirect_function +global_ifunc: + ret + + .type local_ifunc, @gnu_indirect_function +local_ifunc: + ret + + .globl _start + .ent _start +_start: + ret + .end _start + + # The one reference that survives, so that .rela.iplt is not simply + # empty. + .data + .globl ptr +ptr: + .quad global_ifunc + + # A linker script discards these after check_relocs has seen them. + # Nothing relocates them, so nothing may be reserved for them. + .section .data.discard,"aw",@progbits + .quad global_ifunc + .quad local_ifunc + + .section .text.discard,"ax",@progbits + ldq $27, global_ifunc($29) !literal!1 + ldq $27, local_ifunc($29) !literal!2 diff --git ./ld/testsuite/ld-alpha/ifunc-extern.d ./ld/testsuite/ld-alpha/ifunc-extern.d new file mode 100644 index 00000000000..f37118f98bf --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-extern.d @@ -0,0 +1,14 @@ +#source: ifunc-extern.s +#ld: -melf64alpha tmpdir/libalphaifunc.so +#readelf: -Wr + +# The IFUNC is defined in another module, so the dynamic linker resolves +# it: an ordinary PLT entry and a symbolic data relocation, no IRELATIVE. +Relocation section '\.rela\.dyn' .* contains 1 entry: +#... +[0-9a-f]+ +[0-9a-f]+ +R_ALPHA_REFQUAD .*shlib_ifunc \+ 0 +#... +Relocation section '\.rela\.plt' .* contains 1 entry: +#... +[0-9a-f]+ +[0-9a-f]+ +R_ALPHA_JMP_SLOT .*shlib_ifunc \+ 0 +#pass diff --git ./ld/testsuite/ld-alpha/ifunc-extern.s ./ld/testsuite/ld-alpha/ifunc-extern.s new file mode 100644 index 00000000000..d8e2cddaba4 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-extern.s @@ -0,0 +1,16 @@ + .text + + .globl _start + .ent _start +_start: + ldgp $29, 0($27) + ldq $27, shlib_ifunc($29) !literal!1 + jsr $26, ($27), 0 !lituse_jsr!1 + ldgp $29, 0($26) + ret + .end _start + + .data + .globl ptr +ptr: + .quad shlib_ifunc diff --git ./ld/testsuite/ld-alpha/ifunc-gc-local.d ./ld/testsuite/ld-alpha/ifunc-gc-local.d new file mode 100644 index 00000000000..be3336c2e51 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-gc-local.d @@ -0,0 +1,8 @@ +#source: ifunc-gc-local.s +#ld: -melf64alpha --gc-sections -e _start +#readelf: -Wr + +Relocation section '\.rela\.dyn' .* contains 1 entry: +#... +[0-9a-f]+ +[0-9a-f]+ +R_ALPHA_IRELATIVE +[0-9a-f]+ +#pass diff --git ./ld/testsuite/ld-alpha/ifunc-gc-local.s ./ld/testsuite/ld-alpha/ifunc-gc-local.s new file mode 100644 index 00000000000..bcbdbc02202 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-gc-local.s @@ -0,0 +1,32 @@ + .section .text.ifunc,"ax",@progbits + .type local_ifunc, @gnu_indirect_function +local_ifunc: + ret + + # Both of these need an IRELATIVE, but --gc-sections drops the + # section holding the call before check_relocs runs, so only one is + # counted. + .section .text.dead,"ax",@progbits + .globl dead + .ent dead +dead: + ldgp $29, 0($27) + ldq $27, local_ifunc($29) !literal!1 + jsr $26, ($27), 0 !lituse_jsr!1 + ldgp $29, 0($26) + ret + .end dead + + .section .data.live,"aw",@progbits + .globl ptr +ptr: + .quad local_ifunc + + .section .text.start,"ax",@progbits + .globl _start + .ent _start +_start: + ldgp $29, 0($27) + ldah $1, ptr($29) !gprelhigh + ret + .end _start diff --git ./ld/testsuite/ld-alpha/ifunc-gc.d ./ld/testsuite/ld-alpha/ifunc-gc.d new file mode 100644 index 00000000000..c9e9d389d3b --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-gc.d @@ -0,0 +1,8 @@ +#source: ifunc-gc.s +#ld: -melf64alpha --gc-sections -e _start +#readelf: -Wr + +Relocation section '\.rela\.dyn' .* contains 1 entry: +#... +[0-9a-f]+ +[0-9a-f]+ +R_ALPHA_IRELATIVE +[0-9a-f]+ +#pass diff --git ./ld/testsuite/ld-alpha/ifunc-gc.s ./ld/testsuite/ld-alpha/ifunc-gc.s new file mode 100644 index 00000000000..cde51d4c3e4 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-gc.s @@ -0,0 +1,32 @@ + .section .text.ifunc,"ax",@progbits + .globl global_ifunc + .type global_ifunc, @gnu_indirect_function +global_ifunc: + ret + + # Both of these need an IRELATIVE, but --gc-sections drops the + # section holding the call, so only one may be reserved. + .section .text.dead,"ax",@progbits + .globl dead + .ent dead +dead: + ldgp $29, 0($27) + ldq $27, global_ifunc($29) !literal!1 + jsr $26, ($27), 0 !lituse_jsr!1 + ldgp $29, 0($26) + ret + .end dead + + .section .data.live,"aw",@progbits + .globl ptr +ptr: + .quad global_ifunc + + .section .text.start,"ax",@progbits + .globl _start + .ent _start +_start: + ldgp $29, 0($27) + ldah $1, ptr($29) !gprelhigh + ret + .end _start diff --git ./ld/testsuite/ld-alpha/ifunc-global-dynamic.d ./ld/testsuite/ld-alpha/ifunc-global-dynamic.d new file mode 100644 index 00000000000..2915f33fa12 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-global-dynamic.d @@ -0,0 +1,9 @@ +#source: ifunc-global.s +#ld: -melf64alpha tmpdir/libalphaifunc.so +#readelf: -Wr + +Relocation section '\.rela\.dyn' .* contains 2 entries: +#... +[0-9a-f]+ +[0-9a-f]+ +R_ALPHA_IRELATIVE +[0-9a-f]+ +[0-9a-f]+ +[0-9a-f]+ +R_ALPHA_IRELATIVE +[0-9a-f]+ +#pass diff --git ./ld/testsuite/ld-alpha/ifunc-global-export.d ./ld/testsuite/ld-alpha/ifunc-global-export.d new file mode 100644 index 00000000000..9d40e14486a --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-global-export.d @@ -0,0 +1,12 @@ +#source: ifunc-global.s +#ld: -melf64alpha --export-dynamic tmpdir/libalphaifunc.so +#readelf: -Wr + +# One IRELATIVE for the GOT entry and one for ptr, and nothing else. The +# IFUNC is in .dynsym but is not preemptible in an executable, so the link +# resolves it itself and no PLT entry is left over from the guess that +# check_relocs makes about one. +Relocation section '\.rela\.dyn' .* contains 2 entries: + +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend +[0-9a-f]+ +0+2a R_ALPHA_IRELATIVE +[0-9a-f]+ +[0-9a-f]+ +0+2a R_ALPHA_IRELATIVE +[0-9a-f]+ diff --git ./ld/testsuite/ld-alpha/ifunc-global-nocombreloc.d ./ld/testsuite/ld-alpha/ifunc-global-nocombreloc.d new file mode 100644 index 00000000000..2c5a6ebb174 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-global-nocombreloc.d @@ -0,0 +1,9 @@ +#source: ifunc-global.s +#ld: -melf64alpha -z nocombreloc +#readelf: -Wr + +Relocation section '\.rela\.iplt' .* contains 2 entries: +#... +[0-9a-f]+ +[0-9a-f]+ +R_ALPHA_IRELATIVE +[0-9a-f]+ +[0-9a-f]+ +[0-9a-f]+ +R_ALPHA_IRELATIVE +[0-9a-f]+ +#pass diff --git ./ld/testsuite/ld-alpha/ifunc-global-static.d ./ld/testsuite/ld-alpha/ifunc-global-static.d new file mode 100644 index 00000000000..415d5245b68 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-global-static.d @@ -0,0 +1,17 @@ +#source: ifunc-global.s +#ld: -melf64alpha +#readelf: -Wrs + +# One IRELATIVE for the GOT entry and one for ptr. The symbol table +# entries confirm that the resolver kept its IFUNC type. +Relocation section '\.rela\.dyn' .* contains 2 entries: +#... +[0-9a-f]+ +0+2a R_ALPHA_IRELATIVE +[0-9a-f]+ +[0-9a-f]+ +0+2a R_ALPHA_IRELATIVE +[0-9a-f]+ +#... +Symbol table '\.symtab' contains .* entries: +#... + +[0-9]+: [0-9a-f]+ +0 IFUNC +GLOBAL +DEFAULT +[0-9]+ global_ifunc +#... + +[0-9]+: [0-9a-f]+ +0 NOTYPE +GLOBAL +DEFAULT +[0-9]+ ptr +#pass diff --git ./ld/testsuite/ld-alpha/ifunc-local-call-static.d ./ld/testsuite/ld-alpha/ifunc-local-call-static.d new file mode 100644 index 00000000000..f24f9dbd2b2 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-local-call-static.d @@ -0,0 +1,8 @@ +#source: ifunc-local-call.s +#ld: -melf64alpha +#readelf: -Wr + +Relocation section '\.rela\.dyn' .* contains 1 entry: +#... +[0-9a-f]+ +[0-9a-f]+ +R_ALPHA_IRELATIVE +[0-9a-f]+ +#pass diff --git ./ld/testsuite/ld-alpha/ifunc-local-dynamic.d ./ld/testsuite/ld-alpha/ifunc-local-dynamic.d new file mode 100644 index 00000000000..f38004249bf --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-local-dynamic.d @@ -0,0 +1,9 @@ +#source: ifunc-local.s +#ld: -melf64alpha tmpdir/libalphaifunc.so +#readelf: -Wr + +Relocation section '\.rela\.dyn' .* contains 2 entries: +#... +[0-9a-f]+ +[0-9a-f]+ +R_ALPHA_IRELATIVE +[0-9a-f]+ +[0-9a-f]+ +[0-9a-f]+ +R_ALPHA_IRELATIVE +[0-9a-f]+ +#pass diff --git ./ld/testsuite/ld-alpha/ifunc-local-static.d ./ld/testsuite/ld-alpha/ifunc-local-static.d new file mode 100644 index 00000000000..7096633a729 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-local-static.d @@ -0,0 +1,17 @@ +#source: ifunc-local.s +#ld: -melf64alpha +#readelf: -Wrs + +# One IRELATIVE for the GOT entry and one for ptr. The symbol table +# entries confirm that the resolver kept its IFUNC type. +Relocation section '\.rela\.dyn' .* contains 2 entries: +#... +[0-9a-f]+ +0+2a R_ALPHA_IRELATIVE +[0-9a-f]+ +[0-9a-f]+ +0+2a R_ALPHA_IRELATIVE +[0-9a-f]+ +#... +Symbol table '\.symtab' contains .* entries: +#... + +[0-9]+: [0-9a-f]+ +0 IFUNC +LOCAL +DEFAULT +[0-9]+ local_ifunc +#... + +[0-9]+: [0-9a-f]+ +0 NOTYPE +GLOBAL +DEFAULT +[0-9]+ ptr +#pass diff --git ./ld/testsuite/ld-alpha/ifunc-multi-a.s ./ld/testsuite/ld-alpha/ifunc-multi-a.s new file mode 100644 index 00000000000..bfdd314b023 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-multi-a.s @@ -0,0 +1,24 @@ + .text + + # One object defines the IFUNC and both call and reference it, so + # that the GOT entries merge into one and the two data references + # accumulate on the same hash table entry. + .globl global_ifunc + .type global_ifunc, @gnu_indirect_function +global_ifunc: + ret + + .globl _start + .ent _start +_start: + ldgp $29, 0($27) + ldq $27, global_ifunc($29) !literal!1 + jsr $26, ($27), 0 !lituse_jsr!1 + ldgp $29, 0($26) + ret + .end _start + + .data + .globl ptr_a +ptr_a: + .quad global_ifunc diff --git ./ld/testsuite/ld-alpha/ifunc-multi-b.s ./ld/testsuite/ld-alpha/ifunc-multi-b.s new file mode 100644 index 00000000000..119a8b3fbea --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-multi-b.s @@ -0,0 +1,16 @@ + .text + + .globl other + .ent other +other: + ldgp $29, 0($27) + ldq $27, global_ifunc($29) !literal!1 + jsr $26, ($27), 0 !lituse_jsr!1 + ldgp $29, 0($26) + ret + .end other + + .data + .globl ptr_b +ptr_b: + .quad global_ifunc diff --git ./ld/testsuite/ld-alpha/ifunc-multi.d ./ld/testsuite/ld-alpha/ifunc-multi.d new file mode 100644 index 00000000000..d39a428d69a --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-multi.d @@ -0,0 +1,13 @@ +#source: ifunc-multi-a.s +#source: ifunc-multi-b.s +#ld: -melf64alpha +#readelf: -Wr + +# One IRELATIVE for the merged GOT entry and one for each of the two data +# references. +Relocation section '\.rela\.dyn' .* contains 3 entries: +#... +[0-9a-f]+ +0+2a R_ALPHA_IRELATIVE +[0-9a-f]+ +[0-9a-f]+ +0+2a R_ALPHA_IRELATIVE +[0-9a-f]+ +[0-9a-f]+ +0+2a R_ALPHA_IRELATIVE +[0-9a-f]+ +#pass diff --git ./ld/testsuite/ld-alpha/ifunc-none.d ./ld/testsuite/ld-alpha/ifunc-none.d new file mode 100644 index 00000000000..1ab9ce7e457 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-none.d @@ -0,0 +1,7 @@ +#source: ifunc-none.s +#ld: -melf64alpha +#readelf: -Wr + +# A link with nothing to resolve at startup gets no relocations at all, and +# in particular no .rela.iplt. +There are no relocations in this file\. diff --git ./ld/testsuite/ld-alpha/ifunc-none.s ./ld/testsuite/ld-alpha/ifunc-none.s new file mode 100644 index 00000000000..0846a6f7f5e --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-none.s @@ -0,0 +1,12 @@ + .text + + .globl _start + .ent _start +_start: + ret + .end _start + + .data + .globl ptr +ptr: + .quad _start diff --git ./ld/testsuite/ld-alpha/ifunc-relax-a.s ./ld/testsuite/ld-alpha/ifunc-relax-a.s new file mode 100644 index 00000000000..a7253da3ab1 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-relax-a.s @@ -0,0 +1,32 @@ +/* 8000 got entries against undefined symbols, so relaxation cannot remove + any of them. That is 64000 bytes; with the entry for the IFUNC it is + just under MAX_GOT_SIZE, so this object keeps its own got subsection. */ + + .text + .globl global_ifunc + .type global_ifunc, @gnu_indirect_function +global_ifunc: + ret + + .globl _start + .ent _start +_start: + ldgp $29,0($27) + .prologue 1 + ldq $1,global_ifunc($29) !literal + .irpc w,01234567 + .irpc x,0123456789 + .irpc y,0123456789 + .irpc z,0123456789 + ldq $1,g\w\x\y\z($29) !literal + .endr + .endr + .endr + .endr + ret $31,($26),1 + .end _start + + .data + .globl ptr +ptr: + .quad global_ifunc diff --git ./ld/testsuite/ld-alpha/ifunc-relax-b.s ./ld/testsuite/ld-alpha/ifunc-relax-b.s new file mode 100644 index 00000000000..21e097d19af --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-relax-b.s @@ -0,0 +1,47 @@ +/* 251 got entries, of which relaxation removes the 150 that are only used + by a call to a local function. Adding this object's entries to the 8001 + in ifunc-relax-a.s exceeds MAX_GOT_SIZE, so the two subsections cannot be + merged when they are first sized. Once relaxation has dropped the 150 + they fit, and the two entries for the IFUNC merge into one, which is one + fewer R_ALPHA_IRELATIVE than the first sizing reserved. */ + + .macro mkcall name, seq + ldq $27,\name($29) !literal!\seq + jsr $26,($27),\name !lituse_jsr!\seq + .endm + + .text + + .irpc x,012 + .irpc y,0123456789 + .irpc z,01234 + .ent lf\x\y\z +lf\x\y\z: + ldgp $29,0($27) + .prologue 1 + ret $31,($26),1 + .end lf\x\y\z + .endr + .endr + .endr + + .globl bfunc + .ent bfunc +bfunc: + ldgp $29,0($27) + .prologue 1 + ldq $1,global_ifunc($29) !literal + .irpc x,012 + .irpc y,0123456789 + .irpc z,01234 + mkcall lf\x\y\z, 1\x\y\z + .endr + .endr + .endr + .irpc x,0123456789 + .irpc y,0123456789 + ldq $1,h\x\y($29) !literal + .endr + .endr + ret $31,($26),1 + .end bfunc diff --git ./ld/testsuite/ld-alpha/ifunc-relax-discard.d ./ld/testsuite/ld-alpha/ifunc-relax-discard.d new file mode 100644 index 00000000000..433cca04be8 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-relax-discard.d @@ -0,0 +1,14 @@ +#source: ifunc-relax-discard.s +#source: ifunc-relax-b.s +#ld: -relax -melf64alpha --unresolved-symbols=ignore-all --no-warn-rwx-segments -T $srcdir/$subdir/ifunc-discard.ld +#readelf: -Wr + +# The got entry that survives the merge during relaxation is the one whose +# only reference the linker script discarded, so it carries no mark of its +# own. It has to take the one from the entry it absorbs, or nothing is +# reserved for the reference that does survive. +Relocation section '\.rela\.dyn' .* contains 2 entries: +#... +[0-9a-f]+ +0+2a R_ALPHA_IRELATIVE +[0-9a-f]+ +[0-9a-f]+ +0+2a R_ALPHA_IRELATIVE +[0-9a-f]+ +#pass diff --git ./ld/testsuite/ld-alpha/ifunc-relax-discard.s ./ld/testsuite/ld-alpha/ifunc-relax-discard.s new file mode 100644 index 00000000000..450c1029fbf --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-relax-discard.s @@ -0,0 +1,41 @@ +/* As ifunc-relax-a.s, but with this object's reference to the IFUNC in a + section that the linker script discards. */ + + .text + .globl global_ifunc + .type global_ifunc, @gnu_indirect_function +global_ifunc: + ret + + # The only reference in this object to the IFUNC's got entry, in a + # section the linker script discards. The entry is still created and + # still occupies the got, so it is the one that survives when the two + # got subsections merge, and it has to take the mark from the entry + # that the surviving reference in ifunc-relax-b.s made. + .section .text.discard,"ax",@progbits + ldgp $29,0($27) + ldq $1,global_ifunc($29) !literal + ret + + .text + .globl _start + .ent _start +_start: + ldgp $29,0($27) + .prologue 1 + .irpc w,01234567 + .irpc x,0123456789 + .irpc y,0123456789 + .irpc z,0123456789 + ldq $1,g\w\x\y\z($29) !literal + .endr + .endr + .endr + .endr + ret $31,($26),1 + .end _start + + .data + .globl ptr +ptr: + .quad global_ifunc diff --git ./ld/testsuite/ld-alpha/ifunc-relax.d ./ld/testsuite/ld-alpha/ifunc-relax.d new file mode 100644 index 00000000000..37c3ce2b871 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-relax.d @@ -0,0 +1,14 @@ +#source: ifunc-relax-a.s +#source: ifunc-relax-b.s +#ld: -relax -melf64alpha --unresolved-symbols=ignore-all +#readelf: -Wr + +# The two objects' got subsections cannot be merged until relaxation has +# shrunk them, and the merge leaves one entry for the IFUNC where the first +# sizing counted two. One IRELATIVE for that entry and one for ptr; a third +# would mean .rela.iplt was not sized again after the got was. +Relocation section '\.rela\.dyn' .* contains 2 entries: +#... +[0-9a-f]+ +0+2a R_ALPHA_IRELATIVE +[0-9a-f]+ +[0-9a-f]+ +0+2a R_ALPHA_IRELATIVE +[0-9a-f]+ +#pass diff --git ./ld/testsuite/ld-alpha/ifunc-shlib.s ./ld/testsuite/ld-alpha/ifunc-shlib.s new file mode 100644 index 00000000000..ad955ba7466 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-shlib.s @@ -0,0 +1,9 @@ + .text + + # An IFUNC exported from a shared library. A reference from another + # module is resolved by the dynamic linker, not by the static linker, + # so it is treated as an ordinary function here. + .globl shlib_ifunc + .type shlib_ifunc, @gnu_indirect_function +shlib_ifunc: + ret diff --git ./ld/testsuite/ld-alpha/ifunc-weak-dynamic.d ./ld/testsuite/ld-alpha/ifunc-weak-dynamic.d new file mode 100644 index 00000000000..d5c7b4af8ce --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-weak-dynamic.d @@ -0,0 +1,9 @@ +#source: ifunc-weak.s +#ld: -melf64alpha tmpdir/libalphaifunc.so +#readelf: -Wr + +Relocation section '\.rela\.dyn' .* contains 2 entries: +#... +[0-9a-f]+ +[0-9a-f]+ +R_ALPHA_IRELATIVE +[0-9a-f]+ +[0-9a-f]+ +[0-9a-f]+ +R_ALPHA_IRELATIVE +[0-9a-f]+ +#pass diff --git ./ld/testsuite/ld-alpha/ifunc-weak-static.d ./ld/testsuite/ld-alpha/ifunc-weak-static.d new file mode 100644 index 00000000000..2b24975180c --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-weak-static.d @@ -0,0 +1,9 @@ +#source: ifunc-weak.s +#ld: -melf64alpha +#readelf: -Wr + +Relocation section '\.rela\.dyn' .* contains 2 entries: +#... +[0-9a-f]+ +[0-9a-f]+ +R_ALPHA_IRELATIVE +[0-9a-f]+ +[0-9a-f]+ +[0-9a-f]+ +R_ALPHA_IRELATIVE +[0-9a-f]+ +#pass diff --git ./ld/testsuite/ld-alpha/ifunc-weak-undef-dynamic.d ./ld/testsuite/ld-alpha/ifunc-weak-undef-dynamic.d new file mode 100644 index 00000000000..d9a69c98eb9 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-weak-undef-dynamic.d @@ -0,0 +1,5 @@ +#source: ifunc-weak-undef.s +#ld: -melf64alpha tmpdir/libalphaifunc.so +#readelf: -Wr + +There are no relocations in this file\. diff --git ./ld/testsuite/ld-alpha/ifunc-weak-undef-static.d ./ld/testsuite/ld-alpha/ifunc-weak-undef-static.d new file mode 100644 index 00000000000..3f84c7bea2d --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-weak-undef-static.d @@ -0,0 +1,5 @@ +#source: ifunc-weak-undef.s +#ld: -melf64alpha +#readelf: -Wr + +There are no relocations in this file\. diff --git ./ld/testsuite/ld-alpha/ifunc-weak-undef.s ./ld/testsuite/ld-alpha/ifunc-weak-undef.s new file mode 100644 index 00000000000..7d7a812309b --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-weak-undef.s @@ -0,0 +1,22 @@ + .text + + # A weak reference that carries the IFUNC type without a definition. + # It resolves to zero like any other undefined weak function; the + # type must not make the linker treat it as a defined IFUNC. + .weak weak_ifunc + .type weak_ifunc, @gnu_indirect_function + + .globl _start + .ent _start +_start: + ldgp $29, 0($27) + ldq $27, weak_ifunc($29) !literal!1 + jsr $26, ($27), 0 !lituse_jsr!1 + ldgp $29, 0($26) + ret + .end _start + + .data + .globl ptr +ptr: + .quad weak_ifunc diff --git ./ld/testsuite/ld-alpha/ifunc-weak.s ./ld/testsuite/ld-alpha/ifunc-weak.s new file mode 100644 index 00000000000..0461a5f4032 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-weak.s @@ -0,0 +1,24 @@ + .text + + # A weak IFUNC, both called and referenced. It is not preemptible + # in an executable, so this link resolves it itself, but its weak + # binding makes check_relocs guess that it might become dynamic. + .weak weak_ifunc + .type weak_ifunc, @gnu_indirect_function +weak_ifunc: + ret + + .globl _start + .ent _start +_start: + ldgp $29, 0($27) + ldq $27, weak_ifunc($29) !literal!1 + jsr $26, ($27), 0 !lituse_jsr!1 + ldgp $29, 0($26) + ret + .end _start + + .data + .globl ptr +ptr: + .quad weak_ifunc From patchwork Tue Sep 1 02:33:15 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matt Turner X-Patchwork-Id: 142573 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 762AE4BA5434 for ; Tue, 1 Sep 2026 02:36:29 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 762AE4BA5434 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=P3rtDWYF X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from mail-yw1-x112c.google.com (mail-yw1-x112c.google.com [IPv6:2607:f8b0:4864:20::112c]) by sourceware.org (Postfix) with ESMTPS id 82AEA4BA9001 for ; Tue, 1 Sep 2026 02:33:36 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 82AEA4BA9001 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 82AEA4BA9001 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::112c ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1788230016; cv=none; b=IgSIj6HKXLIB2KzZCoKy+B3lm4C7vGX+16mJ3JXxVZtkm6Au6BaU6jgVD4qsbi74EXtrpVplek7Ad7QxzaCrrqxRcfWwR6gpqF2+R6KWGoD7Oa4rd+wdJJk8z0uRPy7dFh7fwz/Eu4Xc5fdSSWoBnJRwicUbYluTQ6fHKeQwY3A= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1788230016; c=relaxed/simple; bh=ZJgRW9GaKL+gLnE1VxaKgfcMp4Ymaf/I3h5n1RRoAII=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=kg4pCK2vq1aN0NAVHV58CYfi2+CSelnQylBXAncXczHEdVGJ+sOBe/aOpqWd8mNQwqxx8mVDt7qa4MUzdh6Gk7m7BILRy7CjqsYpecGeuUV+TXHt+3XIddr0SN3xXoOM/2mgTOK5xPFLpiM3aaxuLAhGkJyQtwTmmb3q2hZATXM= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=P3rtDWYF DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 82AEA4BA9001 Received: by mail-yw1-x112c.google.com with SMTP id 00721157ae682-8630c1503f2so20240467b3.1 for ; Mon, 31 Aug 2026 19:33:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788230016; x=1788834816; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=RFAHhjXP8xb0rrGlsxZH4s286WioOhKwPVToi8Lt+I0=; b=P3rtDWYFCtzNQGZC4OoYYf72tUk1jqPKuvgN1P/oeJJp+GLqrnOT5acgHhZUQO66MQ 7GhJQkLhjY1eucWky1q9L3Z/sPpS07CpFctsO/Ym61PRoVWlMWaiTz0bP7bJZKwxcASl x5yJ2j0/7DPMm2VKVwmeAqp+3RThqsXi6smk6TY5H/LZdyAlo/h1TiiMRJXPAsbi/gLe Fk5bfRhPinTkGQRZywUDmoXZSFDsCwyuxLUk35IO09reRBefSoDjaKhXpqaDmJaolVNZ Ez/OcHxtqV72mpcq6yY3yQCG6eTNYEwcPh9bqZVoJz/LzTXVloQNod0W/BBchK0xkZWu kb3g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788230016; x=1788834816; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=RFAHhjXP8xb0rrGlsxZH4s286WioOhKwPVToi8Lt+I0=; b=CTSRBlPhiAL62bUFaf//WZFIWgNuXOpDZ5l66c2asXWYCvlBkJ8hyol+0wE+2vDJKu OlSL0T8SUJhQxqOagva6YxKfrOJVizmCN1to3tQmHhisTkuMqUveCPULWlApXAIkeXmw cqgHEgF9FX/ZI4PNDTsMZGAbHv7AzE9vwc69FmPbC0Tu1MBAq7WQXs1jRK6LuUpKRe+1 lrJ0wG4rmsijad2PkwdV4ZInOGOQYfhGan0+8UTQNvh/2dB9Vgke3jOAOeOM10w0jkAx 35Wn+ivLnR7y0zMHHlAxZfa66TNXv76HIHwuPFsvAghkX9BoXfUP5SjcVeYZBYMtTSLJ LmAg== X-Gm-Message-State: AFuF++mSvJ1EnutrHUKSP9sTZsZb3GyQ+qS0Cc8I9LBrX9TPLF8yHr6G WRT4RE5UKAt99O+F+1hI3/sMrvhDRAspZoT0rLk5Tv3Xdg3EEsZfovJH8G1OPg== X-Gm-Gg: AYBFou1YT1YYHAYS62feK92RUpToyKU5HxwWQnT0XyfL24bBpS6V8QFYyW63IBj7ABl TUTzUcvCTLXPx13aoVrFuND+dQZUUpWvOZU4zI7Ylwh2XCBUn2D+Dv7eUyihYBziiSFlRNIGQc8 cv6lG6A3ugTixtbJlkCgUhe9KS+DFnKqT2oZcadWf0EpCawa+pfvsaKE2j9/qkoypgwx4XzyQuR ti1WlAkeueRwA0i5uh7emnTpvj/BpSgMvD+9Yypr8Zed8uQCBgPpo2hKhgRaJrCLQnVpkgTtq3B GKUEHKqw8Nfqt/32jR1glG2tdZ2UINV81kMjitOUc70oZ1sS+jQI7gvNZs0kVIPqo18+clD0Qwr 5UGPzGaAeBU3ZQyltBsVJTWZB/CzIbuGetr1H6oXGd7hjGI8nEvkPUV30MmUln0C4ZRXKwX8z8j 3WjNZhPQ+nXpJA+Sz7rZ9RZ5kpv/bSBcPioHqSSFYht14fY+XdrZTlUOBd6ptjvOHFxlAJEMdic STGZxbYHw0rc34vE6P+aQlt348u88ayWC70/Pms X-Received: by 2002:a05:690c:660c:b0:80c:3848:bde6 with SMTP id 00721157ae682-86875b7aa69mr27126847b3.30.1788230015818; Mon, 31 Aug 2026 19:33:35 -0700 (PDT) Received: from localhost (107-220-129-194.lightspeed.chrlnc.sbcglobal.net. [107.220.129.194]) by smtp.gmail.com with ESMTPSA id 00721157ae682-85e66abb13asm65013847b3.36.2026.08.31.19.33.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Aug 2026 19:33:35 -0700 (PDT) From: Matt Turner To: binutils@sourceware.org Cc: Magnus Lindholm , Alan Modra , Matt Turner Subject: [PATCH 08/11] alpha: reject an IFUNC address in read-only data in a static link Date: Mon, 31 Aug 2026 22:33:15 -0400 Message-ID: <20260901023318.3503991-9-mattst88@gmail.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260901023318.3503991-1-mattst88@gmail.com> References: <20260901023318.3503991-1-mattst88@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-11.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on 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 The address of an IFUNC needs an R_ALPHA_IRELATIVE applied to the word that holds it. In a read-only section that means relocating a read-only page, which is DT_TEXTREL in a dynamic link but has nothing to do it in a static one: libc's startup code runs after the kernel has mapped the segment and cannot make it writable. Other targets hand out the address of a PLT stub in that case. Alpha has no PLT entry for a non-dynamic function, so report it instead. --- bfd/elf64-alpha.c | 25 +++++++++++++++++++- ld/testsuite/ld-alpha/ifunc-rodata-dynamic.d | 12 ++++++++++ ld/testsuite/ld-alpha/ifunc-rodata-static.d | 3 +++ ld/testsuite/ld-alpha/ifunc-rodata-ztext.d | 4 ++++ ld/testsuite/ld-alpha/ifunc-rodata.s | 22 +++++++++++++++++ 5 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 ld/testsuite/ld-alpha/ifunc-rodata-dynamic.d create mode 100644 ld/testsuite/ld-alpha/ifunc-rodata-static.d create mode 100644 ld/testsuite/ld-alpha/ifunc-rodata-ztext.d create mode 100644 ld/testsuite/ld-alpha/ifunc-rodata.s diff --git ./bfd/elf64-alpha.c ./bfd/elf64-alpha.c index 470a6818023..687f4134d0e 100644 --- ./bfd/elf64-alpha.c +++ ./bfd/elf64-alpha.c @@ -4901,7 +4901,30 @@ elf64_alpha_relocate_section (struct bfd_link_info *info, dynaddend = value; if (elf64_alpha_ifunc_irelplt_p (h, sym, info)) - srel_out = elf_hash_table (info)->irelplt; + { + srel_out = elf_hash_table (info)->irelplt; + + /* Startup code in a static executable applies this after + the kernel has mapped the segment, and unlike the + dynamic linker it cannot make a read-only one writable. + Other targets hand out the address of a PLT stub + instead; alpha has no PLT entry for a non-dynamic + function. */ + if ((input_section->flags & SEC_READONLY) != 0 + && !elf_hash_table (info)->dynamic_sections_created) + { + _bfd_error_handler + /* xgettext:c-format */ + (_("%pB: address of STT_GNU_IFUNC symbol `%s' in " + "read-only section `%pA' cannot be relocated in " + "a static link"), + input_bfd, + elf64_alpha_sym_name (input_bfd, symtab_hdr, h, + sym, sec), + input_section); + ret_val = false; + } + } } else if (bfd_link_pic (info) && r_symndx != STN_UNDEF diff --git ./ld/testsuite/ld-alpha/ifunc-rodata-dynamic.d ./ld/testsuite/ld-alpha/ifunc-rodata-dynamic.d new file mode 100644 index 00000000000..f796afebca7 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-rodata-dynamic.d @@ -0,0 +1,12 @@ +#source: ifunc-rodata.s +#ld: -melf64alpha -z notext tmpdir/libalphaifunc.so +#readelf: -Wrd + +#... + +0x0+16 +\(TEXTREL\) +0x0 +#... +Relocation section '\.rela\.dyn' .* contains 2 entries: +#... +[0-9a-f]+ +[0-9a-f]+ +R_ALPHA_IRELATIVE +[0-9a-f]+ +[0-9a-f]+ +[0-9a-f]+ +R_ALPHA_IRELATIVE +[0-9a-f]+ +#pass diff --git ./ld/testsuite/ld-alpha/ifunc-rodata-static.d ./ld/testsuite/ld-alpha/ifunc-rodata-static.d new file mode 100644 index 00000000000..44fd3276218 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-rodata-static.d @@ -0,0 +1,3 @@ +#source: ifunc-rodata.s +#ld: -melf64alpha +#error: \A[^\n]*: address of STT_GNU_IFUNC symbol `global_ifunc' in read-only section `\.rodata' cannot be relocated in a static link\n[^\n]*: address of STT_GNU_IFUNC symbol `local_ifunc' in read-only section `\.rodata' cannot be relocated in a static link\n[^\n]*: final link failed[^\n]*\n?\Z diff --git ./ld/testsuite/ld-alpha/ifunc-rodata-ztext.d ./ld/testsuite/ld-alpha/ifunc-rodata-ztext.d new file mode 100644 index 00000000000..c58d7e3536d --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-rodata-ztext.d @@ -0,0 +1,4 @@ +#source: ifunc-rodata.s +#ld: -melf64alpha -z text tmpdir/libalphaifunc.so +#readelf: -Wr +#error: \A[^\n]*: read-only segment has dynamic relocations\n?\Z diff --git ./ld/testsuite/ld-alpha/ifunc-rodata.s ./ld/testsuite/ld-alpha/ifunc-rodata.s new file mode 100644 index 00000000000..f900cb8004d --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-rodata.s @@ -0,0 +1,22 @@ + .text + + .globl global_ifunc + .type global_ifunc, @gnu_indirect_function +global_ifunc: + ret + + .type local_ifunc, @gnu_indirect_function +local_ifunc: + ret + + .globl _start + .ent _start +_start: + ret + .end _start + + # The IRELATIVE for each of these is applied to a read-only page: + # DT_TEXTREL in a dynamic link, an error in a static one. + .section .rodata,"a",@progbits + .quad global_ifunc + .quad local_ifunc From patchwork Tue Sep 1 02:33:16 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matt Turner X-Patchwork-Id: 142571 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id DF53D4BA79A8 for ; Tue, 1 Sep 2026 02:34:56 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org DF53D4BA79A8 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=iI3VsE8V X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from mail-yw1-x1134.google.com (mail-yw1-x1134.google.com [IPv6:2607:f8b0:4864:20::1134]) by sourceware.org (Postfix) with ESMTPS id 262D74BA7987 for ; Tue, 1 Sep 2026 02:33:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 262D74BA7987 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 262D74BA7987 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::1134 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1788230019; cv=none; b=mTBQ8JO5QvtlbjKW+0w9yJAtU0win77g4FsIPk/KoEPZMx0Z8NfhBtSBxbxzRfTKRlp7cKlqJ/9Bs74PFCkrOlB7B8rk3DY1oj9JcSUqZpFTi+qtZZLyQUan2Rco9kEDJTl/MaOzI5ySUV44glP7fK4AkKfXgYQrHeFSzX8DC18= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1788230019; c=relaxed/simple; bh=gYxy1m6PG15vfUraFZvMUL0jarXMD/FkCtViYhV7Bow=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=NKsm3n4JV6cwVmTNtJZkrozNhEZPizMzlf8xxNx5FX/JRsveOIMwlYSvkgmASh2SdQ6YZAO7FJGd0Ao2zNAYUFEor4we2hTvUNIynT/dBhzQEt6HtXsrwVD9kq56lSXU9VOQkZeuDvSdobshDoCcXbYyFz7R1QGZ4LcvWUwC9IU= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=iI3VsE8V DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 262D74BA7987 Received: by mail-yw1-x1134.google.com with SMTP id 00721157ae682-8588583a7c3so4832487b3.2 for ; Mon, 31 Aug 2026 19:33:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788230018; x=1788834818; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=aXL+jVfEyg2ma3Q+cOd5QYgO0/CO9DdDiRIGuh/2lu0=; b=iI3VsE8V9Z66qtzQPeimFqXMyYUQWKXPaGhJGnOK+wF7pycgC7GSvmWYLp7zcXdE3N v34ft8ZvVZZppNPlOERSpMeA7sypB/LWgiOhTQnNzm8cNxYqiBXQUpAZaP7HkWKSIoEj yOTscSnGz6xqOe2NNSzBTgyDm9KbsaXrcn5fz0rrgEj039S+Io+QDB7VulZnEEdYOEte FPMGS3rfQRjddyIylzqW/j/Ry7e64p7SxBxIaCarfzzIoP6e9x3TPJqE6m+aLTQgb1ju aEsd21ByvZtjaoHwmVxHPOWToJU1w6amknzPYDfN0SKkAoA7twLr6WYIbhqo77W1//3F 5gDw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788230018; x=1788834818; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=aXL+jVfEyg2ma3Q+cOd5QYgO0/CO9DdDiRIGuh/2lu0=; b=C7z64xGdP7doCYJ57Jtgb+oUf2Y4V3Pi/0bm7nWSwVwd31VRxwWINgOxWkL8tEZjlF RP4waewLtJK7nYXNnBZKs3Eg/3mh+6KhgD1mzlHIjcA8KzZiMXTZPbPfw7YZ4Xqsmk9q qJLP+er/ASO8qT92FPDdv5SBXxuIFOk51HLqGBbLIkx0DOa74XWdbGOvvGa8lWAEl3Xk lQU7VZ43FR8wzuakiJJ/V8P8YPdgTajKFz/CS7mrm60pCYFlYNzrwfTEisiEa4CEAvK6 DfiNULvQwNa1uqb8t/R8xfP8mCY4qTAzCMmf6VZ2oo/fbkbJQ4RxcfHgUWwlUUPPr+Ko SkNA== X-Gm-Message-State: AFuF++ld6zG2l1zLqeT+D//5cfD0K9wrCLahpH8xww1MCzrnt0q0JNUA WSxtZ3rC4fE1hhk5I7j/p6Q3AgYf4QRVn+QsIYlmhqGlRI/xjMQXXHytHi1sYg== X-Gm-Gg: AYBFou2EJtrTc3yU9XBaBEO1UP3nBkr+On6BZ1SJDnVXJht+7OCn2842llT/5lvkIli 0VuebI4N94imWEWFlVQUOw70fAU5NEnyhYYz09VA9Zyr7OuG6yfPMNQmhaLx+JU9ukG6UPqxXYQ yF8B2YCGGk9o8rsnkU45bDShxCaIOcCfr/fz5sZeKg5yAYqnpiolLRcivADyzz8B/SNpxbFKPdG XMX+mKDCuxXpcsTRb9albpsBQZhQtlzh2ce0Pcot1EUdCxZs1lqFvustxE3MSLry7h3Htc5oQiP qtY69PaV8hMj8yU2U0bhYAqFp1a8b3Lek6J9IOrA4zHKvug/ieFEWhO98DeMtxPYrfspEr4pxDN wpbeXQR6Gz20AatnxcCygQRetENT3wTiEM9/aiuDQOwLNSm4M//U0APOZaqPC4UaJiCImsD8UG0 N2pw+ELepNX+lsdVVm0dMWTm/Yr6Mkxg+KpouEOkB6dba7FX5GtWeGGTNMXl3RV6PJ7/KgKbQL9 Fb8OeNKwQf8YwkYuCBF7rOVBsSIaIR1QDvWapds X-Received: by 2002:a05:690c:6e83:b0:864:7ad7:a2eb with SMTP id 00721157ae682-8647ad7a915mr49920837b3.19.1788230018376; Mon, 31 Aug 2026 19:33:38 -0700 (PDT) Received: from localhost (107-220-129-194.lightspeed.chrlnc.sbcglobal.net. [107.220.129.194]) by smtp.gmail.com with ESMTPSA id 00721157ae682-85e5e18114bsm65426207b3.7.2026.08.31.19.33.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Aug 2026 19:33:37 -0700 (PDT) From: Matt Turner To: binutils@sourceware.org Cc: Magnus Lindholm , Alan Modra , Matt Turner Subject: [PATCH 09/11] alpha: diagnose a reference to an IFUNC whose place is deleted Date: Mon, 31 Aug 2026 22:33:16 -0400 Message-ID: <20260901023318.3503991-10-mattst88@gmail.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260901023318.3503991-1-mattst88@gmail.com> References: <20260901023318.3503991-1-mattst88@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-11.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on 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 Every entry of .rela.iplt is applied by libc's startup code, so it must not contain the R_ALPHA_NONE that elf64_alpha_emit_dynrel writes for a relocation whose place in the output has been removed. Sizing .rela.iplt skips the sections that do not make it into the output, but .eh_frame editing deletes the place of a relocation later still, long after the section has been sized and given an address, so there is nothing left to shrink it by. Report the reference rather than write an executable that faults at startup, naming the symbol, the relocation and the section it was in. Have final_link count the slots too, as a consistency check on the sizing: every way to reserve a slot and then not fill it is now diagnosed where it happens, so a mismatch here means the sizing itself is wrong. Report both counts, since either can be the larger one. --- bfd/elf64-alpha.c | 47 +++++++++++++++++++++++++ ld/testsuite/ld-alpha/ifunc-ehframe-a.s | 19 ++++++++++ ld/testsuite/ld-alpha/ifunc-ehframe-b.s | 10 ++++++ ld/testsuite/ld-alpha/ifunc-ehframe.d | 4 +++ 4 files changed, 80 insertions(+) create mode 100644 ld/testsuite/ld-alpha/ifunc-ehframe-a.s create mode 100644 ld/testsuite/ld-alpha/ifunc-ehframe-b.s create mode 100644 ld/testsuite/ld-alpha/ifunc-ehframe.d diff --git ./bfd/elf64-alpha.c ./bfd/elf64-alpha.c index 687f4134d0e..09e3778f3a9 100644 --- ./bfd/elf64-alpha.c +++ ./bfd/elf64-alpha.c @@ -4904,6 +4904,32 @@ elf64_alpha_relocate_section (struct bfd_link_info *info, { srel_out = elf_hash_table (info)->irelplt; + /* Every entry of .rela.iplt is applied, so it must not + contain the R_ALPHA_NONE that elf64_alpha_emit_dynrel + writes for a relocation whose place in the output has + been removed. Sizing .rela.iplt skips the sections that + do not make it into the output, but .eh_frame editing + deletes the place of a relocation later still, long + after the section has been sized and given an address; + there is nothing left to shrink it by. Report it rather + than produce an executable that faults at startup. */ + if ((_bfd_elf_section_offset (info->output_bfd, info, + input_section, rel->r_offset) + | 1) == (bfd_vma) -1) + { + _bfd_error_handler + /* xgettext:c-format */ + (_("%pB: cannot resolve STT_GNU_IFUNC symbol `%s': " + "the place of its %s relocation in `%pA' was " + "deleted"), + input_bfd, + elf64_alpha_sym_name (input_bfd, symtab_hdr, h, + sym, sec), + howto->name, input_section); + ret_val = false; + continue; + } + /* Startup code in a static executable applies this after the kernel has mapped the segment, and unlike the dynamic linker it cannot make a read-only one writable. @@ -5466,6 +5492,7 @@ elf64_alpha_final_link (bfd *abfd, struct bfd_link_info *info) asection *o; struct bfd_link_order *p; asection *mdebug_sec; + asection *irelplt; struct ecoff_debug_info debug; const struct ecoff_debug_swap *swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap; @@ -5708,6 +5735,26 @@ elf64_alpha_final_link (bfd *abfd, struct bfd_link_info *info) if (! _bfd_elf_final_link (abfd, info)) return false; + /* libc's startup code applies every entry between __rela_iplt_start and + __rela_iplt_end, so an entry left as R_ALPHA_NONE would fault. Every + way for relocate_section to reserve a slot and then not fill it is + diagnosed there, so this is a consistency check on the sizing rather + than something a user can provoke. */ + irelplt = elf_hash_table (info)->irelplt; + if (irelplt != NULL + && irelplt->reloc_count * sizeof (Elf64_External_Rela) != irelplt->size) + { + _bfd_error_handler + /* xgettext:c-format */ + (_("%pB: internal error: %lu .rela.iplt entries were reserved but " + "%lu were written"), + abfd, + (unsigned long) (irelplt->size / sizeof (Elf64_External_Rela)), + (unsigned long) irelplt->reloc_count); + bfd_set_error (bfd_error_bad_value); + return false; + } + /* Now write out the computed sections. */ /* The .got subsections... */ diff --git ./ld/testsuite/ld-alpha/ifunc-ehframe-a.s ./ld/testsuite/ld-alpha/ifunc-ehframe-a.s new file mode 100644 index 00000000000..a4332973069 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-ehframe-a.s @@ -0,0 +1,19 @@ + .text + + # A personality routine named with DW_EH_PE_absptr puts a REFQUAD + # against the IFUNC in .eh_frame. Both objects name the same one, so + # their CIEs are identical and .eh_frame editing deletes one of them, + # along with the place of the relocation that check_relocs counted. + .globl global_ifunc + .type global_ifunc, @gnu_indirect_function +global_ifunc: + ret + + .globl _start + .ent _start +_start: + .cfi_startproc + .cfi_personality 0x00, global_ifunc + ret + .cfi_endproc + .end _start diff --git ./ld/testsuite/ld-alpha/ifunc-ehframe-b.s ./ld/testsuite/ld-alpha/ifunc-ehframe-b.s new file mode 100644 index 00000000000..801a81bc909 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-ehframe-b.s @@ -0,0 +1,10 @@ + .text + + .globl other + .ent other +other: + .cfi_startproc + .cfi_personality 0x00, global_ifunc + ret + .cfi_endproc + .end other diff --git ./ld/testsuite/ld-alpha/ifunc-ehframe.d ./ld/testsuite/ld-alpha/ifunc-ehframe.d new file mode 100644 index 00000000000..3fa213ab0f3 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-ehframe.d @@ -0,0 +1,4 @@ +#source: ifunc-ehframe-a.s +#source: ifunc-ehframe-b.s +#ld: -melf64alpha tmpdir/libalphaifunc.so +#error: \A[^\n]*: cannot resolve STT_GNU_IFUNC symbol `global_ifunc': the place of its REFQUAD relocation in `\.eh_frame' was deleted\n[^\n]*: final link failed[^\n]*\n?\Z From patchwork Tue Sep 1 02:33:17 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matt Turner X-Patchwork-Id: 142578 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 4E5264BA79BA for ; Tue, 1 Sep 2026 02:38:18 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4E5264BA79BA Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=AU+Fw/il X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from mail-yw1-x112f.google.com (mail-yw1-x112f.google.com [IPv6:2607:f8b0:4864:20::112f]) by sourceware.org (Postfix) with ESMTPS id AB10C4BA9019 for ; Tue, 1 Sep 2026 02:33:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org AB10C4BA9019 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org AB10C4BA9019 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::112f ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1788230021; cv=none; b=j2QFYkH+MduuD3DW46OOkgdtj4iJSWQTTGmtuZfwMGPdKp8tqEpBNqGaBPeu2NJmjdk3sSkssB3Nrx0mJuzoIAT3Eq+kYPhuJWitgGD5YdtgsbtmHGm300+YTXINhlmgiZl4YYU56vYxOBRNTWuWPAn/Dh2ZQgVXpzzperhZtLg= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1788230021; c=relaxed/simple; bh=K2FEwqo7b5rd5PF1Lp/DPs/j6sHOPx7CxSEZsBYMHlo=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=n46LYdh5/4IOoDQ6ARykkpP9WxrtgOnNHKpjOxvtPuE/v60z3GX26FPqNYjErjKayPhJI5AagBBCc82I6B+f7uXWYtuEaE418FtaRV/qR8dO95iBkKQOoyOT4BhcdpNc4qUNYVD3ah60dsMX00Un2pcLAQqNG1I7U/lt6+WiR+c= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=AU+Fw/il DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AB10C4BA9019 Received: by mail-yw1-x112f.google.com with SMTP id 00721157ae682-855de2d0d4dso8560337b3.0 for ; Mon, 31 Aug 2026 19:33:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788230021; x=1788834821; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=lgqmmSwtF0bXMuqSjWRgImH6ZdYCtVx4oCvJ7W6zPdU=; b=AU+Fw/ilMBQwtnz9E3W6SMb8Oc2a/LBmIXBerYz7+dV25lLHXeMdCWH0TnkPK+JsRR y1G3PwfxWpaofBE+R0g03/o1cvUQWw3yTLgNo+li/tcCSyb58q+CFTne2F9EEnsW+SuH m6cZn5IG6JDagq0twysAN5AIExd67NIumpwwSKu6CJNd76G4Z356jsfkXGdlmir0jGXU Tk7i77Ci4eHIiEc+VNJlhp0YX86agiPiSAmotSKNlnBTDU210GJAqlI8DSs45O7CMGs3 t3Odj+jaRAkiLnMXkoqta5lh6+p9JbwjdpDbFa33pyoSZlpZxCM/TRvc6SIeXvpFaptb en5Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788230021; x=1788834821; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=lgqmmSwtF0bXMuqSjWRgImH6ZdYCtVx4oCvJ7W6zPdU=; b=PbI39qnZipXzyek9vcwbMVJxPe6kTGYXPJAd1ZyTS3XjqOp70luFO5QBe4uO6s2QMG T0YfuEmYyPxY9Xnv8KAirG5z8cjAXQlZhRpmx/q6G/bBhEDlfRfClU7J5Pp242Ejll2g 0oQfGhiI+g/rS4ocsg/WGV0NT7Bib57J+pUY0ifQrlN5nLuyph4vQCk+v+231Qs6MTl8 hGYbA/sMzL8yCwmtLdhJQ+asvY2Y32tasZQt1yYmb6S/xQmmNZBzjWakJobZWB4q58lf /IYmeLoFFdJDboQKc5+JBDXvuErNtYoEnrHEIn0TWKh2sAdwkCOPGU/uDHVwjEV34CtU /lNw== X-Gm-Message-State: AFuF++nuP/ogkmm9CSYWYM9XRhOyu6GdeC9u6zLqpOsc/Tdrwlr8nDUK VkmwTouKyCshfnY/iXdlmqcNGQQMb8zMjz5/BsDeoL9SjNx9GtEFbRlQSmYbkQ== X-Gm-Gg: AYBFou3LuHhEfv3fUw1sIS83J+GnHJDOyzghAjmLrSb64yUreeBCmhFF0RBGZooXKsF gb2X9IESsaqIB3EJ+7EUPdPxaRzkDFf5Tk14s24qfzfEuxr10xs0MPIhn3GK72km/p0eAJo6N0V rQwz3JRvPAu4Hr8drPIDDTnKmZBXhZl+PpErb3PtHTv6mSrBmjuANqMVSuFJAMqV/LFUuVg68U0 NgyU58DvLk5KfVprGlSyZ2ViGow/Yd42W09W+CX+1ck1HmYCRIEK56UY28fciyi2z/Sc+tCWUcI IUylzktKHglZSEN4FkKRAKKR5BJvxcECwPtWjYNKJ6pBUdSqJnKotcs1YN7Wy0mShjJI7NKuYRH GLlx21hrs/Xu5lSyjNhUNa9/+9vomjlMgRsXhxgXUE2aEWtdHyqTQdXGvvpopS3PuwIZuW2Zdwm mNEp1cqc/nFxewKg7rtbqRVO6je7gzia4IB3WW2mmhN4ZNBMb67pwc40dqQsnwcHR7AEOg76Omo cNoLkVnYPhWlzBhLf7kLBwyOZWkPkxUMBfSiz+L X-Received: by 2002:a05:690c:83:b0:861:7cb6:5790 with SMTP id 00721157ae682-869487f617amr10433527b3.4.1788230020954; Mon, 31 Aug 2026 19:33:40 -0700 (PDT) Received: from localhost (107-220-129-194.lightspeed.chrlnc.sbcglobal.net. [107.220.129.194]) by smtp.gmail.com with ESMTPSA id 00721157ae682-85e65f146f8sm65271647b3.29.2026.08.31.19.33.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Aug 2026 19:33:40 -0700 (PDT) From: Matt Turner To: binutils@sourceware.org Cc: Magnus Lindholm , Alan Modra , Matt Turner Subject: [PATCH 10/11] alpha: reject a non-zero addend on a reference to an IFUNC Date: Mon, 31 Aug 2026 22:33:17 -0400 Message-ID: <20260901023318.3503991-11-mattst88@gmail.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260901023318.3503991-1-mattst88@gmail.com> References: <20260901023318.3503991-1-mattst88@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-11.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on 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 An R_ALPHA_IRELATIVE carries the address of the resolver in its addend, so there is no room in it for an offset from the symbol. A reference that gets one, from an R_ALPHA_LITERAL or an R_ALPHA_REFQUAD, therefore cannot have an addend. Nothing diagnosed that. A reference that the dynamic linker resolves is not affected: it keeps the addend of the symbolic relocation it gets instead, and a shared library that takes the address of one of its own IFUNCs at an offset still links. A local symbol in such a library does not bind dynamically, though, so it is rejected there too. --- bfd/elf64-alpha.c | 21 +++++++++++++++++++ ld/testsuite/ld-alpha/ifunc-addend-literal.d | 3 +++ ld/testsuite/ld-alpha/ifunc-addend-literal.s | 19 +++++++++++++++++ ld/testsuite/ld-alpha/ifunc-addend-local.s | 13 ++++++++++++ ld/testsuite/ld-alpha/ifunc-addend-refquad.d | 3 +++ ld/testsuite/ld-alpha/ifunc-addend-refquad.s | 20 ++++++++++++++++++ .../ld-alpha/ifunc-addend-shared-local.d | 3 +++ ld/testsuite/ld-alpha/ifunc-addend-shared.d | 11 ++++++++++ 8 files changed, 93 insertions(+) create mode 100644 ld/testsuite/ld-alpha/ifunc-addend-literal.d create mode 100644 ld/testsuite/ld-alpha/ifunc-addend-literal.s create mode 100644 ld/testsuite/ld-alpha/ifunc-addend-local.s create mode 100644 ld/testsuite/ld-alpha/ifunc-addend-refquad.d create mode 100644 ld/testsuite/ld-alpha/ifunc-addend-refquad.s create mode 100644 ld/testsuite/ld-alpha/ifunc-addend-shared-local.d create mode 100644 ld/testsuite/ld-alpha/ifunc-addend-shared.d diff --git ./bfd/elf64-alpha.c ./bfd/elf64-alpha.c index 09e3778f3a9..d8f1a3bbf48 100644 --- ./bfd/elf64-alpha.c +++ ./bfd/elf64-alpha.c @@ -4686,6 +4686,27 @@ elf64_alpha_relocate_section (struct bfd_link_info *info, break; } + /* An R_ALPHA_IRELATIVE carries the address of the resolver in its + addend, so there is no room in it for an offset from the symbol. + A reference the dynamic linker resolves is not affected: it keeps + the addend of the symbolic relocation it gets instead. */ + if (addend != 0 + && elf64_alpha_ifunc_reloc_p (r_type) + && elf64_alpha_ifunc_p (h, sym) + && (input_section->flags & SEC_ALLOC) + && (elf64_alpha_ifunc_irelplt_p (h, sym, info) + || (bfd_link_pic (info) && !dynamic_symbol_p))) + { + _bfd_error_handler + /* xgettext:c-format */ + (_("%pB: %s relocation against STT_GNU_IFUNC symbol `%s' has a " + "non-zero addend"), + input_bfd, howto->name, + elf64_alpha_sym_name (input_bfd, symtab_hdr, h, sym, sec)); + ret_val = false; + continue; + } + switch (r_type) { case R_ALPHA_GPDISP: diff --git ./ld/testsuite/ld-alpha/ifunc-addend-literal.d ./ld/testsuite/ld-alpha/ifunc-addend-literal.d new file mode 100644 index 00000000000..2ea6b7df5a5 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-addend-literal.d @@ -0,0 +1,3 @@ +#source: ifunc-addend-literal.s +#ld: -melf64alpha +#error: \A[^\n]*: ELF_LITERAL relocation against STT_GNU_IFUNC symbol `global_ifunc' has a non-zero addend\n[^\n]*: final link failed[^\n]*\n?\Z diff --git ./ld/testsuite/ld-alpha/ifunc-addend-literal.s ./ld/testsuite/ld-alpha/ifunc-addend-literal.s new file mode 100644 index 00000000000..c7c96d2f460 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-addend-literal.s @@ -0,0 +1,19 @@ + .text + + .globl global_ifunc + .type global_ifunc, @gnu_indirect_function +global_ifunc: + ret + ret + + # An IRELATIVE's addend is the address of the resolver, so a + # reference to an IFUNC cannot carry an offset. + .globl _start + .ent _start +_start: + ldgp $29, 0($27) + ldq $27, global_ifunc+4($29) !literal!1 + jsr $26, ($27), 0 !lituse_jsr!1 + ldgp $29, 0($26) + ret + .end _start diff --git ./ld/testsuite/ld-alpha/ifunc-addend-local.s ./ld/testsuite/ld-alpha/ifunc-addend-local.s new file mode 100644 index 00000000000..1aa9138979a --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-addend-local.s @@ -0,0 +1,13 @@ + .text + + .type local_ifunc, @gnu_indirect_function +local_ifunc: + ret + ret + + # A local symbol is not preemptible, so even in a shared library the + # reference becomes an R_ALPHA_IRELATIVE and cannot carry an offset. + .data + .globl ptr +ptr: + .quad local_ifunc+4 diff --git ./ld/testsuite/ld-alpha/ifunc-addend-refquad.d ./ld/testsuite/ld-alpha/ifunc-addend-refquad.d new file mode 100644 index 00000000000..d4a912a9438 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-addend-refquad.d @@ -0,0 +1,3 @@ +#source: ifunc-addend-refquad.s +#ld: -melf64alpha +#error: \A[^\n]*: REFQUAD relocation against STT_GNU_IFUNC symbol `global_ifunc' has a non-zero addend\n[^\n]*: final link failed[^\n]*\n?\Z diff --git ./ld/testsuite/ld-alpha/ifunc-addend-refquad.s ./ld/testsuite/ld-alpha/ifunc-addend-refquad.s new file mode 100644 index 00000000000..95d6dfc1daa --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-addend-refquad.s @@ -0,0 +1,20 @@ + .text + + .globl global_ifunc + .type global_ifunc, @gnu_indirect_function +global_ifunc: + ret + ret + + .globl _start + .ent _start +_start: + ret + .end _start + + # An IRELATIVE's addend is the address of the resolver, so a + # reference to an IFUNC cannot carry an offset. + .data + .globl ptr +ptr: + .quad global_ifunc+4 diff --git ./ld/testsuite/ld-alpha/ifunc-addend-shared-local.d ./ld/testsuite/ld-alpha/ifunc-addend-shared-local.d new file mode 100644 index 00000000000..d3c25eb82aa --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-addend-shared-local.d @@ -0,0 +1,3 @@ +#source: ifunc-addend-local.s +#ld: -shared -melf64alpha +#error: \A[^\n]*: REFQUAD relocation against STT_GNU_IFUNC symbol `local_ifunc' has a non-zero addend\n[^\n]*: final link failed[^\n]*\n?\Z diff --git ./ld/testsuite/ld-alpha/ifunc-addend-shared.d ./ld/testsuite/ld-alpha/ifunc-addend-shared.d new file mode 100644 index 00000000000..31bc77ba4c9 --- /dev/null +++ ./ld/testsuite/ld-alpha/ifunc-addend-shared.d @@ -0,0 +1,11 @@ +#source: ifunc-addend-refquad.s +#ld: -shared -melf64alpha +#readelf: -Wr + +# The IFUNC is preemptible here, so the dynamic linker resolves it and the +# relocation keeps its addend. Nothing turns into an IRELATIVE, so the +# addend is not rejected. +Relocation section '\.rela\.dyn' .* contains 1 entry: +#... +[0-9a-f]+ +[0-9a-f]+ +R_ALPHA_REFQUAD .*global_ifunc \+ 4 +#pass From patchwork Tue Sep 1 02:33:18 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matt Turner X-Patchwork-Id: 142576 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 313774BA7984 for ; Tue, 1 Sep 2026 02:37:58 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 313774BA7984 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=SaB5fM6L X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from mail-yx1-xb131.google.com (mail-yx1-xb131.google.com [IPv6:2607:f8b0:4864:20::b131]) by sourceware.org (Postfix) with ESMTPS id 57AC74BA79B1 for ; Tue, 1 Sep 2026 02:33:44 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 57AC74BA79B1 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 57AC74BA79B1 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::b131 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1788230024; cv=none; b=BGqMgh6TOyTLBT+RUD7mSMwmZEWOrh66QluGtO3/8ZOY+dWMmkJYM2Efwkz03YxnLiewzPvTStrhXC/iYq1w/y8UjDjnDToTjc7f994jB6TOUGxLCUYK/w3Edny+ApIFhtgspKbvJzHTxFhOKMhZOcxfB6iuGvSGr5V1GJMc734= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1788230024; c=relaxed/simple; bh=uPr9W6Y/OnRYUa+Yx/AsTyVRuSfitog985iFO/4k6/8=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=M0/I/it8YWOIBC32XLWIUs+ng6EbFM0pGhEqcS340t1kiSLhrDHLd1tFdj1pUMHMQCuxITS2rJLsMQ8m2LS1NUDnfPPeZ3IWZUabKwTlZ6THpd9/ylQqAa68EaQXNveZbGHG3zmQD5J6TqSXJBky5JqhyGvHvcihAPNZxs9f4Qs= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=SaB5fM6L DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 57AC74BA79B1 Received: by mail-yx1-xb131.google.com with SMTP id 956f58d0204a3-66d116f0de8so3942958d50.0 for ; Mon, 31 Aug 2026 19:33:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788230024; x=1788834824; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=69sbnxCckQ0NBuBYUIsRPAbMTkemFb/59yRUpITOiFc=; b=SaB5fM6LEXnCQYiLmczmlgs8vwQVMMzoN2/A2Ha78lbNRHmtwQy0m7+VK4VB1MIxKn kLoWRBLMwc5uRL581QUELZVLsZii2rWrlgt/JFHrXhDZ8gU7EM1eSFYY81gcTL449RiZ ShlbrSAWagNOOO8TR4EO2D0+d9u+3dWVWJ8LTOZK52htj4PlLNjRT1SHo9xxmVFpib1A 7Gu05hrlHw857DIbQlaB8rA3Cw95eycG4DpfY8uuFXxdHt/frjXwKmDy1l6FQfbgU0z6 aOG7LVnxAu1D0+VtvjyUYW5JUUWGU5wxbRd6jxCpEwh8cSZ+F2rj46bcZyFB3J0AfqPt G9jw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788230024; x=1788834824; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=69sbnxCckQ0NBuBYUIsRPAbMTkemFb/59yRUpITOiFc=; b=PHf2cH4AuCTBbL5G+2csOCJSswtrR7Cz9L9/GLM/yc+B5/ovlO5fbBkCAZHHFK4KIi 5qS4nLzCyk0SKNsM0LTMeqpXO0Ht/JztwHpybHiW3a0Bor4+pbds2+2F0FR9iiB1QVTf NTu/DbVNiShE4s4n1oHTSlG7nTPYUOc3Fg7K7m2WYngDYv+nlNaM9lLLSyATTLBeoaTf GQGB2UNJg3xWxcK55eebPwOmAiXNGF6p/na/JMm2HsqF3Z4EB4yOHqv/Enj3zvnbYyWT sbwQ/+2a1ZPOwhj8YzRmqLLfFnkUOkDUh3wEuM9VXnFJgJZAPCBeSdN3fGaiBVZYPCGL VVjg== X-Gm-Message-State: AFuF++nDY7fTT0CvK2YEXeFNLO7FKpl1+SKgBbQ4sslBgaIclORB+SKH On8WOkCyyhdAIIwx3tHy01//habVrpk7ci9qbDrcl4tP9LJ/cm4pHalyq1Nu6Q== X-Gm-Gg: AYBFou2QPjF0qfixZN6+zRgAHOdRBeVbHCRvhKpji42tIGlU0b34qFV9LxFrrKgjB+w HRyUPjk8qIAp/DKIuZSzwxEUuU8pONuCBq3FAGpZiJRiFHssUg2E7oLbNiyyr/fK216eRyA0m2f 9Pnv+s9jF2N9LUQhGk5WxMttgLYOSInv4D1LIVBoxQUuI8/4t+arVezOlo78/2MvvhG+X1HWb/P mWmLRAUPJzoLvnejiLrTnZCT1TM2QWVoBF6xQQijBXIsFZUpRDkus/E7gwBbyObMl6NSrXYPFM+ UYf0gsgzwNYWrXOmca4UfAlm2Z2+xHDq9+1pNFHAitWJWGLoVxvykM5Bq6aFvJUYBfuqPfpecDq /gfaIitARWwBSXUGbOIBn8+DAyCwfGcgPqGF3FA3ovrM3G6mrkkC1tzspnnQtVC0KAGCbC7jqzd o0K0D1bHgxwCvnvm4/QGGc7oQS6XErvX5enep4ZaddgmwAO2cj+0zeGjED8nkv7Ja5SUmv/ZklO 8aB24GEfYcDJjEk0qlHTSxzK8FEre3zqm4YHb7K X-Received: by 2002:a53:df12:0:b0:66d:2cd9:91d with SMTP id 956f58d0204a3-66f8c938045mr385964d50.50.1788230023609; Mon, 31 Aug 2026 19:33:43 -0700 (PDT) Received: from localhost (107-220-129-194.lightspeed.chrlnc.sbcglobal.net. [107.220.129.194]) by smtp.gmail.com with ESMTPSA id 00721157ae682-85e5ed1cd5bsm64706757b3.17.2026.08.31.19.33.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Aug 2026 19:33:41 -0700 (PDT) From: Matt Turner To: binutils@sourceware.org Cc: Magnus Lindholm , Alan Modra , Matt Turner Subject: [PATCH 11/11] alpha: run the ld-ifunc tests Date: Mon, 31 Aug 2026 22:33:18 -0400 Message-ID: <20260901023318.3503991-12-mattst88@gmail.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260901023318.3503991-1-mattst88@gmail.com> References: <20260901023318.3503991-1-mattst88@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-11.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on 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 Removing alpha from the skip list in ld-ifunc/ifunc.exp runs the tests there. Tested with an alpha-linux-gnu cross toolchain; only the link tests of that directory are supported in a cross configuration. ifunc-26 stays an expected failure, as it has been since commit bb4e012ca04 added the marker. It is not a linker limitation: the test assigns a symbol with .set, which tc-alpha reads as the directive that sets an assembly mode. --- ld/NEWS | 7 +++++++ ld/testsuite/ld-ifunc/ifunc.exp | 1 - 2 files changed, 7 insertions(+), 1 deletion(-) diff --git ./ld/NEWS ./ld/NEWS index e52b0701add..2ff103da11b 100644 --- ./ld/NEWS +++ ./ld/NEWS @@ -1,5 +1,12 @@ -*- text -*- +* The alpha target supports indirect functions (STT_GNU_IFUNC), using the + newly allocated R_ALPHA_IRELATIVE (42) dynamic relocation. No dynamic + linker or C library startup code implements that relocation yet, so a + program that uses an indirect function needs a matching C library to run. + Taking the address of one from a read-only section is not supported in a + static link. + * The avr target supports .gnu_attribute 4 (Tag_GNU_AVR_VTABLE_AS). For details, see https://sourceware.org/PR34305 diff --git ./ld/testsuite/ld-ifunc/ifunc.exp ./ld/testsuite/ld-ifunc/ifunc.exp index 37cbf78840e..d0cbd633f35 100644 --- ./ld/testsuite/ld-ifunc/ifunc.exp +++ ./ld/testsuite/ld-ifunc/ifunc.exp @@ -24,7 +24,6 @@ if { ![is_elf_format] || ![supports_gnu_osabi] - || [istarget alpha-*-*] || [istarget arc*-*-*] || [istarget am33*-*-*] || [istarget bfin-*-*]