LLVM  6.0.0svn
BPFDisassembler.cpp
Go to the documentation of this file.
1 //===- BPFDisassembler.cpp - Disassembler for BPF ---------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file is part of the BPF Disassembler.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "BPF.h"
15 #include "BPFSubtarget.h"
17 #include "llvm/ADT/ArrayRef.h"
18 #include "llvm/MC/MCAsmInfo.h"
19 #include "llvm/MC/MCContext.h"
22 #include "llvm/MC/MCInst.h"
25 #include <cstdint>
26 
27 using namespace llvm;
28 
29 #define DEBUG_TYPE "bpf-disassembler"
30 
32 
33 namespace {
34 
35 /// A disassembler class for BPF.
36 class BPFDisassembler : public MCDisassembler {
37 public:
38  BPFDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
39  : MCDisassembler(STI, Ctx) {}
40  ~BPFDisassembler() override = default;
41 
42  DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
43  ArrayRef<uint8_t> Bytes, uint64_t Address,
44  raw_ostream &VStream,
45  raw_ostream &CStream) const override;
46 };
47 
48 } // end anonymous namespace
49 
51  const MCSubtargetInfo &STI,
52  MCContext &Ctx) {
53  return new BPFDisassembler(STI, Ctx);
54 }
55 
56 
57 extern "C" void LLVMInitializeBPFDisassembler() {
58  // Register the disassembler.
65 }
66 
67 static const unsigned GPRDecoderTable[] = {
68  BPF::R0, BPF::R1, BPF::R2, BPF::R3, BPF::R4, BPF::R5,
69  BPF::R6, BPF::R7, BPF::R8, BPF::R9, BPF::R10, BPF::R11};
70 
71 static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo,
72  uint64_t /*Address*/,
73  const void * /*Decoder*/) {
74  if (RegNo > 11)
75  return MCDisassembler::Fail;
76 
77  unsigned Reg = GPRDecoderTable[RegNo];
80 }
81 
82 static const unsigned GPR32DecoderTable[] = {
83  BPF::W0, BPF::W1, BPF::W2, BPF::W3, BPF::W4, BPF::W5,
84  BPF::W6, BPF::W7, BPF::W8, BPF::W9, BPF::W10, BPF::W11};
85 
86 static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo,
87  uint64_t /*Address*/,
88  const void * /*Decoder*/) {
89  if (RegNo > 11)
90  return MCDisassembler::Fail;
91 
92  unsigned Reg = GPR32DecoderTable[RegNo];
95 }
96 
97 static DecodeStatus decodeMemoryOpValue(MCInst &Inst, unsigned Insn,
98  uint64_t Address, const void *Decoder) {
99  unsigned Register = (Insn >> 16) & 0xf;
100  Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Register]));
101  unsigned Offset = (Insn & 0xffff);
102  Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Offset)));
103 
105 }
106 
107 #include "BPFGenDisassemblerTables.inc"
109  uint64_t &Size, uint64_t &Insn,
110  bool IsLittleEndian) {
111  uint64_t Lo, Hi;
112 
113  if (Bytes.size() < 8) {
114  Size = 0;
115  return MCDisassembler::Fail;
116  }
117 
118  Size = 8;
119  if (IsLittleEndian) {
120  Hi = (Bytes[0] << 24) | (Bytes[1] << 16) | (Bytes[2] << 0) | (Bytes[3] << 8);
121  Lo = (Bytes[4] << 0) | (Bytes[5] << 8) | (Bytes[6] << 16) | (Bytes[7] << 24);
122  } else {
123  Hi = (Bytes[0] << 24) | ((Bytes[1] & 0x0F) << 20) | ((Bytes[1] & 0xF0) << 12) |
124  (Bytes[2] << 8) | (Bytes[3] << 0);
125  Lo = (Bytes[4] << 24) | (Bytes[5] << 16) | (Bytes[6] << 8) | (Bytes[7] << 0);
126  }
127  Insn = Make_64(Hi, Lo);
128 
130 }
131 
132 DecodeStatus BPFDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
133  ArrayRef<uint8_t> Bytes,
134  uint64_t Address,
135  raw_ostream &VStream,
136  raw_ostream &CStream) const {
137  bool IsLittleEndian = getContext().getAsmInfo()->isLittleEndian();
138  uint64_t Insn, Hi;
139  DecodeStatus Result;
140 
141  Result = readInstruction64(Bytes, Address, Size, Insn, IsLittleEndian);
142  if (Result == MCDisassembler::Fail) return MCDisassembler::Fail;
143 
144  Result = decodeInstruction(DecoderTableBPF64, Instr, Insn,
145  Address, this, STI);
146  if (Result == MCDisassembler::Fail) return MCDisassembler::Fail;
147 
148  switch (Instr.getOpcode()) {
149  case BPF::LD_imm64:
150  case BPF::LD_pseudo: {
151  if (Bytes.size() < 16) {
152  Size = 0;
153  return MCDisassembler::Fail;
154  }
155  Size = 16;
156  if (IsLittleEndian)
157  Hi = (Bytes[12] << 0) | (Bytes[13] << 8) | (Bytes[14] << 16) | (Bytes[15] << 24);
158  else
159  Hi = (Bytes[12] << 24) | (Bytes[13] << 16) | (Bytes[14] << 8) | (Bytes[15] << 0);
160  auto& Op = Instr.getOperand(1);
161  Op.setImm(Make_64(Hi, Op.getImm()));
162  break;
163  }
164  case BPF::LD_ABS_B:
165  case BPF::LD_ABS_H:
166  case BPF::LD_ABS_W:
167  case BPF::LD_IND_B:
168  case BPF::LD_IND_H:
169  case BPF::LD_IND_W: {
170  auto Op = Instr.getOperand(0);
171  Instr.clear();
173  Instr.addOperand(Op);
174  break;
175  }
176  }
177 
178  return Result;
179 }
180 
181 typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address,
182  const void *Decoder);
#define R4(n)
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
void clear()
Definition: MCInst.h:189
DecodeStatus(* DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address, const void *Decoder)
DecodeStatus
Ternary decode status.
Superclass for all disassemblers.
static void RegisterMCDisassembler(Target &T, Target::MCDisassemblerCtorTy Fn)
RegisterMCDisassembler - Register a MCDisassembler implementation for the given target.
#define R2(n)
static DecodeStatus readInstruction64(ArrayRef< uint8_t > Bytes, uint64_t Address, uint64_t &Size, uint64_t &Insn, bool IsLittleEndian)
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:116
Reg
All possible values of the reg field in the ModR/M byte.
Context object for machine code objects.
Definition: MCContext.h:59
static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t, const void *)
int decodeInstruction(InternalInstruction *insn, byteReader_t reader, const void *readerArg, dlog_t logger, void *loggerArg, const void *miiArg, uint64_t startLoc, DisassemblerMode mode)
Decode one instruction and store the decoding results in a buffer provided by the consumer...
static const unsigned GPRDecoderTable[]
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:159
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:149
#define R6(n)
static MCDisassembler * createBPFDisassembler(const Target &T, const MCSubtargetInfo &STI, MCContext &Ctx)
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:180
Promote Memory to Register
Definition: Mem2Reg.cpp:110
void LLVMInitializeBPFDisassembler()
Target - Wrapper for Target specific information.
static DecodeStatus decodeMemoryOpValue(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder)
MCSubtargetInfo - Generic base class for all target subtargets.
Target & getTheBPFleTarget()
static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t, const void *)
constexpr char Size[]
Key for Kernel::Arg::Metadata::mSize.
constexpr uint64_t Make_64(uint32_t High, uint32_t Low)
Make a 64-bit integer from a high / low pair of 32-bit integers.
Definition: MathExtras.h:286
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:44
IRTranslator LLVM IR MI
void addOperand(const MCOperand &Op)
Definition: MCInst.h:184
static const unsigned GPR32DecoderTable[]
Target & getTheBPFbeTarget()
unsigned getOpcode() const
Definition: MCInst.h:172
MCDisassembler::DecodeStatus DecodeStatus
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:123
Target & getTheBPFTarget()