Index: llvm/include/llvm/MC/MCInstrAnalysis.h =================================================================== --- llvm/include/llvm/MC/MCInstrAnalysis.h +++ llvm/include/llvm/MC/MCInstrAnalysis.h @@ -148,9 +148,14 @@ /// Given a branch instruction try to get the address the branch /// targets. Return true on success, and the address in Target. - virtual bool - evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size, - uint64_t &Target) const; + virtual bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size, + uint64_t &Target) const; + + /// Given an instruction tries to get the address of a memory operand. Returns + /// true on success, and the address in Target. + virtual bool evaluateMemoryOperandAddress(const MCInst &Inst, uint64_t Addr, + uint64_t Size, + uint64_t &Target) const; /// Returns (PLT virtual address, GOT virtual address) pairs for PLT entries. virtual std::vector> Index: llvm/lib/MC/MCInstrAnalysis.cpp =================================================================== --- llvm/lib/MC/MCInstrAnalysis.cpp +++ llvm/lib/MC/MCInstrAnalysis.cpp @@ -30,6 +30,12 @@ return false; int64_t Imm = Inst.getOperand(0).getImm(); - Target = Addr+Size+Imm; + Target = Addr + Size + Imm; return true; } + +bool MCInstrAnalysis::evaluateMemoryOperandAddress(const MCInst &Inst, + uint64_t Addr, uint64_t Size, + uint64_t &Target) const { + return false; +} Index: llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp =================================================================== --- llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp +++ llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp @@ -399,6 +399,9 @@ findPltEntries(uint64_t PltSectionVA, ArrayRef PltContents, uint64_t GotSectionVA, const Triple &TargetTriple) const override; + bool evaluateMemoryOperandAddress(const MCInst &Inst, uint64_t Addr, + uint64_t Size, + uint64_t &Target) const override; }; #define GET_STIPREDICATE_DEFS_FOR_MC_ANALYSIS @@ -511,7 +514,33 @@ return findX86_64PltEntries(PltSectionVA, PltContents); default: return {}; + } +} + +bool X86MCInstrAnalysis::evaluateMemoryOperandAddress(const MCInst &Inst, + uint64_t Addr, + uint64_t Size, + uint64_t &Target) const { + MCInstrDesc Opcode = Info->get(Inst.getOpcode()); + int MemOpStart = X86II::getMemoryOperandNo(Opcode.TSFlags); + if (MemOpStart == -1) + return false; + MemOpStart += X86II::getOperandBias(Opcode); + + const MCOperand &BaseReg = Inst.getOperand(MemOpStart + X86::AddrBaseReg); + const MCOperand &IndexReg = Inst.getOperand(MemOpStart + X86::AddrIndexReg); + const MCOperand &ScaleAmt = Inst.getOperand(MemOpStart + X86::AddrScaleAmt); + const MCOperand &Disp = Inst.getOperand(MemOpStart + X86::AddrDisp); + if (IndexReg.getReg() != 0 || ScaleAmt.getImm() != 1 || !Disp.isImm()) + return false; + + // RIP-relative addressing + if (BaseReg.getReg() == X86::RIP) { + Target = Addr + Size + Disp.getImm(); + return true; } + + return false; } } // end of namespace X86_MC