aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/BPF/MCTargetDesc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/BPF/MCTargetDesc')
-rw-r--r--lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp15
-rw-r--r--lib/Target/BPF/MCTargetDesc/BPFELFObjectWriter.cpp11
-rw-r--r--lib/Target/BPF/MCTargetDesc/BPFMCCodeEmitter.cpp2
-rw-r--r--lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp44
-rw-r--r--lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.h7
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