yonghong-song wrote:

The following is an example to show 'unsigned int' case. The current behavior 
(i.e., without this patch):
```
$ cat u.c
void foo(unsigned);
void bar(unsigned a, unsigned b) {
  foo(a + b);
}
$ clang --target=bpf -O2 -c u.c && llvm-objdump -d u.o

u.o:    file format elf64-bpf

Disassembly of section .text:

0000000000000000 <bar>:
       0:       0f 12 00 00 00 00 00 00 r2 += r1
       1:       bf 21 00 00 00 00 00 00 r1 = r2
       2:       85 10 00 00 ff ff ff ff call -0x1
       3:       95 00 00 00 00 00 00 00 exit
```
Basically, we didn't do zero extension for 'uint' argument in the above. We 
expect the callee 'foo' to do proper zero extension. If both 'foo' and 'far' 
are functions written in bpf programs, we should be okay. But if 'foo' is a 
kfunc (e.g., a kernel function for a specific arch e.g. riscv) and the arch 
will just use the full register 'r1' to do operation without zero extension of 
32-bit value, the wrong results could happen.

With this patch, we will have the following asm code,
```
$ clang --target=bpf -O2 -c u.c && llvm-objdump -d u.o

u.o:    file format elf64-bpf

Disassembly of section .text:

0000000000000000 <bar>:
       0:       0f 12 00 00 00 00 00 00 r2 += r1
       1:       67 02 00 00 20 00 00 00 r2 <<= 0x20
       2:       77 02 00 00 20 00 00 00 r2 >>= 0x20
       3:       bf 21 00 00 00 00 00 00 r1 = r2
       4:       85 10 00 00 ff ff ff ff call -0x1
       5:       95 00 00 00 00 00 00 00 exit
```
That is, we will do zero extension for uint argument here. This will guarantee 
correct value if 'foo' is a kernel function. If 'foo' is not a kernel function, 
the 'foo' will be able to use r2 directly as a 32-bit value without doing 
shifting, one example like below
```
long g1, g2;
__attribute__((noinline)) void foo(unsigned a) {
  if (a == g1) g2 = 1;
  else g2 = 2;  
}

....
0000000000000000 <foo>:
       0:       18 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r2 = 0x0 ll
       2:       79 23 00 00 00 00 00 00 r3 = *(u64 *)(r2 + 0x0)
       3:       b7 02 00 00 01 00 00 00 r2 = 0x1
       4:       1d 13 01 00 00 00 00 00 if r3 == r1 goto +0x1 <LBB0_2>
       5:       b7 02 00 00 02 00 00 00 r2 = 0x2

0000000000000030 <LBB0_2>:
       6:       18 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r1 = 0x0 ll
       8:       7b 21 00 00 00 00 00 00 *(u64 *)(r1 + 0x0) = r2
       9:       95 00 00 00 00 00 00 00 exit
```


https://github.com/llvm/llvm-project/pull/84874
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to