This is an archive of the discontinued LLVM Phabricator instance.

[WIP][BPF]: Force sign/zero extension for arguments in callee and return values in caller
Needs ReviewPublic

Authored by yonghong-song on Aug 8 2022, 11:21 PM.

Details

Reviewers
ast
anakryiko
Summary

For function arguments, current implementation will do
needed sign/zero extension for 32/64-bit integer types
in callee and 8/16-bit types in caller.
This patch forced sign/zero extension to be done in
callee. Alternatively, with a slightly different
implementation, sign/zero extension can be done in caller.

Similarly for function return value, current implementation
will do needed sign/zero extension for 32/64-bit integer
types in caller and 8/16-bit return values in callee.
This patch forced sign/zero extension in caller.
Alternatively, with a slightly different implementation,
sign/zero extension can be done in callee.

$  cat t.c
unsigned char bar();
char foo(short a) {
      if (bar() != a) return a; else return a + 1;
}
$ clang -target bpf -O2 -g -c t.c
$ llvm-objdump -S t.o
...
; char foo(short a) {
     0:       bf 16 00 00 00 00 00 00 r6 = r1
;       if (bar() != a) return a; else return a + 1;
     1:       bf 67 00 00 00 00 00 00 r7 = r6
     2:       67 07 00 00 30 00 00 00 r7 <<= 48
     3:       c7 07 00 00 30 00 00 00 r7 s>>= 48
     4:       85 10 00 00 ff ff ff ff call -1
     5:       bf 01 00 00 00 00 00 00 r1 = r0
     6:       57 01 00 00 ff 00 00 00 r1 &= 255
     7:       b7 00 00 00 01 00 00 00 r0 = 1
     8:       1d 71 01 00 00 00 00 00 if r1 == r7 goto +1 <LBB0_2>
     9:       b7 00 00 00 00 00 00 00 r0 = 0

0000000000000050 <LBB0_2>:
;       if (bar() != a) return a; else return a + 1;
    10:       0f 60 00 00 00 00 00 00 r0 += r6
; }
    11:       95 00 00 00 00 00 00 00 exit

In the above example, 16-bit argument value has sign extension
is done in callee before it is used. 8-bit return value has
zero extension done in caller before the value is used.

Note that we mostly care about 8-bit return value sign/zero
extension in the context of bpf program calling kernel functions
since for x86_64, the caller can directly access 8-bit %al
register while bpf can only access 32/64-bit registers.

Diff Detail

Event Timeline

yonghong-song created this revision.Aug 8 2022, 11:21 PM
Herald added a project: Restricted Project. · View Herald TranscriptAug 8 2022, 11:21 PM
Herald added a subscriber: pengfei. · View Herald Transcript
yonghong-song requested review of this revision.Aug 8 2022, 11:21 PM
Herald added a project: Restricted Project. · View Herald TranscriptAug 8 2022, 11:21 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript
yonghong-song retitled this revision from [WIP][BPF]: Force truncation for arguments in callee and return values in caller to [WIP][BPF]: Force sign/zero extension for arguments in callee and return values in caller.Aug 8 2022, 11:23 PM

D124435 is going to change the assumption :)

D124435 is going to change the assumption :)

Thanks for the pointer. So looks like there is an effort to always do sign/zero-extension in callee. If the default is not to do extension in callee, we could change default value in BPF related codes, or we could implement bpf target specific code like this patch.

I guess I only need to focus on the func return value for now which is my focus any way.