Index: llvm/trunk/include/llvm/MC/MCInstrAnalysis.h =================================================================== --- llvm/trunk/include/llvm/MC/MCInstrAnalysis.h +++ llvm/trunk/include/llvm/MC/MCInstrAnalysis.h @@ -152,6 +152,12 @@ 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 + /// the address on success. + virtual Optional evaluateMemoryOperandAddress(const MCInst &Inst, + uint64_t Addr, + uint64_t Size) const; + /// Returns (PLT virtual address, GOT virtual address) pairs for PLT entries. virtual std::vector> findPltEntries(uint64_t PltSectionVA, ArrayRef PltContents, Index: llvm/trunk/lib/MC/MCInstrAnalysis.cpp =================================================================== --- llvm/trunk/lib/MC/MCInstrAnalysis.cpp +++ llvm/trunk/lib/MC/MCInstrAnalysis.cpp @@ -33,3 +33,9 @@ Target = Addr+Size+Imm; return true; } + +Optional +MCInstrAnalysis::evaluateMemoryOperandAddress(const MCInst &Inst, uint64_t Addr, + uint64_t Size) const { + return None; +} Index: llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp =================================================================== --- llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp +++ llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp @@ -399,6 +399,9 @@ findPltEntries(uint64_t PltSectionVA, ArrayRef PltContents, uint64_t GotSectionVA, const Triple &TargetTriple) const override; + Optional evaluateMemoryOperandAddress(const MCInst &Inst, + uint64_t Addr, + uint64_t Size) const override; }; #define GET_STIPREDICATE_DEFS_FOR_MC_ANALYSIS @@ -511,7 +514,31 @@ return findX86_64PltEntries(PltSectionVA, PltContents); default: return {}; - } + } +} + +Optional X86MCInstrAnalysis::evaluateMemoryOperandAddress( + const MCInst &Inst, uint64_t Addr, uint64_t Size) const { + const MCInstrDesc &MCID = Info->get(Inst.getOpcode()); + int MemOpStart = X86II::getMemoryOperandNo(MCID.TSFlags); + if (MemOpStart == -1) + return None; + MemOpStart += X86II::getOperandBias(MCID); + + const MCOperand &SegReg = Inst.getOperand(MemOpStart + X86::AddrSegmentReg); + 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 (SegReg.getReg() != 0 || IndexReg.getReg() != 0 || ScaleAmt.getImm() != 1 || + !Disp.isImm()) + return None; + + // RIP-relative addressing. + if (BaseReg.getReg() == X86::RIP) + return Addr + Size + Disp.getImm(); + + return None; } } // end of namespace X86_MC