mirror of
https://github.com/netdata/libbpf.git
synced 2026-04-09 10:09:07 +08:00
libbpf: Add elf_resolve_pattern_offsets function
Adding elf_resolve_pattern_offsets function that looks up offsets for symbols specified by pattern argument. The 'pattern' argument allows wildcards (*?' supported). Offsets are returned in allocated array together with its size and needs to be released by the caller. Signed-off-by: Jiri Olsa <jolsa@kernel.org> Link: https://lore.kernel.org/r/20230809083440.3209381-13-jolsa@kernel.org Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
committed by
Andrii Nakryiko
parent
91fd655644
commit
c7ef3a169e
61
src/elf.c
61
src/elf.c
@@ -377,3 +377,64 @@ out:
|
|||||||
elf_close(&elf_fd);
|
elf_close(&elf_fd);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return offsets in @poffsets for symbols specified by @pattern argument.
|
||||||
|
* On success returns 0 and offsets are returned in allocated @poffsets
|
||||||
|
* array with the @pctn size, that needs to be released by the caller.
|
||||||
|
*/
|
||||||
|
int elf_resolve_pattern_offsets(const char *binary_path, const char *pattern,
|
||||||
|
unsigned long **poffsets, size_t *pcnt)
|
||||||
|
{
|
||||||
|
int sh_types[2] = { SHT_SYMTAB, SHT_DYNSYM };
|
||||||
|
unsigned long *offsets = NULL;
|
||||||
|
size_t cap = 0, cnt = 0;
|
||||||
|
struct elf_fd elf_fd;
|
||||||
|
int err = 0, i;
|
||||||
|
|
||||||
|
err = elf_open(binary_path, &elf_fd);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(sh_types); i++) {
|
||||||
|
struct elf_sym_iter iter;
|
||||||
|
struct elf_sym *sym;
|
||||||
|
|
||||||
|
err = elf_sym_iter_new(&iter, elf_fd.elf, binary_path, sh_types[i], STT_FUNC);
|
||||||
|
if (err == -ENOENT)
|
||||||
|
continue;
|
||||||
|
if (err)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
while ((sym = elf_sym_iter_next(&iter))) {
|
||||||
|
if (!glob_match(sym->name, pattern))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
err = libbpf_ensure_mem((void **) &offsets, &cap, sizeof(*offsets),
|
||||||
|
cnt + 1);
|
||||||
|
if (err)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
offsets[cnt++] = elf_sym_offset(sym);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we found anything in the first symbol section,
|
||||||
|
* do not search others to avoid duplicates.
|
||||||
|
*/
|
||||||
|
if (cnt)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cnt) {
|
||||||
|
*poffsets = offsets;
|
||||||
|
*pcnt = cnt;
|
||||||
|
} else {
|
||||||
|
err = -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (err)
|
||||||
|
free(offsets);
|
||||||
|
elf_close(&elf_fd);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|||||||
@@ -10569,7 +10569,7 @@ struct bpf_link *bpf_program__attach_ksyscall(const struct bpf_program *prog,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Adapted from perf/util/string.c */
|
/* Adapted from perf/util/string.c */
|
||||||
static bool glob_match(const char *str, const char *pat)
|
bool glob_match(const char *str, const char *pat)
|
||||||
{
|
{
|
||||||
while (*str && *pat && *pat != '*') {
|
while (*str && *pat && *pat != '*') {
|
||||||
if (*pat == '?') { /* Matches any single character */
|
if (*pat == '?') { /* Matches any single character */
|
||||||
|
|||||||
@@ -578,6 +578,8 @@ static inline bool is_pow_of_2(size_t x)
|
|||||||
#define PROG_LOAD_ATTEMPTS 5
|
#define PROG_LOAD_ATTEMPTS 5
|
||||||
int sys_bpf_prog_load(union bpf_attr *attr, unsigned int size, int attempts);
|
int sys_bpf_prog_load(union bpf_attr *attr, unsigned int size, int attempts);
|
||||||
|
|
||||||
|
bool glob_match(const char *str, const char *pat);
|
||||||
|
|
||||||
long elf_find_func_offset(Elf *elf, const char *binary_path, const char *name);
|
long elf_find_func_offset(Elf *elf, const char *binary_path, const char *name);
|
||||||
long elf_find_func_offset_from_file(const char *binary_path, const char *name);
|
long elf_find_func_offset_from_file(const char *binary_path, const char *name);
|
||||||
|
|
||||||
@@ -591,4 +593,7 @@ void elf_close(struct elf_fd *elf_fd);
|
|||||||
|
|
||||||
int elf_resolve_syms_offsets(const char *binary_path, int cnt,
|
int elf_resolve_syms_offsets(const char *binary_path, int cnt,
|
||||||
const char **syms, unsigned long **poffsets);
|
const char **syms, unsigned long **poffsets);
|
||||||
|
int elf_resolve_pattern_offsets(const char *binary_path, const char *pattern,
|
||||||
|
unsigned long **poffsets, size_t *pcnt);
|
||||||
|
|
||||||
#endif /* __LIBBPF_LIBBPF_INTERNAL_H */
|
#endif /* __LIBBPF_LIBBPF_INTERNAL_H */
|
||||||
|
|||||||
Reference in New Issue
Block a user