1 //===------- ShadowCallStack.cpp - Shadow Call Stack pass -----------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // The ShadowCallStack pass instruments function prologs/epilogs to check that
11 // the return address has not been corrupted during the execution of the
12 // function. The return address is stored in a 'shadow call stack' addressed
13 // using the %gs segment register.
15 //===----------------------------------------------------------------------===//
18 #include "X86InstrBuilder.h"
19 #include "X86InstrInfo.h"
20 #include "X86Subtarget.h"
22 #include "llvm/CodeGen/MachineFunction.h"
23 #include "llvm/CodeGen/MachineFunctionPass.h"
24 #include "llvm/CodeGen/MachineInstrBuilder.h"
25 #include "llvm/CodeGen/MachineModuleInfo.h"
26 #include "llvm/CodeGen/MachineRegisterInfo.h"
27 #include "llvm/CodeGen/Passes.h"
28 #include "llvm/CodeGen/TargetInstrInfo.h"
29 #include "llvm/Pass.h"
30 #include "llvm/Support/raw_ostream.h"
35 void initializeShadowCallStackPass(PassRegistry
&);
40 class ShadowCallStack
: public MachineFunctionPass
{
44 ShadowCallStack() : MachineFunctionPass(ID
) {
45 initializeShadowCallStackPass(*PassRegistry::getPassRegistry());
48 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
49 MachineFunctionPass::getAnalysisUsage(AU
);
52 bool runOnMachineFunction(MachineFunction
&Fn
) override
;
55 // Do not instrument leaf functions with this many or fewer instructions. The
56 // shadow call stack instrumented prolog/epilog are slightly race-y reading
57 // and checking the saved return address, so it is better to not instrument
58 // functions that have fewer instructions than the instrumented prolog/epilog
60 static const size_t SkipLeafInstructions
= 3;
63 char ShadowCallStack::ID
= 0;
64 } // end anonymous namespace.
66 static void addProlog(MachineFunction
&Fn
, const TargetInstrInfo
*TII
,
67 MachineBasicBlock
&MBB
, const DebugLoc
&DL
);
68 static void addPrologLeaf(MachineFunction
&Fn
, const TargetInstrInfo
*TII
,
69 MachineBasicBlock
&MBB
, const DebugLoc
&DL
,
70 MCPhysReg FreeRegister
);
72 static void addEpilog(const TargetInstrInfo
*TII
, MachineBasicBlock
&MBB
,
73 MachineInstr
&MI
, MachineBasicBlock
&TrapBB
);
74 static void addEpilogLeaf(const TargetInstrInfo
*TII
, MachineBasicBlock
&MBB
,
75 MachineInstr
&MI
, MachineBasicBlock
&TrapBB
,
76 MCPhysReg FreeRegister
);
77 // Generate a longer epilog that only uses r10 when a tailcall branches to r11.
78 static void addEpilogOnlyR10(const TargetInstrInfo
*TII
, MachineBasicBlock
&MBB
,
79 MachineInstr
&MI
, MachineBasicBlock
&TrapBB
);
81 // Helper function to add ModR/M references for [Seg: Reg + Offset] memory
83 static inline const MachineInstrBuilder
&
84 addSegmentedMem(const MachineInstrBuilder
&MIB
, MCPhysReg Seg
, MCPhysReg Reg
,
86 return MIB
.addReg(Reg
).addImm(1).addReg(0).addImm(Offset
).addReg(Seg
);
89 static void addProlog(MachineFunction
&Fn
, const TargetInstrInfo
*TII
,
90 MachineBasicBlock
&MBB
, const DebugLoc
&DL
) {
91 const MCPhysReg ReturnReg
= X86::R10
;
92 const MCPhysReg OffsetReg
= X86::R11
;
94 auto MBBI
= MBB
.begin();
96 addDirectMem(BuildMI(MBB
, MBBI
, DL
, TII
->get(X86::MOV64rm
)).addDef(ReturnReg
),
99 BuildMI(MBB
, MBBI
, DL
, TII
->get(X86::XOR64rr
))
101 .addReg(OffsetReg
, RegState::Undef
)
102 .addReg(OffsetReg
, RegState::Undef
);
103 // add QWORD [gs:r11], 8
104 addSegmentedMem(BuildMI(MBB
, MBBI
, DL
, TII
->get(X86::ADD64mi8
)), X86::GS
,
109 BuildMI(MBB
, MBBI
, DL
, TII
->get(X86::MOV64rm
)).addDef(OffsetReg
), X86::GS
,
112 addSegmentedMem(BuildMI(MBB
, MBBI
, DL
, TII
->get(X86::MOV64mr
)), X86::GS
,
117 static void addPrologLeaf(MachineFunction
&Fn
, const TargetInstrInfo
*TII
,
118 MachineBasicBlock
&MBB
, const DebugLoc
&DL
,
119 MCPhysReg FreeRegister
) {
121 addDirectMem(BuildMI(MBB
, MBB
.begin(), DL
, TII
->get(X86::MOV64rm
))
122 .addDef(FreeRegister
),
126 static void addEpilog(const TargetInstrInfo
*TII
, MachineBasicBlock
&MBB
,
127 MachineInstr
&MI
, MachineBasicBlock
&TrapBB
) {
128 const DebugLoc
&DL
= MI
.getDebugLoc();
131 BuildMI(MBB
, MI
, DL
, TII
->get(X86::XOR64rr
))
133 .addReg(X86::R11
, RegState::Undef
)
134 .addReg(X86::R11
, RegState::Undef
);
136 addSegmentedMem(BuildMI(MBB
, MI
, DL
, TII
->get(X86::MOV64rm
)).addDef(X86::R10
),
139 addSegmentedMem(BuildMI(MBB
, MI
, DL
, TII
->get(X86::MOV64rm
)).addDef(X86::R10
),
141 // sub QWORD [gs:r11], 8
142 // This instruction should not be moved up to avoid a signal race.
143 addSegmentedMem(BuildMI(MBB
, MI
, DL
, TII
->get(X86::SUB64mi8
)),
147 addDirectMem(BuildMI(MBB
, MI
, DL
, TII
->get(X86::CMP64mr
)), X86::RSP
)
150 BuildMI(MBB
, MI
, DL
, TII
->get(X86::JNE_1
)).addMBB(&TrapBB
);
151 MBB
.addSuccessor(&TrapBB
);
154 static void addEpilogLeaf(const TargetInstrInfo
*TII
, MachineBasicBlock
&MBB
,
155 MachineInstr
&MI
, MachineBasicBlock
&TrapBB
,
156 MCPhysReg FreeRegister
) {
157 const DebugLoc
&DL
= MI
.getDebugLoc();
160 addDirectMem(BuildMI(MBB
, MI
, DL
, TII
->get(X86::CMP64mr
)), X86::RSP
)
161 .addReg(FreeRegister
);
163 BuildMI(MBB
, MI
, DL
, TII
->get(X86::JNE_1
)).addMBB(&TrapBB
);
164 MBB
.addSuccessor(&TrapBB
);
167 static void addEpilogOnlyR10(const TargetInstrInfo
*TII
, MachineBasicBlock
&MBB
,
168 MachineInstr
&MI
, MachineBasicBlock
&TrapBB
) {
169 const DebugLoc
&DL
= MI
.getDebugLoc();
172 BuildMI(MBB
, MI
, DL
, TII
->get(X86::XOR64rr
))
174 .addReg(X86::R10
, RegState::Undef
)
175 .addReg(X86::R10
, RegState::Undef
);
177 addSegmentedMem(BuildMI(MBB
, MI
, DL
, TII
->get(X86::MOV64rm
)).addDef(X86::R10
),
180 addSegmentedMem(BuildMI(MBB
, MI
, DL
, TII
->get(X86::MOV64rm
)).addDef(X86::R10
),
182 // sub QWORD [gs:0], 8
183 // This instruction should not be moved up to avoid a signal race.
184 addSegmentedMem(BuildMI(MBB
, MI
, DL
, TII
->get(X86::SUB64mi8
)), X86::GS
, 0)
187 addDirectMem(BuildMI(MBB
, MI
, DL
, TII
->get(X86::CMP64mr
)), X86::RSP
)
190 BuildMI(MBB
, MI
, DL
, TII
->get(X86::JNE_1
)).addMBB(&TrapBB
);
191 MBB
.addSuccessor(&TrapBB
);
194 bool ShadowCallStack::runOnMachineFunction(MachineFunction
&Fn
) {
195 if (!Fn
.getFunction().hasFnAttribute(Attribute::ShadowCallStack
) ||
196 Fn
.getFunction().hasFnAttribute(Attribute::Naked
))
199 if (Fn
.empty() || !Fn
.getRegInfo().tracksLiveness())
202 // FIXME: Skip functions that have r10 or r11 live on entry (r10 can be live
203 // on entry for parameters with the nest attribute.)
204 if (Fn
.front().isLiveIn(X86::R10
) || Fn
.front().isLiveIn(X86::R11
))
207 // FIXME: Skip functions with conditional and r10 tail calls for now.
208 bool HasReturn
= false;
209 for (auto &MBB
: Fn
) {
213 const MachineInstr
&MI
= MBB
.instr_back();
217 if (MI
.isReturn() && MI
.isCall()) {
218 if (MI
.findRegisterUseOperand(X86::EFLAGS
))
220 // This should only be possible on Windows 64 (see GR64_TC versus
222 if (MI
.findRegisterUseOperand(X86::R10
) ||
223 MI
.hasRegisterImplicitUseOperand(X86::R10
))
231 // For leaf functions:
232 // 1. Do not instrument very short functions where it would not improve that
233 // function's security.
234 // 2. Detect if there is an unused caller-saved register we can reserve to
235 // hold the return address instead of writing/reading it from the shadow
237 MCPhysReg LeafFuncRegister
= X86::NoRegister
;
238 if (!Fn
.getFrameInfo().adjustsStack()) {
239 size_t InstructionCount
= 0;
240 std::bitset
<X86::NUM_TARGET_REGS
> UsedRegs
;
241 for (auto &MBB
: Fn
) {
242 for (auto &LiveIn
: MBB
.liveins())
243 UsedRegs
.set(LiveIn
.PhysReg
);
244 for (auto &MI
: MBB
) {
245 if (!MI
.isDebugValue() && !MI
.isCFIInstruction() && !MI
.isLabel())
247 for (auto &Op
: MI
.operands())
248 if (Op
.isReg() && Op
.isDef())
249 UsedRegs
.set(Op
.getReg());
253 if (InstructionCount
<= SkipLeafInstructions
)
256 std::bitset
<X86::NUM_TARGET_REGS
> CalleeSavedRegs
;
257 const MCPhysReg
*CSRegs
= Fn
.getRegInfo().getCalleeSavedRegs();
258 for (size_t i
= 0; CSRegs
[i
]; i
++)
259 CalleeSavedRegs
.set(CSRegs
[i
]);
261 const TargetRegisterInfo
*TRI
= Fn
.getSubtarget().getRegisterInfo();
262 for (auto &Reg
: X86::GR64_NOSPRegClass
.getRegisters()) {
263 // FIXME: Optimization opportunity: spill/restore a callee-saved register
264 // if a caller-saved register is unavailable.
265 if (CalleeSavedRegs
.test(Reg
))
269 for (MCSubRegIterator
SR(Reg
, TRI
, true); SR
.isValid(); ++SR
)
270 if ((Used
= UsedRegs
.test(*SR
)))
274 LeafFuncRegister
= Reg
;
280 const bool LeafFuncOptimization
= LeafFuncRegister
!= X86::NoRegister
;
281 if (LeafFuncOptimization
)
282 // Mark the leaf function register live-in for all MBBs except the entry MBB
283 for (auto I
= ++Fn
.begin(), E
= Fn
.end(); I
!= E
; ++I
)
284 I
->addLiveIn(LeafFuncRegister
);
286 MachineBasicBlock
&MBB
= Fn
.front();
287 const MachineBasicBlock
*NonEmpty
= MBB
.empty() ? MBB
.getFallThrough() : &MBB
;
288 const DebugLoc
&DL
= NonEmpty
->front().getDebugLoc();
290 const TargetInstrInfo
*TII
= Fn
.getSubtarget().getInstrInfo();
291 if (LeafFuncOptimization
)
292 addPrologLeaf(Fn
, TII
, MBB
, DL
, LeafFuncRegister
);
294 addProlog(Fn
, TII
, MBB
, DL
);
296 MachineBasicBlock
*Trap
= nullptr;
297 for (auto &MBB
: Fn
) {
301 MachineInstr
&MI
= MBB
.instr_back();
304 Trap
= Fn
.CreateMachineBasicBlock();
305 BuildMI(Trap
, MI
.getDebugLoc(), TII
->get(X86::TRAP
));
309 if (LeafFuncOptimization
)
310 addEpilogLeaf(TII
, MBB
, MI
, *Trap
, LeafFuncRegister
);
311 else if (MI
.findRegisterUseOperand(X86::R11
))
312 addEpilogOnlyR10(TII
, MBB
, MI
, *Trap
);
314 addEpilog(TII
, MBB
, MI
, *Trap
);
321 INITIALIZE_PASS(ShadowCallStack
, "shadow-call-stack", "Shadow Call Stack",
324 FunctionPass
*llvm::createShadowCallStackPass() {
325 return new ShadowCallStack();