Skip to content

Commit f90eb70

Browse files
olsajiriAlexei Starovoitov
authored andcommitted
libbpf: Add elf_open/elf_close functions
Adding elf_open/elf_close functions and using it in elf_find_func_offset_from_file function. It will be used in following changes to save some common code. Acked-by: Andrii Nakryiko <andrii@kernel.org> Signed-off-by: Jiri Olsa <jolsa@kernel.org> Link: https://lore.kernel.org/r/20230809083440.3209381-10-jolsa@kernel.org Signed-off-by: Alexei Starovoitov <ast@kernel.org>
1 parent 5c74272 commit f90eb70

3 files changed

Lines changed: 57 additions & 42 deletions

File tree

tools/lib/bpf/elf.c

Lines changed: 41 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,42 @@
1010

1111
#define STRERR_BUFSIZE 128
1212

13+
int elf_open(const char *binary_path, struct elf_fd *elf_fd)
14+
{
15+
char errmsg[STRERR_BUFSIZE];
16+
int fd, ret;
17+
Elf *elf;
18+
19+
if (elf_version(EV_CURRENT) == EV_NONE) {
20+
pr_warn("elf: failed to init libelf for %s\n", binary_path);
21+
return -LIBBPF_ERRNO__LIBELF;
22+
}
23+
fd = open(binary_path, O_RDONLY | O_CLOEXEC);
24+
if (fd < 0) {
25+
ret = -errno;
26+
pr_warn("elf: failed to open %s: %s\n", binary_path,
27+
libbpf_strerror_r(ret, errmsg, sizeof(errmsg)));
28+
return ret;
29+
}
30+
elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
31+
if (!elf) {
32+
pr_warn("elf: could not read elf from %s: %s\n", binary_path, elf_errmsg(-1));
33+
close(fd);
34+
return -LIBBPF_ERRNO__FORMAT;
35+
}
36+
elf_fd->fd = fd;
37+
elf_fd->elf = elf;
38+
return 0;
39+
}
40+
41+
void elf_close(struct elf_fd *elf_fd)
42+
{
43+
if (!elf_fd)
44+
return;
45+
elf_end(elf_fd->elf);
46+
close(elf_fd->fd);
47+
}
48+
1349
/* Return next ELF section of sh_type after scn, or first of that type if scn is NULL. */
1450
static Elf_Scn *elf_find_next_scn_by_type(Elf *elf, int sh_type, Elf_Scn *scn)
1551
{
@@ -170,28 +206,13 @@ long elf_find_func_offset(Elf *elf, const char *binary_path, const char *name)
170206
*/
171207
long elf_find_func_offset_from_file(const char *binary_path, const char *name)
172208
{
173-
char errmsg[STRERR_BUFSIZE];
209+
struct elf_fd elf_fd;
174210
long ret = -ENOENT;
175-
Elf *elf;
176-
int fd;
177211

178-
fd = open(binary_path, O_RDONLY | O_CLOEXEC);
179-
if (fd < 0) {
180-
ret = -errno;
181-
pr_warn("failed to open %s: %s\n", binary_path,
182-
libbpf_strerror_r(ret, errmsg, sizeof(errmsg)));
212+
ret = elf_open(binary_path, &elf_fd);
213+
if (ret)
183214
return ret;
184-
}
185-
elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
186-
if (!elf) {
187-
pr_warn("elf: could not read elf from %s: %s\n", binary_path, elf_errmsg(-1));
188-
close(fd);
189-
return -LIBBPF_ERRNO__FORMAT;
190-
}
191-
192-
ret = elf_find_func_offset(elf, binary_path, name);
193-
elf_end(elf);
194-
close(fd);
215+
ret = elf_find_func_offset(elf_fd.elf, binary_path, name);
216+
elf_close(&elf_fd);
195217
return ret;
196218
}
197-

tools/lib/bpf/libbpf_internal.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,4 +581,12 @@ int sys_bpf_prog_load(union bpf_attr *attr, unsigned int size, int attempts);
581581
long elf_find_func_offset(Elf *elf, const char *binary_path, const char *name);
582582
long elf_find_func_offset_from_file(const char *binary_path, const char *name);
583583

584+
struct elf_fd {
585+
Elf *elf;
586+
int fd;
587+
};
588+
589+
int elf_open(const char *binary_path, struct elf_fd *elf_fd);
590+
void elf_close(struct elf_fd *elf_fd);
591+
584592
#endif /* __LIBBPF_LIBBPF_INTERNAL_H */

tools/lib/bpf/usdt.c

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -946,32 +946,22 @@ struct bpf_link *usdt_manager_attach_usdt(struct usdt_manager *man, const struct
946946
const char *usdt_provider, const char *usdt_name,
947947
__u64 usdt_cookie)
948948
{
949-
int i, fd, err, spec_map_fd, ip_map_fd;
949+
int i, err, spec_map_fd, ip_map_fd;
950950
LIBBPF_OPTS(bpf_uprobe_opts, opts);
951951
struct hashmap *specs_hash = NULL;
952952
struct bpf_link_usdt *link = NULL;
953953
struct usdt_target *targets = NULL;
954+
struct elf_fd elf_fd;
954955
size_t target_cnt;
955-
Elf *elf;
956956

957957
spec_map_fd = bpf_map__fd(man->specs_map);
958958
ip_map_fd = bpf_map__fd(man->ip_to_spec_id_map);
959959

960-
fd = open(path, O_RDONLY | O_CLOEXEC);
961-
if (fd < 0) {
962-
err = -errno;
963-
pr_warn("usdt: failed to open ELF binary '%s': %d\n", path, err);
960+
err = elf_open(path, &elf_fd);
961+
if (err)
964962
return libbpf_err_ptr(err);
965-
}
966963

967-
elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
968-
if (!elf) {
969-
err = -EBADF;
970-
pr_warn("usdt: failed to parse ELF binary '%s': %s\n", path, elf_errmsg(-1));
971-
goto err_out;
972-
}
973-
974-
err = sanity_check_usdt_elf(elf, path);
964+
err = sanity_check_usdt_elf(elf_fd.elf, path);
975965
if (err)
976966
goto err_out;
977967

@@ -984,7 +974,7 @@ struct bpf_link *usdt_manager_attach_usdt(struct usdt_manager *man, const struct
984974
/* discover USDT in given binary, optionally limiting
985975
* activations to a given PID, if pid > 0
986976
*/
987-
err = collect_usdt_targets(man, elf, path, pid, usdt_provider, usdt_name,
977+
err = collect_usdt_targets(man, elf_fd.elf, path, pid, usdt_provider, usdt_name,
988978
usdt_cookie, &targets, &target_cnt);
989979
if (err <= 0) {
990980
err = (err == 0) ? -ENOENT : err;
@@ -1069,19 +1059,15 @@ struct bpf_link *usdt_manager_attach_usdt(struct usdt_manager *man, const struct
10691059

10701060
free(targets);
10711061
hashmap__free(specs_hash);
1072-
elf_end(elf);
1073-
close(fd);
1074-
1062+
elf_close(&elf_fd);
10751063
return &link->link;
10761064

10771065
err_out:
10781066
if (link)
10791067
bpf_link__destroy(&link->link);
10801068
free(targets);
10811069
hashmap__free(specs_hash);
1082-
if (elf)
1083-
elf_end(elf);
1084-
close(fd);
1070+
elf_close(&elf_fd);
10851071
return libbpf_err_ptr(err);
10861072
}
10871073

0 commit comments

Comments
 (0)