@@ -254,173 +254,97 @@ extern void bpf_throw(u64 cookie) __ksym;
254
254
} \
255
255
})
256
256
257
- /* Description
258
- * Assert that a conditional expression is true.
259
- * Returns
260
- * Void.
261
- * Throws
262
- * An exception with the value zero when the assertion fails.
263
- */
264
- #define bpf_assert (cond ) if (!(cond)) bpf_throw(0);
265
-
266
- /* Description
267
- * Assert that a conditional expression is true.
268
- * Returns
269
- * Void.
270
- * Throws
271
- * An exception with the specified value when the assertion fails.
272
- */
273
- #define bpf_assert_with (cond , value ) if (!(cond)) bpf_throw(value);
274
-
275
- /* Description
276
- * Assert that LHS is equal to RHS. This statement updates the known value
277
- * of LHS during verification. Note that RHS must be a constant value, and
278
- * must fit within the data type of LHS.
279
- * Returns
280
- * Void.
281
- * Throws
282
- * An exception with the value zero when the assertion fails.
283
- */
284
- #define bpf_assert_eq (LHS , RHS ) \
285
- ({ \
286
- barrier_var(LHS); \
287
- __bpf_assert_op(LHS, ==, RHS, 0, true); \
288
- })
289
-
290
- /* Description
291
- * Assert that LHS is equal to RHS. This statement updates the known value
292
- * of LHS during verification. Note that RHS must be a constant value, and
293
- * must fit within the data type of LHS.
294
- * Returns
295
- * Void.
296
- * Throws
297
- * An exception with the specified value when the assertion fails.
298
- */
299
- #define bpf_assert_eq_with (LHS , RHS , value ) \
300
- ({ \
301
- barrier_var(LHS); \
302
- __bpf_assert_op(LHS, ==, RHS, value, true); \
303
- })
304
-
305
- /* Description
306
- * Assert that LHS is less than RHS. This statement updates the known
307
- * bounds of LHS during verification. Note that RHS must be a constant
308
- * value, and must fit within the data type of LHS.
309
- * Returns
310
- * Void.
311
- * Throws
312
- * An exception with the value zero when the assertion fails.
313
- */
314
- #define bpf_assert_lt (LHS , RHS ) \
315
- ({ \
316
- barrier_var(LHS); \
317
- __bpf_assert_op(LHS, <, RHS, 0, false); \
318
- })
319
-
320
- /* Description
321
- * Assert that LHS is less than RHS. This statement updates the known
322
- * bounds of LHS during verification. Note that RHS must be a constant
323
- * value, and must fit within the data type of LHS.
324
- * Returns
325
- * Void.
326
- * Throws
327
- * An exception with the specified value when the assertion fails.
328
- */
329
- #define bpf_assert_lt_with (LHS , RHS , value ) \
330
- ({ \
331
- barrier_var(LHS); \
332
- __bpf_assert_op(LHS, <, RHS, value, false); \
333
- })
257
+ #define __cmp_cannot_be_signed (x ) \
258
+ __builtin_strcmp(#x, "==") == 0 || __builtin_strcmp(#x, "!=") == 0 || \
259
+ __builtin_strcmp(#x, "&") == 0
334
260
335
- /* Description
336
- * Assert that LHS is greater than RHS. This statement updates the known
337
- * bounds of LHS during verification. Note that RHS must be a constant
338
- * value, and must fit within the data type of LHS.
339
- * Returns
340
- * Void.
341
- * Throws
342
- * An exception with the value zero when the assertion fails.
343
- */
344
- #define bpf_assert_gt (LHS , RHS ) \
345
- ({ \
346
- barrier_var(LHS); \
347
- __bpf_assert_op(LHS, >, RHS, 0, false); \
348
- })
261
+ #define __is_signed_type (type ) (((type)(-1)) < (type)1)
349
262
350
- /* Description
351
- * Assert that LHS is greater than RHS. This statement updates the known
352
- * bounds of LHS during verification. Note that RHS must be a constant
353
- * value, and must fit within the data type of LHS.
354
- * Returns
355
- * Void.
356
- * Throws
357
- * An exception with the specified value when the assertion fails.
263
+ #define __bpf_cmp (LHS , OP , SIGN , PRED , RHS , DEFAULT ) \
264
+ ({ \
265
+ __label__ l_true; \
266
+ bool ret = DEFAULT; \
267
+ asm volatile goto("if %[lhs] " SIGN #OP " %[rhs] goto %l[l_true]" \
268
+ :: [lhs] "r"((short)LHS), [rhs] PRED (RHS) :: l_true); \
269
+ ret = !DEFAULT; \
270
+ l_true: \
271
+ ret; \
272
+ })
273
+
274
+ /* C type conversions coupled with comparison operator are tricky.
275
+ * Make sure BPF program is compiled with -Wsign-compare then
276
+ * __lhs OP __rhs below will catch the mistake.
277
+ * Be aware that we check only __lhs to figure out the sign of compare.
358
278
*/
359
- #define bpf_assert_gt_with (LHS , RHS , value ) \
360
- ({ \
361
- barrier_var(LHS); \
362
- __bpf_assert_op(LHS, >, RHS, value, false); \
363
- })
279
+ #define _bpf_cmp (LHS , OP , RHS , NOFLIP ) \
280
+ ({ \
281
+ typeof(LHS) __lhs = (LHS); \
282
+ typeof(RHS) __rhs = (RHS); \
283
+ bool ret; \
284
+ _Static_assert(sizeof(&(LHS)), "1st argument must be an lvalue expression"); \
285
+ (void)(__lhs OP __rhs); \
286
+ if (__cmp_cannot_be_signed(OP) || !__is_signed_type(typeof(__lhs))) { \
287
+ if (sizeof(__rhs) == 8) \
288
+ ret = __bpf_cmp(__lhs, OP, "", "r", __rhs, NOFLIP); \
289
+ else \
290
+ ret = __bpf_cmp(__lhs, OP, "", "i", __rhs, NOFLIP); \
291
+ } else { \
292
+ if (sizeof(__rhs) == 8) \
293
+ ret = __bpf_cmp(__lhs, OP, "s", "r", __rhs, NOFLIP); \
294
+ else \
295
+ ret = __bpf_cmp(__lhs, OP, "s", "i", __rhs, NOFLIP); \
296
+ } \
297
+ ret; \
298
+ })
299
+
300
+ #ifndef bpf_cmp_unlikely
301
+ #define bpf_cmp_unlikely (LHS , OP , RHS ) _bpf_cmp(LHS, OP, RHS, true)
302
+ #endif
364
303
365
- /* Description
366
- * Assert that LHS is less than or equal to RHS. This statement updates the
367
- * known bounds of LHS during verification. Note that RHS must be a
368
- * constant value, and must fit within the data type of LHS.
369
- * Returns
370
- * Void.
371
- * Throws
372
- * An exception with the value zero when the assertion fails.
373
- */
374
- #define bpf_assert_le (LHS , RHS ) \
375
- ({ \
376
- barrier_var(LHS); \
377
- __bpf_assert_op(LHS, <=, RHS, 0, false); \
378
- })
304
+ #ifndef bpf_cmp_likely
305
+ #define bpf_cmp_likely (LHS , OP , RHS ) \
306
+ ({ \
307
+ bool ret; \
308
+ if (__builtin_strcmp(#OP, "==") == 0) \
309
+ ret = _bpf_cmp(LHS, !=, RHS, false); \
310
+ else if (__builtin_strcmp(#OP, "!=") == 0) \
311
+ ret = _bpf_cmp(LHS, ==, RHS, false); \
312
+ else if (__builtin_strcmp(#OP, "<=") == 0) \
313
+ ret = _bpf_cmp(LHS, >, RHS, false); \
314
+ else if (__builtin_strcmp(#OP, "<") == 0) \
315
+ ret = _bpf_cmp(LHS, >=, RHS, false); \
316
+ else if (__builtin_strcmp(#OP, ">") == 0) \
317
+ ret = _bpf_cmp(LHS, <=, RHS, false); \
318
+ else if (__builtin_strcmp(#OP, ">=") == 0) \
319
+ ret = _bpf_cmp(LHS, <, RHS, false); \
320
+ else \
321
+ (void) "bug"; \
322
+ ret; \
323
+ })
324
+ #endif
379
325
380
- /* Description
381
- * Assert that LHS is less than or equal to RHS. This statement updates the
382
- * known bounds of LHS during verification. Note that RHS must be a
383
- * constant value, and must fit within the data type of LHS.
384
- * Returns
385
- * Void.
386
- * Throws
387
- * An exception with the specified value when the assertion fails.
388
- */
389
- #define bpf_assert_le_with (LHS , RHS , value ) \
390
- ({ \
391
- barrier_var(LHS); \
392
- __bpf_assert_op(LHS, <=, RHS, value, false); \
393
- })
326
+ #ifndef bpf_nop_mov
327
+ #define bpf_nop_mov (var ) \
328
+ asm volatile("%[reg]=%[reg]"::[reg]"r"((short)var))
329
+ #endif
394
330
395
331
/* Description
396
- * Assert that LHS is greater than or equal to RHS. This statement updates
397
- * the known bounds of LHS during verification. Note that RHS must be a
398
- * constant value, and must fit within the data type of LHS.
332
+ * Assert that a conditional expression is true.
399
333
* Returns
400
334
* Void.
401
335
* Throws
402
336
* An exception with the value zero when the assertion fails.
403
337
*/
404
- #define bpf_assert_ge (LHS , RHS ) \
405
- ({ \
406
- barrier_var(LHS); \
407
- __bpf_assert_op(LHS, >=, RHS, 0, false); \
408
- })
338
+ #define bpf_assert (cond ) if (!(cond)) bpf_throw(0);
409
339
410
340
/* Description
411
- * Assert that LHS is greater than or equal to RHS. This statement updates
412
- * the known bounds of LHS during verification. Note that RHS must be a
413
- * constant value, and must fit within the data type of LHS.
341
+ * Assert that a conditional expression is true.
414
342
* Returns
415
343
* Void.
416
344
* Throws
417
345
* An exception with the specified value when the assertion fails.
418
346
*/
419
- #define bpf_assert_ge_with (LHS , RHS , value ) \
420
- ({ \
421
- barrier_var(LHS); \
422
- __bpf_assert_op(LHS, >=, RHS, value, false); \
423
- })
347
+ #define bpf_assert_with (cond , value ) if (!(cond)) bpf_throw(value);
424
348
425
349
/* Description
426
350
* Assert that LHS is in the range [BEG, END] (inclusive of both). This
0 commit comments