diff options
Diffstat (limited to 'samples/bpf/bpf_load.c')
-rw-r--r-- | samples/bpf/bpf_load.c | 97 |
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 | ||
653 | static struct ksym syms[MAX_SYMS]; | ||
654 | static int sym_cnt; | ||
655 | |||
656 | static int ksym_cmp(const void *p1, const void *p2) | ||
657 | { | ||
658 | return ((struct ksym *)p1)->addr - ((struct ksym *)p2)->addr; | ||
659 | } | ||
660 | |||
661 | int 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 | |||
688 | struct 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 | |||