summaryrefslogtreecommitdiff
path: root/tools/perf/util/dso.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/dso.c')
-rw-r--r--tools/perf/util/dso.c65
1 files changed, 45 insertions, 20 deletions
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index dc202d494372..6fa104752de2 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -342,8 +342,14 @@ int filename__decompress(const char *name, char *pathname,
* To keep this transparent, we detect this and return the file
* descriptor to the uncompressed file.
*/
- if (!compressions[comp].is_compressed(name))
- return open(name, O_RDONLY);
+ if (!compressions[comp].is_compressed(name)) {
+ fd = open(name, O_RDONLY | O_CLOEXEC);
+ if (fd < 0)
+ *err = errno;
+ if (pathname && len > 0)
+ pathname[0] = '\0';
+ return fd;
+ }
fd = mkstemp(tmpbuf);
if (fd < 0) {
@@ -539,16 +545,13 @@ static void close_first_dso(void);
static int do_open(char *name) EXCLUSIVE_LOCKS_REQUIRED(_dso__data_open_lock)
{
- int fd;
- char sbuf[STRERR_BUFSIZE];
-
do {
- fd = open(name, O_RDONLY|O_CLOEXEC);
+ int fd = open(name, O_RDONLY|O_CLOEXEC);
+
if (fd >= 0)
return fd;
- pr_debug("dso open failed: %s\n",
- str_error_r(errno, sbuf, sizeof(sbuf)));
+ pr_debug("dso open failed: %m\n");
if (!dso__data_open_cnt || errno != EMFILE)
break;
@@ -596,12 +599,28 @@ static char *dso__get_filename(struct dso *dso, const char *root_dir,
size_t len = sizeof(newpath);
if (dso__decompress_kmodule_path(dso, name, newpath, len) < 0) {
- errno = *dso__load_errno(dso);
+ /*
+ * Use a standard errno value, not the negative custom
+ * DSO_LOAD_ERRNO stored in dso__load_errno(dso):
+ * __open_dso() computes fd = -errno, so a negative
+ * errno produces a positive fd that looks valid.
+ */
+ errno = EIO;
goto out;
}
- *decomp = true;
- strcpy(name, newpath);
+ /* empty pathname means file wasn't actually compressed */
+ if (newpath[0] != '\0') {
+ char *tmp = strdup(newpath);
+
+ if (!tmp) {
+ unlink(newpath);
+ goto out;
+ }
+ free(name);
+ name = tmp;
+ *decomp = true;
+ }
}
return name;
@@ -866,6 +885,12 @@ static ssize_t bpf_read(struct dso *dso, u64 offset, char *data)
return -1;
}
+ /* jited_prog_insns is only valid if bpil_offs_to_addr() converted it */
+ if (!(node->info_linear->arrays & (1UL << PERF_BPIL_JITED_INSNS))) {
+ dso__data(dso)->status = DSO_DATA_STATUS_ERROR;
+ return -1;
+ }
+
len = node->info_linear->info.jited_prog_len;
buf = (u8 *)(uintptr_t)node->info_linear->info.jited_prog_insns;
@@ -1110,7 +1135,6 @@ static int file_size(struct dso *dso, struct machine *machine)
{
int ret = 0;
struct stat st;
- char sbuf[STRERR_BUFSIZE];
mutex_lock(dso__data_open_lock());
@@ -1128,8 +1152,7 @@ static int file_size(struct dso *dso, struct machine *machine)
if (fstat(dso__data(dso)->fd, &st) < 0) {
ret = -errno;
- pr_err("dso cache fstat failed: %s\n",
- str_error_r(errno, sbuf, sizeof(sbuf)));
+ pr_err("dso cache fstat failed: %m\n");
dso__data(dso)->status = DSO_DATA_STATUS_ERROR;
goto out;
}
@@ -1703,7 +1726,7 @@ void dso__read_running_kernel_build_id(struct dso *dso, struct machine *machine)
if (machine__is_default_guest(machine))
return;
- sprintf(path, "%s/sys/kernel/notes", machine->root_dir);
+ snprintf(path, sizeof(path), "%s/sys/kernel/notes", machine->root_dir);
sysfs__read_build_id(path, &bid);
dso__set_build_id(dso, &bid);
}
@@ -1784,10 +1807,8 @@ int dso__strerror_load(struct dso *dso, char *buf, size_t buflen)
BUG_ON(buflen == 0);
if (errnum >= 0) {
- const char *err = str_error_r(errnum, buf, buflen);
-
- if (err != buf)
- scnprintf(buf, buflen, "%s", err);
+ errno = errnum;
+ scnprintf(buf, buflen, "%m");
return 0;
}
@@ -1843,7 +1864,7 @@ static const u8 *__dso__read_symbol(struct dso *dso, const char *symfs_filename,
int saved_errno;
nsinfo__mountns_enter(dso__nsinfo(dso), &nsc);
- fd = open(symfs_filename, O_RDONLY);
+ fd = open(symfs_filename, O_RDONLY | O_CLOEXEC);
saved_errno = errno;
nsinfo__mountns_exit(&nsc);
if (fd < 0) {
@@ -1911,6 +1932,10 @@ const u8 *dso__read_symbol(struct dso *dso, const char *symfs_filename,
return NULL;
}
info_linear = info_node->info_linear;
+ if (!(info_linear->arrays & (1UL << PERF_BPIL_JITED_INSNS))) {
+ errno = SYMBOL_ANNOTATE_ERRNO__BPF_MISSING_BTF;
+ return NULL;
+ }
assert(len <= info_linear->info.jited_prog_len);
*out_buf_len = len;
return (const u8 *)(uintptr_t)(info_linear->info.jited_prog_insns);