This is an archive of the discontinued LLVM Phabricator instance.

[BPF] Add BTF Var and DataSec Support
ClosedPublic

Authored by yonghong-song on Mar 15 2019, 4:23 PM.

Details

Summary
Two new kinds, BTF_KIND_VAR and BTF_KIND_DATASEC, are added.

BTF_KIND_VAR has the following specification:
   btf_type.name: var name
   btf_type.info: type kind
   btf_type.type: var type
   // btf_type is followed by one u32
   u32: varinfo (currently, only 0 - static, 1 - global allocated in elf sections)

Not all globals are supported in this patch. The following globals are supported:
  . static variables with or without section attributes
  . global variables with section attributes

The inclusion of globals with section attributes
is for future potential extraction of key/value
type id's from map definition.

BTF_KIND_DATASEC has the following specification:
  btf_type.name: section name associated with variable or
                 one of .data/.bss/.readonly
  btf_type.info: type kind and vlen for # of variables
  btf_type.size: 0
  #vlen number of the following:
    u32: id of corresponding BTF_KIND_VAR
    u32: in-session offset of the var
    u32: the size of memory var occupied

At the time of debug info emission, the data section
size is unknown, so the btf_type.size = 0 for
BTF_KIND_DATASEC. The loader can patch it during
loading time.

The in-session offseet of the var is only available
for static variables. For global variables, the
loader neeeds to assign the global variable symbol value in
symbol table to in-section offset.

The size of memory is used to specify the amount of the
memory a variable occupies. Typically, it equals to
the type size, but for certain structures, e.g.,
struct tt {
  int a;
  int b;
  char c[];
 };
 static volatile struct tt s2 = {3, 4, "abcdefghi"};
The static variable s2 has size of 20.

Note that for BTF_KIND_DATASEC name, the section name
does not contain object name. The compiler does have
input module name. For example, two cases below:
   . clang -target bpf -O2 -g -c test.c
     The compiler knows the input file (module) is test.c
     and can generate sec name like test.data/test.bss etc.
   . clang -target bpf -O2 -g -emit-llvm -c test.c -o - |
     llc -march=bpf -filetype=obj -o test.o
     The llc compiler has the input file as stdin, and
     would generate something like stdin.data/stdin.bss etc.
     which does not really make sense.

For any user specificed section name, e.g.,
static volatile int a __attribute__((section("id1")));
static volatile const int b __attribute__((section("id2")));
The DataSec with name "id1" and "id2" does not contain
information whether the section is readonly or not.
The loader needs to check the corresponding elf section
flags for such information.

A simple example:
-bash-4.4$ cat t.c
int g1;
int g2 = 3;
const int g3 = 4;
static volatile int s1;
struct tt {
 int a;
 int b;
 char c[];
};
static volatile struct tt s2 = {3, 4, "abcdefghi"};
static volatile const int s3 = 4;
int m __attribute__((section("maps"), used)) = 4;
int test() { return g1 + g2 + g3 + s1 + s2.a + s3 + m; }
-bash-4.4$ clang -target bpf -O2 -g -S t.c
Checking t.s, 4 BTF_KIND_VAR's are generated (s1, s2, s3 and m).
4 BTF_KIND_DATASEC's are generated with names
".data", ".bss", ".rodata" and "maps".

Diff Detail

Repository
rL LLVM

Event Timeline

yonghong-song created this revision.Mar 15 2019, 4:23 PM
Herald added a project: Restricted Project. · View Herald TranscriptMar 15 2019, 4:23 PM
ast accepted this revision.Mar 15 2019, 10:27 PM
ast added inline comments.
lib/Target/BPF/BTF.h
174 ↗(On Diff #190923)

this two are unused. Reserved for future ?

lib/Target/BPF/BTFDebug.cpp
326 ↗(On Diff #190923)

too bad that compiler cannot determine it at the point of btf emission.
i think it's ok to ask libbpf to fix it up.

This revision is now accepted and ready to land.Mar 15 2019, 10:27 PM
yonghong-song marked 2 inline comments as done.Mar 15 2019, 10:38 PM
yonghong-song added inline comments.
lib/Target/BPF/BTF.h
174 ↗(On Diff #190923)

Yes, for future but we can always change.
I put it here so when we implement the kernel interface, we will have a rough idea what to expect.

lib/Target/BPF/BTFDebug.cpp
326 ↗(On Diff #190923)

Right. It is too early in the compilation. We need loader to fix it up.

This revision was automatically updated to reflect the committed changes.