summaryrefslogtreecommitdiffstats
path: root/samples
diff options
context:
space:
mode:
authorAlexei Starovoitov <ast@fb.com>2016-03-08 00:57:19 -0500
committerDavid S. Miller <davem@davemloft.net>2016-03-08 15:28:32 -0500
commit3622e7e4935105991dc648bca650c858576aecda (patch)
treed912d23d7c13a51fce638bd855fb37ef236cc26b /samples
parent618ec9a7b1fda46f8dd4a630ded983aeb51218f3 (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.c62
-rw-r--r--samples/bpf/bpf_load.h6
-rw-r--r--samples/bpf/offwaketime_user.c67
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
351static struct ksym syms[MAX_SYMS];
352static int sym_cnt;
353
354static int ksym_cmp(const void *p1, const void *p2)
355{
356 return ((struct ksym *)p1)->addr - ((struct ksym *)p2)->addr;
357}
358
359int 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
386struct 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];
23int load_bpf_file(char *path); 23int load_bpf_file(char *path);
24 24
25void read_trace_pipe(void); 25void read_trace_pipe(void);
26struct ksym {
27 long addr;
28 char *name;
29};
26 30
31int load_kallsyms(void);
32struct 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
24static struct ksym {
25 long addr;
26 char *name;
27} syms[MAX_SYMS];
28static int sym_cnt;
29
30static int ksym_cmp(const void *p1, const void *p2)
31{
32 return ((struct ksym *)p1)->addr - ((struct ksym *)p2)->addr;
33}
34
35static 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
62static 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
88static void print_ksym(__u64 addr) 23static 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