@@ -87,6 +87,17 @@ const char *const bpf_alu_string[16] = {
87
87
[BPF_END >> 4 ] = "endian" ,
88
88
};
89
89
90
+ const char * const bpf_alu_sign_string [16 ] = {
91
+ [BPF_DIV >> 4 ] = "s/=" ,
92
+ [BPF_MOD >> 4 ] = "s%=" ,
93
+ };
94
+
95
+ const char * const bpf_movsx_string [4 ] = {
96
+ [0 ] = "(s8)" ,
97
+ [1 ] = "(s16)" ,
98
+ [3 ] = "(s32)" ,
99
+ };
100
+
90
101
static const char * const bpf_atomic_alu_string [16 ] = {
91
102
[BPF_ADD >> 4 ] = "add" ,
92
103
[BPF_AND >> 4 ] = "and" ,
@@ -101,6 +112,12 @@ static const char *const bpf_ldst_string[] = {
101
112
[BPF_DW >> 3 ] = "u64" ,
102
113
};
103
114
115
+ static const char * const bpf_ldsx_string [] = {
116
+ [BPF_W >> 3 ] = "s32" ,
117
+ [BPF_H >> 3 ] = "s16" ,
118
+ [BPF_B >> 3 ] = "s8" ,
119
+ };
120
+
104
121
static const char * const bpf_jmp_string [16 ] = {
105
122
[BPF_JA >> 4 ] = "jmp" ,
106
123
[BPF_JEQ >> 4 ] = "==" ,
@@ -128,6 +145,26 @@ static void print_bpf_end_insn(bpf_insn_print_t verbose,
128
145
insn -> imm , insn -> dst_reg );
129
146
}
130
147
148
+ static void print_bpf_bswap_insn (bpf_insn_print_t verbose ,
149
+ void * private_data ,
150
+ const struct bpf_insn * insn )
151
+ {
152
+ verbose (private_data , "(%02x) r%d = bswap%d r%d\n" ,
153
+ insn -> code , insn -> dst_reg ,
154
+ insn -> imm , insn -> dst_reg );
155
+ }
156
+
157
+ static bool is_sdiv_smod (const struct bpf_insn * insn )
158
+ {
159
+ return (BPF_OP (insn -> code ) == BPF_DIV || BPF_OP (insn -> code ) == BPF_MOD ) &&
160
+ insn -> off == 1 ;
161
+ }
162
+
163
+ static bool is_movsx (const struct bpf_insn * insn )
164
+ {
165
+ return BPF_OP (insn -> code ) == BPF_MOV && insn -> off != 0 ;
166
+ }
167
+
131
168
void print_bpf_insn (const struct bpf_insn_cbs * cbs ,
132
169
const struct bpf_insn * insn ,
133
170
bool allow_ptr_leaks )
@@ -138,7 +175,7 @@ void print_bpf_insn(const struct bpf_insn_cbs *cbs,
138
175
if (class == BPF_ALU || class == BPF_ALU64 ) {
139
176
if (BPF_OP (insn -> code ) == BPF_END ) {
140
177
if (class == BPF_ALU64 )
141
- verbose ( cbs -> private_data , "BUG_alu64_%02x\n" , insn -> code );
178
+ print_bpf_bswap_insn ( verbose , cbs -> private_data , insn );
142
179
else
143
180
print_bpf_end_insn (verbose , cbs -> private_data , insn );
144
181
} else if (BPF_OP (insn -> code ) == BPF_NEG ) {
@@ -147,17 +184,20 @@ void print_bpf_insn(const struct bpf_insn_cbs *cbs,
147
184
insn -> dst_reg , class == BPF_ALU ? 'w' : 'r' ,
148
185
insn -> dst_reg );
149
186
} else if (BPF_SRC (insn -> code ) == BPF_X ) {
150
- verbose (cbs -> private_data , "(%02x) %c%d %s %c%d\n" ,
187
+ verbose (cbs -> private_data , "(%02x) %c%d %s %s% c%d\n" ,
151
188
insn -> code , class == BPF_ALU ? 'w' : 'r' ,
152
189
insn -> dst_reg ,
153
- bpf_alu_string [BPF_OP (insn -> code ) >> 4 ],
190
+ is_sdiv_smod (insn ) ? bpf_alu_sign_string [BPF_OP (insn -> code ) >> 4 ]
191
+ : bpf_alu_string [BPF_OP (insn -> code ) >> 4 ],
192
+ is_movsx (insn ) ? bpf_movsx_string [(insn -> off >> 3 ) - 1 ] : "" ,
154
193
class == BPF_ALU ? 'w' : 'r' ,
155
194
insn -> src_reg );
156
195
} else {
157
196
verbose (cbs -> private_data , "(%02x) %c%d %s %d\n" ,
158
197
insn -> code , class == BPF_ALU ? 'w' : 'r' ,
159
198
insn -> dst_reg ,
160
- bpf_alu_string [BPF_OP (insn -> code ) >> 4 ],
199
+ is_sdiv_smod (insn ) ? bpf_alu_sign_string [BPF_OP (insn -> code ) >> 4 ]
200
+ : bpf_alu_string [BPF_OP (insn -> code ) >> 4 ],
161
201
insn -> imm );
162
202
}
163
203
} else if (class == BPF_STX ) {
@@ -218,13 +258,15 @@ void print_bpf_insn(const struct bpf_insn_cbs *cbs,
218
258
verbose (cbs -> private_data , "BUG_st_%02x\n" , insn -> code );
219
259
}
220
260
} else if (class == BPF_LDX ) {
221
- if (BPF_MODE (insn -> code ) != BPF_MEM ) {
261
+ if (BPF_MODE (insn -> code ) != BPF_MEM && BPF_MODE ( insn -> code ) != BPF_MEMSX ) {
222
262
verbose (cbs -> private_data , "BUG_ldx_%02x\n" , insn -> code );
223
263
return ;
224
264
}
225
265
verbose (cbs -> private_data , "(%02x) r%d = *(%s *)(r%d %+d)\n" ,
226
266
insn -> code , insn -> dst_reg ,
227
- bpf_ldst_string [BPF_SIZE (insn -> code ) >> 3 ],
267
+ BPF_MODE (insn -> code ) == BPF_MEM ?
268
+ bpf_ldst_string [BPF_SIZE (insn -> code ) >> 3 ] :
269
+ bpf_ldsx_string [BPF_SIZE (insn -> code ) >> 3 ],
228
270
insn -> src_reg , insn -> off );
229
271
} else if (class == BPF_LD ) {
230
272
if (BPF_MODE (insn -> code ) == BPF_ABS ) {
@@ -279,6 +321,9 @@ void print_bpf_insn(const struct bpf_insn_cbs *cbs,
279
321
} else if (insn -> code == (BPF_JMP | BPF_JA )) {
280
322
verbose (cbs -> private_data , "(%02x) goto pc%+d\n" ,
281
323
insn -> code , insn -> off );
324
+ } else if (insn -> code == (BPF_JMP32 | BPF_JA )) {
325
+ verbose (cbs -> private_data , "(%02x) gotol pc%+d\n" ,
326
+ insn -> code , insn -> imm );
282
327
} else if (insn -> code == (BPF_JMP | BPF_EXIT )) {
283
328
verbose (cbs -> private_data , "(%02x) exit\n" , insn -> code );
284
329
} else if (BPF_SRC (insn -> code ) == BPF_X ) {
0 commit comments