Libbpf Minimal分析

宏定义分析

Minimal程序使用了SEC宏,展开后结果分析如下:

SEC

展开后为

1
2
3
4
5
#define SEC(name) \
	_Pragma("GCC diagnostic push")					    \
	_Pragma("GCC diagnostic ignored \"-Wignored-attributes\"")	    \
	__attribute__((section(name), used))				    \
	_Pragma("GCC diagnostic pop")					    \

源文件中对应给出的注释为

/*

  • Helper macro to place programs, maps, license in
  • different sections in elf_bpf file. Section names
  • are interpreted by libbpf depending on the context (BPF programs, BPF maps,
  • extern variables, etc).
  • To allow use of SEC() with externs (e.g., for extern .maps declarations),
  • make sure attribute((unused)) doesn’t trigger compilation warning.

*/

从注释来看,该宏的作用在于将bpf程序的不同部分放入最终生成的elf文件的不同节中。这个宏是怎么起到这样的作用的。对宏展开后的内容分析。

_Pragma

其中有三句为_Pragma,这是一个C99新引入的运算符,作为运算符的优势在于其可以用于宏中,如该源文件中的SEC宏。该运算符在处理运算符内的表达式后即相当于#pragma指令。处理过程非常简单,将’\\‘替换为’\’,将\“替换为”。这样_Pragma在预处理后即成为 #pragma GCC diagnostic ignored "-Wignored-attributes" 。pragma则是针对编译器给出的控制编译的指令,因此相关信息需要查阅gcc的说明。在该网站可以看到 gcc支持的pragma 。其中该处使用的pragma为 Diagnostic Pragmas ,这里要注意的是这个编译指令会覆盖编译器的命令行参数,push即改变状态,忽视Wignored-attributes参数,pop则恢复原状。

__attribute__

__attribute__也是一种编译器指令,用于在声明(函数,变量,类型)时帮助声明对象向编译器告知某些编译特性。在gnu网站上可以查知 可用的属性 ,在此处的含义为,将对应的函数放入指定的name段中,并且即使该函数没有被引用也不允许将该自定义的段优化掉(used)。

SEC整体功能

博客中给出的解释为

libbpf is able to automatically determine where to attach BPF program to by looking at its special SEC() annotation. This doesn’t work for all possible BPF program types, but it does for lots of them: tracepoints, kprobes, and quite a few others. Additionally, libbpf provides extra APIs to do the attachment programmatically.