diff options
author | Alexei Starovoitov <ast@fb.com> | 2016-03-08 00:57:19 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-03-08 15:28:32 -0500 |
commit | 3622e7e4935105991dc648bca650c858576aecda (patch) | |
tree | d912d23d7c13a51fce638bd855fb37ef236cc26b /samples | |
parent | 618ec9a7b1fda46f8dd4a630ded983aeb51218f3 (diff) |
samples/bpf: move ksym_search() into library
move ksym search from offwaketime into library to be reused
in other tests
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'samples')
-rw-r--r-- | samples/bpf/bpf_load.c | 62 | ||||
-rw-r--r-- | samples/bpf/bpf_load.h | 6 | ||||
-rw-r--r-- | samples/bpf/offwaketime_user.c | 67 |
3 files changed, 69 insertions, 66 deletions
diff --git a/samples/bpf/bpf_load.c b/samples/bpf/bpf_load.c index 816bca5760a0..d16864293c00 100644 --- a/samples/bpf/bpf_load.c +++ b/samples/bpf/bpf_load.c | |||
@@ -346,3 +346,65 @@ void read_trace_pipe(void) | |||
346 | } | 346 | } |
347 | } | 347 | } |
348 | } | 348 | } |
349 | |||
350 | #define MAX_SYMS 300000 | ||
351 | static struct ksym syms[MAX_SYMS]; | ||
352 | static int sym_cnt; | ||
353 | |||
354 | static int ksym_cmp(const void *p1, const void *p2) | ||
355 | { | ||
356 | return ((struct ksym *)p1)->addr - ((struct ksym *)p2)->addr; | ||
357 | } | ||
358 | |||
359 | int load_kallsyms(void) | ||
360 | { | ||
361 | FILE *f = fopen("/proc/kallsyms", "r"); | ||
362 | char func[256], buf[256]; | ||
363 | char symbol; | ||
364 | void *addr; | ||
365 | int i = 0; | ||
366 | |||
367 | if (!f) | ||
368 | return -ENOENT; | ||
369 | |||
370 | while (!feof(f)) { | ||
371 | if (!fgets(buf, sizeof(buf), f)) | ||
372 | break; | ||
373 | if (sscanf(buf, "%p %c %s", &addr, &symbol, func) != 3) | ||
374 | break; | ||
375 | if (!addr) | ||
376 | continue; | ||
377 | syms[i].addr = (long) addr; | ||
378 | syms[i].name = strdup(func); | ||
379 | i++; | ||
380 | } | ||
381 | sym_cnt = i; | ||
382 | qsort(syms, sym_cnt, sizeof(struct ksym), ksym_cmp); | ||
383 | return 0; | ||
384 | } | ||
385 | |||
386 | struct ksym *ksym_search(long key) | ||
387 | { | ||
388 | int start = 0, end = sym_cnt; | ||
389 | int result; | ||
390 | |||
391 | while (start < end) { | ||
392 | size_t mid = start + (end - start) / 2; | ||
393 | |||
394 | result = key - syms[mid].addr; | ||
395 | if (result < 0) | ||
396 | end = mid; | ||
397 | else if (result > 0) | ||
398 | start = mid + 1; | ||
399 | else | ||
400 | return &syms[mid]; | ||
401 | } | ||
402 | |||
403 | if (start >= 1 && syms[start - 1].addr < key && | ||
404 | key < syms[start].addr) | ||
405 | /* valid ksym */ | ||
406 | return &syms[start - 1]; | ||
407 | |||
408 | /* out of range. return _stext */ | ||
409 | return &syms[0]; | ||
410 | } | ||
diff --git a/samples/bpf/bpf_load.h b/samples/bpf/bpf_load.h index cbd7c2b532b9..dfa57fe65c8e 100644 --- a/samples/bpf/bpf_load.h +++ b/samples/bpf/bpf_load.h | |||
@@ -23,5 +23,11 @@ extern int event_fd[MAX_PROGS]; | |||
23 | int load_bpf_file(char *path); | 23 | int load_bpf_file(char *path); |
24 | 24 | ||
25 | void read_trace_pipe(void); | 25 | void read_trace_pipe(void); |
26 | struct ksym { | ||
27 | long addr; | ||
28 | char *name; | ||
29 | }; | ||
26 | 30 | ||
31 | int load_kallsyms(void); | ||
32 | struct ksym *ksym_search(long key); | ||
27 | #endif | 33 | #endif |
diff --git a/samples/bpf/offwaketime_user.c b/samples/bpf/offwaketime_user.c index 17cf3024e22c..6f002a9c24fa 100644 --- a/samples/bpf/offwaketime_user.c +++ b/samples/bpf/offwaketime_user.c | |||
@@ -18,80 +18,15 @@ | |||
18 | #include "libbpf.h" | 18 | #include "libbpf.h" |
19 | #include "bpf_load.h" | 19 | #include "bpf_load.h" |
20 | 20 | ||
21 | #define MAX_SYMS 300000 | ||
22 | #define PRINT_RAW_ADDR 0 | 21 | #define PRINT_RAW_ADDR 0 |
23 | 22 | ||
24 | static struct ksym { | ||
25 | long addr; | ||
26 | char *name; | ||
27 | } syms[MAX_SYMS]; | ||
28 | static int sym_cnt; | ||
29 | |||
30 | static int ksym_cmp(const void *p1, const void *p2) | ||
31 | { | ||
32 | return ((struct ksym *)p1)->addr - ((struct ksym *)p2)->addr; | ||
33 | } | ||
34 | |||
35 | static int load_kallsyms(void) | ||
36 | { | ||
37 | FILE *f = fopen("/proc/kallsyms", "r"); | ||
38 | char func[256], buf[256]; | ||
39 | char symbol; | ||
40 | void *addr; | ||
41 | int i = 0; | ||
42 | |||
43 | if (!f) | ||
44 | return -ENOENT; | ||
45 | |||
46 | while (!feof(f)) { | ||
47 | if (!fgets(buf, sizeof(buf), f)) | ||
48 | break; | ||
49 | if (sscanf(buf, "%p %c %s", &addr, &symbol, func) != 3) | ||
50 | break; | ||
51 | if (!addr) | ||
52 | continue; | ||
53 | syms[i].addr = (long) addr; | ||
54 | syms[i].name = strdup(func); | ||
55 | i++; | ||
56 | } | ||
57 | sym_cnt = i; | ||
58 | qsort(syms, sym_cnt, sizeof(struct ksym), ksym_cmp); | ||
59 | return 0; | ||
60 | } | ||
61 | |||
62 | static void *search(long key) | ||
63 | { | ||
64 | int start = 0, end = sym_cnt; | ||
65 | int result; | ||
66 | |||
67 | while (start < end) { | ||
68 | size_t mid = start + (end - start) / 2; | ||
69 | |||
70 | result = key - syms[mid].addr; | ||
71 | if (result < 0) | ||
72 | end = mid; | ||
73 | else if (result > 0) | ||
74 | start = mid + 1; | ||
75 | else | ||
76 | return &syms[mid]; | ||
77 | } | ||
78 | |||
79 | if (start >= 1 && syms[start - 1].addr < key && | ||
80 | key < syms[start].addr) | ||
81 | /* valid ksym */ | ||
82 | return &syms[start - 1]; | ||
83 | |||
84 | /* out of range. return _stext */ | ||
85 | return &syms[0]; | ||
86 | } | ||
87 | |||
88 | static void print_ksym(__u64 addr) | 23 | static void print_ksym(__u64 addr) |
89 | { | 24 | { |
90 | struct ksym *sym; | 25 | struct ksym *sym; |
91 | 26 | ||
92 | if (!addr) | 27 | if (!addr) |
93 | return; | 28 | return; |
94 | sym = search(addr); | 29 | sym = ksym_search(addr); |
95 | if (PRINT_RAW_ADDR) | 30 | if (PRINT_RAW_ADDR) |
96 | printf("%s/%llx;", sym->name, addr); | 31 | printf("%s/%llx;", sym->name, addr); |
97 | else | 32 | else |