1- // ======- X86RetpolineThunks .cpp - Construct retpoline thunks for x86 --==== =//
1+ // ==- X86IndirectThunks .cpp - Construct indirect call/jump thunks for x86 --=//
22//
33// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44// See https://llvm.org/LICENSE.txt for license information.
77// ===----------------------------------------------------------------------===//
88// / \file
99// /
10- // / Pass that injects an MI thunk implementing a "retpoline". This is
11- // / a RET-implemented trampoline that is used to lower indirect calls in a way
10+ // / Pass that injects an MI thunk that is used to lower indirect calls in a way
1211// / that prevents speculation on some x86 processors and can be used to mitigate
1312// / security vulnerabilities due to targeted speculative execution and side
1413// / channels such as CVE-2017-5715.
1514// /
15+ // / Currently supported thunks include:
16+ // / - Retpoline -- A RET-implemented trampoline that lowers indirect calls
17+ // /
18+ // / Note that the reason that this is implemented as a MachineFunctionPass and
19+ // / not a ModulePass is that ModulePasses at this point in the LLVM X86 pipeline
20+ // / serialize all transformations, which can consume lots of memory.
21+ // /
1622// / TODO(chandlerc): All of this code could use better comments and
1723// / documentation.
1824// /
@@ -37,21 +43,21 @@ using namespace llvm;
3743
3844#define DEBUG_TYPE " x86-retpoline-thunks"
3945
40- static const char ThunkNamePrefix [] = " __llvm_retpoline_" ;
41- static const char R11ThunkName [] = " __llvm_retpoline_r11" ;
42- static const char EAXThunkName [] = " __llvm_retpoline_eax" ;
43- static const char ECXThunkName [] = " __llvm_retpoline_ecx" ;
44- static const char EDXThunkName [] = " __llvm_retpoline_edx" ;
45- static const char EDIThunkName [] = " __llvm_retpoline_edi" ;
46+ static const char RetpolineNamePrefix [] = " __llvm_retpoline_" ;
47+ static const char R11RetpolineName [] = " __llvm_retpoline_r11" ;
48+ static const char EAXRetpolineName [] = " __llvm_retpoline_eax" ;
49+ static const char ECXRetpolineName [] = " __llvm_retpoline_ecx" ;
50+ static const char EDXRetpolineName [] = " __llvm_retpoline_edx" ;
51+ static const char EDIRetpolineName [] = " __llvm_retpoline_edi" ;
4652
4753namespace {
48- class X86RetpolineThunks : public MachineFunctionPass {
54+ class X86IndirectThunks : public MachineFunctionPass {
4955public:
5056 static char ID;
5157
52- X86RetpolineThunks () : MachineFunctionPass(ID) {}
58+ X86IndirectThunks () : MachineFunctionPass(ID) {}
5359
54- StringRef getPassName () const override { return " X86 Retpoline Thunks" ; }
60+ StringRef getPassName () const override { return " X86 Indirect Thunks" ; }
5561
5662 bool doInitialization (Module &M) override ;
5763 bool runOnMachineFunction (MachineFunction &F) override ;
@@ -72,24 +78,24 @@ class X86RetpolineThunks : public MachineFunctionPass {
7278 bool InsertedThunks = false ;
7379
7480 void createThunkFunction (Module &M, StringRef Name);
75- void insertRegReturnAddrClobber (MachineBasicBlock &MBB, unsigned Reg);
76- void populateThunk (MachineFunction &MF, unsigned Reg);
81+ void insertRegReturnAddrClobber (MachineBasicBlock &MBB, Register Reg);
82+ void populateThunk (MachineFunction &MF, Register Reg);
7783};
7884
7985} // end anonymous namespace
8086
81- FunctionPass *llvm::createX86RetpolineThunksPass () {
82- return new X86RetpolineThunks ();
87+ FunctionPass *llvm::createX86IndirectThunksPass () {
88+ return new X86IndirectThunks ();
8389}
8490
85- char X86RetpolineThunks ::ID = 0 ;
91+ char X86IndirectThunks ::ID = 0 ;
8692
87- bool X86RetpolineThunks ::doInitialization (Module &M) {
93+ bool X86IndirectThunks ::doInitialization (Module &M) {
8894 InsertedThunks = false ;
8995 return false ;
9096}
9197
92- bool X86RetpolineThunks ::runOnMachineFunction (MachineFunction &MF) {
98+ bool X86IndirectThunks ::runOnMachineFunction (MachineFunction &MF) {
9399 LLVM_DEBUG (dbgs () << getPassName () << ' \n ' );
94100
95101 TM = &MF.getTarget ();;
@@ -102,7 +108,7 @@ bool X86RetpolineThunks::runOnMachineFunction(MachineFunction &MF) {
102108
103109 // If this function is not a thunk, check to see if we need to insert
104110 // a thunk.
105- if (!MF.getName ().startswith (ThunkNamePrefix )) {
111+ if (!MF.getName ().startswith (RetpolineNamePrefix )) {
106112 // If we've already inserted a thunk, nothing else to do.
107113 if (InsertedThunks)
108114 return false ;
@@ -124,10 +130,11 @@ bool X86RetpolineThunks::runOnMachineFunction(MachineFunction &MF) {
124130 // pass. We extract the module and insert a new function (and machine
125131 // function) directly into the module.
126132 if (Is64Bit)
127- createThunkFunction (M, R11ThunkName );
133+ createThunkFunction (M, R11RetpolineName );
128134 else
129135 for (StringRef Name :
130- {EAXThunkName, ECXThunkName, EDXThunkName, EDIThunkName})
136+ {EAXRetpolineName, ECXRetpolineName, EDXRetpolineName,
137+ EDIRetpolineName})
131138 createThunkFunction (M, Name);
132139 InsertedThunks = true ;
133140 return true ;
@@ -177,13 +184,13 @@ bool X86RetpolineThunks::runOnMachineFunction(MachineFunction &MF) {
177184 // ... # Same setup
178185 // movl %edi, (%esp)
179186 // retl
180- if (MF.getName () == EAXThunkName )
187+ if (MF.getName () == EAXRetpolineName )
181188 populateThunk (MF, X86::EAX);
182- else if (MF.getName () == ECXThunkName )
189+ else if (MF.getName () == ECXRetpolineName )
183190 populateThunk (MF, X86::ECX);
184- else if (MF.getName () == EDXThunkName )
191+ else if (MF.getName () == EDXRetpolineName )
185192 populateThunk (MF, X86::EDX);
186- else if (MF.getName () == EDIThunkName )
193+ else if (MF.getName () == EDIRetpolineName )
187194 populateThunk (MF, X86::EDI);
188195 else
189196 llvm_unreachable (" Invalid thunk name on x86-32!" );
@@ -192,8 +199,8 @@ bool X86RetpolineThunks::runOnMachineFunction(MachineFunction &MF) {
192199 return true ;
193200}
194201
195- void X86RetpolineThunks ::createThunkFunction (Module &M, StringRef Name) {
196- assert (Name.startswith (ThunkNamePrefix ) &&
202+ void X86IndirectThunks ::createThunkFunction (Module &M, StringRef Name) {
203+ assert (Name.startswith (RetpolineNamePrefix ) &&
197204 " Created a thunk with an unexpected prefix!" );
198205
199206 LLVMContext &Ctx = M.getContext ();
@@ -226,16 +233,16 @@ void X86RetpolineThunks::createThunkFunction(Module &M, StringRef Name) {
226233 MF.insert (MF.end (), EntryMBB);
227234}
228235
229- void X86RetpolineThunks ::insertRegReturnAddrClobber (MachineBasicBlock &MBB,
230- unsigned Reg) {
236+ void X86IndirectThunks ::insertRegReturnAddrClobber (MachineBasicBlock &MBB,
237+ Register Reg) {
231238 const unsigned MovOpc = Is64Bit ? X86::MOV64mr : X86::MOV32mr;
232- const unsigned SPReg = Is64Bit ? X86::RSP : X86::ESP;
239+ const Register SPReg = Is64Bit ? X86::RSP : X86::ESP;
233240 addRegOffset (BuildMI (&MBB, DebugLoc (), TII->get (MovOpc)), SPReg, false , 0 )
234241 .addReg (Reg);
235242}
236243
237- void X86RetpolineThunks ::populateThunk (MachineFunction &MF,
238- unsigned Reg) {
244+ void X86IndirectThunks ::populateThunk (MachineFunction &MF,
245+ Register Reg) {
239246 // Set MF properties. We never use vregs...
240247 MF.getProperties ().set (MachineFunctionProperties::Property::NoVRegs);
241248
@@ -246,8 +253,10 @@ void X86RetpolineThunks::populateThunk(MachineFunction &MF,
246253 while (MF.size () > 1 )
247254 MF.erase (std::next (MF.begin ()));
248255
249- MachineBasicBlock *CaptureSpec = MF.CreateMachineBasicBlock (Entry->getBasicBlock ());
250- MachineBasicBlock *CallTarget = MF.CreateMachineBasicBlock (Entry->getBasicBlock ());
256+ MachineBasicBlock *CaptureSpec =
257+ MF.CreateMachineBasicBlock (Entry->getBasicBlock ());
258+ MachineBasicBlock *CallTarget =
259+ MF.CreateMachineBasicBlock (Entry->getBasicBlock ());
251260 MCSymbol *TargetSym = MF.getContext ().createTempSymbol ();
252261 MF.push_back (CaptureSpec);
253262 MF.push_back (CallTarget);
0 commit comments