Skip to content

Conversation

@hvdijk
Copy link
Contributor

@hvdijk hvdijk commented Dec 10, 2025

IFUNCs require loader support, so for arbitrary environments, the safe assumption is to assume that they are not supported.

In particular, aarch64-linux-pauthtest may be used with musl, and was wrongly detected as supporting IFUNCs.

@hvdijk
Copy link
Contributor Author

hvdijk commented Dec 10, 2025

cc @pcc, this changes #133533, does this look okay to you? And if so, do you think it needs a test? (Edit: of course I will update the existing test either way.)

@github-actions
Copy link

github-actions bot commented Dec 10, 2025

🐧 Linux x64 Test Results

  • 187304 tests passed
  • 4952 tests skipped

✅ The build succeeded and all tests passed.

@github-actions
Copy link

github-actions bot commented Dec 10, 2025

🪟 Windows x64 Test Results

  • 128571 tests passed
  • 2805 tests skipped

✅ The build succeeded and all tests passed.

@llvmbot
Copy link
Member

llvmbot commented Dec 10, 2025

@llvm/pr-subscribers-backend-aarch64

Author: Harald van Dijk (hvdijk)

Changes

IFUNCs require loader support, so for arbitrary environments, the safe assumption is to assume that they are not supported.

In particular, aarch64-linux-pauthtest may be used with musl, and was wrongly detected as supporting IFUNCs.


Full diff: https://github.com/llvm/llvm-project/pull/171648.diff

1 Files Affected:

  • (modified) llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp (+2-5)
diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
index 25fc59e3fc258..daf20591b6731 100644
--- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
+++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
@@ -2402,11 +2402,8 @@ static bool targetSupportsIRelativeRelocation(const Triple &TT) {
   if (!TT.isOSBinFormatELF())
     return false;
 
-  // musl doesn't support IFUNCs.
-  if (TT.isMusl())
-    return false;
-
-  return true;
+  // IFUNCs are supported on glibc.
+  return TT.isGNUEnvironment();
 }
 
 // Emit an ifunc resolver that returns a signed pointer to the specified target,

@hvdijk
Copy link
Contributor Author

hvdijk commented Dec 10, 2025

Oh, I see a problem. From targetSupportsPAuthRelocation: "No released version of glibc supports PAuth relocations."

So basically, we need to disable PAuth relocations for glibc, but we also need to disable IFUNC for anything not glibc. What target is meant to be handled here?

Either way, even without this PR, #133533 looks like it has a problem, it results in a crash if the existing test is updated to use aarch64-linux-gnu.

@pcc
Copy link
Contributor

pcc commented Dec 10, 2025

Several other libcs support IFUNC, musl is the exception. Can we make it so that isMusl() or some other predicate returns true for pauthtest?

@hvdijk
Copy link
Contributor Author

hvdijk commented Dec 10, 2025

Several other libcs support IFUNC, musl is the exception.

I do not think musl is alone in not supporting it, I see no support for it in uclibc-ng either.

Can we make it so that isMusl() or some other predicate returns true for pauthtest?

I think that would be wrong, pauthtest does not imply any particular libc. Any triple that does not indicate what loader is used should be taken as suggesting a loader may be used that does not support IFUNC.

What are the other triples that do support IFUNCs? Searching a bit more, I find FreeBSD and bionic and have no issue adding these in this PR, are there more?

@pcc
Copy link
Contributor

pcc commented Dec 10, 2025

I do not think musl is alone in not supporting it, I see no support for it in uclibc-ng either.

Yeah, there are some others that don't support it.

What are the other triples that do support IFUNCs? Searching a bit more, I find FreeBSD and bionic and have no issue adding these in this PR, are there more?

I wanted to avoid this turning into a long list of libcs but maybe that would be better than the somewhat confusing predicate that I added in #133533. From a quick look:

  • Support: glibc, bionic, FreeBSD, DragonflyBSD, NetBSD
  • Do not support: musl, OpenBSD, uclibc-ng I guess

So how about we make the logic like this: if the libc supports IFUNC (according to the list above), use IFUNC, otherwise use PAuth relocations. That's still not 100% correct because we will end up using PAuth relocations even when we don't know that the target supports them, but that was the status quo before so maybe that's fine.

I think that would be wrong, pauthtest does not imply any particular libc. Any triple that does not indicate what loader is used should be taken as suggesting a loader may be used that does not support IFUNC.

Okay, I was under the impression that pauthtest referred to the musl-based system that was created for testing.

@hvdijk
Copy link
Contributor Author

hvdijk commented Dec 10, 2025

So how about we make the logic like this: if the libc supports IFUNC (according to the list above), use IFUNC, otherwise use PAuth relocations. That's still not 100% correct because we will end up using PAuth relocations even when we don't know that the target supports them, but that was the status quo before so maybe that's fine.

Thanks, I'll update this PR accordingly.

I've posted the details about the crash that I noticed earlier on #133533, but I think we can handle that separately from this PR.

Okay, I was under the impression that pauthtest referred to the musl-based system that was created for testing.

That is how we are using it, but we are doing that through config file overrides. What has been merged into LLVM does not make pauthtest imply musl, and the defaults do not work for musl. (Mind you, if we want to change it so that it does imply musl, personally I have no issue with that.)

@hvdijk hvdijk force-pushed the aarch64-ifunc-opt-in branch from 0bb2d20 to 0184403 Compare December 10, 2025 22:45
@hvdijk
Copy link
Contributor Author

hvdijk commented Dec 10, 2025

Updated accordingly, does that look okay? I'm a little bit concerned that a global fix like isOSGlibc() shouldn't be included in a commit that's meant to be limited to AArch64. Edit: It turned out that that did have an unwanted effect on other targets. I've split this out into a larger NFC PR, #171734. I will rebase this one once that other one is ready (either in its current form or some other way).

@hvdijk hvdijk force-pushed the aarch64-ifunc-opt-in branch from 0184403 to 9458793 Compare December 11, 2025 04:05
@hvdijk
Copy link
Contributor Author

hvdijk commented Dec 11, 2025

The current test update no longer works now that targetSupportsPAuthRelocation is no longer there: it means aarch64-android no longer works as an alternative target to preserve the existing test exactly. It will need a bit more work on the test, but review of the rest of the PR is welcome.

IFUNCs require loader support, so for arbitrary environments, the safe
assumption is to assume that they are not supported.

In particular, aarch64-linux-pauthtest may be used with musl, and was
wrongly detected as supporting IFUNCs.
@hvdijk hvdijk force-pushed the aarch64-ifunc-opt-in branch from 9458793 to d9f5db5 Compare December 11, 2025 16:36
@hvdijk
Copy link
Contributor Author

hvdijk commented Dec 11, 2025

I took out the removal of targetSupportsPAuthRelocation from this PR. It was a good suggestion to look at but in retrospect I don't think it's right, unless I am misunderstanding. For targets that support some PAuth relocations directly, and also support IFUNCs, we should still emit those PAuth relocations directly, that is what that targetSupportsPAuthRelocation check achieved before, I don't see how we can do that another way.

Copy link
Contributor

@kovdan01 kovdan01 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks! This resolves the following linker errors which started to appear after #133533 when building libcxx with signed GOT enabled:

ld.lld: error: both AUTH and non-AUTH GOT entries for '_ZTVNSt3__113basic_istreamIcNS_11char_traitsIcEEEE' requested, but only one type of GOT entry per symbol is supported
ld.lld: error: both AUTH and non-AUTH GOT entries for '_ZTVNSt3__113basic_ostreamIcNS_11char_traitsIcEEEE' requested, but only one type of GOT entry per symbol is supported
ld.lld: error: both AUTH and non-AUTH GOT entries for '_ZTVNSt3__114basic_iostreamIcNS_11char_traitsIcEEEE' requested, but only one type of GOT entry per symbol is supported
ld.lld: error: both AUTH and non-AUTH GOT entries for '_ZTVNSt3__113basic_istreamIwNS_11char_traitsIwEEEE' requested, but only one type of GOT entry per symbol is supported
ld.lld: error: both AUTH and non-AUTH GOT entries for '_ZTVNSt3__113basic_ostreamIwNS_11char_traitsIwEEEE' requested, but only one type of GOT entry per symbol is supported
ld.lld: error: both AUTH and non-AUTH GOT entries for '_ZTVNSt3__114basic_ifstreamIcNS_11char_traitsIcEEEE' requested, but only one type of GOT entry per symbol is supported
ld.lld: error: both AUTH and non-AUTH GOT entries for '_ZTVNSt3__114basic_ofstreamIcNS_11char_traitsIcEEEE' requested, but only one type of GOT entry per symbol is supported

@pcc I would appreciate if you could take a look at this as soon as you can since your changes from #133533 unfortunately break pauthtest toolchain build with signed GOT enabled, and this PR resolves the issue.

@kovdan01
Copy link
Contributor

@hvdijk Could you please update the PR description adding info about the error introduced in #133533 which is fixed by this PR? See my comment above

@hvdijk
Copy link
Contributor Author

hvdijk commented Dec 12, 2025

Could you please update the PR description adding info about the error introduced in #133533 which is fixed by this PR?

I do mention already that this fixes aarch64-linux-pauthtest, but that particular error can still occur for other targets, because that is not specific to aarch64-linux-pauthtest, but to -fptrauth-elf-got. I am working on a separate PR fixing that.

return (getOS() == Triple::Linux || getOS() == Triple::KFreeBSD ||
getOS() == Triple::Hurd) &&
!isAndroid() && !isMusl();
!isAndroid() && !isMusl() && getEnvironment() != Triple::PAuthTest;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add comment that pauthtest as of now implies not particular libc implementation

static bool targetSupportsPAuthRelocation(const Triple &TT,
const MCExpr *Target,
const MCExpr *DSExpr) {
// No released version of glibc supports PAuth relocations.
Copy link
Collaborator

@asl asl Dec 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change above also implicitly changed the behavior here (as isOSGlibc() started to return false for pauthtest). In order to correctly represent the intended semantics we need to gate the libc check with environment check first as this also would protect us from potential future changes if / when pautest might imply a particular libc implementation.

Ideally the check whether pauth relocations are supported or not, should also be opt-in rather than opt-out, but we'd need to add some additional hooks for this, so probably not worth at the present time.

const MCExpr *Target,
const MCExpr *DSExpr) {
// No released version of glibc supports PAuth relocations.
if (TT.isOSGlibc() || TT.isMusl())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (TT.getEnvironment() != Triple::PAuthTest &&
(TT.isOSGlibc() || TT.isMusl()))

; RUN: llc < ok.ll -mtriple arm64e-apple-darwin \
; RUN: | FileCheck %s --check-prefix=CHECK-MACHO
; RUN: llc < ok.ll -mtriple aarch64-elf -mattr=+pauth \
; RUN: llc < ok.ll -mtriple aarch64-android -mattr=+pauth \
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tests should remain test elf triple.

@hvdijk hvdijk closed this Dec 12, 2025
@hvdijk
Copy link
Contributor Author

hvdijk commented Dec 12, 2025

This is not productive.

@hvdijk hvdijk deleted the aarch64-ifunc-opt-in branch December 12, 2025 17:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants