Skip to content

Commit 05c0a80

Browse files
committed
[PowerPC][ISelLowering] Support -mstack-protector-guard=tls
Add support for using a thread-local variable with a specified offset for holding the stack guard canary value. To keep Linux targets from also getting another load due to LOAD_STACK_GUARD, kill that instruction when using "tls" mode. We can't use LOAD_STACK_GUARD for this new case as that is gated by useLoadStackGuardNode() and that function doesn't have a reference to the Module where we could test for "tls" mode. Signed-off-by: Keith Packard <[email protected]>
1 parent 144dc4c commit 05c0a80

File tree

4 files changed

+41
-4
lines changed

4 files changed

+41
-4
lines changed

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3605,7 +3605,7 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
36053605
StringRef Value = A->getValue();
36063606
if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
36073607
!EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
3608-
!EffectiveTriple.isRISCV())
3608+
!EffectiveTriple.isRISCV() && !EffectiveTriple.isPPC())
36093609
D.Diag(diag::err_drv_unsupported_opt_for_target)
36103610
<< A->getAsString(Args) << TripleStr;
36113611
if ((EffectiveTriple.isX86() || EffectiveTriple.isARM() ||
@@ -3645,7 +3645,7 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
36453645
<< A->getOption().getName() << Value << "sysreg global";
36463646
return;
36473647
}
3648-
if (EffectiveTriple.isRISCV()) {
3648+
if (EffectiveTriple.isRISCV() || EffectiveTriple.isPPC()) {
36493649
if (Value != "tls" && Value != "global") {
36503650
D.Diag(diag::err_drv_invalid_value_with_suggestion)
36513651
<< A->getOption().getName() << Value << "tls global";
@@ -3666,7 +3666,7 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
36663666
StringRef Value = A->getValue();
36673667
if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
36683668
!EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
3669-
!EffectiveTriple.isRISCV())
3669+
!EffectiveTriple.isRISCV() && !EffectiveTriple.isPPC())
36703670
D.Diag(diag::err_drv_unsupported_opt_for_target)
36713671
<< A->getAsString(Args) << TripleStr;
36723672
int Offset;
@@ -3686,7 +3686,7 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
36863686
if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_reg_EQ)) {
36873687
StringRef Value = A->getValue();
36883688
if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
3689-
!EffectiveTriple.isRISCV())
3689+
!EffectiveTriple.isRISCV() && !EffectiveTriple.isPPC())
36903690
D.Diag(diag::err_drv_unsupported_opt_for_target)
36913691
<< A->getAsString(Args) << TripleStr;
36923692
if (EffectiveTriple.isX86() && (Value != "fs" && Value != "gs")) {
@@ -3703,6 +3703,16 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
37033703
<< A->getOption().getName() << Value << "tp";
37043704
return;
37053705
}
3706+
if (EffectiveTriple.isPPC64() && Value != "r13") {
3707+
D.Diag(diag::err_drv_invalid_value_with_suggestion)
3708+
<< A->getOption().getName() << Value << "r13";
3709+
return;
3710+
}
3711+
if (EffectiveTriple.isPPC32() && Value != "r2") {
3712+
D.Diag(diag::err_drv_invalid_value_with_suggestion)
3713+
<< A->getOption().getName() << Value << "r2";
3714+
return;
3715+
}
37063716
A->render(Args, CmdArgs);
37073717
}
37083718

llvm/lib/Target/PowerPC/PPCISelLowering.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17913,6 +17913,26 @@ Value *PPCTargetLowering::getSDagStackGuard(const Module &M) const {
1791317913
return TargetLowering::getSDagStackGuard(M);
1791417914
}
1791517915

17916+
static Value *useTpOffset(IRBuilderBase &IRB, unsigned Offset) {
17917+
Module *M = IRB.GetInsertBlock()->getModule();
17918+
Function *ThreadPointerFunc =
17919+
Intrinsic::getDeclaration(M, Intrinsic::thread_pointer);
17920+
return IRB.CreateConstGEP1_32(IRB.getInt8Ty(),
17921+
IRB.CreateCall(ThreadPointerFunc), Offset);
17922+
}
17923+
17924+
Value *PPCTargetLowering::getIRStackGuard(IRBuilderBase &IRB) const {
17925+
Module *M = IRB.GetInsertBlock()->getModule();
17926+
17927+
if (M->getStackProtectorGuard() == "tls") {
17928+
// Specially, some users may customize the base reg and offset.
17929+
int Offset = M->getStackProtectorGuardOffset();
17930+
return useTpOffset(IRB, Offset);
17931+
}
17932+
17933+
return TargetLowering::getIRStackGuard(IRB);
17934+
}
17935+
1791617936
bool PPCTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
1791717937
bool ForCodeSize) const {
1791817938
if (!VT.isSimple() || !Subtarget.hasVSX())

llvm/lib/Target/PowerPC/PPCISelLowering.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1140,6 +1140,7 @@ namespace llvm {
11401140
bool useLoadStackGuardNode() const override;
11411141
void insertSSPDeclarations(Module &M) const override;
11421142
Value *getSDagStackGuard(const Module &M) const override;
1143+
Value *getIRStackGuard(IRBuilderBase &IRB) const override;
11431144

11441145
bool isFPImmLegal(const APFloat &Imm, EVT VT,
11451146
bool ForCodeSize) const override;

llvm/lib/Target/PowerPC/PPCInstrInfo.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "llvm/CodeGen/ScheduleDAG.h"
3636
#include "llvm/CodeGen/SlotIndexes.h"
3737
#include "llvm/CodeGen/StackMaps.h"
38+
#include "llvm/IR/Module.h"
3839
#include "llvm/MC/MCAsmInfo.h"
3940
#include "llvm/MC/MCInst.h"
4041
#include "llvm/MC/TargetRegistry.h"
@@ -3107,6 +3108,11 @@ bool PPCInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
31073108
return true;
31083109
}
31093110
case TargetOpcode::LOAD_STACK_GUARD: {
3111+
const Module *M = MI.getParent()->getBasicBlock()->getModule();
3112+
if (M->getStackProtectorGuard() == "tls") {
3113+
MI.setDesc(get(PPC::UNENCODED_NOP));
3114+
return true;
3115+
}
31103116
assert(Subtarget.isTargetLinux() &&
31113117
"Only Linux target is expected to contain LOAD_STACK_GUARD");
31123118
const int64_t Offset = Subtarget.isPPC64() ? -0x7010 : -0x7008;

0 commit comments

Comments
 (0)