libbpf 开发指南:获取bpf_object 关联的 BTF(BPF Type Format)信息与文件描述符

目录

获取给定的 bpf_object 关联的 BTF(BPF Type Format)信息

函数原型与解释

代码demo

makefile

cmake

期望输出

获取给定的 bpf_object 关联的 BTF 文件描述符

函数原型与解释

代码demo

makefile

cmake

期望输出


获取给定的 bpf_object 关联的 BTF(BPF Type Format)信息

函数原型与解释

LIBBPF_API struct btf *bpf_object__btf(const struct bpf_object *obj);

参数解释:

  • obj:要获取其关联 BTF 信息的 bpf_object 实例。

返回值:

  • 返回一个指向 btf 结构的指针,该结构包含了与 bpf_object 关联的 BTF 信息。如果没有可用的 BTF 信息,返回 NULL。

代码demo

#include <bpf/bpf_helpers.h>
#include <linux/bpf.h>

struct data {
    int key;
    int value;
};

SEC("maps")
struct bpf_map_def data_map = {
    .type = BPF_MAP_TYPE_HASH,
    .key_size = sizeof(int),
    .value_size = sizeof(struct data),
    .max_entries = 128,
};

SEC("kprobe/__x64_sys_getpid")
int bpf_prog1(struct pt_regs *ctx) {
    return 0;
}

char _license[] SEC("license") = "GPL";
#include <stdio.h>
#include <stdlib.h>
#include <bpf/libbpf.h>
#include <bpf/btf.h>

int main() {
    struct bpf_object *bpf_obj;
    struct btf *btf_info;

    // 加载 BPF 程序
    bpf_obj = bpf_object__open("prog.o");
    if (libbpf_get_error(bpf_obj)) {
        fprintf(stderr, "Error opening BPF object: %d\n", libbpf_get_error(bpf_obj));
        return 1;
    }

    // 获取 BPF 对象的 BTF 信息
    btf_info = bpf_object__btf(bpf_obj);
    if (!btf_info) {
        fprintf(stderr, "No BTF info available for the BPF object\n");
        bpf_object__close(bpf_obj);
        return 1;
    }

    // 获取 BTF 类型数量
    int type_count = btf__get_nr_types(btf_info);
    printf("Number of BTF types: %d\n", type_count);

    // 关闭 BPF 对象
    bpf_object__close(bpf_obj);

    return 0;
}

makefile

CC = gcc
CLANG = clang
CFLAGS = -Wall -I/usr/include/bpf
LDFLAGS = -lbpf

BPF_TARGET = prog.o
BPF_SRC = prog.c

BTF_TARGET = get_btf
BTF_SRC = get_btf.c

all: $(BPF_TARGET) $(BTF_TARGET)

$(BPF_TARGET): $(BPF_SRC)
	$(CLANG) -O2 -target bpf -g -c $(BPF_SRC) -o $(BPF_TARGET)

$(BTF_TARGET): $(BTF_SRC)
	$(CC) $(CFLAGS) $(BTF_SRC) -o $(BTF_TARGET) $(LDFLAGS)

clean:
	rm -f $(BPF_TARGET) $(BTF_TARGET)

.PHONY: all clean

cmake

cmake_minimum_required(VERSION 3.10)
project(bpf_btf_example)

set(CMAKE_C_STANDARD 99)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")

find_library(LIBBPF libbpf.so REQUIRED)

add_custom_command(
    OUTPUT prog.o
    COMMAND clang -O2 -target bpf -g -c ${CMAKE_CURRENT_SOURCE_DIR}/prog.c -o prog.o
    DEPENDS prog.c
    VERBATIM
)

add_custom_target(
    prog_bpf
    DEPENDS prog.o
)

add_executable(get_btf get_btf.c)
target_link_libraries(get_btf ${LIBBPF})
target_include_directories(get_btf PUBLIC /usr/include/bpf)

期望输出

在上述示例中,get_object_name 程序加载 BPF 对象(prog.o),然后使用 bpf_object__name 函数获取其名称。输出为以下内容:

Number of BTF types: 7

BTF(BPF Type Format)是一种类型和数据格式,用于在 eBPF 程序之间共享类型和数据结构信息。BTF 类型数量表示 BPF 程序中的不同数据类型和结构的数量。在我们的示例中,Number of BTF types: 7 表示 BPF 程序中有 7 个不同的类型和结构。

这些类型可以包括:

  1. 基本类型(如 int)
  2. 结构体(如示例中的 struct data)
  3. 枚举
  4. 函数指针等

这个数量是通过分析 BPF 程序中的类型和数据结构计算出来的。BTF 类型数量有助于了解 BPF 程序中的类型复杂性。请注意,这个数字可能因不同的 BPF 程序和环境而变化。

在我们的示例中,打印的 BTF 类型数量 7 是根据示例 BPF 程序中的数据类型和结构得出的。这个数字对于演示如何使用 bpf_object__btf 函数从 BPF 对象获取 BTF 信息来说是次要的,关键是理解如何使用这个 API 函数。

获取给定的 bpf_object 关联的 BTF 文件描述符

函数原型与解释

LIBBPF_API int bpf_object__btf_fd(const struct bpf_object *obj);

参数解释:

  • obj:要获取其关联 BTF 文件描述符的 bpf_object 实例。

返回值:

  • 返回一个正整数,表示与 bpf_object 关联的 BTF 文件描述符。如果没有可用的 BTF 文件描述符,返回 -1。

代码demo

#include <bpf/bpf_helpers.h>
#include <linux/bpf.h>

struct data {
    int key;
    int value;
};

SEC("maps")
struct bpf_map_def data_map = {
    .type = BPF_MAP_TYPE_HASH,
    .key_size = sizeof(int),
    .value_size = sizeof(struct data),
    .max_entries = 128,
};

SEC("kprobe/__x64_sys_getpid")
int bpf_prog1(struct pt_regs *ctx) {
    return 0;
}

char _license[] SEC("license") = "GPL";
#include <stdio.h>
#include <stdlib.h>
#include <bpf/libbpf.h>
#include <bpf/btf.h>

int main() {
    struct bpf_object *bpf_obj;
    int btf_fd;

    // 加载 BPF 程序
    bpf_obj = bpf_object__open("prog.o");
    if (libbpf_get_error(bpf_obj)) {
        fprintf(stderr, "Error opening BPF object: %d\n", libbpf_get_error(bpf_obj));
        return 1;
    }

    // 获取 BPF 对象的 BTF 文件描述符
    btf_fd = bpf_object__btf_fd(bpf_obj);
    if (btf_fd < 0) {
        fprintf(stderr, "No BTF file descriptor available for the BPF object\n");
        bpf_object__close(bpf_obj);
        return 1;
    }

    printf("BTF file descriptor: %d\n", btf_fd);

    // 关闭 BPF 对象
    bpf_object__close(bpf_obj);

    return 0;
}

makefile

CC = gcc
CLANG = clang
CFLAGS = -Wall -I/usr/include/bpf
LDFLAGS = -lbpf

BPF_TARGET = prog.o
BPF_SRC = prog.c

BTF_FD_TARGET = get_btf_fd
BTF_FD_SRC = get_btf_fd.c

all: $(BPF_TARGET) $(BTF_FD_TARGET)

$(BPF_TARGET): $(BPF_SRC)
	$(CLANG) -O2 -target bpf -g -c $(BPF_SRC) -o $(BPF_TARGET)

$(BTF_FD_TARGET): $(BTF_FD_SRC)
	$(CC) $(CFLAGS) $(BTF_FD_SRC) -o $(BTF_FD_TARGET) $(LDFLAGS)

clean:
	rm -f $(BPF_TARGET) $(BTF_FD_TARGET)

.PHONY: all clean

cmake

cmake_minimum_required(VERSION 3.10)
project(bpf_btf_fd_example)

set(CMAKE_C_STANDARD 99)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")

find_library(LIBBPF libbpf.so REQUIRED)

add_custom_command(
    OUTPUT prog.o
    COMMAND clang -O2 -target bpf -g -c ${CMAKE_CURRENT_SOURCE_DIR}/prog.c -o prog.o
    DEPENDS prog.c
    VERBATIM
)

add_custom_target(
    prog_bpf
    DEPENDS prog.o
)

add_executable(get_btf_fd get_btf_fd.c)
target_link_libraries(get_btf_fd ${LIBBPF})
target_include_directories(get_btf_fd PUBLIC /usr/include/bpf)

期望输出

在上述示例中,get_object_name 程序加载 BPF 对象(prog.o),然后使用 bpf_object__name 函数获取其名称。输出为以下内容:

BTF file descriptor: 3

BTF 文件描述符可以用于与 Linux 内核进行通信,以便获取或设置 BTF 信息。例如,通过使用 BTF 文件描述符,您可以查询 BTF 类型信息、加载 BTF 类型信息到内核中,或者使用 BTF 信息来实现更高级的 eBPF 功能,如 CO-RE(Compile Once - Run Everywhere)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ym影子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值