diff options
Diffstat (limited to 'tools/perf/builtin-trace.c')
-rw-r--r-- | tools/perf/builtin-trace.c | 54 |
1 files changed, 51 insertions, 3 deletions
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 20916dd77aac..8dc98c598b1a 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include "util/stat.h" | 33 | #include "util/stat.h" |
34 | #include "trace-event.h" | 34 | #include "trace-event.h" |
35 | #include "util/parse-events.h" | 35 | #include "util/parse-events.h" |
36 | #include "util/bpf-loader.h" | ||
36 | 37 | ||
37 | #include <libaudit.h> | 38 | #include <libaudit.h> |
38 | #include <stdlib.h> | 39 | #include <stdlib.h> |
@@ -1724,8 +1725,12 @@ static int trace__read_syscall_info(struct trace *trace, int id) | |||
1724 | 1725 | ||
1725 | sc->args = sc->tp_format->format.fields; | 1726 | sc->args = sc->tp_format->format.fields; |
1726 | sc->nr_args = sc->tp_format->format.nr_fields; | 1727 | sc->nr_args = sc->tp_format->format.nr_fields; |
1727 | /* drop nr field - not relevant here; does not exist on older kernels */ | 1728 | /* |
1728 | if (sc->args && strcmp(sc->args->name, "nr") == 0) { | 1729 | * We need to check and discard the first variable '__syscall_nr' |
1730 | * or 'nr' that mean the syscall number. It is needless here. | ||
1731 | * So drop '__syscall_nr' or 'nr' field but does not exist on older kernels. | ||
1732 | */ | ||
1733 | if (sc->args && (!strcmp(sc->args->name, "__syscall_nr") || !strcmp(sc->args->name, "nr"))) { | ||
1729 | sc->args = sc->args->next; | 1734 | sc->args = sc->args->next; |
1730 | --sc->nr_args; | 1735 | --sc->nr_args; |
1731 | } | 1736 | } |
@@ -2177,6 +2182,37 @@ out_dump: | |||
2177 | return 0; | 2182 | return 0; |
2178 | } | 2183 | } |
2179 | 2184 | ||
2185 | static void bpf_output__printer(enum binary_printer_ops op, | ||
2186 | unsigned int val, void *extra) | ||
2187 | { | ||
2188 | FILE *output = extra; | ||
2189 | unsigned char ch = (unsigned char)val; | ||
2190 | |||
2191 | switch (op) { | ||
2192 | case BINARY_PRINT_CHAR_DATA: | ||
2193 | fprintf(output, "%c", isprint(ch) ? ch : '.'); | ||
2194 | break; | ||
2195 | case BINARY_PRINT_DATA_BEGIN: | ||
2196 | case BINARY_PRINT_LINE_BEGIN: | ||
2197 | case BINARY_PRINT_ADDR: | ||
2198 | case BINARY_PRINT_NUM_DATA: | ||
2199 | case BINARY_PRINT_NUM_PAD: | ||
2200 | case BINARY_PRINT_SEP: | ||
2201 | case BINARY_PRINT_CHAR_PAD: | ||
2202 | case BINARY_PRINT_LINE_END: | ||
2203 | case BINARY_PRINT_DATA_END: | ||
2204 | default: | ||
2205 | break; | ||
2206 | } | ||
2207 | } | ||
2208 | |||
2209 | static void bpf_output__fprintf(struct trace *trace, | ||
2210 | struct perf_sample *sample) | ||
2211 | { | ||
2212 | print_binary(sample->raw_data, sample->raw_size, 8, | ||
2213 | bpf_output__printer, trace->output); | ||
2214 | } | ||
2215 | |||
2180 | static int trace__event_handler(struct trace *trace, struct perf_evsel *evsel, | 2216 | static int trace__event_handler(struct trace *trace, struct perf_evsel *evsel, |
2181 | union perf_event *event __maybe_unused, | 2217 | union perf_event *event __maybe_unused, |
2182 | struct perf_sample *sample) | 2218 | struct perf_sample *sample) |
@@ -2189,7 +2225,9 @@ static int trace__event_handler(struct trace *trace, struct perf_evsel *evsel, | |||
2189 | 2225 | ||
2190 | fprintf(trace->output, "%s:", evsel->name); | 2226 | fprintf(trace->output, "%s:", evsel->name); |
2191 | 2227 | ||
2192 | if (evsel->tp_format) { | 2228 | if (perf_evsel__is_bpf_output(evsel)) { |
2229 | bpf_output__fprintf(trace, sample); | ||
2230 | } else if (evsel->tp_format) { | ||
2193 | event_format__fprintf(evsel->tp_format, sample->cpu, | 2231 | event_format__fprintf(evsel->tp_format, sample->cpu, |
2194 | sample->raw_data, sample->raw_size, | 2232 | sample->raw_data, sample->raw_size, |
2195 | trace->output); | 2233 | trace->output); |
@@ -2586,6 +2624,16 @@ static int trace__run(struct trace *trace, int argc, const char **argv) | |||
2586 | if (err < 0) | 2624 | if (err < 0) |
2587 | goto out_error_open; | 2625 | goto out_error_open; |
2588 | 2626 | ||
2627 | err = bpf__apply_obj_config(); | ||
2628 | if (err) { | ||
2629 | char errbuf[BUFSIZ]; | ||
2630 | |||
2631 | bpf__strerror_apply_obj_config(err, errbuf, sizeof(errbuf)); | ||
2632 | pr_err("ERROR: Apply config to BPF failed: %s\n", | ||
2633 | errbuf); | ||
2634 | goto out_error_open; | ||
2635 | } | ||
2636 | |||
2589 | /* | 2637 | /* |
2590 | * Better not use !target__has_task() here because we need to cover the | 2638 | * Better not use !target__has_task() here because we need to cover the |
2591 | * case where no threads were specified in the command line, but a | 2639 | * case where no threads were specified in the command line, but a |