diff options
Diffstat (limited to 'lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp')
| -rw-r--r-- | lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp | 44 |
1 files changed, 40 insertions, 4 deletions
diff --git a/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp b/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp index 797904e1c976..cbf1ea7d7fb8 100644 --- a/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp +++ b/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp @@ -15,6 +15,7 @@ #include "BPF.h" #include "InstPrinter/BPFInstPrinter.h" #include "MCTargetDesc/BPFMCAsmInfo.h" +#include "llvm/MC/MCInstrAnalysis.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSubtargetInfo.h" @@ -49,11 +50,13 @@ static MCSubtargetInfo *createBPFMCSubtargetInfo(const Triple &TT, return createBPFMCSubtargetInfoImpl(TT, CPU, FS); } -static MCStreamer *createBPFMCStreamer(const Triple &T, - MCContext &Ctx, MCAsmBackend &MAB, - raw_pwrite_stream &OS, MCCodeEmitter *Emitter, +static MCStreamer *createBPFMCStreamer(const Triple &T, MCContext &Ctx, + std::unique_ptr<MCAsmBackend> &&MAB, + raw_pwrite_stream &OS, + std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll) { - return createELFStreamer(Ctx, MAB, OS, Emitter, RelaxAll); + return createELFStreamer(Ctx, std::move(MAB), OS, std::move(Emitter), + RelaxAll); } static MCInstPrinter *createBPFMCInstPrinter(const Triple &T, @@ -66,6 +69,35 @@ static MCInstPrinter *createBPFMCInstPrinter(const Triple &T, return nullptr; } +namespace { + +class BPFMCInstrAnalysis : public MCInstrAnalysis { +public: + explicit BPFMCInstrAnalysis(const MCInstrInfo *Info) + : MCInstrAnalysis(Info) {} + + bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size, + uint64_t &Target) const override { + // The target is the 3rd operand of cond inst and the 1st of uncond inst. + int16_t Imm; + if (isConditionalBranch(Inst)) { + Imm = Inst.getOperand(2).getImm(); + } else if (isUnconditionalBranch(Inst)) + Imm = Inst.getOperand(0).getImm(); + else + return false; + + Target = Addr + Size + Imm * Size; + return true; + } +}; + +} // end anonymous namespace + +static MCInstrAnalysis *createBPFInstrAnalysis(const MCInstrInfo *Info) { + return new BPFMCInstrAnalysis(Info); +} + extern "C" void LLVMInitializeBPFTargetMC() { for (Target *T : {&getTheBPFleTarget(), &getTheBPFbeTarget(), &getTheBPFTarget()}) { @@ -87,6 +119,9 @@ extern "C" void LLVMInitializeBPFTargetMC() { // Register the MCInstPrinter. TargetRegistry::RegisterMCInstPrinter(*T, createBPFMCInstPrinter); + + // Register the MC instruction analyzer. + TargetRegistry::RegisterMCInstrAnalysis(*T, createBPFInstrAnalysis); } // Register the MC code emitter @@ -112,4 +147,5 @@ extern "C" void LLVMInitializeBPFTargetMC() { TargetRegistry::RegisterMCAsmBackend(getTheBPFTarget(), createBPFbeAsmBackend); } + } |
