mirror of
https://github.com/netdata/libbpf.git
synced 2026-03-22 01:09:06 +08:00
libbpf: Pull file-opening logic up to top-level functions
Move the filename arguments and file-descriptor handling from init_output_elf() and linker_load_obj_file() and instead handle them at the top-level in bpf_linker__new() and bpf_linker__add_file(). This will allow the inner functions to be shared with a new, non-filename-based, API in the next commit. Signed-off-by: Alastair Robertson <ajor@meta.com> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Link: https://lore.kernel.org/bpf/20241211164030.573042-2-ajor@meta.com
This commit is contained in:
committed by
Andrii Nakryiko
parent
984dcc97ae
commit
f00fad0951
84
src/linker.c
84
src/linker.c
@@ -157,10 +157,9 @@ struct bpf_linker {
|
||||
#define pr_warn_elf(fmt, ...) \
|
||||
libbpf_print(LIBBPF_WARN, "libbpf: " fmt ": %s\n", ##__VA_ARGS__, elf_errmsg(-1))
|
||||
|
||||
static int init_output_elf(struct bpf_linker *linker, const char *file);
|
||||
static int init_output_elf(struct bpf_linker *linker);
|
||||
|
||||
static int linker_load_obj_file(struct bpf_linker *linker, const char *filename,
|
||||
const struct bpf_linker_file_opts *opts,
|
||||
static int linker_load_obj_file(struct bpf_linker *linker,
|
||||
struct src_obj *obj);
|
||||
static int linker_sanity_check_elf(struct src_obj *obj);
|
||||
static int linker_sanity_check_elf_symtab(struct src_obj *obj, struct src_sec *sec);
|
||||
@@ -233,9 +232,20 @@ struct bpf_linker *bpf_linker__new(const char *filename, struct bpf_linker_opts
|
||||
if (!linker)
|
||||
return errno = ENOMEM, NULL;
|
||||
|
||||
linker->fd = -1;
|
||||
linker->filename = strdup(filename);
|
||||
if (!linker->filename) {
|
||||
err = -ENOMEM;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
err = init_output_elf(linker, filename);
|
||||
linker->fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0644);
|
||||
if (linker->fd < 0) {
|
||||
err = -errno;
|
||||
pr_warn("failed to create '%s': %d\n", filename, err);
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
err = init_output_elf(linker);
|
||||
if (err)
|
||||
goto err_out;
|
||||
|
||||
@@ -294,23 +304,12 @@ static Elf64_Sym *add_new_sym(struct bpf_linker *linker, size_t *sym_idx)
|
||||
return sym;
|
||||
}
|
||||
|
||||
static int init_output_elf(struct bpf_linker *linker, const char *file)
|
||||
static int init_output_elf(struct bpf_linker *linker)
|
||||
{
|
||||
int err, str_off;
|
||||
Elf64_Sym *init_sym;
|
||||
struct dst_sec *sec;
|
||||
|
||||
linker->filename = strdup(file);
|
||||
if (!linker->filename)
|
||||
return -ENOMEM;
|
||||
|
||||
linker->fd = open(file, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0644);
|
||||
if (linker->fd < 0) {
|
||||
err = -errno;
|
||||
pr_warn("failed to create '%s': %s\n", file, errstr(err));
|
||||
return err;
|
||||
}
|
||||
|
||||
linker->elf = elf_begin(linker->fd, ELF_C_WRITE, NULL);
|
||||
if (!linker->elf) {
|
||||
pr_warn_elf("failed to create ELF object");
|
||||
@@ -440,7 +439,7 @@ int bpf_linker__add_file(struct bpf_linker *linker, const char *filename,
|
||||
const struct bpf_linker_file_opts *opts)
|
||||
{
|
||||
struct src_obj obj = {};
|
||||
int err = 0;
|
||||
int err = 0, fd;
|
||||
|
||||
if (!OPTS_VALID(opts, bpf_linker_file_opts))
|
||||
return libbpf_err(-EINVAL);
|
||||
@@ -448,7 +447,17 @@ int bpf_linker__add_file(struct bpf_linker *linker, const char *filename,
|
||||
if (!linker->elf)
|
||||
return libbpf_err(-EINVAL);
|
||||
|
||||
err = err ?: linker_load_obj_file(linker, filename, opts, &obj);
|
||||
fd = open(filename, O_RDONLY | O_CLOEXEC);
|
||||
if (fd < 0) {
|
||||
err = -errno;
|
||||
pr_warn("failed to open file '%s': %s\n", filename, errstr(err));
|
||||
return libbpf_err(err);
|
||||
}
|
||||
|
||||
obj.filename = filename;
|
||||
obj.fd = fd;
|
||||
|
||||
err = err ?: linker_load_obj_file(linker, &obj);
|
||||
err = err ?: linker_append_sec_data(linker, &obj);
|
||||
err = err ?: linker_append_elf_syms(linker, &obj);
|
||||
err = err ?: linker_append_elf_relos(linker, &obj);
|
||||
@@ -534,8 +543,7 @@ static struct src_sec *add_src_sec(struct src_obj *obj, const char *sec_name)
|
||||
return sec;
|
||||
}
|
||||
|
||||
static int linker_load_obj_file(struct bpf_linker *linker, const char *filename,
|
||||
const struct bpf_linker_file_opts *opts,
|
||||
static int linker_load_obj_file(struct bpf_linker *linker,
|
||||
struct src_obj *obj)
|
||||
{
|
||||
int err = 0;
|
||||
@@ -554,26 +562,18 @@ static int linker_load_obj_file(struct bpf_linker *linker, const char *filename,
|
||||
#error "Unknown __BYTE_ORDER__"
|
||||
#endif
|
||||
|
||||
pr_debug("linker: adding object file '%s'...\n", filename);
|
||||
pr_debug("linker: adding object file '%s'...\n", obj->filename);
|
||||
|
||||
obj->filename = filename;
|
||||
|
||||
obj->fd = open(filename, O_RDONLY | O_CLOEXEC);
|
||||
if (obj->fd < 0) {
|
||||
err = -errno;
|
||||
pr_warn("failed to open file '%s': %s\n", filename, errstr(err));
|
||||
return err;
|
||||
}
|
||||
obj->elf = elf_begin(obj->fd, ELF_C_READ_MMAP, NULL);
|
||||
if (!obj->elf) {
|
||||
pr_warn_elf("failed to parse ELF file '%s'", filename);
|
||||
pr_warn_elf("failed to parse ELF file '%s'", obj->filename);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Sanity check ELF file high-level properties */
|
||||
ehdr = elf64_getehdr(obj->elf);
|
||||
if (!ehdr) {
|
||||
pr_warn_elf("failed to get ELF header for %s", filename);
|
||||
pr_warn_elf("failed to get ELF header for %s", obj->filename);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -581,7 +581,7 @@ static int linker_load_obj_file(struct bpf_linker *linker, const char *filename,
|
||||
obj_byteorder = ehdr->e_ident[EI_DATA];
|
||||
if (obj_byteorder != ELFDATA2LSB && obj_byteorder != ELFDATA2MSB) {
|
||||
err = -EOPNOTSUPP;
|
||||
pr_warn("unknown byte order of ELF file %s\n", filename);
|
||||
pr_warn("unknown byte order of ELF file %s\n", obj->filename);
|
||||
return err;
|
||||
}
|
||||
if (link_byteorder == ELFDATANONE) {
|
||||
@@ -591,7 +591,7 @@ static int linker_load_obj_file(struct bpf_linker *linker, const char *filename,
|
||||
obj_byteorder == ELFDATA2MSB ? "big" : "little");
|
||||
} else if (link_byteorder != obj_byteorder) {
|
||||
err = -EOPNOTSUPP;
|
||||
pr_warn("byte order mismatch with ELF file %s\n", filename);
|
||||
pr_warn("byte order mismatch with ELF file %s\n", obj->filename);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -599,12 +599,12 @@ static int linker_load_obj_file(struct bpf_linker *linker, const char *filename,
|
||||
|| ehdr->e_machine != EM_BPF
|
||||
|| ehdr->e_ident[EI_CLASS] != ELFCLASS64) {
|
||||
err = -EOPNOTSUPP;
|
||||
pr_warn_elf("unsupported kind of ELF file %s", filename);
|
||||
pr_warn_elf("unsupported kind of ELF file %s", obj->filename);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (elf_getshdrstrndx(obj->elf, &obj->shstrs_sec_idx)) {
|
||||
pr_warn_elf("failed to get SHSTRTAB section index for %s", filename);
|
||||
pr_warn_elf("failed to get SHSTRTAB section index for %s", obj->filename);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -616,21 +616,21 @@ static int linker_load_obj_file(struct bpf_linker *linker, const char *filename,
|
||||
shdr = elf64_getshdr(scn);
|
||||
if (!shdr) {
|
||||
pr_warn_elf("failed to get section #%zu header for %s",
|
||||
sec_idx, filename);
|
||||
sec_idx, obj->filename);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sec_name = elf_strptr(obj->elf, obj->shstrs_sec_idx, shdr->sh_name);
|
||||
if (!sec_name) {
|
||||
pr_warn_elf("failed to get section #%zu name for %s",
|
||||
sec_idx, filename);
|
||||
sec_idx, obj->filename);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
data = elf_getdata(scn, 0);
|
||||
if (!data) {
|
||||
pr_warn_elf("failed to get section #%zu (%s) data from %s",
|
||||
sec_idx, sec_name, filename);
|
||||
sec_idx, sec_name, obj->filename);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -666,7 +666,7 @@ static int linker_load_obj_file(struct bpf_linker *linker, const char *filename,
|
||||
err = libbpf_get_error(obj->btf);
|
||||
if (err) {
|
||||
pr_warn("failed to parse .BTF from %s: %s\n",
|
||||
filename, errstr(err));
|
||||
obj->filename, errstr(err));
|
||||
return err;
|
||||
}
|
||||
sec->skipped = true;
|
||||
@@ -677,7 +677,7 @@ static int linker_load_obj_file(struct bpf_linker *linker, const char *filename,
|
||||
err = libbpf_get_error(obj->btf_ext);
|
||||
if (err) {
|
||||
pr_warn("failed to parse .BTF.ext from '%s': %s\n",
|
||||
filename, errstr(err));
|
||||
obj->filename, errstr(err));
|
||||
return err;
|
||||
}
|
||||
sec->skipped = true;
|
||||
@@ -694,7 +694,7 @@ static int linker_load_obj_file(struct bpf_linker *linker, const char *filename,
|
||||
break;
|
||||
default:
|
||||
pr_warn("unrecognized section #%zu (%s) in %s\n",
|
||||
sec_idx, sec_name, filename);
|
||||
sec_idx, sec_name, obj->filename);
|
||||
err = -EINVAL;
|
||||
return err;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user