|
|
@@ -5,6 +5,7 @@
|
|
5
|
5
|
#include <stdio.h>
|
|
6
|
6
|
#include <stdlib.h>
|
|
7
|
7
|
|
|
|
8
|
+#include <bits/wordsize.h>
|
|
8
|
9
|
#include <linux/bpf.h>
|
|
9
|
10
|
|
|
10
|
11
|
#define INSN(_code, _dst, _src, _off, _imm) \
|
|
|
@@ -24,8 +25,11 @@
|
|
24
|
25
|
#define JMP(_op, _dst, _src, _off) INSN(BPF_JMP | BPF_OP((_op)) | BPF_X, _dst, _src, _off, 0)
|
|
25
|
26
|
#define JMP_IMM(_op, _dst, _imm, _off) INSN(BPF_JMP | BPF_OP((_op)) | BPF_K, _dst, 0, _off, _imm)
|
|
26
|
27
|
|
|
27
|
|
-#define ALU(_op, _dst, _src) INSN(BPF_ALU64 | BPF_OP((_op)) | BPF_X, _dst, _src, 0, 0)
|
|
28
|
|
-#define ALU_IMM(_op, _dst, _imm) INSN(BPF_ALU64 | BPF_OP((_op)) | BPF_K, _dst, 0, 0, _imm)
|
|
|
28
|
+#define ALU32(_op, _dst, _src) INSN(BPF_ALU | BPF_OP((_op)) | BPF_X, _dst, _src, 0, 0)
|
|
|
29
|
+#define ALU32_IMM(_op, _dst, _imm) INSN(BPF_ALU | BPF_OP((_op)) | BPF_K, _dst, 0, 0, _imm)
|
|
|
30
|
+
|
|
|
31
|
+#define ALU64(_op, _dst, _src) INSN(BPF_ALU64 | BPF_OP((_op)) | BPF_X, _dst, _src, 0, 0)
|
|
|
32
|
+#define ALU64_IMM(_op, _dst, _imm) INSN(BPF_ALU64 | BPF_OP((_op)) | BPF_K, _dst, 0, 0, _imm)
|
|
29
|
33
|
|
|
30
|
34
|
#define STW_IMM(_dst, _off, _imm) INSN(BPF_ST | BPF_SIZE(BPF_W) | BPF_MEM, _dst, 0, _off, _imm)
|
|
31
|
35
|
#define STXB(_dst, _off, _src) INSN(BPF_STX | BPF_SIZE(BPF_B) | BPF_MEM, _dst, _src, _off, 0)
|
|
|
@@ -38,6 +42,20 @@
|
|
38
|
42
|
#define LDXW(_dst, _off, _src) INSN(BPF_LDX | BPF_SIZE(BPF_W) | BPF_MEM, _dst, _src, _off, 0)
|
|
39
|
43
|
#define LDXDW(_dst, _off, _src) INSN(BPF_LDX | BPF_SIZE(BPF_DW) | BPF_MEM, _dst, _src, _off, 0)
|
|
40
|
44
|
|
|
|
45
|
+#if __WORDSIZE == 64
|
|
|
46
|
+# define ALU ALU64
|
|
|
47
|
+# define ALU_IMM ALU64_IMM
|
|
|
48
|
+# define STX STXDW
|
|
|
49
|
+# define LDX LDXDW
|
|
|
50
|
+#else
|
|
|
51
|
+# define ALU ALU32
|
|
|
52
|
+# define ALU_IMM ALU32_IMM
|
|
|
53
|
+# define STX STXW
|
|
|
54
|
+# define LDX LDXW
|
|
|
55
|
+#endif
|
|
|
56
|
+
|
|
|
57
|
+#define BPF_REG_BP BPF_REG_10
|
|
|
58
|
+
|
|
41
|
59
|
struct sym;
|
|
42
|
60
|
|
|
43
|
61
|
enum vitype {
|
|
|
@@ -74,6 +92,28 @@ struct ir {
|
|
74
|
92
|
|
|
75
|
93
|
int16_t next_label;
|
|
76
|
94
|
uint16_t next_reg;
|
|
|
95
|
+
|
|
|
96
|
+ ssize_t sp;
|
|
|
97
|
+};
|
|
|
98
|
+
|
|
|
99
|
+enum irloc {
|
|
|
100
|
+ LOC_IMM = (1 << 0),
|
|
|
101
|
+ LOC_REG = (1 << 1),
|
|
|
102
|
+ LOC_STACK = (1 << 2),
|
|
|
103
|
+};
|
|
|
104
|
+
|
|
|
105
|
+
|
|
|
106
|
+struct irstate {
|
|
|
107
|
+ int loc;
|
|
|
108
|
+
|
|
|
109
|
+ uint16_t reg;
|
|
|
110
|
+ int32_t stack;
|
|
|
111
|
+ int32_t imm;
|
|
|
112
|
+
|
|
|
113
|
+ struct {
|
|
|
114
|
+ int dot:1;
|
|
|
115
|
+ int stack:1;
|
|
|
116
|
+ } hint;
|
|
77
|
117
|
};
|
|
78
|
118
|
|
|
79
|
119
|
void insn_dump(struct bpf_insn insn, FILE *fp);
|
|
|
@@ -82,50 +122,29 @@ void ir_dump(struct ir *ir, FILE *fp);
|
|
82
|
122
|
|
|
83
|
123
|
int16_t ir_alloc_label (struct ir *ir);
|
|
84
|
124
|
uint16_t ir_alloc_register(struct ir *ir);
|
|
|
125
|
+ssize_t ir_alloc_stack (struct ir *ir, size_t size);
|
|
85
|
126
|
|
|
86
|
127
|
void ir_emit_insn (struct ir *ir, struct bpf_insn bpf, uint16_t dst, uint16_t src);
|
|
87
|
128
|
void ir_emit_ldmap (struct ir *ir, uint16_t dst, struct sym *map);
|
|
88
|
129
|
void ir_emit_label (struct ir *ir, int16_t label);
|
|
89
|
|
-void ir_emit_reg_get(struct ir *ir, uint16_t reg);
|
|
90
|
|
-void ir_emit_reg_put(struct ir *ir, uint16_t reg);
|
|
91
|
|
-
|
|
92
|
|
-static inline void ir_emit_call(struct ir *ir, enum bpf_func_id func)
|
|
93
|
|
-{
|
|
94
|
|
- ir_emit_reg_get(ir, BPF_REG_0);
|
|
95
|
|
- ir_emit_reg_get(ir, BPF_REG_1);
|
|
96
|
|
- ir_emit_reg_get(ir, BPF_REG_2);
|
|
97
|
|
- ir_emit_reg_get(ir, BPF_REG_3);
|
|
98
|
|
- ir_emit_reg_get(ir, BPF_REG_4);
|
|
99
|
|
- ir_emit_reg_get(ir, BPF_REG_5);
|
|
100
|
|
- ir_emit_insn(ir, CALL(func), 0, 0);
|
|
101
|
|
- ir_emit_reg_put(ir, BPF_REG_5);
|
|
102
|
|
- ir_emit_reg_put(ir, BPF_REG_4);
|
|
103
|
|
- ir_emit_reg_put(ir, BPF_REG_3);
|
|
104
|
|
- ir_emit_reg_put(ir, BPF_REG_2);
|
|
105
|
|
- ir_emit_reg_put(ir, BPF_REG_1);
|
|
106
|
|
- ir_emit_reg_put(ir, BPF_REG_0);
|
|
107
|
|
-}
|
|
|
130
|
+/* void ir_emit_reg_get(struct ir *ir, uint16_t reg); */
|
|
|
131
|
+/* void ir_emit_reg_put(struct ir *ir, uint16_t reg); */
|
|
|
132
|
+void ir_emit_mov_irs(struct ir *ir, uint16_t dst, struct irstate *src);
|
|
108
|
133
|
|
|
109
|
134
|
struct ir *ir_new(void);
|
|
110
|
135
|
|
|
111
|
|
-enum irloc {
|
|
112
|
|
- LOC_IMM = (1 << 0),
|
|
113
|
|
- LOC_REG = (1 << 1),
|
|
114
|
|
- LOC_STACK = (1 << 2),
|
|
115
|
|
-};
|
|
116
|
136
|
|
|
117
|
|
-struct irstate {
|
|
118
|
|
- int loc;
|
|
119
|
|
-
|
|
120
|
|
- uint16_t reg;
|
|
121
|
|
- int16_t stack;
|
|
122
|
|
-};
|
|
123
|
|
-
|
|
124
|
|
-static inline void irs_alloc_reg(struct irstate *irs, struct ir *ir)
|
|
|
137
|
+static inline void irs_alloc_register(struct irstate *irs, struct ir *ir)
|
|
125
|
138
|
{
|
|
126
|
139
|
irs->loc = LOC_REG;
|
|
127
|
140
|
irs->reg = ir_alloc_register(ir);
|
|
128
|
|
- ir_emit_reg_get(ir, irs->reg);
|
|
|
141
|
+}
|
|
|
142
|
+
|
|
|
143
|
+static inline void irs_alloc_stack(struct irstate *irs, struct ir *ir,
|
|
|
144
|
+ size_t size)
|
|
|
145
|
+{
|
|
|
146
|
+ irs->loc = LOC_STACK;
|
|
|
147
|
+ irs->stack = ir_alloc_stack(ir, size);
|
|
129
|
148
|
}
|
|
130
|
149
|
|
|
131
|
150
|
#endif /* _PLY_IR_H */
|