@@ -254,173 +254,97 @@ extern void bpf_throw(u64 cookie) __ksym;
254254 } \
255255 })
256256
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
334260
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)
349262
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.
358278 */
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
364303
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
379325
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
394330
395331/* 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.
399333 * Returns
400334 * Void.
401335 * Throws
402336 * An exception with the value zero when the assertion fails.
403337 */
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);
409339
410340/* 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.
414342 * Returns
415343 * Void.
416344 * Throws
417345 * An exception with the specified value when the assertion fails.
418346 */
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);
424348
425349/* Description
426350 * Assert that LHS is in the range [BEG, END] (inclusive of both). This
0 commit comments