-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[AArch64][PAC] Lower ptrauth constants in code for MachO. #97665
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[AArch64][PAC] Lower ptrauth constants in code for MachO. #97665
Conversation
Some of the machinery for auth stubs is already implemented; this generalizes that a bit to support MachO. This also moves some of the shared logic into MMIImpls. In particular, this originally had an AuthStubInfo struct, but we no longer need it beyond a single MCExpr. So this provides variants of the symbol stub helper type declarations and functions for "expr stubs", where a stub points at an arbitrary MCExpr, rather than a simple MCSymbol. On MachO, the auth stubs are emitted in __DATA,__auth_ptr.
✅ With the latest revision this PR passed the C/C++ code formatter. |
10c4dbf
to
8a298e1
Compare
@llvm/pr-subscribers-llvm-globalisel @llvm/pr-subscribers-mc Author: Ahmed Bougacha (ahmedbougacha) ChangesThis also adds support for auth stubs on MachO using __DATA,__auth_ptr. Some of the machinery for auth stubs is already implemented; this On MachO, the auth stubs are emitted in __DATA,__auth_ptr. Beyond that, this is mostly straightforward. Patch is 45.28 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/97665.diff 11 Files Affected:
diff --git a/llvm/include/llvm/CodeGen/MachineModuleInfo.h b/llvm/include/llvm/CodeGen/MachineModuleInfo.h
index 92ea3c902ce95e..97b439c726b0ab 100644
--- a/llvm/include/llvm/CodeGen/MachineModuleInfo.h
+++ b/llvm/include/llvm/CodeGen/MachineModuleInfo.h
@@ -58,12 +58,20 @@ class MachineModuleInfoImpl {
using StubValueTy = PointerIntPair<MCSymbol *, 1, bool>;
using SymbolListTy = std::vector<std::pair<MCSymbol *, StubValueTy>>;
+ /// A variant of SymbolListTy where the stub is a generalized MCExpr.
+ using ExprStubListTy = std::vector<std::pair<MCSymbol *, const MCExpr *>>;
+
virtual ~MachineModuleInfoImpl();
protected:
/// Return the entries from a DenseMap in a deterministic sorted orer.
/// Clears the map.
static SymbolListTy getSortedStubs(DenseMap<MCSymbol*, StubValueTy>&);
+
+ /// Return the entries from a DenseMap in a deterministic sorted orer.
+ /// Clears the map.
+ static ExprStubListTy
+ getSortedExprStubs(DenseMap<MCSymbol *, const MCExpr *> &);
};
//===----------------------------------------------------------------------===//
diff --git a/llvm/include/llvm/CodeGen/MachineModuleInfoImpls.h b/llvm/include/llvm/CodeGen/MachineModuleInfoImpls.h
index 64d841d86c7c4e..80f132483ad973 100644
--- a/llvm/include/llvm/CodeGen/MachineModuleInfoImpls.h
+++ b/llvm/include/llvm/CodeGen/MachineModuleInfoImpls.h
@@ -36,6 +36,11 @@ class MachineModuleInfoMachO : public MachineModuleInfoImpl {
/// bit is true if this GV is external.
DenseMap<MCSymbol *, StubValueTy> ThreadLocalGVStubs;
+ /// Darwin '$auth_ptr' stubs. The key is the stub symbol, like
+ /// "Lfoo$addend$auth_ptr$ib$12". The value is the MCExpr representing that
+ /// pointer, something like "_foo+addend@AUTH(ib, 12)".
+ DenseMap<MCSymbol *, const MCExpr *> AuthPtrStubs;
+
virtual void anchor(); // Out of line virtual method.
public:
@@ -51,29 +56,32 @@ class MachineModuleInfoMachO : public MachineModuleInfoImpl {
return ThreadLocalGVStubs[Sym];
}
+ const MCExpr *&getAuthPtrStubEntry(MCSymbol *Sym) {
+ assert(Sym && "Key cannot be null");
+ return AuthPtrStubs[Sym];
+ }
+
/// Accessor methods to return the set of stubs in sorted order.
SymbolListTy GetGVStubList() { return getSortedStubs(GVStubs); }
SymbolListTy GetThreadLocalGVStubList() {
return getSortedStubs(ThreadLocalGVStubs);
}
+
+ ExprStubListTy getAuthGVStubList() {
+ return getSortedExprStubs(AuthPtrStubs);
+ }
};
/// MachineModuleInfoELF - This is a MachineModuleInfoImpl implementation
/// for ELF targets.
class MachineModuleInfoELF : public MachineModuleInfoImpl {
-public:
- struct AuthStubInfo {
- const MCExpr *AuthPtrRef;
- };
-
-private:
/// GVStubs - These stubs are used to materialize global addresses in PIC
/// mode.
DenseMap<MCSymbol *, StubValueTy> GVStubs;
/// AuthPtrStubs - These stubs are used to materialize signed addresses for
/// extern_weak symbols.
- DenseMap<MCSymbol *, AuthStubInfo> AuthPtrStubs;
+ DenseMap<MCSymbol *, const MCExpr *> AuthPtrStubs;
virtual void anchor(); // Out of line virtual method.
@@ -85,7 +93,7 @@ class MachineModuleInfoELF : public MachineModuleInfoImpl {
return GVStubs[Sym];
}
- AuthStubInfo &getAuthPtrStubEntry(MCSymbol *Sym) {
+ const MCExpr *&getAuthPtrStubEntry(MCSymbol *Sym) {
assert(Sym && "Key cannot be null");
return AuthPtrStubs[Sym];
}
@@ -94,10 +102,9 @@ class MachineModuleInfoELF : public MachineModuleInfoImpl {
SymbolListTy GetGVStubList() { return getSortedStubs(GVStubs); }
- using AuthStubPairTy = std::pair<MCSymbol *, AuthStubInfo>;
- typedef std::vector<AuthStubPairTy> AuthStubListTy;
-
- AuthStubListTy getAuthGVStubList();
+ ExprStubListTy getAuthGVStubList() {
+ return getSortedExprStubs(AuthPtrStubs);
+ }
};
/// MachineModuleInfoCOFF - This is a MachineModuleInfoImpl implementation
diff --git a/llvm/lib/CodeGen/MachineModuleInfoImpls.cpp b/llvm/lib/CodeGen/MachineModuleInfoImpls.cpp
index f114f1ecc0baec..956317510dc736 100644
--- a/llvm/lib/CodeGen/MachineModuleInfoImpls.cpp
+++ b/llvm/lib/CodeGen/MachineModuleInfoImpls.cpp
@@ -43,24 +43,19 @@ MachineModuleInfoImpl::SymbolListTy MachineModuleInfoImpl::getSortedStubs(
return List;
}
-template <typename MachineModuleInfoTarget>
-static typename MachineModuleInfoTarget::AuthStubListTy getAuthGVStubListHelper(
- DenseMap<MCSymbol *, typename MachineModuleInfoTarget::AuthStubInfo>
- &AuthPtrStubs) {
- typename MachineModuleInfoTarget::AuthStubListTy List(AuthPtrStubs.begin(),
- AuthPtrStubs.end());
+using ExprStubPairTy = std::pair<MCSymbol *, const MCExpr *>;
+static int SortAuthStubPair(const ExprStubPairTy *LHS,
+ const ExprStubPairTy *RHS) {
+ return LHS->first->getName().compare(RHS->first->getName());
+}
- if (!List.empty())
- llvm::sort(List.begin(), List.end(),
- [](const typename MachineModuleInfoTarget::AuthStubPairTy &LHS,
- const typename MachineModuleInfoTarget::AuthStubPairTy &RHS) {
- return LHS.first->getName() < RHS.first->getName();
- });
+MachineModuleInfoImpl::ExprStubListTy MachineModuleInfoImpl::getSortedExprStubs(
+ DenseMap<MCSymbol *, const MCExpr *> &ExprStubs) {
+ MachineModuleInfoImpl::ExprStubListTy List(ExprStubs.begin(),
+ ExprStubs.end());
- AuthPtrStubs.clear();
- return List;
-}
+ array_pod_sort(List.begin(), List.end(), SortAuthStubPair);
-MachineModuleInfoELF::AuthStubListTy MachineModuleInfoELF::getAuthGVStubList() {
- return getAuthGVStubListHelper<MachineModuleInfoELF>(AuthPtrStubs);
+ ExprStubs.clear();
+ return List;
}
diff --git a/llvm/lib/MC/MCMachOStreamer.cpp b/llvm/lib/MC/MCMachOStreamer.cpp
index 6eb9f44de44fdf..06b4dba8b0c65f 100644
--- a/llvm/lib/MC/MCMachOStreamer.cpp
+++ b/llvm/lib/MC/MCMachOStreamer.cpp
@@ -161,6 +161,10 @@ static bool canGoAfterDWARF(const MCSectionMachO &MSec) {
return true;
if (SegName == "__LLVM" && (SecName == "__cg_profile"))
return true;
+
+ if (SegName == "__DATA" && SecName == "__auth_ptr")
+ return true;
+
return false;
}
diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
index 64d41d41476440..af0b8aa6bc9503 100644
--- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
+++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
@@ -848,13 +848,12 @@ void AArch64AsmPrinter::emitHwasanMemaccessSymbols(Module &M) {
}
}
-template <typename MachineModuleInfoTarget>
-static void emitAuthenticatedPointer(
- MCStreamer &OutStreamer, MCSymbol *StubLabel,
- const typename MachineModuleInfoTarget::AuthStubInfo &StubInfo) {
+static void emitAuthenticatedPointer(MCStreamer &OutStreamer,
+ MCSymbol *StubLabel,
+ const MCExpr *StubAuthPtrRef) {
// sym$auth_ptr$key$disc:
OutStreamer.emitLabel(StubLabel);
- OutStreamer.emitValue(StubInfo.AuthPtrRef, /*size=*/8);
+ OutStreamer.emitValue(StubAuthPtrRef, /*size=*/8);
}
void AArch64AsmPrinter::emitEndOfAsmFile(Module &M) {
@@ -862,6 +861,26 @@ void AArch64AsmPrinter::emitEndOfAsmFile(Module &M) {
const Triple &TT = TM.getTargetTriple();
if (TT.isOSBinFormatMachO()) {
+
+ // Output authenticated pointers as indirect symbols, if we have any.
+ MachineModuleInfoMachO &MMIMacho =
+ MMI->getObjFileInfo<MachineModuleInfoMachO>();
+
+ auto Stubs = MMIMacho.getAuthGVStubList();
+
+ if (!Stubs.empty()) {
+ // Switch to the "__auth_ptr" section.
+ OutStreamer->switchSection(
+ OutContext.getMachOSection("__DATA", "__auth_ptr", MachO::S_REGULAR,
+ SectionKind::getMetadata()));
+ emitAlignment(Align(8));
+
+ for (auto &Stub : Stubs)
+ emitAuthenticatedPointer(*OutStreamer, Stub.first, Stub.second);
+
+ OutStreamer->addBlankLine();
+ }
+
// Funny Darwin hack: This flag tells the linker that no global symbols
// contain code that falls through to other global symbols (e.g. the obvious
// implementation of multiple entry points). If this doesn't occur, the
@@ -882,8 +901,7 @@ void AArch64AsmPrinter::emitEndOfAsmFile(Module &M) {
emitAlignment(Align(8));
for (const auto &Stub : Stubs)
- emitAuthenticatedPointer<MachineModuleInfoELF>(*OutStreamer, Stub.first,
- Stub.second);
+ emitAuthenticatedPointer(*OutStreamer, Stub.first, Stub.second);
OutStreamer->addBlankLine();
}
@@ -1676,16 +1694,29 @@ void AArch64AsmPrinter::LowerLOADauthptrstatic(const MachineInstr &MI) {
//
// Where the $auth_ptr$ symbol is the stub slot containing the signed pointer
// to symbol.
- assert(TM.getTargetTriple().isOSBinFormatELF() &&
- "LOADauthptrstatic is implemented only for ELF");
- const auto &TLOF =
- static_cast<const AArch64_ELFTargetObjectFile &>(getObjFileLowering());
-
- assert(GAOp.getOffset() == 0 &&
- "non-zero offset for $auth_ptr$ stub slots is not supported");
- const MCSymbol *GASym = TM.getSymbol(GAOp.getGlobal());
- MCSymbol *AuthPtrStubSym =
- TLOF.getAuthPtrSlotSymbol(TM, &MF->getMMI(), GASym, Key, Disc);
+ MCSymbol *AuthPtrStubSym;
+ if (TM.getTargetTriple().isOSBinFormatELF()) {
+ const auto &TLOF =
+ static_cast<const AArch64_ELFTargetObjectFile &>(getObjFileLowering());
+
+ assert(GAOp.getOffset() == 0 &&
+ "non-zero offset for $auth_ptr$ stub slots is not supported");
+ const MCSymbol *GASym = TM.getSymbol(GAOp.getGlobal());
+ AuthPtrStubSym =
+ TLOF.getAuthPtrSlotSymbol(TM, &MF->getMMI(), GASym, Key, Disc);
+ } else {
+ assert(TM.getTargetTriple().isOSBinFormatMachO() &&
+ "LOADauthptrstatic is implemented only for MachO/ELF");
+
+ const auto &TLOF = static_cast<const AArch64_MachoTargetObjectFile &>(
+ getObjFileLowering());
+
+ assert(GAOp.getOffset() == 0 &&
+ "non-zero offset for $auth_ptr$ stub slots is not supported");
+ const MCSymbol *GASym = TM.getSymbol(GAOp.getGlobal());
+ AuthPtrStubSym =
+ TLOF.getAuthPtrSlotSymbol(TM, &MF->getMMI(), GASym, Key, Disc);
+ }
MachineOperand StubMOHi =
MachineOperand::CreateMCSymbol(AuthPtrStubSym, AArch64II::MO_PAGE);
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index e0c3cc5eddb827..dbd9a5430752ac 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -9545,8 +9545,7 @@ SDValue AArch64TargetLowering::LowerGlobalTLSAddress(SDValue Op,
// Load a signed pointer for symbol 'sym' from a stub slot named
// 'sym$auth_ptr$key$disc' filled by dynamic linker during relocation
// resolving. This usually lowers to adrp+ldr, but also emits an entry into
-// .data with an
-// @AUTH relocation. See LowerLOADauthptrstatic.
+// .data with an @AUTH relocation. See LowerLOADauthptrstatic.
//
// All 3 are pseudos that are expand late to longer sequences: this lets us
// provide integrity guarantees on the to-be-signed intermediate values.
@@ -9599,8 +9598,8 @@ AArch64TargetLowering::LowerPtrAuthGlobalAddress(SDValue Op,
"constant discriminator in ptrauth global out of range [0, 0xffff]");
// Choosing between 3 lowering alternatives is target-specific.
- if (!Subtarget->isTargetELF())
- report_fatal_error("ptrauth global lowering is only implemented for ELF");
+ if (!Subtarget->isTargetELF() && !Subtarget->isTargetMachO())
+ report_fatal_error("ptrauth global lowering only supported on MachO/ELF");
int64_t PtrOffsetC = 0;
if (Ptr.getOpcode() == ISD::ADD) {
diff --git a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp
index 3c0facd5867329..d916f644de9b50 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp
@@ -105,15 +105,14 @@ static MCSymbol *getAuthPtrSlotSymbolHelper(
Twine("$auth_ptr$") + AArch64PACKeyIDToString(Key) + Twine('$') +
Twine(Discriminator));
- typename MachineModuleInfoTarget::AuthStubInfo &StubInfo =
- TargetMMI.getAuthPtrStubEntry(StubSym);
+ const MCExpr *&StubAuthPtrRef = TargetMMI.getAuthPtrStubEntry(StubSym);
- if (StubInfo.AuthPtrRef)
+ if (StubAuthPtrRef)
return StubSym;
const MCExpr *Sym = MCSymbolRefExpr::create(RawSym, Ctx);
- StubInfo.AuthPtrRef =
+ StubAuthPtrRef =
AArch64AuthMCExpr::create(Sym, Discriminator, Key,
/*HasAddressDiversity=*/false, Ctx);
return StubSym;
@@ -126,3 +125,11 @@ MCSymbol *AArch64_ELFTargetObjectFile::getAuthPtrSlotSymbol(
return getAuthPtrSlotSymbolHelper(getContext(), TM, MMI, ELFMMI, RawSym, Key,
Discriminator);
}
+
+MCSymbol *AArch64_MachoTargetObjectFile::getAuthPtrSlotSymbol(
+ const TargetMachine &TM, MachineModuleInfo *MMI, const MCSymbol *RawSym,
+ AArch64PACKey::ID Key, uint16_t Discriminator) const {
+ auto &MachOMMI = MMI->getObjFileInfo<MachineModuleInfoMachO>();
+ return getAuthPtrSlotSymbolHelper(getContext(), TM, MMI, MachOMMI, RawSym,
+ Key, Discriminator);
+}
diff --git a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.h b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.h
index c5ebf03c39c77a..2ef8bda2988d47 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.h
+++ b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.h
@@ -60,6 +60,11 @@ class AArch64_MachoTargetObjectFile : public TargetLoweringObjectFileMachO {
void getNameWithPrefix(SmallVectorImpl<char> &OutName, const GlobalValue *GV,
const TargetMachine &TM) const override;
+
+ MCSymbol *getAuthPtrSlotSymbol(const TargetMachine &TM,
+ MachineModuleInfo *MMI, const MCSymbol *RawSym,
+ AArch64PACKey::ID Key,
+ uint16_t Discriminator) const;
};
/// This implementation is used for AArch64 COFF targets.
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
index 9e0860934f777e..dc47bdf6b351b7 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
@@ -6636,8 +6636,8 @@ bool AArch64InstructionSelector::selectPtrAuthGlobalValue(
"constant discriminator in ptrauth global out of range [0, 0xffff]");
// Choosing between 3 lowering alternatives is target-specific.
- if (!STI.isTargetELF())
- report_fatal_error("ptrauth global lowering is only implemented for ELF");
+ if (!STI.isTargetELF() && !STI.isTargetMachO())
+ report_fatal_error("ptrauth global lowering only supported on MachO/ELF");
if (!MRI.hasOneDef(Addr))
return false;
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/ptrauth-constant-in-code.ll b/llvm/test/CodeGen/AArch64/GlobalISel/ptrauth-constant-in-code.ll
index 7b85b12bb89520..094b85431f4041 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/ptrauth-constant-in-code.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/ptrauth-constant-in-code.ll
@@ -5,6 +5,9 @@
; RUN: not --crash llc < err1.ll -mtriple aarch64-elf -mattr=+pauth \
; RUN: -global-isel=1 -verify-machineinstrs -global-isel-abort=1 2>&1 | \
; RUN: FileCheck --check-prefix=ERR1 %s
+; RUN: not --crash llc < err1.ll -mtriple arm64-apple-ios -mattr=+pauth \
+; RUN: -global-isel=1 -verify-machineinstrs -global-isel-abort=1 2>&1 | \
+; RUN: FileCheck --check-prefix=ERR1 %s
@g = external global i32
@@ -18,6 +21,9 @@ define ptr @foo() {
; RUN: not --crash llc < err2.ll -mtriple aarch64-elf -mattr=+pauth \
; RUN: -global-isel=1 -verify-machineinstrs -global-isel-abort=1 2>&1 | \
; RUN: FileCheck --check-prefix=ERR2 %s
+; RUN: not --crash llc < err2.ll -mtriple arm64-apple-ios -mattr=+pauth \
+; RUN: -global-isel=1 -verify-machineinstrs -global-isel-abort=1 2>&1 | \
+; RUN: FileCheck --check-prefix=ERR2 %s
@g = external global i32
@@ -31,6 +37,9 @@ define ptr @foo() {
; RUN: not --crash llc < err3.ll -mtriple aarch64-elf -mattr=+pauth \
; RUN: -global-isel=1 -verify-machineinstrs -global-isel-abort=1 2>&1 | \
; RUN: FileCheck --check-prefix=ERR3 %s
+; RUN: not --crash llc < err3.ll -mtriple arm64-apple-ios -mattr=+pauth \
+; RUN: -global-isel=1 -verify-machineinstrs -global-isel-abort=1 2>&1 | \
+; RUN: FileCheck --check-prefix=ERR3 %s
@g_weak = extern_weak global i32
@@ -44,6 +53,9 @@ define ptr @foo() {
; RUN: not --crash llc < err4.ll -mtriple aarch64-elf -mattr=+pauth \
; RUN: -global-isel=1 -verify-machineinstrs -global-isel-abort=1 2>&1 | \
; RUN: FileCheck --check-prefix=ERR4 %s
+; RUN: not --crash llc < err4.ll -mtriple arm64-apple-ios -mattr=+pauth \
+; RUN: -global-isel=1 -verify-machineinstrs -global-isel-abort=1 2>&1 | \
+; RUN: FileCheck --check-prefix=ERR4 %s
@g_weak = extern_weak global i32
@g_weak.ref.da.42.addr = dso_local constant ptr ptrauth (ptr @g_weak, i32 2, i64 42, ptr @g_weak.ref.da.42.addr)
@@ -55,21 +67,28 @@ define ptr @foo() {
;--- err5.ll
-; RUN: not --crash llc < err5.ll -mtriple arm64-apple-darwin -mattr=+pauth \
+; RUN: not --crash llc < err5.ll -mtriple aarch64-windows -mattr=+pauth \
; RUN: -global-isel=1 -verify-machineinstrs -global-isel-abort=1 2>&1 | \
; RUN: FileCheck --check-prefix=ERR5 %s
@g = external global i32
define ptr @foo() {
-; ERR5: LLVM ERROR: ptrauth global lowering is only implemented for ELF
+; ERR5: LLVM ERROR: ptrauth global lowering only supported on MachO/ELF
ret ptr ptrauth (ptr @g, i32 0)
}
;--- ok.ll
; RUN: llc < ok.ll -mtriple aarch64-elf -mattr=+pauth -global-isel=1 \
-; RUN: -verify-machineinstrs -global-isel-abort=1 | FileCheck %s
+; RUN: -verify-machineinstrs -global-isel-abort=1 | \
+; RUN: FileCheck %s --check-prefix=ELF
+; RUN: llc < ok.ll -mtriple aarch64-elf -mattr=+pauth -global-isel=1 \
+; RUN: -verify-machineinstrs -global-isel-abort=1 -filetype=obj
+
+; RUN: llc < ok.ll -mtriple arm64-apple-ios -mattr=+pauth -global-isel=1 \
+; RUN: -verify-machineinstrs -global-isel-abort=1 | \
+; RUN: FileCheck %s --check-prefix=MACHO
; RUN: llc < ok.ll -mtriple aarch64-elf -mattr=+pauth -global-isel=1 \
; RUN: -verify-machineinstrs -global-isel-abort=1 -filetype=obj
@@ -78,100 +97,171 @@ define ptr @foo() {
@g_strong_def = dso_local constant i32 42
define ptr @test_global_zero_disc() {
-; CHECK-LABEL: test_global_zero_disc:
-; CHECK: // %bb.0:
-; CHECK-NEXT: adrp x16, :got:g
-; CHECK-NEXT: ldr x16, [x16, :got_lo12:g]
-; CHECK-NEXT: paciza x16
-; CHECK-NEXT: mov x0, x16
-; CHECK-NEXT: ret
+; ELF-LABEL: test_global_zero_disc:
+; ELF: // %bb.0:
+; ELF-NEXT: adrp x16, :got:g
+; ELF-NEXT: ldr x16, [x16, :got_lo12:g]
+; ELF-NEXT: paciza x16
+; ELF-NEXT: mov x0, x16
+; ELF-NEXT: ret
+
+; MACHO-LABEL: _test_global_zero_disc:
+; MACHO: ; %bb.0:
+; MACHO-NEXT: adrp x16, _g@GOTPAGE
+; MACHO-NEXT: ldr x16, [x16, _g@GOTPAGEOFF]
+; MACHO-NEXT: paciza x16
+; MACHO-NEXT: mov x0, x16
+; MACHO-NEXT: ret
ret ptr ptrauth (ptr @g, i32 0)
}
define ptr @test_global_offset_zero_disc() {
-; CHECK-LABEL: test_global_offset_zero_disc:
-; CHECK: // %bb.0:
-; CHECK-NEXT: adrp x16, :got:g
-; CHECK-NEXT: ldr x16, [x16, :got_lo12:g]
-; CHECK-NEXT: add x16, x16, #16
-; CHECK-NEXT: pacdza x16
-; CHECK-NEXT: mov x0, x16
-; CHECK-NEXT: ret
+; ELF-LABEL: test_global_offset_zero_disc:
+; ELF: // %bb.0:
+; ELF-NEXT: adrp x16, :got:g
+; ELF-NEXT: ldr x16, [x16, :got_lo12:g]
+; ELF-NEXT: add x16, x16, #16
+; ELF-NEXT: pacdza x16
+; ELF-NEXT: mov x0, x16
+; ELF-NEXT: ret
+
+; MACHO-LABEL: _test_global_offset_zero_disc:
+; MACHO: ; %bb.0:
+; MACHO-NEXT: adrp x16, _g@GOTPAGE
+; MACHO-NEXT: ldr x16, [x16, _g@GOTPAGEOFF]
+; MACHO-NEXT: add x16, x16, #16
+; MACHO-NEXT: pacdza x16
+; MACHO-NEXT: mov x0...
[truncated]
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with a couple of minor nits. Thanks for getting rid of useless struct AuthStubInfo
in favor of just const MCExpr *
.
typename MachineModuleInfoTarget::AuthStubListTy List(AuthPtrStubs.begin(), | ||
AuthPtrStubs.end()); | ||
using ExprStubPairTy = std::pair<MCSymbol *, const MCExpr *>; | ||
static int SortAuthStubPair(const ExprStubPairTy *LHS, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's probably worth adding a test which checks that stubs are sorted. I'm OK with merging this "as is" and implementing new tests as a separate patch later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, the ordering doesn't matter as long as it's stable; I added another extern_weak as the barest of sanity checks.
@@ -36,6 +36,11 @@ class MachineModuleInfoMachO : public MachineModuleInfoImpl { | |||
/// bit is true if this GV is external. | |||
DenseMap<MCSymbol *, StubValueTy> ThreadLocalGVStubs; | |||
|
|||
/// Darwin '$auth_ptr' stubs. The key is the stub symbol, like | |||
/// "Lfoo$addend$auth_ptr$ib$12". The value is the MCExpr representing that |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just in case you've missed that - currently, there is no addend support for $auth_ptr$
symbols - see getAuthPtrSlotSymbolHelper
. It's probably worth mentioning that addend is optional in this comment. Feel free to ignore though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, I don't think we'll ever need the addend support here, I'm keeping it downstream for some other use-cases.
I should mention we're also missing the address-diversity support here, and that one we'll likely want to add here in the future, at least for MachO; we'll see then whether it's needed for ELF, given the broader support for auth GOT relocations that MachO doesn't expose.
Move the extern_weak testcase to be adjacent to the emitted stubs, and add another testcase to check emission stability.
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/50/builds/946 Here is the relevant piece of the build log for the reference:
|
This also adds support for auth stubs on MachO using __DATA,__auth_ptr. Some of the machinery for auth stubs is already implemented; this generalizes that a bit to support MachO, and moves some of the shared logic into MMIImpls. In particular, this originally had an AuthStubInfo struct, but we no longer need it beyond a single MCExpr. So this provides variants of the symbol stub helper type declarations and functions for "expr stubs", where a stub points at an arbitrary MCExpr, rather than a simple MCSymbol (and a bit).
add back -fallow-half-arguments-and-returns for hipRuntime builds. ---------------------------------------------------------------------- Revert "[PAC][AArch64] Lower ptrauth constants in code (llvm#96879)" This reverts commit 88dd10c. ---------------------------------------------------------------------- [PAC][AArch64] Lower ptrauth constants in code (llvm#96879) This re-applies llvm#94241 after fixing buildbot failure, see https://lab.llvm.org/buildbot/#/builders/51/builds/570 According to standard, `constexpr` variables and `const` variables initialized with constant expressions can be used in lambdas w/o capturing - see https://en.cppreference.com/w/cpp/language/lambda. However, MSVC used on buildkite seems to ignore that rule and does not allow using such uncaptured variables in lambdas: we have "error C3493: 'Mask16' cannot be implicitly captured because no default capture mode has been specified" - see https://buildkite.com/llvm-project/github-pull-requests/builds/73238 Explicitly capturing such a variable, however, makes buildbot fail with "error: lambda capture 'Mask16' is not required to be captured for this use [-Werror,-Wunused-lambda-capture]" - see https://lab.llvm.org/buildbot/#/builders/51/builds/570. Fix both cases by using `0xffff` value directly instead of giving a name to it. Original PR description below. Depends on llvm#94240. Define the following pseudos for lowering ptrauth constants in code: - non-`extern_weak`: - no GOT load needed: `MOVaddrPAC` - similar to `MOVaddr`, with added PAC; - GOT load needed: `LOADgotPAC` - similar to `LOADgot`, with added PAC; - `extern_weak`: `LOADauthptrstatic` - similar to `LOADgot`, but use a special stub slot named `sym$auth_ptr$key$disc` filled by dynamic linker during relocation resolving instead of a GOT slot. --------- Co-authored-by: Ahmed Bougacha <[email protected]> (cherry picked from commit 1488fb4) ---------------------------------------------------------------------- [AArch64][PAC] Lower ptrauth constants in code for MachO. (llvm#97665) This also adds support for auth stubs on MachO using __DATA,__auth_ptr. Some of the machinery for auth stubs is already implemented; this generalizes that a bit to support MachO, and moves some of the shared logic into MMIImpls. In particular, this originally had an AuthStubInfo struct, but we no longer need it beyond a single MCExpr. So this provides variants of the symbol stub helper type declarations and functions for "expr stubs", where a stub points at an arbitrary MCExpr, rather than a simple MCSymbol (and a bit). (cherry picked from commit 5f1bb62) ---------------------------------------------------------------------- [AArch64][PAC] Sign block addresses used in indirectbr. (llvm#97647) Enabled in clang using: -fptrauth-indirect-gotos and at the IR level using function attribute: "ptrauth-indirect-gotos" Signing uses IA and a per-function integer discriminator. The discriminator isn't ABI-visible, and is currently: ptrauth_string_discriminator("<function_name> blockaddress") A sufficiently sophisticated frontend could benefit from per-indirectbr discrimination, which would need additional machinery, such as allowing "ptrauth" bundles on indirectbr. For our purposes, the simple scheme above is sufficient. This approach doesn't support subtracting label addresses and using the result as offsets, because each label address is signed. Pointer arithmetic on signed pointers corrupts the signature bits, and because label address expressions aren't typed beyond void*, we can't do anything reliably intelligent on the arithmetic exprs. Not signing addresses when used to form offsets would allow easily hijacking control flow by overwriting the offset. This diagnoses the basic cases (`&&lbl2 - &&lbl1`) in the frontend, while we evaluate either alternative implementations (e.g., lowering blockaddress to a bb number, and indirectbr to a checked jump-table), or better diagnostics (both at the frontend level and on unencodable IR constants). (cherry picked from commit b8721fa) ---------------------------------------------------------------------- [AArch64][PAC] Lower auth/resign into checked sequence. (llvm#79024) This introduces 3 hardening modes in the authentication step of auth/resign lowering: - unchecked, which uses the AUT instructions as-is - poison, which detects authentication failure (using an XPAC+CMP sequence), explicitly yielding the XPAC result rather than the AUT result, to avoid leaking - trap, which additionally traps on authentication failure, using BRK #0xC470 + key (IA C470, IB C471, DA C472, DB C473.) Not all modes are necessarily useful in all contexts, and there are more performant alternative lowerings in specific contexts (e.g., when I/D TBI enablement is a target ABI guarantee.) These will be implemented separately. This is controlled by the `ptrauth-auth-traps` function attributes, and can be overridden using `-aarch64-ptrauth-auth-checks=`. This also adds the FPAC extension, which we haven't needed before, to improve isel when we can rely on HW checking. (cherry picked from commit d7e8a74) ---------------------------------------------------------------------- [Clang][Arm] Convert -fallow-half-arguments-and-returns to a target option. NFC This cc1 option -fallow-half-arguments-and-returns allows __fp16 to be passed by argument and returned, without giving an error. It is currently always enabled for Arm and AArch64, by forcing the option in the driver. This means any cc1 tests (especially those needing arm_neon.h) need to specify the option too, to prevent the error from being emitted. This changes it to a target option instead, set to true for Arm and AArch64. This allows the option to be removed. Previously it was implied by -fnative_half_arguments_and_returns, which is set for certain languages like open_cl, renderscript and hlsl, so that option now too controls the errors. There were are few other non-arm uses of -fallow-half-arguments-and-returns but I believe they were unnecessary. The strictfp_builtins.c tests were converted from __fp16 to _Float16 to avoid the issues. Differential Revision: https://reviews.llvm.org/D133885 (cherry picked from commit 9ef11036505c0ae6cdb56ff49f39ab7abcded3cf) ---------------------------------------------------------------------- [clang] XFAIL a few tests due to 'noundef' etc Not all, but most of these are failing due to the presence of a 'noundef' call return attribute on some intrinsics. This is not present on upstream 'main' due to the AlwaysInliner pass being run. See commit 1a2e77c. ---------------------------------------------------------------------- [DebugInfo] Restore missing disabled ptrauth support See "[DebugInfo] Teach LLVM and LLDB about ptrauth in DWARF": commit a8c3d98 Author: Jonas Devlieghere <[email protected]> Date: Wed Jul 27 10:44:15 2022 -0700 ---------------------------------------------------------------------- Apply simple-do.ll test change from b46c085 ---------------------------------------------------------------------- Adjust ptrauth.s test for ptrauth_authentication_mode encoding ---------------------------------------------------------------------- Fix dwarf-eh-prepare-dbg.ll test: dwarfAddressSpace=>addressSpace ---------------------------------------------------------------------- Update some SLPVectorizer/AArch64 tests from upstream ---------------------------------------------------------------------- Regenerate assertions in arm_mult_q15.ll ---------------------------------------------------------------------- [AsmPrinter] Handle null extracted addr class ---------------------------------------------------------------------- [PowerPC] Account for custom LLVM moniker in aix tests ---------------------------------------------------------------------- [LoongArch] Add "Verify Heterogeneous Debug Preconditions" to pipeline test ---------------------------------------------------------------------- [JITLink][RISCV] Un-XFAIL ELF_pc_indirect.s ---------------------------------------------------------------------- Change-Id: Ie6ab500b2451b3ed070dfad0bc16d003e5e2fe10
This also adds support for auth stubs on MachO using __DATA,__auth_ptr.
Some of the machinery for auth stubs is already implemented; this
generalizes that a bit to support MachO, and moves some of the shared logic into MMIImpls.
In particular, this originally had an AuthStubInfo struct, but we no longer need it
beyond a single MCExpr. So this provides variants of the symbol stub
helper type declarations and functions for "expr stubs", where a
stub points at an arbitrary MCExpr, rather than a simple MCSymbol (and a bit).
On MachO, the auth stubs are emitted in __DATA,__auth_ptr.
Beyond that, this is mostly straightforward.