diff options
Diffstat (limited to 'lib/Target/BPF/MCTargetDesc')
| -rw-r--r-- | lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp | 15 | ||||
| -rw-r--r-- | lib/Target/BPF/MCTargetDesc/BPFELFObjectWriter.cpp | 11 | ||||
| -rw-r--r-- | lib/Target/BPF/MCTargetDesc/BPFMCCodeEmitter.cpp | 2 | ||||
| -rw-r--r-- | lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp | 44 | ||||
| -rw-r--r-- | lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.h | 7 |
5 files changed, 66 insertions, 13 deletions
diff --git a/lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp b/lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp index 9fc812cdef14..e6ea92e08364 100644 --- a/lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp +++ b/lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp @@ -31,7 +31,8 @@ public: const MCValue &Target, MutableArrayRef<char> Data, uint64_t Value, bool IsResolved) const override; - MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override; + std::unique_ptr<MCObjectWriter> + createObjectWriter(raw_pwrite_stream &OS) const override; // No instruction requires relaxation bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, @@ -75,6 +76,15 @@ void BPFAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, unsigned Idx = IsLittleEndian ? i : Size - i - 1; Data[Fixup.getOffset() + Idx] = uint8_t(Value >> (i * 8)); } + } else if (Fixup.getKind() == FK_PCRel_4) { + Value = (uint32_t)((Value - 8) / 8); + if (IsLittleEndian) { + Data[Fixup.getOffset() + 1] = 0x10; + support::endian::write32le(&Data[Fixup.getOffset() + 4], Value); + } else { + Data[Fixup.getOffset() + 1] = 0x1; + support::endian::write32be(&Data[Fixup.getOffset() + 4], Value); + } } else { assert(Fixup.getKind() == FK_PCRel_2); Value = (uint16_t)((Value - 8) / 8); @@ -88,7 +98,8 @@ void BPFAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, } } -MCObjectWriter *BPFAsmBackend::createObjectWriter(raw_pwrite_stream &OS) const { +std::unique_ptr<MCObjectWriter> +BPFAsmBackend::createObjectWriter(raw_pwrite_stream &OS) const { return createBPFELFObjectWriter(OS, 0, IsLittleEndian); } diff --git a/lib/Target/BPF/MCTargetDesc/BPFELFObjectWriter.cpp b/lib/Target/BPF/MCTargetDesc/BPFELFObjectWriter.cpp index d5e1d7706edc..f7de612dab15 100644 --- a/lib/Target/BPF/MCTargetDesc/BPFELFObjectWriter.cpp +++ b/lib/Target/BPF/MCTargetDesc/BPFELFObjectWriter.cpp @@ -11,6 +11,7 @@ #include "llvm/BinaryFormat/ELF.h" #include "llvm/MC/MCELFObjectWriter.h" #include "llvm/MC/MCFixup.h" +#include "llvm/MC/MCObjectWriter.h" #include "llvm/Support/ErrorHandling.h" #include <cstdint> @@ -43,6 +44,7 @@ unsigned BPFELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target, llvm_unreachable("invalid fixup kind!"); case FK_SecRel_8: return ELF::R_BPF_64_64; + case FK_PCRel_4: case FK_SecRel_4: return ELF::R_BPF_64_32; case FK_Data_8: @@ -52,8 +54,9 @@ unsigned BPFELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target, } } -MCObjectWriter *llvm::createBPFELFObjectWriter(raw_pwrite_stream &OS, - uint8_t OSABI, bool IsLittleEndian) { - MCELFObjectTargetWriter *MOTW = new BPFELFObjectWriter(OSABI); - return createELFObjectWriter(MOTW, OS, IsLittleEndian); +std::unique_ptr<MCObjectWriter> +llvm::createBPFELFObjectWriter(raw_pwrite_stream &OS, uint8_t OSABI, + bool IsLittleEndian) { + return createELFObjectWriter(llvm::make_unique<BPFELFObjectWriter>(OSABI), OS, + IsLittleEndian); } diff --git a/lib/Target/BPF/MCTargetDesc/BPFMCCodeEmitter.cpp b/lib/Target/BPF/MCTargetDesc/BPFMCCodeEmitter.cpp index e8c974479828..b4ecfdee7bff 100644 --- a/lib/Target/BPF/MCTargetDesc/BPFMCCodeEmitter.cpp +++ b/lib/Target/BPF/MCTargetDesc/BPFMCCodeEmitter.cpp @@ -100,7 +100,7 @@ unsigned BPFMCCodeEmitter::getMachineOpValue(const MCInst &MI, if (MI.getOpcode() == BPF::JAL) // func call name - Fixups.push_back(MCFixup::create(0, Expr, FK_SecRel_4)); + Fixups.push_back(MCFixup::create(0, Expr, FK_PCRel_4)); else if (MI.getOpcode() == BPF::LD_imm64) Fixups.push_back(MCFixup::create(0, Expr, FK_SecRel_8)); else 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); } + } diff --git a/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.h b/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.h index d1c97c9987e1..6466042f6929 100644 --- a/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.h +++ b/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.h @@ -17,6 +17,8 @@ #include "llvm/Config/config.h" #include "llvm/Support/DataTypes.h" +#include <memory> + namespace llvm { class MCAsmBackend; class MCCodeEmitter; @@ -50,8 +52,9 @@ MCAsmBackend *createBPFbeAsmBackend(const Target &T, const MCRegisterInfo &MRI, const Triple &TT, StringRef CPU, const MCTargetOptions &Options); -MCObjectWriter *createBPFELFObjectWriter(raw_pwrite_stream &OS, - uint8_t OSABI, bool IsLittleEndian); +std::unique_ptr<MCObjectWriter> createBPFELFObjectWriter(raw_pwrite_stream &OS, + uint8_t OSABI, + bool IsLittleEndian); } // Defines symbolic names for BPF registers. This defines a mapping from |
