40 return Inst.
getOpcode() == X86::CALL64pcrel32;
92 return Reg == X86::NoRegister ||
93 getX86MCRegisterClass(X86::GR64RegClassID).contains(
Reg);
103void X86::X86MCLFIRewriter::rewriteSyscall(
const MCInst &Inst,
MCStreamer &Out,
105 Out.emitBundleLock(
false, STI);
111 MCInstBuilder(X86::LEA64r)
115 .addReg(X86::NoRegister)
117 .addReg(X86::NoRegister),
121 Out.emitInstruction(MCInstBuilder(X86::JMP64m)
124 .addReg(X86::NoRegister)
126 .addReg(X86::NoRegister),
129 Out.emitLabel(Symbol);
130 Out.emitBundleUnlock(STI);
135void X86::X86MCLFIRewriter::emitSandboxBranchReg(MCRegister
Reg,
137 const MCSubtargetInfo &STI) {
138 MCRegister Reg32 = RegInfo->getSubReg(
Reg, X86::sub_32bit);
140 Out.emitInstruction(MCInstBuilder(X86::AND32ri8)
173void X86::X86MCLFIRewriter::rewriteIndirectBranch(
const MCInst &Inst,
175 const MCSubtargetInfo &STI) {
182 MCInstBuilder Mov(X86::MOV64rm);
186 Mov.setLoc(Inst.
getLoc());
187 doRewriteInst(Mov, Out, STI);
192 return error(Inst,
"indirect branch through reserved register");
195 Out.emitBundleLock(isCall(Inst), STI);
197 emitSandboxBranchReg(Target, Out, STI);
200 MCInstBuilder(isCall(Inst) ? X86::CALL64r : X86::JMP64r).addReg(Target);
203 Out.emitInstruction(Branch, STI);
205 Out.emitBundleUnlock(STI);
210void X86::X86MCLFIRewriter::rewriteDirectCall(
const MCInst &Inst,
212 const MCSubtargetInfo &STI) {
213 Out.emitBundleLock(
true, STI);
214 Out.emitInstruction(Inst, STI);
215 Out.emitBundleUnlock(STI);
239void X86::X86MCLFIRewriter::rewriteReturn(
const MCInst &Inst, MCStreamer &Out,
240 const MCSubtargetInfo &STI) {
242 return error(Inst,
"unsupported return instruction");
249 doRewriteInst(MCInstBuilder(X86::ADD64ri32)
257 Out.emitBundleLock(
false, STI);
263 Out.emitBundleUnlock(STI);
273 .addReg(X86::NoRegister)
275 .addReg(X86::NoRegister),
279bool X86::X86MCLFIRewriter::isFSAccess(
const MCInst &Inst) {
280 return (mayLoad(Inst) || mayStore(Inst)) &&
302void X86::X86MCLFIRewriter::rewriteFSAccess(
const MCInst &Inst, MCStreamer &Out,
303 const MCSubtargetInfo &STI) {
309 bool HasBase =
BaseReg != X86::NoRegister;
310 bool HasIndex = IndexReg != X86::NoRegister;
315 if (!HasBase && !HasIndex && !HasDisp) {
324 BaseReg == X86::RSP || BaseReg == X86::RIP)
325 return error(Inst,
"unsupported addressing mode for %fs access");
334 if (
Desc.getNumDefs() > 0 &&
335 getX86MCRegisterClass(X86::GR64RegClassID).
contains(DestReg) &&
342 return error(Inst,
"%fs access reads reserved register %r11");
353 if (HasBase && HasIndex) {
354 Out.emitInstruction(MCInstBuilder(X86::LEA64r)
360 .addReg(X86::NoRegister),
373 if (HasBase && !HasIndex)
379void X86::X86MCLFIRewriter::doRewriteInst(
const MCInst &Inst, MCStreamer &Out,
380 const MCSubtargetInfo &STI) {
382 return error(Inst,
"LFI only supports 64-bit mode");
385 return error(Inst,
"illegal modification of reserved LFI register");
388 return rewriteSyscall(Inst, Out, STI);
391 return rewriteReturn(Inst, Out, STI);
394 return rewriteDirectCall(Inst, Out, STI);
398 return error(Inst,
"unsupported branch instruction");
400 if (isIndirectBranch(Inst) || isCall(Inst)) {
402 return error(Inst,
"unsupported indirect branch");
403 return rewriteIndirectBranch(Inst, Out, STI);
406 if (isFSAccess(Inst))
407 return rewriteFSAccess(Inst, Out, STI);
409 Out.emitInstruction(Inst, STI);
420 doRewriteInst(Inst, Out, STI);
static constexpr MCRegister LFIScratchReg
static bool isSyscall(const MCInst &Inst)
static constexpr MCRegister LFIBaseReg
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static MCDisassembler::DecodeStatus addOperand(MCInst &Inst, const MCOperand &Opnd)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
static bool isDirectCall(const MCInst &Inst)
static void emitTPLoad(MCRegister Reg, MCStreamer &Out, const MCSubtargetInfo &STI)
static bool hasNoTrackPrefix(const MCInst &Inst, const MCInstrInfo &InstInfo)
static bool isGR64OrNone(MCRegister Reg)
static bool isSupportedIndirectBranch(const MCInst &Inst)
static int findFSMemOperand(const MCInst &Inst, const MCInstrInfo &InstInfo)
static constexpr MCRegister LFITPReg
static constexpr int TPOffset
static bool isSyscall(const MCInst &Inst)
static bool readsRegister(const MCInst &Inst, const MCInstrDesc &Desc, MCRegister Reg, const MCRegisterInfo &RI)
Instances of this class represent a single low-level machine instruction.
unsigned getNumOperands() const
unsigned getFlags() const
unsigned getOpcode() const
const MCOperand & getOperand(unsigned i) const
Describe properties that are true of each instruction in the target description file.
Interface to description of machine instruction set.
Instances of this class represent operands of the MCInst class.
MCRegister getReg() const
Returns the register number.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
bool regsOverlap(MCRegister RegA, MCRegister RegB) const
Returns true if the two registers are equal or alias each other.
Wrapper class representing physical registers. Should be passed by value.
Streaming machine code generation interface.
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
A Use represents the edge between a Value definition and its users.
bool rewriteInst(const MCInst &Inst, MCStreamer &Out, const MCSubtargetInfo &STI) override
int getMemoryOperandIdx(const MCInstrDesc &Desc)
constexpr unsigned LFIBundleSize
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
DWARFExpression::Operation Op