aboutsummaryrefslogtreecommitdiffstats
path: root/samples/bpf/bpf_load.c
diff options
context:
space:
mode:
Diffstat (limited to 'samples/bpf/bpf_load.c')
-rw-r--r--samples/bpf/bpf_load.c97
1 files changed, 26 insertions, 71 deletions
diff --git a/samples/bpf/bpf_load.c b/samples/bpf/bpf_load.c
index feca497d6afd..da9bccfaf391 100644
--- a/samples/bpf/bpf_load.c
+++ b/samples/bpf/bpf_load.c
@@ -145,6 +145,9 @@ static int load_and_attach(const char *event, struct bpf_insn *prog, int size)
145 } 145 }
146 146
147 if (is_kprobe || is_kretprobe) { 147 if (is_kprobe || is_kretprobe) {
148 bool need_normal_check = true;
149 const char *event_prefix = "";
150
148 if (is_kprobe) 151 if (is_kprobe)
149 event += 7; 152 event += 7;
150 else 153 else
@@ -158,18 +161,33 @@ static int load_and_attach(const char *event, struct bpf_insn *prog, int size)
158 if (isdigit(*event)) 161 if (isdigit(*event))
159 return populate_prog_array(event, fd); 162 return populate_prog_array(event, fd);
160 163
161 snprintf(buf, sizeof(buf), 164#ifdef __x86_64__
162 "echo '%c:%s %s' >> /sys/kernel/debug/tracing/kprobe_events", 165 if (strncmp(event, "sys_", 4) == 0) {
163 is_kprobe ? 'p' : 'r', event, event); 166 snprintf(buf, sizeof(buf),
164 err = system(buf); 167 "echo '%c:__x64_%s __x64_%s' >> /sys/kernel/debug/tracing/kprobe_events",
165 if (err < 0) { 168 is_kprobe ? 'p' : 'r', event, event);
166 printf("failed to create kprobe '%s' error '%s'\n", 169 err = system(buf);
167 event, strerror(errno)); 170 if (err >= 0) {
168 return -1; 171 need_normal_check = false;
172 event_prefix = "__x64_";
173 }
174 }
175#endif
176 if (need_normal_check) {
177 snprintf(buf, sizeof(buf),
178 "echo '%c:%s %s' >> /sys/kernel/debug/tracing/kprobe_events",
179 is_kprobe ? 'p' : 'r', event, event);
180 err = system(buf);
181 if (err < 0) {
182 printf("failed to create kprobe '%s' error '%s'\n",
183 event, strerror(errno));
184 return -1;
185 }
169 } 186 }
170 187
171 strcpy(buf, DEBUGFS); 188 strcpy(buf, DEBUGFS);
172 strcat(buf, "events/kprobes/"); 189 strcat(buf, "events/kprobes/");
190 strcat(buf, event_prefix);
173 strcat(buf, event); 191 strcat(buf, event);
174 strcat(buf, "/id"); 192 strcat(buf, "/id");
175 } else if (is_tracepoint) { 193 } else if (is_tracepoint) {
@@ -648,66 +666,3 @@ void read_trace_pipe(void)
648 } 666 }
649 } 667 }
650} 668}
651
652#define MAX_SYMS 300000
653static struct ksym syms[MAX_SYMS];
654static int sym_cnt;
655
656static int ksym_cmp(const void *p1, const void *p2)
657{
658 return ((struct ksym *)p1)->addr - ((struct ksym *)p2)->addr;
659}
660
661int load_kallsyms(void)
662{
663 FILE *f = fopen("/proc/kallsyms", "r");
664 char func[256], buf[256];
665 char symbol;
666 void *addr;
667 int i = 0;
668
669 if (!f)
670 return -ENOENT;
671
672 while (!feof(f)) {
673 if (!fgets(buf, sizeof(buf), f))
674 break;
675 if (sscanf(buf, "%p %c %s", &addr, &symbol, func) != 3)
676 break;
677 if (!addr)
678 continue;
679 syms[i].addr = (long) addr;
680 syms[i].name = strdup(func);
681 i++;
682 }
683 sym_cnt = i;
684 qsort(syms, sym_cnt, sizeof(struct ksym), ksym_cmp);
685 return 0;
686}
687
688struct ksym *ksym_search(long key)
689{
690 int start = 0, end = sym_cnt;
691 int result;
692
693 while (start < end) {
694 size_t mid = start + (end - start) / 2;
695
696 result = key - syms[mid].addr;
697 if (result < 0)
698 end = mid;
699 else if (result > 0)
700 start = mid + 1;
701 else
702 return &syms[mid];
703 }
704
705 if (start >= 1 && syms[start - 1].addr < key &&
706 key < syms[start].addr)
707 /* valid ksym */
708 return &syms[start - 1];
709
710 /* out of range. return _stext */
711 return &syms[0];
712}
713