Skip to content

Commit e613d1d

Browse files
olsajiriAlexei Starovoitov
authored andcommitted
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>
1 parent 7ace84c commit e613d1d

3 files changed

Lines changed: 67 additions & 1 deletion

File tree

tools/lib/bpf/elf.c

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,3 +377,64 @@ int elf_resolve_syms_offsets(const char *binary_path, int cnt,
377377
elf_close(&elf_fd);
378378
return err;
379379
}
380+
381+
/*
382+
* Return offsets in @poffsets for symbols specified by @pattern argument.
383+
* On success returns 0 and offsets are returned in allocated @poffsets
384+
* array with the @pctn size, that needs to be released by the caller.
385+
*/
386+
int elf_resolve_pattern_offsets(const char *binary_path, const char *pattern,
387+
unsigned long **poffsets, size_t *pcnt)
388+
{
389+
int sh_types[2] = { SHT_SYMTAB, SHT_DYNSYM };
390+
unsigned long *offsets = NULL;
391+
size_t cap = 0, cnt = 0;
392+
struct elf_fd elf_fd;
393+
int err = 0, i;
394+
395+
err = elf_open(binary_path, &elf_fd);
396+
if (err)
397+
return err;
398+
399+
for (i = 0; i < ARRAY_SIZE(sh_types); i++) {
400+
struct elf_sym_iter iter;
401+
struct elf_sym *sym;
402+
403+
err = elf_sym_iter_new(&iter, elf_fd.elf, binary_path, sh_types[i], STT_FUNC);
404+
if (err == -ENOENT)
405+
continue;
406+
if (err)
407+
goto out;
408+
409+
while ((sym = elf_sym_iter_next(&iter))) {
410+
if (!glob_match(sym->name, pattern))
411+
continue;
412+
413+
err = libbpf_ensure_mem((void **) &offsets, &cap, sizeof(*offsets),
414+
cnt + 1);
415+
if (err)
416+
goto out;
417+
418+
offsets[cnt++] = elf_sym_offset(sym);
419+
}
420+
421+
/* If we found anything in the first symbol section,
422+
* do not search others to avoid duplicates.
423+
*/
424+
if (cnt)
425+
break;
426+
}
427+
428+
if (cnt) {
429+
*poffsets = offsets;
430+
*pcnt = cnt;
431+
} else {
432+
err = -ENOENT;
433+
}
434+
435+
out:
436+
if (err)
437+
free(offsets);
438+
elf_close(&elf_fd);
439+
return err;
440+
}

tools/lib/bpf/libbpf.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10569,7 +10569,7 @@ struct bpf_link *bpf_program__attach_ksyscall(const struct bpf_program *prog,
1056910569
}
1057010570

1057110571
/* Adapted from perf/util/string.c */
10572-
static bool glob_match(const char *str, const char *pat)
10572+
bool glob_match(const char *str, const char *pat)
1057310573
{
1057410574
while (*str && *pat && *pat != '*') {
1057510575
if (*pat == '?') { /* Matches any single character */

tools/lib/bpf/libbpf_internal.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,8 @@ static inline bool is_pow_of_2(size_t x)
578578
#define PROG_LOAD_ATTEMPTS 5
579579
int sys_bpf_prog_load(union bpf_attr *attr, unsigned int size, int attempts);
580580

581+
bool glob_match(const char *str, const char *pat);
582+
581583
long elf_find_func_offset(Elf *elf, const char *binary_path, const char *name);
582584
long elf_find_func_offset_from_file(const char *binary_path, const char *name);
583585

@@ -591,4 +593,7 @@ void elf_close(struct elf_fd *elf_fd);
591593

592594
int elf_resolve_syms_offsets(const char *binary_path, int cnt,
593595
const char **syms, unsigned long **poffsets);
596+
int elf_resolve_pattern_offsets(const char *binary_path, const char *pattern,
597+
unsigned long **poffsets, size_t *pcnt);
598+
594599
#endif /* __LIBBPF_LIBBPF_INTERNAL_H */

0 commit comments

Comments
 (0)