xref: /openbsd-src/gnu/llvm/llvm/lib/Target/X86/X86FixupGadgets.cpp (revision a96b36398fcfb4953e8190127da8bf074c7552f1)
1 //===-- X86FixupGadgets.cpp - Fixup Instructions that make ROP Gadgets ----===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 /// \file
10 /// This file defines a function pass that checks instructions for sequences
11 /// that will lower to a potentially useful ROP gadget, and attempts to
12 /// replace those sequences with alternatives that are not useful for ROP.
13 ///
14 //===----------------------------------------------------------------------===//
15 
16 #include "X86.h"
17 #include "X86InstrBuilder.h"
18 #include "X86InstrInfo.h"
19 #include "X86MachineFunctionInfo.h"
20 #include "X86Subtarget.h"
21 #include "X86TargetMachine.h"
22 #include "llvm/CodeGen/MachineFunction.h"
23 #include "llvm/CodeGen/MachineFunctionPass.h"
24 #include "llvm/CodeGen/MachineInstrBuilder.h"
25 #include "llvm/CodeGen/MachineRegisterInfo.h"
26 #include "llvm/CodeGen/Passes.h"
27 #include "llvm/MC/MCAsmInfo.h"
28 #include "llvm/MC/MCSymbol.h"
29 #include "llvm/Support/Debug.h"
30 #include "llvm/Support/raw_ostream.h"
31 using namespace llvm;
32 
33 #define FIXUPGADGETS_DESC "X86 ROP Gadget Fixup"
34 #define FIXUPGADGETS_NAME "x86-fixup-gadgets"
35 
36 #define DEBUG_TYPE FIXUPGADGETS_NAME
37 
38 // Toggle with cc1 option: -mllvm -x86-fixup-gadgets=<true|false>
39 static cl::opt<bool> FixupGadgets(
40     "x86-fixup-gadgets", cl::Hidden,
41     cl::desc("Replace ROP friendly instructions with safe alternatives"),
42     cl::init(true));
43 
44 namespace {
45 class FixupGadgetsPass : public MachineFunctionPass {
46 
47 public:
48   static char ID;
49 
getPassName() const50   StringRef getPassName() const override { return FIXUPGADGETS_DESC; }
51 
FixupGadgetsPass()52   FixupGadgetsPass()
53       : MachineFunctionPass(ID), STI(nullptr), TII(nullptr), TRI(nullptr) {}
54 
55   /// Loop over all the instructions and replace ROP friendly
56   /// seuqences with less ROP friendly alternatives
57   bool runOnMachineFunction(MachineFunction &MF) override;
58 
getRequiredProperties() const59   MachineFunctionProperties getRequiredProperties() const override {
60     return MachineFunctionProperties().set(
61         MachineFunctionProperties::Property::NoVRegs);
62   }
63 
64 private:
65   const X86Subtarget *STI;
66   const X86InstrInfo *TII;
67   const X86RegisterInfo *TRI;
68   bool Is64Bit;
69 
70   struct FixupInfo {
71     unsigned op1;
72     unsigned op2;
73     bool fixup;
74     bool align;
75   };
76 
77   uint8_t getRegNum(const MachineOperand &MO) const;
78   uint8_t getRegNum(unsigned reg) const;
79   struct FixupInfo isROPFriendly(MachineInstr &MI) const;
80   bool isROPFriendlyImm(const MachineOperand &MO) const;
81   bool isROPFriendlyRegPair(const MachineOperand &Dst,
82                             const MachineOperand &Src) const;
83   bool isROPFriendlyReg(const MachineOperand &Dst, uint8_t RegOpcode) const;
84   bool badModRM(uint8_t Mod, uint8_t RegOpcode, uint8_t RM) const;
85   void checkSIB(const MachineInstr &MI, unsigned CurOp,
86                 struct FixupInfo &info) const;
87   bool needsFixup(struct FixupInfo &fi) const;
88   bool needsAlign(struct FixupInfo &fi) const;
89   unsigned getWidestRegForReg(unsigned reg) const;
90   unsigned getEquivalentRegForReg(unsigned oreg, unsigned nreg) const;
91   bool hasImplicitUseOrDef(const MachineInstr &MI, unsigned Reg1,
92                            unsigned Reg2) const;
93   bool fixupWithoutExchange(MachineInstr &MI);
94 
95   bool fixupInstruction(MachineFunction &MF, MachineBasicBlock &MBB,
96                         MachineInstr &MI, struct FixupInfo Info);
97 };
98 char FixupGadgetsPass::ID = 0;
99 } // namespace
100 
createX86FixupGadgetsPass()101 FunctionPass *llvm::createX86FixupGadgetsPass() {
102   return new FixupGadgetsPass();
103 }
104 
getRegNum(const MachineOperand & MO) const105 uint8_t FixupGadgetsPass::getRegNum(const MachineOperand &MO) const {
106   return TRI->getEncodingValue(MO.getReg()) & 0x7;
107 }
108 
getRegNum(unsigned reg) const109 uint8_t FixupGadgetsPass::getRegNum(unsigned reg) const {
110   return TRI->getEncodingValue(reg) & 0x7;
111 }
112 
isROPFriendlyImm(const MachineOperand & MO) const113 bool FixupGadgetsPass::isROPFriendlyImm(const MachineOperand &MO) const {
114   int64_t imm = MO.getImm();
115   for (int i = 0; i < 8; ++i) {
116     uint8_t byte = (imm & 0xff);
117     if (byte == 0xc2 || byte == 0xc3 || byte == 0xca || byte == 0xcb) {
118       return true;
119     }
120     imm = imm >> 8;
121   }
122   return false;
123 }
124 
isROPFriendlyRegPair(const MachineOperand & Dst,const MachineOperand & Src) const125 bool FixupGadgetsPass::isROPFriendlyRegPair(const MachineOperand &Dst,
126                                             const MachineOperand &Src) const {
127 
128   if (!Dst.isReg() || !Src.isReg())
129     llvm_unreachable("Testing non registers for bad reg pair!");
130 
131   uint8_t Mod = 3;
132   uint8_t RegOpcode = getRegNum(Src);
133   uint8_t RM = getRegNum(Dst);
134   return badModRM(Mod, RegOpcode, RM);
135 }
136 
isROPFriendlyReg(const MachineOperand & Dst,uint8_t RegOpcode) const137 bool FixupGadgetsPass::isROPFriendlyReg(const MachineOperand &Dst, uint8_t RegOpcode) const {
138 
139   if (!Dst.isReg())
140     llvm_unreachable("Testing non register for bad reg!");
141 
142   uint8_t Mod = 3;
143   uint8_t RM = getRegNum(Dst);
144   return badModRM(Mod, RegOpcode, RM);
145 }
146 
badModRM(uint8_t Mod,uint8_t RegOpcode,uint8_t RM) const147 bool FixupGadgetsPass::badModRM(uint8_t Mod, uint8_t RegOpcode,
148                                 uint8_t RM) const {
149   uint8_t ModRM = ((Mod << 6) | (RegOpcode << 3) | RM);
150   if (ModRM == 0xc2 || ModRM == 0xc3 || ModRM == 0xca || ModRM == 0xcb)
151     return true;
152   return false;
153 }
154 
checkSIB(const MachineInstr & MI,unsigned CurOp,struct FixupInfo & info) const155 void FixupGadgetsPass::checkSIB(const MachineInstr &MI, unsigned CurOp,
156                                 struct FixupInfo &info) const {
157 
158   const MachineOperand &Base = MI.getOperand(CurOp + X86::AddrBaseReg);
159   const MachineOperand &Scale = MI.getOperand(CurOp + X86::AddrScaleAmt);
160   const MachineOperand &Index = MI.getOperand(CurOp + X86::AddrIndexReg);
161 
162   if (!Scale.isImm() || !Base.isReg() || !Index.isReg())
163     llvm_unreachable("Wrong type operands");
164 
165   if (Scale.getImm() != 8 || Base.getReg() == 0 || Index.getReg() == 0)
166     return;
167 
168   if (badModRM(3, getRegNum(Index), getRegNum(Base))) {
169     info.op1 = CurOp + X86::AddrBaseReg;
170     info.op2 = CurOp + X86::AddrIndexReg;
171     info.fixup = true;
172   }
173 }
174 
175 struct FixupGadgetsPass::FixupInfo
isROPFriendly(MachineInstr & MI) const176 FixupGadgetsPass::isROPFriendly(MachineInstr &MI) const {
177 
178   const MCInstrDesc &Desc = MI.getDesc();
179   unsigned CurOp = X86II::getOperandBias(Desc);
180   uint64_t TSFlags = Desc.TSFlags;
181   uint64_t Form = TSFlags & X86II::FormMask;
182   bool HasVEX_4V = TSFlags & X86II::VEX_4V;
183   bool HasEVEX_K = TSFlags & X86II::EVEX_K;
184 
185   struct FixupInfo info = {0, 0, false, false};
186 
187   // Look for constants with c3 in them
188   for (const auto &MO : MI.operands()) {
189     if (MO.isImm() && isROPFriendlyImm(MO)) {
190       info.align = true;
191       break;
192     }
193   }
194 
195   switch (Form) {
196   case X86II::Pseudo: {
197     // Pesudos that are replaced with real instructions later
198     switch (MI.getOpcode()) {
199     case X86::ADD64rr_DB:
200     case X86::ADD32rr_DB:
201     case X86::ADD16rr_DB:
202       goto Handle_MRMDestReg;
203     case X86::ADD16ri_DB:
204     case X86::ADD32ri_DB:
205     case X86::ADD64ri32_DB:
206     case X86::ADD16ri8_DB:
207     case X86::ADD32ri8_DB:
208     case X86::ADD64ri8_DB:
209       goto Handle_MRMXr;
210     default:
211       break;
212     }
213     break;
214   }
215   case X86II::AddRegFrm: {
216     uint8_t BaseOpcode = X86II::getBaseOpcodeFor(TSFlags);
217     uint8_t Opcode = BaseOpcode + getRegNum(MI.getOperand(CurOp));
218     if (Opcode == 0xc2 || Opcode == 0xc3 || Opcode == 0xca || Opcode == 0xcb) {
219       info.op1 = CurOp;
220       info.fixup = true;
221     }
222     break;
223   }
224   case X86II::MRMDestMem: {
225     checkSIB(MI, CurOp, info);
226     unsigned opcode = MI.getOpcode();
227     if (opcode == X86::MOVNTImr || opcode == X86::MOVNTI_64mr)
228       info.align = true;
229     break;
230   }
231   case X86II::MRMSrcMem: {
232     CurOp += 1;
233     if (HasVEX_4V)
234       CurOp += 1;
235     if (HasEVEX_K)
236       CurOp += 1;
237     checkSIB(MI, CurOp, info);
238     break;
239   }
240   case X86II::MRMSrcMem4VOp3: {
241     CurOp += 1;
242     checkSIB(MI, CurOp, info);
243     break;
244   }
245   case X86II::MRMSrcMemOp4: {
246     CurOp += 3;
247     checkSIB(MI, CurOp, info);
248     break;
249   }
250   case X86II::MRMXm:
251   case X86II::MRM0m:
252   case X86II::MRM1m:
253   case X86II::MRM2m:
254   case X86II::MRM3m:
255   case X86II::MRM4m:
256   case X86II::MRM5m:
257   case X86II::MRM6m:
258   case X86II::MRM7m: {
259     if (HasVEX_4V)
260       CurOp += 1;
261     if (HasEVEX_K)
262       CurOp += 1;
263     checkSIB(MI, CurOp, info);
264     break;
265   }
266   case X86II::MRMDestReg: {
267   Handle_MRMDestReg:
268     const MachineOperand &DstReg = MI.getOperand(CurOp);
269     info.op1 = CurOp;
270     CurOp += 1;
271     if (HasVEX_4V)
272       CurOp += 1;
273     if (HasEVEX_K)
274       CurOp += 1;
275     const MachineOperand &SrcReg = MI.getOperand(CurOp);
276     info.op2 = CurOp;
277     if (isROPFriendlyRegPair(DstReg, SrcReg))
278       info.fixup = true;
279     break;
280   }
281   case X86II::MRMSrcReg: {
282     const MachineOperand &DstReg = MI.getOperand(CurOp);
283     info.op1 = CurOp;
284     CurOp += 1;
285     if (HasVEX_4V)
286       CurOp += 1;
287     if (HasEVEX_K)
288       CurOp += 1;
289     const MachineOperand &SrcReg = MI.getOperand(CurOp);
290     info.op2 = CurOp;
291     if (isROPFriendlyRegPair(SrcReg, DstReg))
292       info.fixup = true;
293     break;
294   }
295   case X86II::MRMSrcReg4VOp3: {
296     const MachineOperand &DstReg = MI.getOperand(CurOp);
297     info.op1 = CurOp;
298     CurOp += 1;
299     const MachineOperand &SrcReg = MI.getOperand(CurOp);
300     info.op2 = CurOp;
301     if (isROPFriendlyRegPair(SrcReg, DstReg))
302       info.fixup = true;
303     break;
304   }
305   case X86II::MRMSrcRegOp4: {
306     const MachineOperand &DstReg = MI.getOperand(CurOp);
307     info.op1 = CurOp;
308     CurOp += 3;
309     const MachineOperand &SrcReg = MI.getOperand(CurOp);
310     info.op2 = CurOp;
311     if (isROPFriendlyRegPair(SrcReg, DstReg))
312       info.fixup = true;
313     break;
314   }
315   case X86II::MRMXr:
316   case X86II::MRM0r:
317   case X86II::MRM1r: {
318 Handle_MRMXr:
319     if (HasVEX_4V)
320       CurOp += 1;
321     if (HasEVEX_K)
322       CurOp += 1;
323     const MachineOperand &DstReg = MI.getOperand(CurOp);
324     info.op1 = CurOp;
325     if (isROPFriendlyReg(DstReg, Form == X86II::MRM1r ? 1 : 0))
326       info.fixup = true;
327     break;
328   }
329   case X86II::MRM_C2:
330   case X86II::MRM_C3:
331   case X86II::MRM_CA:
332   case X86II::MRM_CB: {
333     info.align = true;
334     break;
335   }
336   default:
337     break;
338   }
339   return info;
340 }
341 
needsFixup(struct FixupInfo & fi) const342 bool FixupGadgetsPass::needsFixup(struct FixupInfo &fi) const {
343   return (fi.fixup == true);
344 }
345 
needsAlign(struct FixupInfo & fi) const346 bool FixupGadgetsPass::needsAlign(struct FixupInfo &fi) const {
347   return (fi.align == true);
348 }
349 
getWidestRegForReg(unsigned reg) const350 unsigned FixupGadgetsPass::getWidestRegForReg(unsigned reg) const {
351 
352   switch (reg) {
353   case X86::AL:
354   case X86::AH:
355   case X86::AX:
356   case X86::EAX:
357   case X86::RAX:
358     return Is64Bit ? X86::RAX : X86::EAX;
359   case X86::BL:
360   case X86::BH:
361   case X86::BX:
362   case X86::EBX:
363   case X86::RBX:
364     return Is64Bit ? X86::RBX : X86::EBX;
365   case X86::CL:
366   case X86::CH:
367   case X86::CX:
368   case X86::ECX:
369   case X86::RCX:
370     return Is64Bit ? X86::RCX : X86::ECX;
371   case X86::DL:
372   case X86::DH:
373   case X86::DX:
374   case X86::EDX:
375   case X86::RDX:
376     return Is64Bit ? X86::RDX : X86::EDX;
377   case X86::R8B:
378   case X86::R8W:
379   case X86::R8D:
380   case X86::R8:
381     return X86::R8;
382   case X86::R9B:
383   case X86::R9W:
384   case X86::R9D:
385   case X86::R9:
386     return X86::R9;
387   case X86::R10B:
388   case X86::R10W:
389   case X86::R10D:
390   case X86::R10:
391     return X86::R10;
392   case X86::R11B:
393   case X86::R11W:
394   case X86::R11D:
395   case X86::R11:
396     return X86::R11;
397   default:
398     return X86::NoRegister; // Non-GP Reg
399   }
400   return 0;
401 }
402 
403 // For given register oreg return the equivalent size register
404 // from the nreg register set. Eg. For oreg ebx and nreg ax, return eax.
getEquivalentRegForReg(unsigned oreg,unsigned nreg) const405 unsigned FixupGadgetsPass::getEquivalentRegForReg(unsigned oreg,
406                                                   unsigned nreg) const {
407   unsigned compreg = getWidestRegForReg(nreg);
408 
409   switch (oreg) {
410   case X86::AL:
411   case X86::BL:
412   case X86::CL:
413   case X86::DL:
414   case X86::R8B:
415   case X86::R9B:
416   case X86::R10B:
417   case X86::R11B:
418     switch (compreg) {
419     case X86::EAX:
420     case X86::RAX:
421       return X86::AL;
422     case X86::EBX:
423     case X86::RBX:
424       return X86::BL;
425     case X86::ECX:
426     case X86::RCX:
427       return X86::CL;
428     case X86::EDX:
429     case X86::RDX:
430       return X86::DL;
431     case X86::R8:
432       return X86::R8B;
433     case X86::R9:
434       return X86::R9B;
435     case X86::R10:
436       return X86::R10B;
437     case X86::R11:
438       return X86::R11B;
439     default:
440       llvm_unreachable("Unknown 8 bit register");
441     }
442     break;
443   case X86::AH:
444   case X86::BH:
445   case X86::CH:
446   case X86::DH:
447     switch (compreg) {
448     case X86::EAX:
449       return X86::AH;
450     case X86::EBX:
451       return X86::BH;
452     case X86::ECX:
453       return X86::CH;
454     case X86::EDX:
455       return X86::DH;
456     default:
457       llvm_unreachable("Using H registers in REX mode");
458     }
459     break;
460   case X86::AX:
461   case X86::BX:
462   case X86::CX:
463   case X86::DX:
464   case X86::R8W:
465   case X86::R9W:
466   case X86::R10W:
467   case X86::R11W:
468     switch (compreg) {
469     case X86::EAX:
470     case X86::RAX:
471       return X86::AX;
472     case X86::EBX:
473     case X86::RBX:
474       return X86::BX;
475     case X86::ECX:
476     case X86::RCX:
477       return X86::CX;
478     case X86::EDX:
479     case X86::RDX:
480       return X86::DX;
481     case X86::R8:
482       return X86::R8W;
483     case X86::R9:
484       return X86::R9W;
485     case X86::R10:
486       return X86::R10W;
487     case X86::R11:
488       return X86::R11W;
489     default:
490       llvm_unreachable("Unknown 16 bit register");
491     }
492     break;
493   case X86::EAX:
494   case X86::EBX:
495   case X86::ECX:
496   case X86::EDX:
497   case X86::R8D:
498   case X86::R9D:
499   case X86::R10D:
500   case X86::R11D:
501     switch (compreg) {
502     case X86::EAX:
503     case X86::RAX:
504       return X86::EAX;
505     case X86::EBX:
506     case X86::RBX:
507       return X86::EBX;
508     case X86::ECX:
509     case X86::RCX:
510       return X86::ECX;
511     case X86::EDX:
512     case X86::RDX:
513       return X86::EDX;
514     case X86::R8:
515       return X86::R8D;
516     case X86::R9:
517       return X86::R9D;
518     case X86::R10:
519       return X86::R10D;
520     case X86::R11:
521       return X86::R11D;
522     default:
523       llvm_unreachable("Unknown 32 bit register");
524     }
525     break;
526   case X86::RAX:
527   case X86::RBX:
528   case X86::RCX:
529   case X86::RDX:
530   case X86::R8:
531   case X86::R9:
532   case X86::R10:
533   case X86::R11:
534     return compreg;
535   default:
536     llvm_unreachable("Unknown input register!");
537   }
538 }
539 
hasImplicitUseOrDef(const MachineInstr & MI,unsigned Reg1,unsigned Reg2) const540 bool FixupGadgetsPass::hasImplicitUseOrDef(const MachineInstr &MI,
541                                            unsigned Reg1, unsigned Reg2) const {
542 
543   const MCInstrDesc &Desc = MI.getDesc();
544 
545   const ArrayRef<MCPhysReg> ImpDefs = Desc.implicit_defs();
546   for (MCPhysReg ImpDef : ImpDefs) {
547     unsigned w = getWidestRegForReg(ImpDef);
548     if (w == Reg1 || w == Reg2) {
549       return true;
550     }
551   }
552 
553   const ArrayRef<MCPhysReg> ImpUses = Desc.implicit_uses();
554   for (MCPhysReg ImpUse : ImpUses) {
555     unsigned w = getWidestRegForReg(ImpUse);
556     if (w == Reg1 || w == Reg2) {
557       return true;
558     }
559   }
560   return false;
561 }
562 
fixupWithoutExchange(MachineInstr & MI)563 bool FixupGadgetsPass::fixupWithoutExchange(MachineInstr &MI) {
564   switch (MI.getOpcode()) {
565     case X86::MOV8rr_REV:
566       MI.setDesc(TII->get(X86::MOV8rr));
567       break;
568     case X86::MOV16rr_REV:
569       MI.setDesc(TII->get(X86::MOV16rr));
570       break;
571     case X86::MOV32rr_REV:
572       MI.setDesc(TII->get(X86::MOV32rr));
573       break;
574     case X86::MOV64rr_REV:
575       MI.setDesc(TII->get(X86::MOV64rr));
576       break;
577     case X86::MOV8rr:
578       MI.setDesc(TII->get(X86::MOV8rr_REV));
579       break;
580     case X86::MOV16rr:
581       MI.setDesc(TII->get(X86::MOV16rr_REV));
582       break;
583     case X86::MOV32rr:
584       MI.setDesc(TII->get(X86::MOV32rr_REV));
585       break;
586     case X86::MOV64rr:
587       MI.setDesc(TII->get(X86::MOV64rr_REV));
588       break;
589     default:
590       return false;
591   }
592   return true;
593 }
594 
fixupInstruction(MachineFunction & MF,MachineBasicBlock & MBB,MachineInstr & MI,FixupInfo Info)595 bool FixupGadgetsPass::fixupInstruction(MachineFunction &MF,
596                                         MachineBasicBlock &MBB,
597                                         MachineInstr &MI, FixupInfo Info) {
598 
599   if (!needsAlign(Info) && !needsFixup(Info))
600     return false;
601 
602   DebugLoc DL = MI.getDebugLoc();
603 
604   // Check for only needs alignment
605   if (needsAlign(Info) && !needsFixup(Info)) {
606     BuildMI(MBB, MI, DL, TII->get(X86::JMP_TRAP));
607     return true;
608   }
609 
610   unsigned XCHG = Is64Bit ? X86::XCHG64rr : X86::XCHG32rr;
611 
612   unsigned OrigReg1 = MI.getOperand(Info.op1).getReg();
613   // Swap with RAX/EAX unless we have a second register to swap with
614   unsigned OrigReg2 = Is64Bit ? X86::RAX : X86::EAX;
615   if (Info.op2)
616     OrigReg2 = MI.getOperand(Info.op2).getReg();
617 
618   unsigned SwapReg1 = getWidestRegForReg(OrigReg1);
619   unsigned SwapReg2 = getWidestRegForReg(OrigReg2);
620   unsigned CompReg1 = SwapReg1;
621   unsigned CompReg2 = SwapReg2;
622 
623   // Just align if:
624   // - we have a non-GP reg to swap with
625   // - the instruction implicitly uses one of the registers we are swapping
626   // - if we are fixing an instruction that skips the xchg back
627   if (SwapReg1 == X86::NoRegister || SwapReg2 == X86::NoRegister ||
628       hasImplicitUseOrDef(MI, CompReg1, CompReg2) || MI.isCall() ||
629       MI.isReturn() || MI.isBranch() || MI.isIndirectBranch() ||
630       MI.isBarrier()) {
631     BuildMI(MBB, MI, DL, TII->get(X86::JMP_TRAP));
632     return true;
633   }
634 
635   // Make sure our XCHG doesn't make a gadget
636   if (badModRM(3, getRegNum(SwapReg1), getRegNum(SwapReg2))) {
637     unsigned treg = SwapReg1;
638     SwapReg1 = SwapReg2;
639     SwapReg2 = treg;
640   }
641 
642   // Check for specific instructions we can fix without the xchg dance
643   if (fixupWithoutExchange(MI)) {
644       return true;
645   }
646 
647   // Swap the two registers to start
648   BuildMI(MBB, MI, DL, TII->get(XCHG))
649       .addReg(SwapReg1, RegState::Define)
650       .addReg(SwapReg2, RegState::Define)
651       .addReg(SwapReg1).addReg(SwapReg2);
652 
653   // Check for needs alignment
654   if (needsAlign(Info))
655     BuildMI(MBB, MI, DL, TII->get(X86::JMP_TRAP));
656 
657   // Swap the registers inside the instruction
658   for (MachineOperand &MO : MI.operands()) {
659     if (!MO.isReg())
660       continue;
661 
662     unsigned reg = MO.getReg();
663     unsigned match = getWidestRegForReg(reg);
664     if (match == CompReg1)
665       MO.setReg(getEquivalentRegForReg(reg, OrigReg2));
666     else if (match == CompReg2)
667       MO.setReg(getEquivalentRegForReg(reg, OrigReg1));
668   }
669 
670   // And swap the two registers back
671   BuildMI(MBB, ++MachineBasicBlock::instr_iterator(MI), DL, TII->get(XCHG))
672       .addReg(SwapReg1, RegState::Define)
673       .addReg(SwapReg2, RegState::Define)
674       .addReg(SwapReg1).addReg(SwapReg2);
675 
676   return true;
677 }
678 
runOnMachineFunction(MachineFunction & MF)679 bool FixupGadgetsPass::runOnMachineFunction(MachineFunction &MF) {
680   if (!FixupGadgets)
681     return false;
682 
683   STI = &MF.getSubtarget<X86Subtarget>();
684   TII = STI->getInstrInfo();
685   TRI = STI->getRegisterInfo();
686   Is64Bit = STI->is64Bit();
687   std::vector<std::pair<MachineInstr *, FixupInfo>> fixups;
688   FixupInfo info;
689 
690   bool modified = false;
691 
692   for (auto &MBB : MF) {
693     fixups.clear();
694     for (auto &MI : MBB) {
695       info = isROPFriendly(MI);
696       if (needsAlign(info) || needsFixup(info))
697         fixups.push_back(std::make_pair(&MI, info));
698     }
699     for (auto &fixup : fixups)
700       modified |= fixupInstruction(MF, MBB, *fixup.first, fixup.second);
701   }
702 
703   return modified;
704 }
705