Skip to content

Commit 65d1262

Browse files
authored
RuntimeLibcalls: Add entries for stackprotector globals (llvm#154930)
Add entries for_stack_chk_guard, __ssp_canary_word, __security_cookie, and __guard_local. As far as I can tell these are all just different names for the same shaped functionality on different systems. These aren't really functions, but special global variable names. They should probably be treated the same way; all the same contexts that need to know about emittable function names also need to know about this. This avoids a special case check in IRSymtab. This isn't a complete change, there's a lot more cleanup which should be done. The stack protector configuration system is a complete mess. There are multiple overlapping controls, used in 3 different places. Some of the target control implementations overlap with conditions used in the emission points, and some use correlated but not identical conditions in different contexts. i.e. useLoadStackGuardNode, getIRStackGuard, getSSPStackGuardCheck and insertSSPDeclarations are all used in inconsistent ways so I don't know if I've tracked the intention of the system correctly. The PowerPC test change is a bug fix on linux. Previously the manual conditions were based around !isOSOpenBSD, which is not the condition where __stack_chk_guard are used. Now getSDagStackGuard returns the proper global reference, resulting in LOAD_STACK_GUARD getting a MachineMemOperand which allows scheduling.
1 parent fd330de commit 65d1262

14 files changed

+92
-109
lines changed

llvm/include/llvm/IR/RuntimeLibcalls.td

Lines changed: 56 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,20 @@ def isOSOpenBSD : RuntimeLibcallPredicate<"TT.isOSOpenBSD()">;
2121
def isNotOSOpenBSD : RuntimeLibcallPredicate<"!TT.isOSOpenBSD()">;
2222
def isOSWindows : RuntimeLibcallPredicate<"TT.isOSWindows()">;
2323
def isNotOSWindows : RuntimeLibcallPredicate<"!TT.isOSWindows()">;
24+
def isNotOSLinux : RuntimeLibcallPredicate<[{!TT.isOSLinux()}]>;
2425
def isNotOSMSVCRT : RuntimeLibcallPredicate<"!TT.isOSMSVCRT()">;
2526
def isPS : RuntimeLibcallPredicate<"TT.isPS()">;
2627
def isNotOSWindowsOrIsCygwinMinGW
2728
: RuntimeLibcallPredicate<"!TT.isOSWindows() || TT.isOSCygMing()">;
2829
def isWindowsMSVCEnvironment : RuntimeLibcallPredicate<
2930
[{TT.isWindowsMSVCEnvironment()}]>;
3031

32+
def isNotOSLinuxAndNotOSOpenBSD : RuntimeLibcallPredicate<
33+
[{!TT.isOSLinux() && !TT.isOSOpenBSD()}]>;
34+
35+
def isWindowsMSVCOrItaniumEnvironment : RuntimeLibcallPredicate<
36+
[{TT.isWindowsMSVCEnvironment() || TT.isWindowsItaniumEnvironment()}]>;
37+
3138
def isGNUEnvironment : RuntimeLibcallPredicate<"TT.isGNUEnvironment()">;
3239
def darwinHasSinCosStret : RuntimeLibcallPredicate<"darwinHasSinCosStret(TT)">;
3340
def darwinHasExp10 : RuntimeLibcallPredicate<"darwinHasExp10(TT)">;
@@ -471,6 +478,16 @@ def OBJC_RETAIN_AUTORELEASE : RuntimeLibcall;
471478
def OBJC_SYNC_ENTER : RuntimeLibcall;
472479
def OBJC_SYNC_EXIT : RuntimeLibcall;
473480

481+
//--------------------------------------------------------------------
482+
// Global variable references
483+
//--------------------------------------------------------------------
484+
//
485+
// TODO: These are not libcalls and probably should be distinguished
486+
// in some way from callable functions.
487+
// --------------------------------------------------------------------
488+
489+
def STACK_CHECK_GUARD : RuntimeLibcall;
490+
474491
//--------------------------------------------------------------------
475492
// Define implementation default libcalls
476493
//--------------------------------------------------------------------
@@ -1103,6 +1120,21 @@ defset list<RuntimeLibcallImpl> LibmF128FiniteLibcalls = {
11031120
def __powf128_finite : RuntimeLibcallImpl<POW_FINITE_F128>;
11041121
}
11051122

1123+
//--------------------------------------------------------------------
1124+
// Global variable references
1125+
//--------------------------------------------------------------------
1126+
1127+
def __stack_chk_guard : RuntimeLibcallImpl<STACK_CHECK_GUARD>;
1128+
1129+
// Name used on OpenBSD
1130+
def __guard_local : RuntimeLibcallImpl<STACK_CHECK_GUARD>;
1131+
1132+
// Name used with Windows MSVC
1133+
def __security_cookie : RuntimeLibcallImpl<STACK_CHECK_GUARD>;
1134+
1135+
// Name used on AIX
1136+
def __ssp_canary_word : RuntimeLibcallImpl<STACK_CHECK_GUARD>;
1137+
11061138
//===----------------------------------------------------------------------===//
11071139
// Common Libcall Sets
11081140
//===----------------------------------------------------------------------===//
@@ -1159,7 +1191,8 @@ defvar DarwinSinCosStret = LibcallImpls<(add __sincosf_stret, __sincos_stret),
11591191
defvar DarwinExp10 = LibcallImpls<(add __exp10f, __exp10), darwinHasExp10>;
11601192

11611193
defvar SecurityCheckCookieIfWinMSVC =
1162-
LibcallImpls<(add __security_check_cookie), isWindowsMSVCEnvironment>;
1194+
LibcallImpls<(add __security_check_cookie, __security_cookie),
1195+
isWindowsMSVCOrItaniumEnvironment>;
11631196

11641197
defvar LibmHasSinCosF32 = LibcallImpls<(add sincosf), hasSinCos>;
11651198
defvar LibmHasSinCosF64 = LibcallImpls<(add sincos), hasSinCos>;
@@ -1205,10 +1238,13 @@ defvar LibmHasFrexpF128 = LibcallImpls<(add frexp_f128), isNotOSWindowsOrIsCygwi
12051238
defvar LibmHasLdexpF128 = LibcallImpls<(add ldexp_f128), isNotOSWindowsOrIsCygwinMinGW>;
12061239

12071240
defvar has__stack_chk_fail = LibcallImpls<(add __stack_chk_fail), isNotOSOpenBSD>;
1241+
defvar has__stack_chk_guard =
1242+
LibcallImpls<(add __stack_chk_guard), isNotOSOpenBSD>;
12081243
defvar has__stack_smash_handler = LibcallImpls<(add __stack_smash_handler), isOSOpenBSD>;
1244+
defvar has___guard_local = LibcallImpls<(add __guard_local), isOSOpenBSD>;
12091245

1210-
defvar DefaultStackProtector = (add has__stack_chk_fail,
1211-
has__stack_smash_handler);
1246+
defvar DefaultStackProtector = (add has__stack_chk_fail, has__stack_chk_guard,
1247+
has__stack_smash_handler, has___guard_local);
12121248

12131249
//===----------------------------------------------------------------------===//
12141250
// Objective-C Runtime Libcalls
@@ -1357,7 +1393,9 @@ def WindowsARM64ECSystemLibrary
13571393
: SystemRuntimeLibrary<isWindowsArm64EC,
13581394
(add WinArm64ECDefaultRuntimeLibcallImpls,
13591395
arm64ec___stack_chk_fail,
1360-
LibcallImpls<(add __security_check_cookie_arm64ec),
1396+
__stack_chk_guard,
1397+
LibcallImpls<(add __security_check_cookie_arm64ec,
1398+
__security_cookie),
13611399
isWindowsMSVCEnvironment>,
13621400
ExceptionModelCallsArm64EC)>;
13631401

@@ -1848,7 +1886,7 @@ def HexagonSystemLibrary
18481886
__umoddi3, __divdf3, __muldf3, __divsi3, __subdf3, sqrtf,
18491887
__divdi3, __umodsi3, __moddi3, __modsi3), HexagonLibcalls,
18501888
LibmHasSinCosF32, LibmHasSinCosF64, LibmHasSinCosF128,
1851-
exp10f, exp10, exp10l_f128, __stack_chk_fail)>;
1889+
exp10f, exp10, exp10l_f128, __stack_chk_fail, __stack_chk_guard)>;
18521890

18531891
//===----------------------------------------------------------------------===//
18541892
// Lanai Runtime Libcalls
@@ -1859,7 +1897,7 @@ def isLanai : RuntimeLibcallPredicate<"TT.getArch() == Triple::lanai">;
18591897
// Use fast calling convention for library functions.
18601898
def LanaiSystemLibrary
18611899
: SystemRuntimeLibrary<isLanai, (add DefaultRuntimeLibcallImpls,
1862-
__stack_chk_fail)> {
1900+
__stack_chk_fail, __stack_chk_guard)> {
18631901
let DefaultLibcallCallingConv = FASTCC;
18641902
}
18651903

@@ -2157,7 +2195,8 @@ def MSP430SystemLibrary
21572195
__mspabi_slll,
21582196
// __mspabi_[srlll/srall/sllll/rlli/rlll] are NOT implemented in libgcc
21592197

2160-
__stack_chk_fail
2198+
__stack_chk_fail,
2199+
__stack_chk_guard
21612200
)
21622201
>;
21632202

@@ -2251,7 +2290,11 @@ def PPCSystemLibrary
22512290
LibmHasSinCosPPCF128,
22522291
AvailableIf<memcpy, isNotAIX>,
22532292
LibcallImpls<(add Int128RTLibcalls), isPPC64>,
2254-
DefaultStackProtector)>;
2293+
has__stack_chk_fail,
2294+
has__stack_smash_handler,
2295+
has___guard_local,
2296+
AvailableIf<__ssp_canary_word, isAIX>,
2297+
AvailableIf<__stack_chk_guard, isNotAIX>)>;
22552298

22562299
//===----------------------------------------------------------------------===//
22572300
// RISCV Runtime Libcalls
@@ -2334,7 +2377,10 @@ def SPARCSystemLibrary
23342377
LibcallImpls<(add _Q_qtoll, _Q_qtoull, _Q_lltoq, _Q_ulltoq), isSPARC32>,
23352378
LibcallImpls<(add SPARC64_MulDivCalls, Int128RTLibcalls), isSPARC64>,
23362379
LibmHasSinCosF32, LibmHasSinCosF64, LibmHasSinCosF128,
2337-
DefaultStackProtector)
2380+
has__stack_chk_fail,
2381+
has__stack_smash_handler,
2382+
has___guard_local,
2383+
AvailableIf<__stack_chk_guard, isNotOSLinuxAndNotOSOpenBSD>)
23382384
>;
23392385

23402386
//===----------------------------------------------------------------------===//
@@ -2544,7 +2590,7 @@ def WasmSystemLibrary
25442590
exp10f, exp10,
25452591
_Unwind_CallPersonality,
25462592
emscripten_return_address,
2547-
__stack_chk_fail)>;
2593+
__stack_chk_fail, __stack_chk_guard)>;
25482594

25492595
//===----------------------------------------------------------------------===//
25502596
// Legacy Default Runtime Libcalls

llvm/lib/CodeGen/TargetLoweringBase.cpp

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2059,29 +2059,37 @@ Value *TargetLoweringBase::getIRStackGuard(IRBuilderBase &IRB) const {
20592059
// Currently only support "standard" __stack_chk_guard.
20602060
// TODO: add LOAD_STACK_GUARD support.
20612061
void TargetLoweringBase::insertSSPDeclarations(Module &M) const {
2062-
if (!M.getNamedValue("__stack_chk_guard")) {
2063-
auto *GV = new GlobalVariable(M, PointerType::getUnqual(M.getContext()),
2064-
false, GlobalVariable::ExternalLinkage,
2065-
nullptr, "__stack_chk_guard");
2066-
2067-
// FreeBSD has "__stack_chk_guard" defined externally on libc.so
2068-
if (M.getDirectAccessExternalData() &&
2069-
!TM.getTargetTriple().isOSCygMing() &&
2070-
!(TM.getTargetTriple().isPPC64() &&
2071-
TM.getTargetTriple().isOSFreeBSD()) &&
2072-
(!TM.getTargetTriple().isOSDarwin() ||
2073-
TM.getRelocationModel() == Reloc::Static))
2074-
GV->setDSOLocal(true);
2075-
}
2062+
RTLIB::LibcallImpl StackGuardImpl = getLibcallImpl(RTLIB::STACK_CHECK_GUARD);
2063+
if (StackGuardImpl == RTLIB::Unsupported)
2064+
return;
2065+
2066+
StringRef StackGuardVarName = getLibcallImplName(StackGuardImpl);
2067+
M.getOrInsertGlobal(
2068+
StackGuardVarName, PointerType::getUnqual(M.getContext()), [=, &M]() {
2069+
auto *GV = new GlobalVariable(M, PointerType::getUnqual(M.getContext()),
2070+
false, GlobalVariable::ExternalLinkage,
2071+
nullptr, StackGuardVarName);
2072+
2073+
// FreeBSD has "__stack_chk_guard" defined externally on libc.so
2074+
if (M.getDirectAccessExternalData() &&
2075+
!TM.getTargetTriple().isOSCygMing() &&
2076+
!(TM.getTargetTriple().isPPC64() &&
2077+
TM.getTargetTriple().isOSFreeBSD()) &&
2078+
(!TM.getTargetTriple().isOSDarwin() ||
2079+
TM.getRelocationModel() == Reloc::Static))
2080+
GV->setDSOLocal(true);
2081+
2082+
return GV;
2083+
});
20762084
}
20772085

20782086
// Currently only support "standard" __stack_chk_guard.
20792087
// TODO: add LOAD_STACK_GUARD support.
20802088
Value *TargetLoweringBase::getSDagStackGuard(const Module &M) const {
2081-
if (getTargetMachine().getTargetTriple().isOSOpenBSD()) {
2082-
return M.getNamedValue("__guard_local");
2083-
}
2084-
return M.getNamedValue("__stack_chk_guard");
2089+
RTLIB::LibcallImpl GuardVarImpl = getLibcallImpl(RTLIB::STACK_CHECK_GUARD);
2090+
if (GuardVarImpl == RTLIB::Unsupported)
2091+
return nullptr;
2092+
return M.getNamedValue(getLibcallImplName(GuardVarImpl));
20852093
}
20862094

20872095
Function *TargetLoweringBase::getSSPStackGuardCheck(const Module &M) const {

llvm/lib/Object/IRSymtab.cpp

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -46,18 +46,6 @@ static cl::opt<bool> DisableBitcodeVersionUpgrade(
4646
"disable-bitcode-version-upgrade", cl::Hidden,
4747
cl::desc("Disable automatic bitcode upgrade for version mismatch"));
4848

49-
static constexpr StringLiteral PreservedSymbols[] = {
50-
// There are global variables, so put it here instead of in
51-
// RuntimeLibcalls.td.
52-
// TODO: Are there similar such variables?
53-
"__ssp_canary_word",
54-
"__stack_chk_guard",
55-
};
56-
57-
static bool isPreservedGlobalVarName(StringRef Name) {
58-
return PreservedSymbols[0] == Name || PreservedSymbols[1] == Name;
59-
}
60-
6149
namespace {
6250

6351
const char *getExpectedProducerName() {
@@ -106,7 +94,7 @@ struct Builder {
10694

10795
std::vector<storage::Str> DependentLibraries;
10896

109-
bool isPreservedLibFuncName(StringRef Name) {
97+
bool isPreservedName(StringRef Name) {
11098
return Libcalls.getSupportedLibcallImpl(Name) != RTLIB::Unsupported;
11199
}
112100

@@ -281,8 +269,7 @@ Error Builder::addSymbol(const ModuleSymbolTable &Msymtab,
281269
StringRef GVName = GV->getName();
282270
setStr(Sym.IRName, GVName);
283271

284-
if (Used.count(GV) || isPreservedLibFuncName(GVName) ||
285-
isPreservedGlobalVarName(GVName))
272+
if (Used.count(GV) || isPreservedName(GVName))
286273
Sym.Flags |= 1 << storage::Symbol::FB_used;
287274
if (GV->isThreadLocal())
288275
Sym.Flags |= 1 << storage::Symbol::FB_tls;

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28686,9 +28686,13 @@ void AArch64TargetLowering::insertSSPDeclarations(Module &M) const {
2868628686
// MSVC CRT provides functionalities for stack protection.
2868728687
RTLIB::LibcallImpl SecurityCheckCookieLibcall =
2868828688
getLibcallImpl(RTLIB::SECURITY_CHECK_COOKIE);
28689-
if (SecurityCheckCookieLibcall != RTLIB::Unsupported) {
28689+
28690+
RTLIB::LibcallImpl SecurityCookieVar =
28691+
getLibcallImpl(RTLIB::STACK_CHECK_GUARD);
28692+
if (SecurityCheckCookieLibcall != RTLIB::Unsupported &&
28693+
SecurityCookieVar != RTLIB::Unsupported) {
2869028694
// MSVC CRT has a global variable holding security cookie.
28691-
M.getOrInsertGlobal("__security_cookie",
28695+
M.getOrInsertGlobal(getLibcallImplName(SecurityCookieVar),
2869228696
PointerType::getUnqual(M.getContext()));
2869328697

2869428698
// MSVC CRT has a function to validate security cookie.
@@ -28705,13 +28709,6 @@ void AArch64TargetLowering::insertSSPDeclarations(Module &M) const {
2870528709
TargetLowering::insertSSPDeclarations(M);
2870628710
}
2870728711

28708-
Value *AArch64TargetLowering::getSDagStackGuard(const Module &M) const {
28709-
// MSVC CRT has a global variable holding security cookie.
28710-
if (Subtarget->getTargetTriple().isWindowsMSVCEnvironment())
28711-
return M.getGlobalVariable("__security_cookie");
28712-
return TargetLowering::getSDagStackGuard(M);
28713-
}
28714-
2871528712
Function *AArch64TargetLowering::getSSPStackGuardCheck(const Module &M) const {
2871628713
// MSVC CRT has a function to validate security cookie.
2871728714
RTLIB::LibcallImpl SecurityCheckCookieLibcall =

llvm/lib/Target/AArch64/AArch64ISelLowering.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,6 @@ class AArch64TargetLowering : public TargetLowering {
354354
Value *getIRStackGuard(IRBuilderBase &IRB) const override;
355355

356356
void insertSSPDeclarations(Module &M) const override;
357-
Value *getSDagStackGuard(const Module &M) const override;
358357
Function *getSSPStackGuardCheck(const Module &M) const override;
359358

360359
/// If the target has a standard location for the unsafe stack pointer,

llvm/lib/Target/ARM/ARMISelLowering.cpp

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21341,20 +21341,6 @@ void ARMTargetLowering::insertSSPDeclarations(Module &M) const {
2134121341
F->addParamAttr(0, Attribute::AttrKind::InReg);
2134221342
}
2134321343

21344-
Value *ARMTargetLowering::getSDagStackGuard(const Module &M) const {
21345-
RTLIB::LibcallImpl SecurityCheckCookieLibcall =
21346-
getLibcallImpl(RTLIB::SECURITY_CHECK_COOKIE);
21347-
if (SecurityCheckCookieLibcall != RTLIB::Unsupported) {
21348-
// MSVC CRT has a global variable holding security cookie.
21349-
//
21350-
// FIXME: We have a libcall entry for the correlated check function, but not
21351-
// the global name.
21352-
return M.getGlobalVariable("__security_cookie");
21353-
}
21354-
21355-
return TargetLowering::getSDagStackGuard(M);
21356-
}
21357-
2135821344
Function *ARMTargetLowering::getSSPStackGuardCheck(const Module &M) const {
2135921345
// MSVC CRT has a function to validate security cookie.
2136021346
RTLIB::LibcallImpl SecurityCheckCookie =

llvm/lib/Target/ARM/ARMISelLowering.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -704,7 +704,6 @@ class VectorType;
704704
bool useLoadStackGuardNode(const Module &M) const override;
705705

706706
void insertSSPDeclarations(Module &M) const override;
707-
Value *getSDagStackGuard(const Module &M) const override;
708707
Function *getSSPStackGuardCheck(const Module &M) const override;
709708

710709
bool canCombineStoreAndExtract(Type *VectorTy, Value *Idx,

llvm/lib/Target/PowerPC/PPCISelLowering.cpp

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,6 @@ static bool isNByteElemShuffleMask(ShuffleVectorSDNode *, unsigned, int);
157157

158158
static SDValue widenVec(SelectionDAG &DAG, SDValue Vec, const SDLoc &dl);
159159

160-
static const char AIXSSPCanaryWordName[] = "__ssp_canary_word";
161-
162160
// A faster local-[exec|dynamic] TLS access sequence (enabled with the
163161
// -maix-small-local-[exec|dynamic]-tls option) can be produced for TLS
164162
// variables; consistent with the IBM XL compiler, we apply a max size of
@@ -18655,24 +18653,6 @@ bool PPCTargetLowering::useLoadStackGuardNode(const Module &M) const {
1865518653
return TargetLowering::useLoadStackGuardNode(M);
1865618654
}
1865718655

18658-
// Override to disable global variable loading on Linux and insert AIX canary
18659-
// word declaration.
18660-
void PPCTargetLowering::insertSSPDeclarations(Module &M) const {
18661-
if (Subtarget.isAIXABI()) {
18662-
M.getOrInsertGlobal(AIXSSPCanaryWordName,
18663-
PointerType::getUnqual(M.getContext()));
18664-
return;
18665-
}
18666-
if (!Subtarget.isTargetLinux())
18667-
return TargetLowering::insertSSPDeclarations(M);
18668-
}
18669-
18670-
Value *PPCTargetLowering::getSDagStackGuard(const Module &M) const {
18671-
if (Subtarget.isAIXABI())
18672-
return M.getGlobalVariable(AIXSSPCanaryWordName);
18673-
return TargetLowering::getSDagStackGuard(M);
18674-
}
18675-
1867618656
bool PPCTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
1867718657
bool ForCodeSize) const {
1867818658
if (!VT.isSimple() || !Subtarget.hasVSX())

llvm/lib/Target/PowerPC/PPCISelLowering.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1141,8 +1141,6 @@ namespace llvm {
11411141

11421142
/// Override to support customized stack guard loading.
11431143
bool useLoadStackGuardNode(const Module &M) const override;
1144-
void insertSSPDeclarations(Module &M) const override;
1145-
Value *getSDagStackGuard(const Module &M) const override;
11461144

11471145
bool isFPImmLegal(const APFloat &Imm, EVT VT,
11481146
bool ForCodeSize) const override;

llvm/lib/Target/Sparc/SparcISelLowering.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3549,12 +3549,6 @@ bool SparcTargetLowering::isFMAFasterThanFMulAndFAdd(const MachineFunction &MF,
35493549
return Subtarget->isUA2007() && !Subtarget->useSoftFloat();
35503550
}
35513551

3552-
// Override to disable global variable loading on Linux.
3553-
void SparcTargetLowering::insertSSPDeclarations(Module &M) const {
3554-
if (!Subtarget->isTargetLinux())
3555-
return TargetLowering::insertSSPDeclarations(M);
3556-
}
3557-
35583552
void SparcTargetLowering::AdjustInstrPostInstrSelection(MachineInstr &MI,
35593553
SDNode *Node) const {
35603554
assert(MI.getOpcode() == SP::SUBCCrr || MI.getOpcode() == SP::SUBCCri);

0 commit comments

Comments
 (0)