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 <deso@posteo.net> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Link: https://lore.kernel.org/bpf/20230301212308.1839139-3-deso@posteo.net
This commit is contained in:
parent
1eebcb6063
commit
434fdcead7
|
@ -10530,32 +10530,19 @@ static Elf_Scn *elf_find_next_scn_by_type(Elf *elf, int sh_type, Elf_Scn *scn)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Find offset of function name in object specified by path. "name" matches
|
||||
* symbol name or name@@LIB for library functions.
|
||||
/* Find offset of function name in the provided ELF object. "binary_path" is
|
||||
* the path to the ELF binary represented by "elf", and only used for error
|
||||
* reporting matters. "name" matches symbol name or name@@LIB for library
|
||||
* functions.
|
||||
*/
|
||||
static long elf_find_func_offset(const char *binary_path, const char *name)
|
||||
static long elf_find_func_offset(Elf *elf, const char *binary_path, const char *name)
|
||||
{
|
||||
int fd, i, sh_types[2] = { SHT_DYNSYM, SHT_SYMTAB };
|
||||
int i, sh_types[2] = { SHT_DYNSYM, SHT_SYMTAB };
|
||||
bool is_shared_lib, is_name_qualified;
|
||||
char errmsg[STRERR_BUFSIZE];
|
||||
long ret = -ENOENT;
|
||||
size_t name_len;
|
||||
GElf_Ehdr ehdr;
|
||||
Elf *elf;
|
||||
|
||||
fd = open(binary_path, O_RDONLY | O_CLOEXEC);
|
||||
if (fd < 0) {
|
||||
ret = -errno;
|
||||
pr_warn("failed to open %s: %s\n", binary_path,
|
||||
libbpf_strerror_r(ret, errmsg, sizeof(errmsg)));
|
||||
return ret;
|
||||
}
|
||||
elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
|
||||
if (!elf) {
|
||||
pr_warn("elf: could not read elf from %s: %s\n", binary_path, elf_errmsg(-1));
|
||||
close(fd);
|
||||
return -LIBBPF_ERRNO__FORMAT;
|
||||
}
|
||||
if (!gelf_getehdr(elf, &ehdr)) {
|
||||
pr_warn("elf: failed to get ehdr from %s: %s\n", binary_path, elf_errmsg(-1));
|
||||
ret = -LIBBPF_ERRNO__FORMAT;
|
||||
|
@ -10568,7 +10555,7 @@ static long elf_find_func_offset(const char *binary_path, const char *name)
|
|||
/* Does name specify "@@LIB"? */
|
||||
is_name_qualified = strstr(name, "@@") != NULL;
|
||||
|
||||
/* Search SHT_DYNSYM, SHT_SYMTAB for symbol. This search order is used because if
|
||||
/* Search SHT_DYNSYM, SHT_SYMTAB for symbol. This search order is used because if
|
||||
* a binary is stripped, it may only have SHT_DYNSYM, and a fully-statically
|
||||
* linked binary may not have SHT_DYMSYM, so absence of a section should not be
|
||||
* reported as a warning/error.
|
||||
|
@ -10681,6 +10668,34 @@ static long elf_find_func_offset(const char *binary_path, const char *name)
|
|||
}
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Find offset of function name in ELF object specified by path. "name" matches
|
||||
* symbol name or name@@LIB for library functions.
|
||||
*/
|
||||
static long elf_find_func_offset_from_file(const char *binary_path, const char *name)
|
||||
{
|
||||
char errmsg[STRERR_BUFSIZE];
|
||||
long ret = -ENOENT;
|
||||
Elf *elf;
|
||||
int fd;
|
||||
|
||||
fd = open(binary_path, O_RDONLY | O_CLOEXEC);
|
||||
if (fd < 0) {
|
||||
ret = -errno;
|
||||
pr_warn("failed to open %s: %s\n", binary_path,
|
||||
libbpf_strerror_r(ret, errmsg, sizeof(errmsg)));
|
||||
return ret;
|
||||
}
|
||||
elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
|
||||
if (!elf) {
|
||||
pr_warn("elf: could not read elf from %s: %s\n", binary_path, elf_errmsg(-1));
|
||||
close(fd);
|
||||
return -LIBBPF_ERRNO__FORMAT;
|
||||
}
|
||||
|
||||
ret = elf_find_func_offset(elf, binary_path, name);
|
||||
elf_end(elf);
|
||||
close(fd);
|
||||
return ret;
|
||||
|
@ -10804,7 +10819,7 @@ bpf_program__attach_uprobe_opts(const struct bpf_program *prog, pid_t pid,
|
|||
if (func_name) {
|
||||
long sym_off;
|
||||
|
||||
sym_off = elf_find_func_offset(binary_path, func_name);
|
||||
sym_off = elf_find_func_offset_from_file(binary_path, func_name);
|
||||
if (sym_off < 0)
|
||||
return libbpf_err_ptr(sym_off);
|
||||
func_offset += sym_off;
|
||||
|
|
Loading…
Reference in New Issue