27
27
#define MAX_INSNS 512
28
28
#define MAX_MATCHES 16
29
29
30
+ struct bpf_reg_match {
31
+ unsigned int line ;
32
+ const char * match ;
33
+ };
34
+
30
35
struct bpf_align_test {
31
36
const char * descr ;
32
37
struct bpf_insn insns [MAX_INSNS ];
@@ -36,10 +41,14 @@ struct bpf_align_test {
36
41
REJECT
37
42
} result ;
38
43
enum bpf_prog_type prog_type ;
39
- const char * matches [MAX_MATCHES ];
44
+ /* Matches must be in order of increasing line */
45
+ struct bpf_reg_match matches [MAX_MATCHES ];
40
46
};
41
47
42
48
static struct bpf_align_test tests [] = {
49
+ /* Four tests of known constants. These aren't staggeringly
50
+ * interesting since we track exact values now.
51
+ */
43
52
{
44
53
.descr = "mov" ,
45
54
.insns = {
@@ -53,11 +62,13 @@ static struct bpf_align_test tests[] = {
53
62
},
54
63
.prog_type = BPF_PROG_TYPE_SCHED_CLS ,
55
64
.matches = {
56
- "1: R1=ctx R3=imm2,min_value=2,max_value=2,min_align=2 R10=fp" ,
57
- "2: R1=ctx R3=imm4,min_value=4,max_value=4,min_align=4 R10=fp" ,
58
- "3: R1=ctx R3=imm8,min_value=8,max_value=8,min_align=8 R10=fp" ,
59
- "4: R1=ctx R3=imm16,min_value=16,max_value=16,min_align=16 R10=fp" ,
60
- "5: R1=ctx R3=imm32,min_value=32,max_value=32,min_align=32 R10=fp" ,
65
+ {1 , "R1=ctx(id=0,off=0,imm=0)" },
66
+ {1 , "R10=fp0" },
67
+ {1 , "R3=inv2" },
68
+ {2 , "R3=inv4" },
69
+ {3 , "R3=inv8" },
70
+ {4 , "R3=inv16" },
71
+ {5 , "R3=inv32" },
61
72
},
62
73
},
63
74
{
@@ -79,17 +90,19 @@ static struct bpf_align_test tests[] = {
79
90
},
80
91
.prog_type = BPF_PROG_TYPE_SCHED_CLS ,
81
92
.matches = {
82
- "1: R1=ctx R3=imm1,min_value=1,max_value=1,min_align=1 R10=fp" ,
83
- "2: R1=ctx R3=imm2,min_value=2,max_value=2,min_align=2 R10=fp" ,
84
- "3: R1=ctx R3=imm4,min_value=4,max_value=4,min_align=4 R10=fp" ,
85
- "4: R1=ctx R3=imm8,min_value=8,max_value=8,min_align=8 R10=fp" ,
86
- "5: R1=ctx R3=imm16,min_value=16,max_value=16,min_align=16 R10=fp" ,
87
- "6: R1=ctx R3=imm1,min_value=1,max_value=1,min_align=1 R10=fp" ,
88
- "7: R1=ctx R3=imm1,min_value=1,max_value=1,min_align=1 R4=imm32,min_value=32,max_value=32,min_align=32 R10=fp" ,
89
- "8: R1=ctx R3=imm1,min_value=1,max_value=1,min_align=1 R4=imm16,min_value=16,max_value=16,min_align=16 R10=fp" ,
90
- "9: R1=ctx R3=imm1,min_value=1,max_value=1,min_align=1 R4=imm8,min_value=8,max_value=8,min_align=8 R10=fp" ,
91
- "10: R1=ctx R3=imm1,min_value=1,max_value=1,min_align=1 R4=imm4,min_value=4,max_value=4,min_align=4 R10=fp" ,
92
- "11: R1=ctx R3=imm1,min_value=1,max_value=1,min_align=1 R4=imm2,min_value=2,max_value=2,min_align=2 R10=fp" ,
93
+ {1 , "R1=ctx(id=0,off=0,imm=0)" },
94
+ {1 , "R10=fp0" },
95
+ {1 , "R3=inv1" },
96
+ {2 , "R3=inv2" },
97
+ {3 , "R3=inv4" },
98
+ {4 , "R3=inv8" },
99
+ {5 , "R3=inv16" },
100
+ {6 , "R3=inv1" },
101
+ {7 , "R4=inv32" },
102
+ {8 , "R4=inv16" },
103
+ {9 , "R4=inv8" },
104
+ {10 , "R4=inv4" },
105
+ {11 , "R4=inv2" },
93
106
},
94
107
},
95
108
{
@@ -106,12 +119,14 @@ static struct bpf_align_test tests[] = {
106
119
},
107
120
.prog_type = BPF_PROG_TYPE_SCHED_CLS ,
108
121
.matches = {
109
- "1: R1=ctx R3=imm4,min_value=4,max_value=4,min_align=4 R10=fp" ,
110
- "2: R1=ctx R3=imm8,min_value=8,max_value=8,min_align=4 R10=fp" ,
111
- "3: R1=ctx R3=imm10,min_value=10,max_value=10,min_align=2 R10=fp" ,
112
- "4: R1=ctx R3=imm10,min_value=10,max_value=10,min_align=2 R4=imm8,min_value=8,max_value=8,min_align=8 R10=fp" ,
113
- "5: R1=ctx R3=imm10,min_value=10,max_value=10,min_align=2 R4=imm12,min_value=12,max_value=12,min_align=4 R10=fp" ,
114
- "6: R1=ctx R3=imm10,min_value=10,max_value=10,min_align=2 R4=imm14,min_value=14,max_value=14,min_align=2 R10=fp" ,
122
+ {1 , "R1=ctx(id=0,off=0,imm=0)" },
123
+ {1 , "R10=fp0" },
124
+ {1 , "R3=inv4" },
125
+ {2 , "R3=inv8" },
126
+ {3 , "R3=inv10" },
127
+ {4 , "R4=inv8" },
128
+ {5 , "R4=inv12" },
129
+ {6 , "R4=inv14" },
115
130
},
116
131
},
117
132
{
@@ -126,13 +141,16 @@ static struct bpf_align_test tests[] = {
126
141
},
127
142
.prog_type = BPF_PROG_TYPE_SCHED_CLS ,
128
143
.matches = {
129
- "1: R1=ctx R3=imm7,min_value=7,max_value=7,min_align=1 R10=fp" ,
130
- "2: R1=ctx R3=imm7,min_value=7,max_value=7,min_align=1 R10=fp" ,
131
- "3: R1=ctx R3=imm14,min_value=14,max_value=14,min_align=2 R10=fp" ,
132
- "4: R1=ctx R3=imm56,min_value=56,max_value=56,min_align=4 R10=fp" ,
144
+ {1 , "R1=ctx(id=0,off=0,imm=0)" },
145
+ {1 , "R10=fp0" },
146
+ {1 , "R3=inv7" },
147
+ {2 , "R3=inv7" },
148
+ {3 , "R3=inv14" },
149
+ {4 , "R3=inv56" },
133
150
},
134
151
},
135
152
153
+ /* Tests using unknown values */
136
154
#define PREP_PKT_POINTERS \
137
155
BPF_LDX_MEM (BPF_W , BPF_REG_2 , BPF_REG_1 , \
138
156
offsetof(struct __sk_buff , data )), \
@@ -166,17 +184,19 @@ static struct bpf_align_test tests[] = {
166
184
},
167
185
.prog_type = BPF_PROG_TYPE_SCHED_CLS ,
168
186
.matches = {
169
- "7: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv56 R10=fp" ,
170
- "8: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv55,min_align=2 R10=fp" ,
171
- "9: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv54,min_align=4 R10=fp" ,
172
- "10: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv53,min_align=8 R10=fp" ,
173
- "11: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv52,min_align=16 R10=fp" ,
174
- "18: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv56 R10=fp" ,
175
- "19: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv51,min_align=32 R10=fp" ,
176
- "20: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv52,min_align=16 R10=fp" ,
177
- "21: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv53,min_align=8 R10=fp" ,
178
- "22: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv54,min_align=4 R10=fp" ,
179
- "23: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv55,min_align=2 R10=fp" ,
187
+ {7 , "R0=pkt(id=0,off=8,r=8,imm=0)" },
188
+ {7 , "R3=inv(id=0,umax_value=255,var_off=(0x0; 0xff))" },
189
+ {8 , "R3=inv(id=0,umax_value=510,var_off=(0x0; 0x1fe))" },
190
+ {9 , "R3=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))" },
191
+ {10 , "R3=inv(id=0,umax_value=2040,var_off=(0x0; 0x7f8))" },
192
+ {11 , "R3=inv(id=0,umax_value=4080,var_off=(0x0; 0xff0))" },
193
+ {18 , "R3=pkt_end(id=0,off=0,imm=0)" },
194
+ {18 , "R4=inv(id=0,umax_value=255,var_off=(0x0; 0xff))" },
195
+ {19 , "R4=inv(id=0,umax_value=8160,var_off=(0x0; 0x1fe0))" },
196
+ {20 , "R4=inv(id=0,umax_value=4080,var_off=(0x0; 0xff0))" },
197
+ {21 , "R4=inv(id=0,umax_value=2040,var_off=(0x0; 0x7f8))" },
198
+ {22 , "R4=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))" },
199
+ {23 , "R4=inv(id=0,umax_value=510,var_off=(0x0; 0x1fe))" },
180
200
},
181
201
},
182
202
{
@@ -197,16 +217,16 @@ static struct bpf_align_test tests[] = {
197
217
},
198
218
.prog_type = BPF_PROG_TYPE_SCHED_CLS ,
199
219
.matches = {
200
- "7: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt (id=0,off=0,r=8) R3=inv56 R10=fp" ,
201
- "8: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt (id=0,off=0,r=8) R3=inv56 R4=inv56 R10=fp" ,
202
- "9: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt (id=0,off=0,r=8) R3=inv56 R4=inv55,min_align=1 R10=fp" ,
203
- "10: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt (id=0,off=0,r=8) R3=inv56 R4=inv56 R10=fp" ,
204
- "11: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt (id=0,off=0,r=8) R3=inv56 R4=inv54,min_align=2 R10=fp" ,
205
- "12: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt (id=0,off=0,r=8) R3=inv56 R4=inv56 R10=fp" ,
206
- "13: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt (id=0,off=0,r=8) R3=inv56 R4=inv53,min_align=4 R10=fp" ,
207
- "14: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt (id=0,off=0,r=8) R3=inv56 R4=inv56 R10=fp" ,
208
- "15: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt (id=0,off=0,r=8) R3=inv56 R4=inv52,min_align=8 R10=fp" ,
209
- "16: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt (id=0,off=0,r=8) R3=inv56 R4=inv50,min_align=8 R10=fp"
220
+ { 7 , "R3=inv (id=0,umax_value=255,var_off=(0x0; 0xff))" } ,
221
+ { 8 , "R4=inv (id=0,umax_value=255,var_off=(0x0; 0xff))" } ,
222
+ { 9 , "R4=inv (id=0,umax_value=255,var_off=(0x0; 0xff))" } ,
223
+ { 10 , "R4=inv (id=0,umax_value=255,var_off=(0x0; 0xff))" } ,
224
+ { 11 , "R4=inv (id=0,umax_value=510,var_off=(0x0; 0x1fe))" } ,
225
+ { 12 , "R4=inv (id=0,umax_value=255,var_off=(0x0; 0xff))" } ,
226
+ { 13 , "R4=inv (id=0,umax_value=1020,var_off=(0x0; 0x3fc))" } ,
227
+ { 14 , "R4=inv (id=0,umax_value=255,var_off=(0x0; 0xff))" } ,
228
+ { 15 , "R4=inv (id=0,umax_value=2040,var_off=(0x0; 0x7f8))" } ,
229
+ { 16 , "R4=inv (id=0,umax_value=4080,var_off=(0x0; 0xff0))" },
210
230
},
211
231
},
212
232
{
@@ -237,12 +257,14 @@ static struct bpf_align_test tests[] = {
237
257
},
238
258
.prog_type = BPF_PROG_TYPE_SCHED_CLS ,
239
259
.matches = {
240
- "4: R0=imm0,min_value=0,max_value=0,min_align=2147483648 R1=ctx R2=pkt(id=0,off=0,r=0) R3=pkt_end R5=pkt(id=0,off=0,r=0) R10=fp" ,
241
- "5: R0=imm0,min_value=0,max_value=0,min_align=2147483648 R1=ctx R2=pkt(id=0,off=0,r=0) R3=pkt_end R5=pkt(id=0,off=14,r=0) R10=fp" ,
242
- "6: R0=imm0,min_value=0,max_value=0,min_align=2147483648 R1=ctx R2=pkt(id=0,off=0,r=0) R3=pkt_end R4=pkt(id=0,off=14,r=0) R5=pkt(id=0,off=14,r=0) R10=fp" ,
243
- "10: R0=imm0,min_value=0,max_value=0,min_align=2147483648 R1=ctx R2=pkt(id=0,off=0,r=18) R3=pkt_end R4=inv56 R5=pkt(id=0,off=14,r=18) R10=fp" ,
244
- "14: R0=imm0,min_value=0,max_value=0,min_align=2147483648 R1=ctx R2=pkt(id=0,off=0,r=18) R3=pkt_end R4=inv48 R5=pkt(id=0,off=14,r=18) R10=fp" ,
245
- "15: R0=imm0,min_value=0,max_value=0,min_align=2147483648 R1=ctx R2=pkt(id=0,off=0,r=18) R3=pkt_end R4=inv48 R5=pkt(id=0,off=14,r=18) R10=fp" ,
260
+ {4 , "R5=pkt(id=0,off=0,r=0,imm=0)" },
261
+ {5 , "R5=pkt(id=0,off=14,r=0,imm=0)" },
262
+ {6 , "R4=pkt(id=0,off=14,r=0,imm=0)" },
263
+ {10 , "R2=pkt(id=0,off=0,r=18,imm=0)" },
264
+ {10 , "R5=pkt(id=0,off=14,r=18,imm=0)" },
265
+ {10 , "R4=inv(id=0,umax_value=255,var_off=(0x0; 0xff))" },
266
+ {14 , "R4=inv(id=0,umax_value=65535,var_off=(0x0; 0xffff))" },
267
+ {15 , "R4=inv(id=0,umax_value=65535,var_off=(0x0; 0xffff))" },
246
268
},
247
269
},
248
270
{
@@ -297,62 +319,59 @@ static struct bpf_align_test tests[] = {
297
319
/* Calculated offset in R6 has unknown value, but known
298
320
* alignment of 4.
299
321
*/
300
- "8: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R6=inv54,min_align=4 R10=fp" ,
301
-
302
- /* Offset is added to packet pointer R5, resulting in known
303
- * auxiliary alignment and offset.
322
+ { 8 , " R2=pkt(id=0,off=0,r=8,imm=0)" } ,
323
+ { 8 , "R6=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))" },
324
+ /* Offset is added to packet pointer R5, resulting in
325
+ * known fixed offset, and variable offset from R6 .
304
326
*/
305
- "11: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R5=pkt(id=1,off=0,r=0),aux_off=14,aux_off_align=4 R6=inv54,min_align=4 R10=fp" ,
306
-
327
+ {11 , "R5=pkt(id=1,off=14,r=0,umax_value=1020,var_off=(0x0; 0x3fc))" },
307
328
/* At the time the word size load is performed from R5,
308
329
* it's total offset is NET_IP_ALIGN + reg->off (0) +
309
330
* reg->aux_off (14) which is 16. Then the variable
310
331
* offset is considered using reg->aux_off_align which
311
332
* is 4 and meets the load's requirements.
312
333
*/
313
- "15: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=pkt(id=1,off=4,r=4),aux_off=14,aux_off_align=4 R5=pkt(id=1,off=0,r=4),aux_off=14,aux_off_align=4 R6=inv54,min_align=4 R10=fp" ,
314
-
315
-
334
+ {15 , "R4=pkt(id=1,off=18,r=18,umax_value=1020,var_off=(0x0; 0x3fc))" },
335
+ {15 , "R5=pkt(id=1,off=14,r=18,umax_value=1020,var_off=(0x0; 0x3fc))" },
316
336
/* Variable offset is added to R5 packet pointer,
317
337
* resulting in auxiliary alignment of 4.
318
338
*/
319
- "18: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv,aux_off=14,aux_off_align=4 R5=pkt(id=2,off=0,r=0),aux_off_align=4 R6=inv54,min_align=4 R10=fp" ,
320
-
339
+ {18 , "R5=pkt(id=2,off=0,r=0,umax_value=1020,var_off=(0x0; 0x3fc))" },
321
340
/* Constant offset is added to R5, resulting in
322
341
* reg->off of 14.
323
342
*/
324
- "19: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv,aux_off=14,aux_off_align=4 R5=pkt(id=2,off=14,r=0),aux_off_align=4 R6=inv54,min_align=4 R10=fp" ,
325
-
343
+ {19 , "R5=pkt(id=2,off=14,r=0,umax_value=1020,var_off=(0x0; 0x3fc))" },
326
344
/* At the time the word size load is performed from R5,
327
- * it's total offset is NET_IP_ALIGN + reg->off (14) which
328
- * is 16. Then the variable offset is considered using
329
- * reg->aux_off_align which is 4 and meets the load's
330
- * requirements.
345
+ * its total fixed offset is NET_IP_ALIGN + reg->off
346
+ * (14) which is 16. Then the variable offset is 4-byte
347
+ * aligned, so the total offset is 4-byte aligned and
348
+ * meets the load's requirements.
331
349
*/
332
- "23: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=pkt(id=2,off=18,r=18),aux_off_align=4 R5=pkt(id=2,off=14,r=18),aux_off_align=4 R6=inv54,min_align=4 R10=fp" ,
333
-
350
+ { 23 , " R4=pkt(id=2,off=18,r=18,umax_value=1020,var_off=(0x0; 0x3fc))" } ,
351
+ { 23 , "R5=pkt(id=2,off=14,r=18,umax_value=1020,var_off=(0x0; 0x3fc))" },
334
352
/* Constant offset is added to R5 packet pointer,
335
353
* resulting in reg->off value of 14.
336
354
*/
337
- "26: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv,aux_off_align=4 R5=pkt(id=0,off=14,r=8) R6=inv54,min_align=4 R10=fp" ,
338
- /* Variable offset is added to R5, resulting in an
339
- * auxiliary offset of 14, and an auxiliary alignment of 4 .
355
+ { 26 , " R5=pkt(id=0,off=14,r=8" } ,
356
+ /* Variable offset is added to R5, resulting in a
357
+ * variable offset of (4n) .
340
358
*/
341
- "27: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv,aux_off_align=4 R5=pkt(id=3,off=0 ,r=0),aux_off=14,aux_off_align=4 R6=inv54,min_align=4 R10=fp" ,
342
- /* Constant is added to R5 again, setting reg->off to 4 . */
343
- "28: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv,aux_off_align=4 R5=pkt(id=3,off=4 ,r=0),aux_off=14,aux_off_align=4 R6=inv54,min_align=4 R10=fp" ,
344
- /* And once more we add a variable, which causes an accumulation
345
- * of reg->off into reg->aux_off_align, with resulting value of
346
- * 18. The auxiliary alignment stays at 4 .
359
+ { 27 , " R5=pkt(id=3,off=14 ,r=0,umax_value=1020,var_off=(0x0; 0x3fc))" } ,
360
+ /* Constant is added to R5 again, setting reg->off to 18 . */
361
+ { 28 , " R5=pkt(id=3,off=18 ,r=0,umax_value=1020,var_off=(0x0; 0x3fc))" } ,
362
+ /* And once more we add a variable; resulting var_off
363
+ * is still (4n), fixed offset is not changed.
364
+ * Also, we create a new reg->id .
347
365
*/
348
- "29: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv,aux_off_align=4 R5=pkt(id=4,off=0 ,r=0),aux_off=18,aux_off_align=4 R6=inv54,min_align=4 R10=fp" ,
366
+ { 29 , " R5=pkt(id=4,off=18 ,r=0,umax_value=2040,var_off=(0x0; 0x7fc))" } ,
349
367
/* At the time the word size load is performed from R5,
350
- * it's total offset is NET_IP_ALIGN + reg->off (0) +
351
- * reg->aux_off (18) which is 20. Then the variable offset
352
- * is considered using reg->aux_off_align which is 4 and meets
353
- * the load's requirements.
368
+ * its total fixed offset is NET_IP_ALIGN + reg->off (18)
369
+ * which is 20. Then the variable offset is (4n), so
370
+ * the total offset is 4-byte aligned and meets the
371
+ * load's requirements.
354
372
*/
355
- "33: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=pkt(id=4,off=4,r=4),aux_off=18,aux_off_align=4 R5=pkt(id=4,off=0,r=4),aux_off=18,aux_off_align=4 R6=inv54,min_align=4 R10=fp" ,
373
+ {33 , "R4=pkt(id=4,off=22,r=22,umax_value=2040,var_off=(0x0; 0x7fc))" },
374
+ {33 , "R5=pkt(id=4,off=18,r=22,umax_value=2040,var_off=(0x0; 0x7fc))" },
356
375
},
357
376
},
358
377
};
@@ -373,6 +392,9 @@ static int do_test_single(struct bpf_align_test *test)
373
392
{
374
393
struct bpf_insn * prog = test -> insns ;
375
394
int prog_type = test -> prog_type ;
395
+ char bpf_vlog_copy [32768 ];
396
+ const char * line_ptr ;
397
+ int cur_line = -1 ;
376
398
int prog_len , i ;
377
399
int fd_prog ;
378
400
int ret ;
@@ -387,14 +409,31 @@ static int do_test_single(struct bpf_align_test *test)
387
409
ret = 1 ;
388
410
} else {
389
411
ret = 0 ;
412
+ /* We make a local copy so that we can strtok() it */
413
+ strncpy (bpf_vlog_copy , bpf_vlog , sizeof (bpf_vlog_copy ));
414
+ line_ptr = strtok (bpf_vlog_copy , "\n" );
390
415
for (i = 0 ; i < MAX_MATCHES ; i ++ ) {
391
- const char * t , * m = test -> matches [i ];
416
+ struct bpf_reg_match m = test -> matches [i ];
392
417
393
- if (!m )
418
+ if (!m . match )
394
419
break ;
395
- t = strstr (bpf_vlog , m );
396
- if (!t ) {
397
- printf ("Failed to find match: %s\n" , m );
420
+ while (line_ptr ) {
421
+ cur_line = -1 ;
422
+ sscanf (line_ptr , "%u: " , & cur_line );
423
+ if (cur_line == m .line )
424
+ break ;
425
+ line_ptr = strtok (NULL , "\n" );
426
+ }
427
+ if (!line_ptr ) {
428
+ printf ("Failed to find line %u for match: %s\n" ,
429
+ m .line , m .match );
430
+ ret = 1 ;
431
+ printf ("%s" , bpf_vlog );
432
+ break ;
433
+ }
434
+ if (!strstr (line_ptr , m .match )) {
435
+ printf ("Failed to find match %u: %s\n" ,
436
+ m .line , m .match );
398
437
ret = 1 ;
399
438
printf ("%s" , bpf_vlog );
400
439
break ;
0 commit comments