Skip to content

Commit 6b19bf6

Browse files
r41k0uclaude
andcommitted
Tests: Unsigned augmented assignment, helper results, map values, ctx field rank
One IR-shape case per fix: u32 >>= / //= / %= emit lshr/udiv/urem; ktime() >> 1 and pid() // 3 emit lshr/udiv; p >> 63 on a c_uint64 map value is lshr; ctx.data - c_int32 is a u32 subtraction with the trunc/zext pair rather than a 64-bit one. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
1 parent e35d4c0 commit 6b19bf6

5 files changed

Lines changed: 120 additions & 0 deletions

File tree

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Augmented assignment picks its operator from the promoted type like a
2+
# binary operation does: on a c_uint32, >>= is a logical shift and //= and
3+
# %= are unsigned division and remainder.
4+
from pythonbpf import bpf, section, bpfglobal, compile
5+
from ctypes import c_void_p, c_int64, c_uint32
6+
7+
8+
@bpf
9+
@section("tracepoint/raw_syscalls/sys_enter")
10+
def prog(ctx: c_void_p) -> c_int64:
11+
u = c_uint32(0xF0000000)
12+
u >>= 4 # lshr: 0x0F000000, not sign-filled
13+
u //= 3 # udiv
14+
u %= 7 # urem
15+
return c_int64(u)
16+
17+
18+
@bpf
19+
@bpfglobal
20+
def LICENSE() -> str:
21+
return "GPL"
22+
23+
24+
compile()
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# A helper's value carries the sign its registry entry declares: ktime()
2+
# and pid() are unsigned, so a right shift is logical and a division is
3+
# unsigned, the same as for a c_uint64 local.
4+
from pythonbpf import bpf, section, bpfglobal, compile
5+
from pythonbpf.helper import ktime, pid
6+
from ctypes import c_void_p, c_int64
7+
8+
9+
@bpf
10+
@section("tracepoint/raw_syscalls/sys_enter")
11+
def prog(ctx: c_void_p) -> c_int64:
12+
t = ktime() >> 1 # lshr
13+
q = pid() // 3 # udiv
14+
return c_int64(t + q)
15+
16+
17+
@bpf
18+
@bpfglobal
19+
def LICENSE() -> str:
20+
return "GPL"
21+
22+
23+
compile()
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# A map-lookup local dereferenced to its value carries the map's declared
2+
# value type: on a c_uint64 map, p >> 63 is a logical shift.
3+
from pythonbpf import bpf, map, section, bpfglobal, compile
4+
from pythonbpf.maps import HashMap
5+
from ctypes import c_void_p, c_int64, c_uint32, c_uint64
6+
7+
8+
@bpf
9+
@map
10+
def m() -> HashMap:
11+
return HashMap(key=c_uint32, value=c_uint64, max_entries=4)
12+
13+
14+
@bpf
15+
@section("tracepoint/raw_syscalls/sys_enter")
16+
def prog(ctx: c_void_p) -> c_int64:
17+
k = c_uint32(1)
18+
p = m.lookup(k)
19+
if p:
20+
top = p >> 63 # lshr: 0 or 1, never -1
21+
return c_int64(top)
22+
return c_int64(0)
23+
24+
25+
@bpf
26+
@bpfglobal
27+
def LICENSE() -> str:
28+
return "GPL"
29+
30+
31+
compile()
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# A sub-register context field is loaded widened to i64, but C ranks it by
2+
# its declared width: xdp_md.data is a u32, so data - k with a c_int32 k is
3+
# a u32 subtraction (the result is cut to 32 bits and zero-extended), not a
4+
# 64-bit one.
5+
from ctypes import c_int32, c_int64
6+
from pythonbpf import bpf, section, bpfglobal, compile
7+
from vmlinux import struct_xdp_md
8+
9+
10+
@bpf
11+
@section("xdp")
12+
def prog(ctx: struct_xdp_md) -> c_int64:
13+
k = c_int32(1)
14+
d = ctx.data - k
15+
return c_int64(d)
16+
17+
18+
@bpf
19+
@bpfglobal
20+
def LICENSE() -> str:
21+
return "GPL"
22+
23+
24+
compile()

‎tests/test_signedness_ir.py‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,24 @@
5050
[r"\budiv i64 .*, 4294967294"],
5151
[r"\bsdiv i64"],
5252
),
53+
"signedness/augassign_unsigned.py": (
54+
[r"\blshr i64", r"\budiv i64", r"\burem i64"],
55+
[r"\bashr i64", r"\bsdiv i64", r"\bsrem i64"],
56+
),
57+
"signedness/helper_results.py": (
58+
[r"\blshr i64", r"\budiv i64"],
59+
[r"\bashr i64", r"\bsdiv i64"],
60+
),
61+
"signedness/map_value_sign.py": (
62+
[r"\blshr i64 [^,]*, 63"],
63+
[r"\bashr i64"],
64+
),
65+
# u32 - int is a u32 operation: the result is cut to 32 bits and
66+
# zero-extended; ranked as 64-bit there would be no trunc at all.
67+
"vmlinux/ctx_field_rank.py": (
68+
[r"\bsub i64", r"trunc i64 .* to i32", r"zext i32 .* to i64"],
69+
[],
70+
),
5371
# A bool widens with zext and an integer narrows to it by != 0, never by
5472
# trunc; sext of an i1 would return -1 for True.
5573
"signedness/bool_int.py": (

0 commit comments

Comments
 (0)