Skip to content

Commit 58650cc

Browse files
anakryikoAlexei Starovoitov
authored andcommitted
bpftool: use libbpf's btf__parse_elf API
Use btf__parse_elf() API, provided by libbpf, instead of implementing ELF parsing by itself. Signed-off-by: Andrii Nakryiko <andriin@fb.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
1 parent e6c6485 commit 58650cc

File tree

1 file changed

+8
-109
lines changed

1 file changed

+8
-109
lines changed

tools/bpf/bpftool/btf.c

Lines changed: 8 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
#include <stdio.h>
99
#include <string.h>
1010
#include <unistd.h>
11-
#include <gelf.h>
1211
#include <bpf.h>
12+
#include <libbpf.h>
1313
#include <linux/btf.h>
1414

1515
#include "btf.h"
@@ -340,112 +340,6 @@ static int dump_btf_raw(const struct btf *btf,
340340
return 0;
341341
}
342342

343-
static bool check_btf_endianness(GElf_Ehdr *ehdr)
344-
{
345-
static unsigned int const endian = 1;
346-
347-
switch (ehdr->e_ident[EI_DATA]) {
348-
case ELFDATA2LSB:
349-
return *(unsigned char const *)&endian == 1;
350-
case ELFDATA2MSB:
351-
return *(unsigned char const *)&endian == 0;
352-
default:
353-
return 0;
354-
}
355-
}
356-
357-
static int btf_load_from_elf(const char *path, struct btf **btf)
358-
{
359-
int err = -1, fd = -1, idx = 0;
360-
Elf_Data *btf_data = NULL;
361-
Elf_Scn *scn = NULL;
362-
Elf *elf = NULL;
363-
GElf_Ehdr ehdr;
364-
365-
if (elf_version(EV_CURRENT) == EV_NONE) {
366-
p_err("failed to init libelf for %s", path);
367-
return -1;
368-
}
369-
370-
fd = open(path, O_RDONLY);
371-
if (fd < 0) {
372-
p_err("failed to open %s: %s", path, strerror(errno));
373-
return -1;
374-
}
375-
376-
elf = elf_begin(fd, ELF_C_READ, NULL);
377-
if (!elf) {
378-
p_err("failed to open %s as ELF file", path);
379-
goto done;
380-
}
381-
if (!gelf_getehdr(elf, &ehdr)) {
382-
p_err("failed to get EHDR from %s", path);
383-
goto done;
384-
}
385-
if (!check_btf_endianness(&ehdr)) {
386-
p_err("non-native ELF endianness is not supported");
387-
goto done;
388-
}
389-
if (!elf_rawdata(elf_getscn(elf, ehdr.e_shstrndx), NULL)) {
390-
p_err("failed to get e_shstrndx from %s\n", path);
391-
goto done;
392-
}
393-
394-
while ((scn = elf_nextscn(elf, scn)) != NULL) {
395-
GElf_Shdr sh;
396-
char *name;
397-
398-
idx++;
399-
if (gelf_getshdr(scn, &sh) != &sh) {
400-
p_err("failed to get section(%d) header from %s",
401-
idx, path);
402-
goto done;
403-
}
404-
name = elf_strptr(elf, ehdr.e_shstrndx, sh.sh_name);
405-
if (!name) {
406-
p_err("failed to get section(%d) name from %s",
407-
idx, path);
408-
goto done;
409-
}
410-
if (strcmp(name, BTF_ELF_SEC) == 0) {
411-
btf_data = elf_getdata(scn, 0);
412-
if (!btf_data) {
413-
p_err("failed to get section(%d, %s) data from %s",
414-
idx, name, path);
415-
goto done;
416-
}
417-
break;
418-
}
419-
}
420-
421-
if (!btf_data) {
422-
p_err("%s ELF section not found in %s", BTF_ELF_SEC, path);
423-
goto done;
424-
}
425-
426-
*btf = btf__new(btf_data->d_buf, btf_data->d_size);
427-
if (IS_ERR(*btf)) {
428-
err = PTR_ERR(*btf);
429-
*btf = NULL;
430-
p_err("failed to load BTF data from %s: %s",
431-
path, strerror(err));
432-
goto done;
433-
}
434-
435-
err = 0;
436-
done:
437-
if (err) {
438-
if (*btf) {
439-
btf__free(*btf);
440-
*btf = NULL;
441-
}
442-
}
443-
if (elf)
444-
elf_end(elf);
445-
close(fd);
446-
return err;
447-
}
448-
449343
static int do_dump(int argc, char **argv)
450344
{
451345
struct btf *btf = NULL;
@@ -522,9 +416,14 @@ static int do_dump(int argc, char **argv)
522416
}
523417
NEXT_ARG();
524418
} else if (is_prefix(src, "file")) {
525-
err = btf_load_from_elf(*argv, &btf);
526-
if (err)
419+
btf = btf__parse_elf(*argv, NULL);
420+
if (IS_ERR(btf)) {
421+
err = PTR_ERR(btf);
422+
btf = NULL;
423+
p_err("failed to load BTF from %s: %s",
424+
*argv, strerror(err));
527425
goto done;
426+
}
528427
NEXT_ARG();
529428
} else {
530429
err = -1;

0 commit comments

Comments
 (0)