Skip to content

Commit 4e9e076

Browse files
anakryikoAlexei Starovoitov
authored andcommitted
selftests/bpf: make use of PROCMAP_QUERY ioctl if available
Instead of parsing text-based /proc/<pid>/maps file, try to use PROCMAP_QUERY ioctl() to simplify and speed up data fetching. This logic is used to do uprobe file offset calculation, so any bugs in this logic would manifest as failing uprobe BPF selftests. This also serves as a simple demonstration of one of the intended uses. Signed-off-by: Andrii Nakryiko <[email protected]> Acked-by: Jiri Olsa <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent b4406e1 commit 4e9e076

File tree

3 files changed

+94
-15
lines changed

3 files changed

+94
-15
lines changed

tools/testing/selftests/bpf/test_progs.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ __weak void backtrace_symbols_fd(void *const *buffer, int size, int fd)
3535
dprintf(fd, "<backtrace not supported>\n");
3636
}
3737

38+
int env_verbosity = 0;
39+
3840
static bool verbose(void)
3941
{
4042
return env.verbosity > VERBOSE_NONE;
@@ -973,6 +975,7 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state)
973975
return -EINVAL;
974976
}
975977
}
978+
env_verbosity = env->verbosity;
976979

977980
if (verbose()) {
978981
if (setenv("SELFTESTS_VERBOSE", "1", 1) == -1) {

tools/testing/selftests/bpf/test_progs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ struct test_state {
9696
FILE *stdout_saved;
9797
};
9898

99+
extern int env_verbosity;
100+
99101
struct test_env {
100102
struct test_selector test_selector;
101103
struct test_selector subtest_selector;

tools/testing/selftests/bpf/trace_helpers.c

Lines changed: 89 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
#include <pthread.h>
1111
#include <unistd.h>
1212
#include <linux/perf_event.h>
13+
#include <linux/fs.h>
14+
#include <sys/ioctl.h>
1315
#include <sys/mman.h>
1416
#include "trace_helpers.h"
1517
#include <linux/limits.h>
@@ -244,29 +246,91 @@ int kallsyms_find(const char *sym, unsigned long long *addr)
244246
return err;
245247
}
246248

249+
#ifdef PROCMAP_QUERY
250+
int env_verbosity __weak = 0;
251+
252+
int procmap_query(int fd, const void *addr, __u32 query_flags, size_t *start, size_t *offset, int *flags)
253+
{
254+
char path_buf[PATH_MAX], build_id_buf[20];
255+
struct procmap_query q;
256+
int err;
257+
258+
memset(&q, 0, sizeof(q));
259+
q.size = sizeof(q);
260+
q.query_flags = query_flags;
261+
q.query_addr = (__u64)addr;
262+
q.vma_name_addr = (__u64)path_buf;
263+
q.vma_name_size = sizeof(path_buf);
264+
q.build_id_addr = (__u64)build_id_buf;
265+
q.build_id_size = sizeof(build_id_buf);
266+
267+
err = ioctl(fd, PROCMAP_QUERY, &q);
268+
if (err < 0) {
269+
err = -errno;
270+
if (err == -ENOTTY)
271+
return -EOPNOTSUPP; /* ioctl() not implemented yet */
272+
if (err == -ENOENT)
273+
return -ESRCH; /* vma not found */
274+
return err;
275+
}
276+
277+
if (env_verbosity >= 1) {
278+
printf("VMA FOUND (addr %08lx): %08lx-%08lx %c%c%c%c %08lx %02x:%02x %ld %s (build ID: %s, %d bytes)\n",
279+
(long)addr, (long)q.vma_start, (long)q.vma_end,
280+
(q.vma_flags & PROCMAP_QUERY_VMA_READABLE) ? 'r' : '-',
281+
(q.vma_flags & PROCMAP_QUERY_VMA_WRITABLE) ? 'w' : '-',
282+
(q.vma_flags & PROCMAP_QUERY_VMA_EXECUTABLE) ? 'x' : '-',
283+
(q.vma_flags & PROCMAP_QUERY_VMA_SHARED) ? 's' : 'p',
284+
(long)q.vma_offset, q.dev_major, q.dev_minor, (long)q.inode,
285+
q.vma_name_size ? path_buf : "",
286+
q.build_id_size ? "YES" : "NO",
287+
q.build_id_size);
288+
}
289+
290+
*start = q.vma_start;
291+
*offset = q.vma_offset;
292+
*flags = q.vma_flags;
293+
return 0;
294+
}
295+
#else
296+
int procmap_query(int fd, const void *addr, size_t *start, size_t *offset, int *flags)
297+
{
298+
return -EOPNOTSUPP;
299+
}
300+
#endif
301+
247302
ssize_t get_uprobe_offset(const void *addr)
248303
{
249-
size_t start, end, base;
250-
char buf[256];
251-
bool found = false;
304+
size_t start, base, end;
252305
FILE *f;
306+
char buf[256];
307+
int err, flags;
253308

254309
f = fopen("/proc/self/maps", "r");
255310
if (!f)
256311
return -errno;
257312

258-
while (fscanf(f, "%zx-%zx %s %zx %*[^\n]\n", &start, &end, buf, &base) == 4) {
259-
if (buf[2] == 'x' && (uintptr_t)addr >= start && (uintptr_t)addr < end) {
260-
found = true;
261-
break;
313+
/* requested executable VMA only */
314+
err = procmap_query(fileno(f), addr, PROCMAP_QUERY_VMA_EXECUTABLE, &start, &base, &flags);
315+
if (err == -EOPNOTSUPP) {
316+
bool found = false;
317+
318+
while (fscanf(f, "%zx-%zx %s %zx %*[^\n]\n", &start, &end, buf, &base) == 4) {
319+
if (buf[2] == 'x' && (uintptr_t)addr >= start && (uintptr_t)addr < end) {
320+
found = true;
321+
break;
322+
}
323+
}
324+
if (!found) {
325+
fclose(f);
326+
return -ESRCH;
262327
}
328+
} else if (err) {
329+
fclose(f);
330+
return err;
263331
}
264-
265332
fclose(f);
266333

267-
if (!found)
268-
return -ESRCH;
269-
270334
#if defined(__powerpc64__) && defined(_CALL_ELF) && _CALL_ELF == 2
271335

272336
#define OP_RT_RA_MASK 0xffff0000UL
@@ -307,15 +371,25 @@ ssize_t get_rel_offset(uintptr_t addr)
307371
size_t start, end, offset;
308372
char buf[256];
309373
FILE *f;
374+
int err, flags;
310375

311376
f = fopen("/proc/self/maps", "r");
312377
if (!f)
313378
return -errno;
314379

315-
while (fscanf(f, "%zx-%zx %s %zx %*[^\n]\n", &start, &end, buf, &offset) == 4) {
316-
if (addr >= start && addr < end) {
317-
fclose(f);
318-
return (size_t)addr - start + offset;
380+
err = procmap_query(fileno(f), (const void *)addr, 0, &start, &offset, &flags);
381+
if (err == 0) {
382+
fclose(f);
383+
return (size_t)addr - start + offset;
384+
} else if (err != -EOPNOTSUPP) {
385+
fclose(f);
386+
return err;
387+
} else if (err) {
388+
while (fscanf(f, "%zx-%zx %s %zx %*[^\n]\n", &start, &end, buf, &offset) == 4) {
389+
if (addr >= start && addr < end) {
390+
fclose(f);
391+
return (size_t)addr - start + offset;
392+
}
319393
}
320394
}
321395

0 commit comments

Comments
 (0)