From patchwork Wed Aug 12 01:19:55 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matt Turner X-Patchwork-Id: 141159 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 216634B99F5F for ; Wed, 12 Aug 2026 01:26:50 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 216634B99F5F 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=M33vp4Ub X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@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 A65B64BAE7E4 for ; Wed, 12 Aug 2026 01:20:42 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A65B64BAE7E4 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 A65B64BAE7E4 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=1786497642; cv=none; b=jhWXwHIVWLAAno6q2ejGt2+IXDkHZYgjjqcnu7tSex/lA55YS8WXFRtaQhJ6fygWm87pyXtIDPX2ipy9ig1w44Ni3C2ymAc9gv9dMloRgwRsjnTzWcoKBmwEoUEmeCMFhU48PUkJViz1UseRWUEHAfnzNHqfJhEYKAQr518Ie38= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1786497642; c=relaxed/simple; bh=miwtazb2/LyhGOFnpq6DKBoLcO/s4EEbLphblSvXQoU=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=PIOvNQ8si8Gmjl8gn4ir2rKt3kPInQ/LNaKVzaanqDu2KHlruBpu2DkZgiV9rlnoHAtNc1w2K3gAuvQTlv+PxAZEtTFVbKYw8+0YNxTRMGV1uILiG7yxRhQTI6BKJYZ/ZKUXJpPaGXb9O8blwfTczQ10s2ZMpiYB+rxSr+RA60c= 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=M33vp4Ub DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A65B64BAE7E4 Received: by mail-yx1-xb12a.google.com with SMTP id 956f58d0204a3-66899fe9077so825196d50.1 for ; Tue, 11 Aug 2026 18:20:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786497642; x=1787102442; 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=7mqABDO/g3Kw31UWtKCcwM7SRBA25GTNc4coKuHKKpc=; b=M33vp4Ub85qZC9dfPp9CtVnMZuJXww8csk9ugqgoHbvPvxKg4KtH7m1jFFehCdfexF wdbnjrjwMWP59gdIZyAhvPHzwVnLuNToCu4dfx1RD5FmRAYk4MWMpGDIYB2MD7PjAlpL 8bV8cA8wc7Xg8SNBS9jidC9I8macZPdEBOYn+yyotEx7291L2voR3v38W5wySA5I7MLW 7N09qjt3gXeB34FQyonxLY4v8v0QVXhLhcX3nlxmlq+GwS8yQTBxj/aRYg8c9zaOFSVS xgG8XxPcTB1IxqpxmEZB3cTLR7WyftmSRWeZHGutjFzLAwWbZrRdGCCe4DXJcLBH2cGp 6hNw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786497642; x=1787102442; 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=7mqABDO/g3Kw31UWtKCcwM7SRBA25GTNc4coKuHKKpc=; b=QJ7HyBaI1NDD5M2pgUdq7oW+WUSop/QhfB9qnRqQLmJDBHTp0yn9Eu6TjPsWGL4C0i 7XhWGrd4KiHXCzoHTsA8CfStYYIVoinTLWUjaPSSHwIMLzAA0/3qFZUj9eWi6b3SCUIR nZwSigNMsfPeXBZWn+XxiuzT3S5Uj8HosS5nVQrnIWTlUmomhDj70+nqybl3ZdDl636/ w/6bPD5u7IuSQBe+ADYIUirDBR36BOoLSw1dpnyb72D7MfUEzkXf05cQUJV5epCWwkZg 7XqUZdL3nhCh9vML9WnufRoc9kGP2dFs38bWxXAcrf8nabEsvUFHmrHhGWPC8RFVDYnO genQ== X-Gm-Message-State: AOJu0YzfgluzlhxsBmOHvGJf7txjtN+LMh6vuzoFotrwr0mwmCsuwUDq 6WEa/rt2FbQxEx8DVIzJSLKlvPYZVyNFEggFfkXF92kyFwWKJN+COZ+URP1kK8LYesE= X-Gm-Gg: AR+sD10ljl5zJ+oN69Auaesu0EGgAY+YxtNuvT7P9MvicAuqC329iAKPhFBkqiof7OC xZru2ugWaIERVOL3S6QGFP24RiLqiDQCvEBS4QZG9uoOR+EO/HZD2woz2J9h1+iSUKVFTSoWK+Q V9zIBSqz3evlfz5yjxxVSM3iqgFaypO2w93HqEHP9DpDT91bJnKQGtbJ7AtYKRJPSJ7kXWs4A/9 qcpNLgWbnuWBY1e4Qu0ARg+DiBVnSen3JNqBQ648dGawhZcQ6a9ONFUsE1llUvDagpUtpIPCmMY /kX6Pk1ZrGbOiCDxamRVOzNNZmTiMuNmGC830bgIMP9QeqhtE1mNCfa4NCl28aLpyDaeyIN8qe8 ZEljrf6oAiOQRJbUxJZT8f8AHQmv9E7Kl7GMoKXQUmy3Xu39FbZXRHSrW4fahG/ZQKyQ80zWli9 HNOPXT7KejFRRTQ0tVdtM0RvAOxWJhKpIWl7yCEIb9vKWXFiWJ2dxdzId+d7s= X-Received: by 2002:a05:690e:190d:b0:668:99f0:92f0 with SMTP id 956f58d0204a3-66b3432e787mr769494d50.48.1786497641821; Tue, 11 Aug 2026 18:20:41 -0700 (PDT) Received: from localhost ([2600:1702:7a90:6f9f:482:39fe:7891:c084]) by smtp.gmail.com with ESMTPSA id 00721157ae682-830a953c118sm6350437b3.32.2026.08.11.18.20.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Aug 2026 18:20:41 -0700 (PDT) From: Matt Turner To: libc-alpha@sourceware.org Cc: Magnus Lindholm , Michael Cree Subject: [PATCH 18/20] alpha: add IFUNC support to the dynamic linker Date: Tue, 11 Aug 2026 21:19:55 -0400 Message-ID: <46ed5941dbb09cf7b8dc3b0b67c68b904a94052f.1786497497.git.mattst88@gmail.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: References: MIME-Version: 1.0 X-Spam-Status: No, score=-10.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, KAM_SHORT, KAM_STOCKGEN, 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: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org Define R_ALPHA_IRELATIVE (42) and teach the dynamic linker to resolve STT_GNU_IFUNC symbols with it. elf_machine_rela runs the resolver for R_ALPHA_IRELATIVE and stores what it returns, and ELF_MACHINE_IRELATIVE turns on the IRELATIVE pass in elf/do-rel.h. elf_machine_lazy_rel resolves an IFUNC PLT entry eagerly rather than deferring it to the trampoline, which has no way to tell an IFUNC apart from an ordinary lazy binding. A symbolic reference to an IFUNC needs the same treatment: for R_ALPHA_GLOB_DAT, R_ALPHA_JMP_SLOT and R_ALPHA_REFQUAD the address the lookup returns is the resolver, not the implementation it picks, so the resolver has to run there too, as the other targets do. Without it every call through such a symbol enters the resolver and takes the address it returns as the result of the call. With multi-arch enabled that is most of the string functions -- strlen returning an address, memcmp a nonzero constant for equal buffers, math/test-fenv crashing -- and quietly, since the values look like plausible integers. dl-irel.h provides elf_ifunc_invoke and elf_irela for a static binary, where the C library applies the IRELATIVE relocations itself at startup. --- elf/elf.h | 1 + sysdeps/alpha/dl-irel.h | 51 ++++++++++++++++++++++++++++++++++++++ sysdeps/alpha/dl-machine.h | 29 ++++++++++++++++++++++ 3 files changed, 81 insertions(+) create mode 100644 sysdeps/alpha/dl-irel.h diff --git ./elf/elf.h ./elf/elf.h index b482fcfb64..f93215d8e6 100644 --- ./elf/elf.h +++ ./elf/elf.h @@ -2544,6 +2544,7 @@ enum #define R_ALPHA_TPRELHI 39 #define R_ALPHA_TPRELLO 40 #define R_ALPHA_TPREL16 41 +#define R_ALPHA_IRELATIVE 42 /* Keep this the last entry. */ #define R_ALPHA_NUM 46 diff --git ./sysdeps/alpha/dl-irel.h ./sysdeps/alpha/dl-irel.h new file mode 100644 index 0000000000..bbceaf846c --- /dev/null +++ ./sysdeps/alpha/dl-irel.h @@ -0,0 +1,51 @@ +/* Machine-dependent ELF indirect relocation inline functions. + Alpha version. + Copyright (C) 2026 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _DL_IREL_H +#define _DL_IREL_H + +#include +#include + +#define ELF_MACHINE_IRELA 1 + +static inline ElfW(Addr) +__attribute ((always_inline)) +elf_ifunc_invoke (ElfW(Addr) addr) +{ + return ((ElfW(Addr) (*) (void)) (addr)) (); +} + +static inline void +__attribute ((always_inline)) +elf_irela (const ElfW(Rela) *reloc) +{ + ElfW(Addr) *const reloc_addr = (void *) reloc->r_offset; + const unsigned long int r_type = ELFW(R_TYPE) (reloc->r_info); + + if (__glibc_likely (r_type == R_ALPHA_IRELATIVE)) + { + ElfW(Addr) value = elf_ifunc_invoke (reloc->r_addend); + *reloc_addr = value; + } + else + __libc_fatal ("Unexpected reloc type in static binary.\n"); +} + +#endif /* dl-irel.h */ diff --git ./sysdeps/alpha/dl-machine.h ./sysdeps/alpha/dl-machine.h index 7c500ea850..c357484cf1 100644 --- ./sysdeps/alpha/dl-machine.h +++ ./sysdeps/alpha/dl-machine.h @@ -203,6 +203,9 @@ _dl_start_user: \n\ /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */ #define ELF_MACHINE_JMP_SLOT R_ALPHA_JMP_SLOT +/* The IRELATIVE relocation for this architecture. */ +#define ELF_MACHINE_IRELATIVE R_ALPHA_IRELATIVE + /* We define an initialization functions. This is called very early in * _dl_sysdep_start. */ #define DL_PLATFORM_INIT dl_platform_init () @@ -367,6 +370,16 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], sym_value += SYMBOL_ADDRESS (sym_map, sym, true); } +#ifndef RTLD_BOOTSTRAP + /* For an IFUNC symbol the address above is the resolver's; the + address to use is what calling it returns. */ + if (sym != NULL + && __glibc_unlikely (ELF64_ST_TYPE (sym->st_info) == STT_GNU_IFUNC) + && __glibc_likely (sym->st_shndx != SHN_UNDEF) + && __glibc_likely (!skip_ifunc)) + sym_value = ((Elf64_Addr (*) (void)) sym_value) (); +#endif + if (r_type == R_ALPHA_GLOB_DAT) *reloc_addr = sym_value; else if (r_type == R_ALPHA_JMP_SLOT) @@ -410,6 +423,15 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], } # endif } +#ifndef RTLD_BOOTSTRAP + else if (r_type == R_ALPHA_IRELATIVE) + { + Elf64_Addr value = map->l_addr + reloc->r_addend; + if (__glibc_likely (!skip_ifunc)) + value = ((Elf64_Addr (*) (void)) value) (); + *reloc_addr = value; + } +#endif else _dl_reloc_bad_type (map, r_type, 0); } @@ -451,6 +473,13 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], to the .plt. */ *reloc_addr += l_addr; } + else if (r_type == R_ALPHA_IRELATIVE) + { + Elf64_Addr value = l_addr + reloc->r_addend; + if (__glibc_likely (!skip_ifunc)) + value = ((Elf64_Addr (*) (void)) value) (); + *reloc_addr = value; + } else if (r_type == R_ALPHA_NONE) return; else