LLVM: lib/Target/BPF/Disassembler/BPFDisassembler.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

26#include

27

28using namespace llvm;

30

31#define DEBUG_TYPE "bpf-disassembler"

32

34

35namespace {

36

37

39public:

40 enum BPF_CLASS {

41 BPF_LD = 0x0,

42 BPF_LDX = 0x1,

43 BPF_ST = 0x2,

44 BPF_STX = 0x3,

45 BPF_ALU = 0x4,

46 BPF_JMP = 0x5,

47 BPF_JMP32 = 0x6,

48 BPF_ALU64 = 0x7

49 };

50

51 enum BPF_SIZE {

52 BPF_W = 0x0,

53 BPF_H = 0x1,

54 BPF_B = 0x2,

55 BPF_DW = 0x3

56 };

57

58 enum BPF_MODE {

59 BPF_IMM = 0x0,

60 BPF_ABS = 0x1,

61 BPF_IND = 0x2,

62 BPF_MEM = 0x3,

63 BPF_MEMSX = 0x4,

64 BPF_ATOMIC = 0x6

65 };

66

69 ~BPFDisassembler() override = default;

70

74

75 uint8_t getInstClass(uint64_t Inst) const { return (Inst >> 56) & 0x7; };

76 uint8_t getInstSize(uint64_t Inst) const { return (Inst >> 59) & 0x3; };

77 uint8_t getInstMode(uint64_t Inst) const { return (Inst >> 61) & 0x7; };

78};

79

80}

81

85 return new BPFDisassembler(STI, Ctx);

86}

87

98

100 BPF::R0, BPF::R1, BPF::R2, BPF::R3, BPF::R4, BPF::R5,

101 BPF::R6, BPF::R7, BPF::R8, BPF::R9, BPF::R10, BPF::R11};

102

106 if (RegNo > 11)

108

112}

113

115 BPF::W0, BPF::W1, BPF::W2, BPF::W3, BPF::W4, BPF::W5,

116 BPF::W6, BPF::W7, BPF::W8, BPF::W9, BPF::W10, BPF::W11};

117

121 if (RegNo > 11)

123

127}

128

132 unsigned Register = (Insn >> 16) & 0xf;

135

137 unsigned Offset = (Insn & 0xffff);

139

141}

142

143#include "BPFGenDisassemblerTables.inc"

146 bool IsLittleEndian) {

148

149 if (Bytes.size() < 8) {

152 }

153

155 if (IsLittleEndian) {

156 Hi = (Bytes[0] << 24) | (Bytes[1] << 16) | (Bytes[2] << 0) | (Bytes[3] << 8);

157 Lo = (Bytes[4] << 0) | (Bytes[5] << 8) | (Bytes[6] << 16) | (Bytes[7] << 24);

158 } else {

159 Hi = (Bytes[0] << 24) | ((Bytes[1] & 0x0F) << 20) | ((Bytes[1] & 0xF0) << 12) |

160 (Bytes[2] << 8) | (Bytes[3] << 0);

161 Lo = (Bytes[4] << 24) | (Bytes[5] << 16) | (Bytes[6] << 8) | (Bytes[7] << 0);

162 }

164

166}

167

172 bool IsLittleEndian = getContext().getAsmInfo()->isLittleEndian();

173 uint64_t Insn, Hi;

175

178

179 uint8_t InstClass = getInstClass(Insn);

180 uint8_t InstMode = getInstMode(Insn);

181 if ((InstClass == BPF_LDX || InstClass == BPF_STX) &&

182 getInstSize(Insn) != BPF_DW &&

183 (InstMode == BPF_MEM || InstMode == BPF_ATOMIC) &&

184 STI.hasFeature(BPF::ALU32))

185 Result = decodeInstruction(DecoderTableBPFALU3264, Instr, Insn, Address,

186 this, STI);

187 else

188 Result = decodeInstruction(DecoderTableBPF64, Instr, Insn, Address, this,

189 STI);

190

192

193 switch (Instr.getOpcode()) {

194 case BPF::LD_imm64:

195 case BPF::LD_pseudo: {

196 if (Bytes.size() < 16) {

199 }

201 if (IsLittleEndian)

202 Hi = (Bytes[12] << 0) | (Bytes[13] << 8) | (Bytes[14] << 16) | (Bytes[15] << 24);

203 else

204 Hi = (Bytes[12] << 24) | (Bytes[13] << 16) | (Bytes[14] << 8) | (Bytes[15] << 0);

205 auto& Op = Instr.getOperand(1);

207 break;

208 }

209 }

210

212}

213

MCDisassembler::DecodeStatus DecodeStatus

static bool readInstruction64(ArrayRef< uint8_t > Bytes, uint64_t Address, uint64_t &Size, uint64_t &Insn)

static const uint16_t GPR32DecoderTable[]

static const uint16_t GPRDecoderTable[]

DecodeStatus(* DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address, const MCDisassembler *Decoder)

static DecodeStatus decodeMemoryOpValue(MCInst &Inst, unsigned Insn, uint64_t Address, const MCDisassembler *Decoder)

Definition BPFDisassembler.cpp:129

static DecodeStatus readInstruction64(ArrayRef< uint8_t > Bytes, uint64_t Address, uint64_t &Size, uint64_t &Insn, bool IsLittleEndian)

Definition BPFDisassembler.cpp:144

LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeBPFDisassembler()

Definition BPFDisassembler.cpp:89

static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t, const MCDisassembler *)

Definition BPFDisassembler.cpp:119

static MCDisassembler * createBPFDisassembler(const Target &T, const MCSubtargetInfo &STI, MCContext &Ctx)

Definition BPFDisassembler.cpp:82

static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t, const MCDisassembler *)

Definition BPFDisassembler.cpp:103

#define LLVM_EXTERNAL_VISIBILITY

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

size_t size() const

size - Get the array size.

Context object for machine code objects.

Superclass for all disassemblers.

DecodeStatus

Ternary decode status.

Instances of this class represent a single low-level machine instruction.

void addOperand(const MCOperand Op)

static MCOperand createReg(MCRegister Reg)

static MCOperand createImm(int64_t Val)

Generic base class for all target subtargets.

Wrapper class representing virtual and physical registers.

Target - Wrapper for Target specific information.

This class implements an extremely fast bulk output stream that can only output to a stream.

NodeAddr< InstrNode * > Instr

Context & getContext() const

This is an optimization pass for GlobalISel generic memory operations.

Target & getTheBPFleTarget()

Target & getTheBPFbeTarget()

Target & getTheBPFTarget()

DWARFExpression::Operation Op

constexpr int32_t SignExtend32(uint32_t X)

Sign-extend the number in the bottom B bits of X to a 32-bit integer.

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.

static void RegisterMCDisassembler(Target &T, Target::MCDisassemblerCtorTy Fn)

RegisterMCDisassembler - Register a MCDisassembler implementation for the given target.