Skip to content

Commit aa7b282

Browse files
committed
[AArch64][PAC] Support 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. 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.
1 parent 507b0f6 commit aa7b282

7 files changed

+84
-40
lines changed

llvm/include/llvm/CodeGen/MachineModuleInfo.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,20 @@ class MachineModuleInfoImpl {
5858
using StubValueTy = PointerIntPair<MCSymbol *, 1, bool>;
5959
using SymbolListTy = std::vector<std::pair<MCSymbol *, StubValueTy>>;
6060

61+
/// A variant of SymbolListTy where the stub is a generalized MCExpr.
62+
using ExprStubListTy = std::vector<std::pair<MCSymbol *, const MCExpr *>>;
63+
6164
virtual ~MachineModuleInfoImpl();
6265

6366
protected:
6467
/// Return the entries from a DenseMap in a deterministic sorted orer.
6568
/// Clears the map.
6669
static SymbolListTy getSortedStubs(DenseMap<MCSymbol*, StubValueTy>&);
70+
71+
/// Return the entries from a DenseMap in a deterministic sorted orer.
72+
/// Clears the map.
73+
static ExprStubListTy
74+
getSortedExprStubs(DenseMap<MCSymbol *, const MCExpr *> &);
6775
};
6876

6977
//===----------------------------------------------------------------------===//

llvm/include/llvm/CodeGen/MachineModuleInfoImpls.h

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ class MachineModuleInfoMachO : public MachineModuleInfoImpl {
3636
/// bit is true if this GV is external.
3737
DenseMap<MCSymbol *, StubValueTy> ThreadLocalGVStubs;
3838

39+
/// Darwin '$auth_ptr' stubs. The key is the stub symbol, like
40+
/// "Lfoo$addend$auth_ptr$ib$12". The value is the MCExpr representing that
41+
/// pointer, something like "_foo+addend@AUTH(ib, 12)".
42+
DenseMap<MCSymbol *, const MCExpr *> AuthPtrStubs;
43+
3944
virtual void anchor(); // Out of line virtual method.
4045

4146
public:
@@ -51,29 +56,32 @@ class MachineModuleInfoMachO : public MachineModuleInfoImpl {
5156
return ThreadLocalGVStubs[Sym];
5257
}
5358

59+
const MCExpr *&getAuthPtrStubEntry(MCSymbol *Sym) {
60+
assert(Sym && "Key cannot be null");
61+
return AuthPtrStubs[Sym];
62+
}
63+
5464
/// Accessor methods to return the set of stubs in sorted order.
5565
SymbolListTy GetGVStubList() { return getSortedStubs(GVStubs); }
5666
SymbolListTy GetThreadLocalGVStubList() {
5767
return getSortedStubs(ThreadLocalGVStubs);
5868
}
69+
70+
ExprStubListTy getAuthGVStubList() {
71+
return getSortedExprStubs(AuthPtrStubs);
72+
}
5973
};
6074

6175
/// MachineModuleInfoELF - This is a MachineModuleInfoImpl implementation
6276
/// for ELF targets.
6377
class MachineModuleInfoELF : public MachineModuleInfoImpl {
64-
public:
65-
struct AuthStubInfo {
66-
const MCExpr *AuthPtrRef;
67-
};
68-
69-
private:
7078
/// GVStubs - These stubs are used to materialize global addresses in PIC
7179
/// mode.
7280
DenseMap<MCSymbol *, StubValueTy> GVStubs;
7381

7482
/// AuthPtrStubs - These stubs are used to materialize signed addresses for
7583
/// extern_weak symbols.
76-
DenseMap<MCSymbol *, AuthStubInfo> AuthPtrStubs;
84+
DenseMap<MCSymbol *, const MCExpr *> AuthPtrStubs;
7785

7886
virtual void anchor(); // Out of line virtual method.
7987

@@ -85,7 +93,7 @@ class MachineModuleInfoELF : public MachineModuleInfoImpl {
8593
return GVStubs[Sym];
8694
}
8795

88-
AuthStubInfo &getAuthPtrStubEntry(MCSymbol *Sym) {
96+
const MCExpr *&getAuthPtrStubEntry(MCSymbol *Sym) {
8997
assert(Sym && "Key cannot be null");
9098
return AuthPtrStubs[Sym];
9199
}
@@ -94,10 +102,9 @@ class MachineModuleInfoELF : public MachineModuleInfoImpl {
94102

95103
SymbolListTy GetGVStubList() { return getSortedStubs(GVStubs); }
96104

97-
using AuthStubPairTy = std::pair<MCSymbol *, AuthStubInfo>;
98-
typedef std::vector<AuthStubPairTy> AuthStubListTy;
99-
100-
AuthStubListTy getAuthGVStubList();
105+
ExprStubListTy getAuthGVStubList() {
106+
return getSortedExprStubs(AuthPtrStubs);
107+
}
101108
};
102109

103110
/// MachineModuleInfoCOFF - This is a MachineModuleInfoImpl implementation

llvm/lib/CodeGen/MachineModuleInfoImpls.cpp

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -43,24 +43,19 @@ MachineModuleInfoImpl::SymbolListTy MachineModuleInfoImpl::getSortedStubs(
4343
return List;
4444
}
4545

46-
template <typename MachineModuleInfoTarget>
47-
static typename MachineModuleInfoTarget::AuthStubListTy getAuthGVStubListHelper(
48-
DenseMap<MCSymbol *, typename MachineModuleInfoTarget::AuthStubInfo>
49-
&AuthPtrStubs) {
50-
typename MachineModuleInfoTarget::AuthStubListTy List(AuthPtrStubs.begin(),
51-
AuthPtrStubs.end());
46+
using ExprStubPairTy = std::pair<MCSymbol *, const MCExpr *>;
47+
static int SortAuthStubPair(const ExprStubPairTy *LHS,
48+
const ExprStubPairTy *RHS) {
49+
return LHS->first->getName().compare(RHS->first->getName());
50+
}
5251

53-
if (!List.empty())
54-
llvm::sort(List.begin(), List.end(),
55-
[](const typename MachineModuleInfoTarget::AuthStubPairTy &LHS,
56-
const typename MachineModuleInfoTarget::AuthStubPairTy &RHS) {
57-
return LHS.first->getName() < RHS.first->getName();
58-
});
52+
MachineModuleInfoImpl::ExprStubListTy MachineModuleInfoImpl::getSortedExprStubs(
53+
DenseMap<MCSymbol *, const MCExpr *> &ExprStubs) {
54+
MachineModuleInfoImpl::ExprStubListTy List(ExprStubs.begin(),
55+
ExprStubs.end());
5956

60-
AuthPtrStubs.clear();
61-
return List;
62-
}
57+
array_pod_sort(List.begin(), List.end(), SortAuthStubPair);
6358

64-
MachineModuleInfoELF::AuthStubListTy MachineModuleInfoELF::getAuthGVStubList() {
65-
return getAuthGVStubListHelper<MachineModuleInfoELF>(AuthPtrStubs);
59+
ExprStubs.clear();
60+
return List;
6661
}

llvm/lib/MC/MCMachOStreamer.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,10 @@ static bool canGoAfterDWARF(const MCSectionMachO &MSec) {
161161
return true;
162162
if (SegName == "__LLVM" && (SecName == "__cg_profile"))
163163
return true;
164+
165+
if (SegName == "__DATA" && SecName == "__auth_ptr")
166+
return true;
167+
164168
return false;
165169
}
166170

llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -848,20 +848,39 @@ void AArch64AsmPrinter::emitHwasanMemaccessSymbols(Module &M) {
848848
}
849849
}
850850

851-
template <typename MachineModuleInfoTarget>
852-
static void emitAuthenticatedPointer(
853-
MCStreamer &OutStreamer, MCSymbol *StubLabel,
854-
const typename MachineModuleInfoTarget::AuthStubInfo &StubInfo) {
851+
static void emitAuthenticatedPointer(MCStreamer &OutStreamer,
852+
MCSymbol *StubLabel,
853+
const MCExpr *StubAuthPtrRef) {
855854
// sym$auth_ptr$key$disc:
856855
OutStreamer.emitLabel(StubLabel);
857-
OutStreamer.emitValue(StubInfo.AuthPtrRef, /*size=*/8);
856+
OutStreamer.emitValue(StubAuthPtrRef, /*size=*/8);
858857
}
859858

860859
void AArch64AsmPrinter::emitEndOfAsmFile(Module &M) {
861860
emitHwasanMemaccessSymbols(M);
862861

863862
const Triple &TT = TM.getTargetTriple();
864863
if (TT.isOSBinFormatMachO()) {
864+
865+
// Output authenticated pointers as indirect symbols, if we have any.
866+
MachineModuleInfoMachO &MMIMacho =
867+
MMI->getObjFileInfo<MachineModuleInfoMachO>();
868+
869+
auto Stubs = MMIMacho.getAuthGVStubList();
870+
871+
if (!Stubs.empty()) {
872+
// Switch to the "__auth_ptr" section.
873+
OutStreamer->switchSection(
874+
OutContext.getMachOSection("__DATA", "__auth_ptr", MachO::S_REGULAR,
875+
SectionKind::getMetadata()));
876+
emitAlignment(Align(8));
877+
878+
for (auto &Stub : Stubs)
879+
emitAuthenticatedPointer(*OutStreamer, Stub.first, Stub.second);
880+
881+
OutStreamer->addBlankLine();
882+
}
883+
865884
// Funny Darwin hack: This flag tells the linker that no global symbols
866885
// contain code that falls through to other global symbols (e.g. the obvious
867886
// implementation of multiple entry points). If this doesn't occur, the
@@ -882,8 +901,7 @@ void AArch64AsmPrinter::emitEndOfAsmFile(Module &M) {
882901
emitAlignment(Align(8));
883902

884903
for (const auto &Stub : Stubs)
885-
emitAuthenticatedPointer<MachineModuleInfoELF>(*OutStreamer, Stub.first,
886-
Stub.second);
904+
emitAuthenticatedPointer(*OutStreamer, Stub.first, Stub.second);
887905

888906
OutStreamer->addBlankLine();
889907
}

llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,15 +105,14 @@ static MCSymbol *getAuthPtrSlotSymbolHelper(
105105
Twine("$auth_ptr$") + AArch64PACKeyIDToString(Key) + Twine('$') +
106106
Twine(Discriminator));
107107

108-
typename MachineModuleInfoTarget::AuthStubInfo &StubInfo =
109-
TargetMMI.getAuthPtrStubEntry(StubSym);
108+
const MCExpr *&StubAuthPtrRef = TargetMMI.getAuthPtrStubEntry(StubSym);
110109

111-
if (StubInfo.AuthPtrRef)
110+
if (StubAuthPtrRef)
112111
return StubSym;
113112

114113
const MCExpr *Sym = MCSymbolRefExpr::create(RawSym, Ctx);
115114

116-
StubInfo.AuthPtrRef =
115+
StubAuthPtrRef =
117116
AArch64AuthMCExpr::create(Sym, Discriminator, Key,
118117
/*HasAddressDiversity=*/false, Ctx);
119118
return StubSym;
@@ -126,3 +125,11 @@ MCSymbol *AArch64_ELFTargetObjectFile::getAuthPtrSlotSymbol(
126125
return getAuthPtrSlotSymbolHelper(getContext(), TM, MMI, ELFMMI, RawSym, Key,
127126
Discriminator);
128127
}
128+
129+
MCSymbol *AArch64_MachoTargetObjectFile::getAuthPtrSlotSymbol(
130+
const TargetMachine &TM, MachineModuleInfo *MMI, const MCSymbol *RawSym,
131+
AArch64PACKey::ID Key, uint16_t Discriminator) const {
132+
auto &MachOMMI = MMI->getObjFileInfo<MachineModuleInfoMachO>();
133+
return getAuthPtrSlotSymbolHelper(getContext(), TM, MMI, MachOMMI, RawSym,
134+
Key, Discriminator);
135+
}

llvm/lib/Target/AArch64/AArch64TargetObjectFile.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ class AArch64_MachoTargetObjectFile : public TargetLoweringObjectFileMachO {
6060

6161
void getNameWithPrefix(SmallVectorImpl<char> &OutName, const GlobalValue *GV,
6262
const TargetMachine &TM) const override;
63+
64+
MCSymbol *getAuthPtrSlotSymbol(const TargetMachine &TM,
65+
MachineModuleInfo *MMI, const MCSymbol *RawSym,
66+
AArch64PACKey::ID Key,
67+
uint16_t Discriminator) const;
6368
};
6469

6570
/// This implementation is used for AArch64 COFF targets.

0 commit comments

Comments
 (0)