mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-17 17:24:17 +08:00
Merge branch 'bpf-libbpf-btf-parsing'
Andrii Nakryiko says: ==================== It's pretty common for applications to want to parse raw (binary) BTF data from file, as opposed to parsing it from ELF sections. It's also pretty common for tools to not care whether given file is ELF or raw BTF format. This patch series exposes internal raw BTF parsing API and adds generic variant of BTF parsing, which will efficiently determine the format of a given fail and will parse BTF appropriately. Patches #2 and #3 removes re-implementations of such APIs from bpftool and resolve_btfids tools. ==================== Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
This commit is contained in:
commit
cfa3eb65a7
@ -422,54 +422,6 @@ done:
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct btf *btf__parse_raw(const char *file)
|
||||
{
|
||||
struct btf *btf;
|
||||
struct stat st;
|
||||
__u8 *buf;
|
||||
FILE *f;
|
||||
|
||||
if (stat(file, &st))
|
||||
return NULL;
|
||||
|
||||
f = fopen(file, "rb");
|
||||
if (!f)
|
||||
return NULL;
|
||||
|
||||
buf = malloc(st.st_size);
|
||||
if (!buf) {
|
||||
btf = ERR_PTR(-ENOMEM);
|
||||
goto exit_close;
|
||||
}
|
||||
|
||||
if ((size_t) st.st_size != fread(buf, 1, st.st_size, f)) {
|
||||
btf = ERR_PTR(-EINVAL);
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
btf = btf__new(buf, st.st_size);
|
||||
|
||||
exit_free:
|
||||
free(buf);
|
||||
exit_close:
|
||||
fclose(f);
|
||||
return btf;
|
||||
}
|
||||
|
||||
static bool is_btf_raw(const char *file)
|
||||
{
|
||||
__u16 magic = 0;
|
||||
int fd, nb_read;
|
||||
|
||||
fd = open(file, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return false;
|
||||
|
||||
nb_read = read(fd, &magic, sizeof(magic));
|
||||
close(fd);
|
||||
return nb_read == sizeof(magic) && magic == BTF_MAGIC;
|
||||
}
|
||||
|
||||
static int do_dump(int argc, char **argv)
|
||||
{
|
||||
struct btf *btf = NULL;
|
||||
@ -547,11 +499,7 @@ static int do_dump(int argc, char **argv)
|
||||
}
|
||||
NEXT_ARG();
|
||||
} else if (is_prefix(src, "file")) {
|
||||
if (is_btf_raw(*argv))
|
||||
btf = btf__parse_raw(*argv);
|
||||
else
|
||||
btf = btf__parse_elf(*argv, NULL);
|
||||
|
||||
btf = btf__parse(*argv, NULL);
|
||||
if (IS_ERR(btf)) {
|
||||
err = -PTR_ERR(btf);
|
||||
btf = NULL;
|
||||
|
4
tools/bpf/resolve_btfids/.gitignore
vendored
Normal file
4
tools/bpf/resolve_btfids/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
/FEATURE-DUMP.libbpf
|
||||
/bpf_helper_defs.h
|
||||
/fixdep
|
||||
/resolve_btfids
|
@ -403,62 +403,6 @@ static int symbols_collect(struct object *obj)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct btf *btf__parse_raw(const char *file)
|
||||
{
|
||||
struct btf *btf;
|
||||
struct stat st;
|
||||
__u8 *buf;
|
||||
FILE *f;
|
||||
|
||||
if (stat(file, &st))
|
||||
return NULL;
|
||||
|
||||
f = fopen(file, "rb");
|
||||
if (!f)
|
||||
return NULL;
|
||||
|
||||
buf = malloc(st.st_size);
|
||||
if (!buf) {
|
||||
btf = ERR_PTR(-ENOMEM);
|
||||
goto exit_close;
|
||||
}
|
||||
|
||||
if ((size_t) st.st_size != fread(buf, 1, st.st_size, f)) {
|
||||
btf = ERR_PTR(-EINVAL);
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
btf = btf__new(buf, st.st_size);
|
||||
|
||||
exit_free:
|
||||
free(buf);
|
||||
exit_close:
|
||||
fclose(f);
|
||||
return btf;
|
||||
}
|
||||
|
||||
static bool is_btf_raw(const char *file)
|
||||
{
|
||||
__u16 magic = 0;
|
||||
int fd, nb_read;
|
||||
|
||||
fd = open(file, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return false;
|
||||
|
||||
nb_read = read(fd, &magic, sizeof(magic));
|
||||
close(fd);
|
||||
return nb_read == sizeof(magic) && magic == BTF_MAGIC;
|
||||
}
|
||||
|
||||
static struct btf *btf_open(const char *path)
|
||||
{
|
||||
if (is_btf_raw(path))
|
||||
return btf__parse_raw(path);
|
||||
else
|
||||
return btf__parse_elf(path, NULL);
|
||||
}
|
||||
|
||||
static int symbols_resolve(struct object *obj)
|
||||
{
|
||||
int nr_typedefs = obj->nr_typedefs;
|
||||
@ -469,7 +413,7 @@ static int symbols_resolve(struct object *obj)
|
||||
struct btf *btf;
|
||||
__u32 nr;
|
||||
|
||||
btf = btf_open(obj->btf ?: obj->path);
|
||||
btf = btf__parse(obj->btf ?: obj->path, NULL);
|
||||
err = libbpf_get_error(btf);
|
||||
if (err) {
|
||||
pr_err("FAILED: load BTF from %s: %s",
|
||||
|
@ -562,6 +562,83 @@ done:
|
||||
return btf;
|
||||
}
|
||||
|
||||
struct btf *btf__parse_raw(const char *path)
|
||||
{
|
||||
void *data = NULL;
|
||||
struct btf *btf;
|
||||
FILE *f = NULL;
|
||||
__u16 magic;
|
||||
int err = 0;
|
||||
long sz;
|
||||
|
||||
f = fopen(path, "rb");
|
||||
if (!f) {
|
||||
err = -errno;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
/* check BTF magic */
|
||||
if (fread(&magic, 1, sizeof(magic), f) < sizeof(magic)) {
|
||||
err = -EIO;
|
||||
goto err_out;
|
||||
}
|
||||
if (magic != BTF_MAGIC) {
|
||||
/* definitely not a raw BTF */
|
||||
err = -EPROTO;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
/* get file size */
|
||||
if (fseek(f, 0, SEEK_END)) {
|
||||
err = -errno;
|
||||
goto err_out;
|
||||
}
|
||||
sz = ftell(f);
|
||||
if (sz < 0) {
|
||||
err = -errno;
|
||||
goto err_out;
|
||||
}
|
||||
/* rewind to the start */
|
||||
if (fseek(f, 0, SEEK_SET)) {
|
||||
err = -errno;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
/* pre-alloc memory and read all of BTF data */
|
||||
data = malloc(sz);
|
||||
if (!data) {
|
||||
err = -ENOMEM;
|
||||
goto err_out;
|
||||
}
|
||||
if (fread(data, 1, sz, f) < sz) {
|
||||
err = -EIO;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
/* finally parse BTF data */
|
||||
btf = btf__new(data, sz);
|
||||
|
||||
err_out:
|
||||
free(data);
|
||||
if (f)
|
||||
fclose(f);
|
||||
return err ? ERR_PTR(err) : btf;
|
||||
}
|
||||
|
||||
struct btf *btf__parse(const char *path, struct btf_ext **btf_ext)
|
||||
{
|
||||
struct btf *btf;
|
||||
|
||||
if (btf_ext)
|
||||
*btf_ext = NULL;
|
||||
|
||||
btf = btf__parse_raw(path);
|
||||
if (!IS_ERR(btf) || PTR_ERR(btf) != -EPROTO)
|
||||
return btf;
|
||||
|
||||
return btf__parse_elf(path, btf_ext);
|
||||
}
|
||||
|
||||
static int compare_vsi_off(const void *_a, const void *_b)
|
||||
{
|
||||
const struct btf_var_secinfo *a = _a;
|
||||
@ -2951,41 +3028,6 @@ static int btf_dedup_remap_types(struct btf_dedup *d)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct btf *btf_load_raw(const char *path)
|
||||
{
|
||||
struct btf *btf;
|
||||
size_t read_cnt;
|
||||
struct stat st;
|
||||
void *data;
|
||||
FILE *f;
|
||||
|
||||
if (stat(path, &st))
|
||||
return ERR_PTR(-errno);
|
||||
|
||||
data = malloc(st.st_size);
|
||||
if (!data)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
f = fopen(path, "rb");
|
||||
if (!f) {
|
||||
btf = ERR_PTR(-errno);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
read_cnt = fread(data, 1, st.st_size, f);
|
||||
fclose(f);
|
||||
if (read_cnt < st.st_size) {
|
||||
btf = ERR_PTR(-EBADF);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
btf = btf__new(data, read_cnt);
|
||||
|
||||
cleanup:
|
||||
free(data);
|
||||
return btf;
|
||||
}
|
||||
|
||||
/*
|
||||
* Probe few well-known locations for vmlinux kernel image and try to load BTF
|
||||
* data out of it to use for target BTF.
|
||||
@ -3021,7 +3063,7 @@ struct btf *libbpf_find_kernel_btf(void)
|
||||
continue;
|
||||
|
||||
if (locations[i].raw_btf)
|
||||
btf = btf_load_raw(path);
|
||||
btf = btf__parse_raw(path);
|
||||
else
|
||||
btf = btf__parse_elf(path, NULL);
|
||||
|
||||
|
@ -64,8 +64,9 @@ struct btf_ext_header {
|
||||
|
||||
LIBBPF_API void btf__free(struct btf *btf);
|
||||
LIBBPF_API struct btf *btf__new(const void *data, __u32 size);
|
||||
LIBBPF_API struct btf *btf__parse_elf(const char *path,
|
||||
struct btf_ext **btf_ext);
|
||||
LIBBPF_API struct btf *btf__parse(const char *path, struct btf_ext **btf_ext);
|
||||
LIBBPF_API struct btf *btf__parse_elf(const char *path, struct btf_ext **btf_ext);
|
||||
LIBBPF_API struct btf *btf__parse_raw(const char *path);
|
||||
LIBBPF_API int btf__finalize_data(struct bpf_object *obj, struct btf *btf);
|
||||
LIBBPF_API int btf__load(struct btf *btf);
|
||||
LIBBPF_API __s32 btf__find_by_name(const struct btf *btf,
|
||||
|
@ -293,5 +293,7 @@ LIBBPF_0.1.0 {
|
||||
bpf_program__is_sk_lookup;
|
||||
bpf_program__set_autoload;
|
||||
bpf_program__set_sk_lookup;
|
||||
btf__parse;
|
||||
btf__parse_raw;
|
||||
btf__set_fd;
|
||||
} LIBBPF_0.0.9;
|
||||
|
Loading…
Reference in New Issue
Block a user