Search code examples
cbpfebpf

What is variable attribute SEC means?


Currently, I'm tracing a bpf program and found something I can't understand.

There're several declaration like:

struct bpf_map_def SEC("maps") map_parsing_context = {
...
};
struct {
...
} map_keys SEC(".maps");

My question are:

  1. What did this syntax called?
  2. Is this same with __attribute__((section("name")))?
  3. What is different between map and .map? Are they just user-defined sections?

Solution

  • This is for declaring the structure of the object (in this case, the keys for the map) for BTF.

    SEC() is the same as __attribute__((section("name"), used)) so what it does is putting the defined object into the given ELF section.

    Now, eBPF maps were (and still can) be defined in the maps ELF section for libbpf to be able to parse the relevant metadata and find or create these maps before the program can use them, hence: SEC("maps").

    The other call to SEC() is to put additional metadata into the .maps ELF section: this information is a declaration of the structure of the map_keys, it tells what fields the key is made of. Libbpf will use this information to generate the BTF information related to the structure of the map. This information is passed to the kernel, and can be used for several purposes. One use case is to see the structure of the map when examining it, for example with bpftool map dump, and to easily dump each key (and value) fields individually instead of printing a raw single hexadecimal blob for the whole structure the key (or value) is made of. The kernel may also use it for other advanced eBPF features: for example, using spinlocks on fields in map entries requires the BTF information to be present, so that the kernel can understand what the struct fields are and which one should be locked.

    [Edit] Using the maps section is the “legacy” way to declare maps, still valid when declaring without BTF. When BTF information is added, everything (map metadata and structure layout) should go into the .maps section, although redundancy with metadata in maps is supported. Usually, you don't use maps when declaring into .maps, simply because this is useless.

    Some pointers related to BTF: blog post, kernel documentation. See also OP's link in the comments.

    So to answer your questions directly:

    1. The syntax is used to declare the map metadata (size, type, etc.) (maps) as well as the structure of the map keys (.maps), in this case.
    2. The SEC() macro itself is the same as the one you provide.
    3. maps and .maps are different ELF sections. They are defined by the user, but they are used as a convention by libbpf to parse data from the ELF object and to extract metadata for the map, and for metadata and the structure of map entries, respectively.