mirror of
https://github.com/netdata/libbpf.git
synced 2026-04-05 16:19:06 +08:00
libbpf: streamline ELF parsing error-handling
Simplify ELF parsing logic by exiting early, as there is no common clean up path to execute. That makes it unnecessary to track when err was set and when it was cleared. It also reduces nesting in some places. Signed-off-by: Andrii Nakryiko <andriin@fb.com> Acked-by: Song Liu <songliubraving@fb.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
This commit is contained in:
committed by
Andrii Nakryiko
parent
0559e41969
commit
bdf65f9fea
46
src/libbpf.c
46
src/libbpf.c
@@ -1154,24 +1154,21 @@ static int bpf_object__elf_collect(struct bpf_object *obj, int flags)
|
|||||||
if (gelf_getshdr(scn, &sh) != &sh) {
|
if (gelf_getshdr(scn, &sh) != &sh) {
|
||||||
pr_warning("failed to get section(%d) header from %s\n",
|
pr_warning("failed to get section(%d) header from %s\n",
|
||||||
idx, obj->path);
|
idx, obj->path);
|
||||||
err = -LIBBPF_ERRNO__FORMAT;
|
return -LIBBPF_ERRNO__FORMAT;
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
name = elf_strptr(elf, ep->e_shstrndx, sh.sh_name);
|
name = elf_strptr(elf, ep->e_shstrndx, sh.sh_name);
|
||||||
if (!name) {
|
if (!name) {
|
||||||
pr_warning("failed to get section(%d) name from %s\n",
|
pr_warning("failed to get section(%d) name from %s\n",
|
||||||
idx, obj->path);
|
idx, obj->path);
|
||||||
err = -LIBBPF_ERRNO__FORMAT;
|
return -LIBBPF_ERRNO__FORMAT;
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data = elf_getdata(scn, 0);
|
data = elf_getdata(scn, 0);
|
||||||
if (!data) {
|
if (!data) {
|
||||||
pr_warning("failed to get section(%d) data from %s(%s)\n",
|
pr_warning("failed to get section(%d) data from %s(%s)\n",
|
||||||
idx, name, obj->path);
|
idx, name, obj->path);
|
||||||
err = -LIBBPF_ERRNO__FORMAT;
|
return -LIBBPF_ERRNO__FORMAT;
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
pr_debug("section(%d) %s, size %ld, link %d, flags %lx, type=%d\n",
|
pr_debug("section(%d) %s, size %ld, link %d, flags %lx, type=%d\n",
|
||||||
idx, name, (unsigned long)data->d_size,
|
idx, name, (unsigned long)data->d_size,
|
||||||
@@ -1182,10 +1179,14 @@ static int bpf_object__elf_collect(struct bpf_object *obj, int flags)
|
|||||||
err = bpf_object__init_license(obj,
|
err = bpf_object__init_license(obj,
|
||||||
data->d_buf,
|
data->d_buf,
|
||||||
data->d_size);
|
data->d_size);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
} else if (strcmp(name, "version") == 0) {
|
} else if (strcmp(name, "version") == 0) {
|
||||||
err = bpf_object__init_kversion(obj,
|
err = bpf_object__init_kversion(obj,
|
||||||
data->d_buf,
|
data->d_buf,
|
||||||
data->d_size);
|
data->d_size);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
} else if (strcmp(name, "maps") == 0) {
|
} else if (strcmp(name, "maps") == 0) {
|
||||||
obj->efile.maps_shndx = idx;
|
obj->efile.maps_shndx = idx;
|
||||||
} else if (strcmp(name, BTF_ELF_SEC) == 0) {
|
} else if (strcmp(name, BTF_ELF_SEC) == 0) {
|
||||||
@@ -1196,11 +1197,10 @@ static int bpf_object__elf_collect(struct bpf_object *obj, int flags)
|
|||||||
if (obj->efile.symbols) {
|
if (obj->efile.symbols) {
|
||||||
pr_warning("bpf: multiple SYMTAB in %s\n",
|
pr_warning("bpf: multiple SYMTAB in %s\n",
|
||||||
obj->path);
|
obj->path);
|
||||||
err = -LIBBPF_ERRNO__FORMAT;
|
return -LIBBPF_ERRNO__FORMAT;
|
||||||
} else {
|
|
||||||
obj->efile.symbols = data;
|
|
||||||
obj->efile.strtabidx = sh.sh_link;
|
|
||||||
}
|
}
|
||||||
|
obj->efile.symbols = data;
|
||||||
|
obj->efile.strtabidx = sh.sh_link;
|
||||||
} else if (sh.sh_type == SHT_PROGBITS && data->d_size > 0) {
|
} else if (sh.sh_type == SHT_PROGBITS && data->d_size > 0) {
|
||||||
if (sh.sh_flags & SHF_EXECINSTR) {
|
if (sh.sh_flags & SHF_EXECINSTR) {
|
||||||
if (strcmp(name, ".text") == 0)
|
if (strcmp(name, ".text") == 0)
|
||||||
@@ -1214,6 +1214,7 @@ static int bpf_object__elf_collect(struct bpf_object *obj, int flags)
|
|||||||
|
|
||||||
pr_warning("failed to alloc program %s (%s): %s",
|
pr_warning("failed to alloc program %s (%s): %s",
|
||||||
name, obj->path, cp);
|
name, obj->path, cp);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
} else if (strcmp(name, ".data") == 0) {
|
} else if (strcmp(name, ".data") == 0) {
|
||||||
obj->efile.data = data;
|
obj->efile.data = data;
|
||||||
@@ -1225,8 +1226,8 @@ static int bpf_object__elf_collect(struct bpf_object *obj, int flags)
|
|||||||
pr_debug("skip section(%d) %s\n", idx, name);
|
pr_debug("skip section(%d) %s\n", idx, name);
|
||||||
}
|
}
|
||||||
} else if (sh.sh_type == SHT_REL) {
|
} else if (sh.sh_type == SHT_REL) {
|
||||||
|
int nr_reloc = obj->efile.nr_reloc;
|
||||||
void *reloc = obj->efile.reloc;
|
void *reloc = obj->efile.reloc;
|
||||||
int nr_reloc = obj->efile.nr_reloc + 1;
|
|
||||||
int sec = sh.sh_info; /* points to other section */
|
int sec = sh.sh_info; /* points to other section */
|
||||||
|
|
||||||
/* Only do relo for section with exec instructions */
|
/* Only do relo for section with exec instructions */
|
||||||
@@ -1236,28 +1237,24 @@ static int bpf_object__elf_collect(struct bpf_object *obj, int flags)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
reloc = reallocarray(reloc, nr_reloc,
|
reloc = reallocarray(reloc, nr_reloc + 1,
|
||||||
sizeof(*obj->efile.reloc));
|
sizeof(*obj->efile.reloc));
|
||||||
if (!reloc) {
|
if (!reloc) {
|
||||||
pr_warning("realloc failed\n");
|
pr_warning("realloc failed\n");
|
||||||
err = -ENOMEM;
|
return -ENOMEM;
|
||||||
} else {
|
|
||||||
int n = nr_reloc - 1;
|
|
||||||
|
|
||||||
obj->efile.reloc = reloc;
|
|
||||||
obj->efile.nr_reloc = nr_reloc;
|
|
||||||
|
|
||||||
obj->efile.reloc[n].shdr = sh;
|
|
||||||
obj->efile.reloc[n].data = data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
obj->efile.reloc = reloc;
|
||||||
|
obj->efile.nr_reloc++;
|
||||||
|
|
||||||
|
obj->efile.reloc[nr_reloc].shdr = sh;
|
||||||
|
obj->efile.reloc[nr_reloc].data = data;
|
||||||
} else if (sh.sh_type == SHT_NOBITS && strcmp(name, ".bss") == 0) {
|
} else if (sh.sh_type == SHT_NOBITS && strcmp(name, ".bss") == 0) {
|
||||||
obj->efile.bss = data;
|
obj->efile.bss = data;
|
||||||
obj->efile.bss_shndx = idx;
|
obj->efile.bss_shndx = idx;
|
||||||
} else {
|
} else {
|
||||||
pr_debug("skip section(%d) %s\n", idx, name);
|
pr_debug("skip section(%d) %s\n", idx, name);
|
||||||
}
|
}
|
||||||
if (err)
|
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!obj->efile.strtabidx || obj->efile.strtabidx >= idx) {
|
if (!obj->efile.strtabidx || obj->efile.strtabidx >= idx) {
|
||||||
@@ -1270,10 +1267,9 @@ static int bpf_object__elf_collect(struct bpf_object *obj, int flags)
|
|||||||
if (bpf_object__has_maps(obj)) {
|
if (bpf_object__has_maps(obj)) {
|
||||||
err = bpf_object__init_maps(obj, flags);
|
err = bpf_object__init_maps(obj, flags);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
return err;
|
||||||
}
|
}
|
||||||
err = bpf_object__init_prog_names(obj);
|
err = bpf_object__init_prog_names(obj);
|
||||||
out:
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user