Skip to content

Commit 434fdce

Browse files
d-e-s-oanakryiko
authored andcommitted
libbpf: Introduce elf_find_func_offset_from_file() function
This change splits the elf_find_func_offset() function in two: elf_find_func_offset(), which now accepts an already opened Elf object instead of a path to a file that is to be opened, as well as elf_find_func_offset_from_file(), which opens a binary based on a path and then invokes elf_find_func_offset() on the Elf object. Having this split in responsibilities will allow us to call elf_find_func_offset() from other code paths on Elf objects that did not necessarily come from a file on disk. Signed-off-by: Daniel Müller <[email protected]> Signed-off-by: Andrii Nakryiko <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent 1eebcb6 commit 434fdce

File tree

1 file changed

+36
-21
lines changed

1 file changed

+36
-21
lines changed

tools/lib/bpf/libbpf.c

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10530,32 +10530,19 @@ static Elf_Scn *elf_find_next_scn_by_type(Elf *elf, int sh_type, Elf_Scn *scn)
1053010530
return NULL;
1053110531
}
1053210532

10533-
/* Find offset of function name in object specified by path. "name" matches
10534-
* symbol name or name@@LIB for library functions.
10533+
/* Find offset of function name in the provided ELF object. "binary_path" is
10534+
* the path to the ELF binary represented by "elf", and only used for error
10535+
* reporting matters. "name" matches symbol name or name@@LIB for library
10536+
* functions.
1053510537
*/
10536-
static long elf_find_func_offset(const char *binary_path, const char *name)
10538+
static long elf_find_func_offset(Elf *elf, const char *binary_path, const char *name)
1053710539
{
10538-
int fd, i, sh_types[2] = { SHT_DYNSYM, SHT_SYMTAB };
10540+
int i, sh_types[2] = { SHT_DYNSYM, SHT_SYMTAB };
1053910541
bool is_shared_lib, is_name_qualified;
10540-
char errmsg[STRERR_BUFSIZE];
1054110542
long ret = -ENOENT;
1054210543
size_t name_len;
1054310544
GElf_Ehdr ehdr;
10544-
Elf *elf;
1054510545

10546-
fd = open(binary_path, O_RDONLY | O_CLOEXEC);
10547-
if (fd < 0) {
10548-
ret = -errno;
10549-
pr_warn("failed to open %s: %s\n", binary_path,
10550-
libbpf_strerror_r(ret, errmsg, sizeof(errmsg)));
10551-
return ret;
10552-
}
10553-
elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
10554-
if (!elf) {
10555-
pr_warn("elf: could not read elf from %s: %s\n", binary_path, elf_errmsg(-1));
10556-
close(fd);
10557-
return -LIBBPF_ERRNO__FORMAT;
10558-
}
1055910546
if (!gelf_getehdr(elf, &ehdr)) {
1056010547
pr_warn("elf: failed to get ehdr from %s: %s\n", binary_path, elf_errmsg(-1));
1056110548
ret = -LIBBPF_ERRNO__FORMAT;
@@ -10568,7 +10555,7 @@ static long elf_find_func_offset(const char *binary_path, const char *name)
1056810555
/* Does name specify "@@LIB"? */
1056910556
is_name_qualified = strstr(name, "@@") != NULL;
1057010557

10571-
/* Search SHT_DYNSYM, SHT_SYMTAB for symbol. This search order is used because if
10558+
/* Search SHT_DYNSYM, SHT_SYMTAB for symbol. This search order is used because if
1057210559
* a binary is stripped, it may only have SHT_DYNSYM, and a fully-statically
1057310560
* linked binary may not have SHT_DYMSYM, so absence of a section should not be
1057410561
* reported as a warning/error.
@@ -10681,6 +10668,34 @@ static long elf_find_func_offset(const char *binary_path, const char *name)
1068110668
}
1068210669
}
1068310670
out:
10671+
return ret;
10672+
}
10673+
10674+
/* Find offset of function name in ELF object specified by path. "name" matches
10675+
* symbol name or name@@LIB for library functions.
10676+
*/
10677+
static long elf_find_func_offset_from_file(const char *binary_path, const char *name)
10678+
{
10679+
char errmsg[STRERR_BUFSIZE];
10680+
long ret = -ENOENT;
10681+
Elf *elf;
10682+
int fd;
10683+
10684+
fd = open(binary_path, O_RDONLY | O_CLOEXEC);
10685+
if (fd < 0) {
10686+
ret = -errno;
10687+
pr_warn("failed to open %s: %s\n", binary_path,
10688+
libbpf_strerror_r(ret, errmsg, sizeof(errmsg)));
10689+
return ret;
10690+
}
10691+
elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
10692+
if (!elf) {
10693+
pr_warn("elf: could not read elf from %s: %s\n", binary_path, elf_errmsg(-1));
10694+
close(fd);
10695+
return -LIBBPF_ERRNO__FORMAT;
10696+
}
10697+
10698+
ret = elf_find_func_offset(elf, binary_path, name);
1068410699
elf_end(elf);
1068510700
close(fd);
1068610701
return ret;
@@ -10804,7 +10819,7 @@ bpf_program__attach_uprobe_opts(const struct bpf_program *prog, pid_t pid,
1080410819
if (func_name) {
1080510820
long sym_off;
1080610821

10807-
sym_off = elf_find_func_offset(binary_path, func_name);
10822+
sym_off = elf_find_func_offset_from_file(binary_path, func_name);
1080810823
if (sym_off < 0)
1080910824
return libbpf_err_ptr(sym_off);
1081010825
func_offset += sym_off;

0 commit comments

Comments
 (0)