diff options
-rw-r--r-- | tools/bpf/bpftool/jit_disasm.c | 86 |
1 files changed, 80 insertions, 6 deletions
diff --git a/tools/bpf/bpftool/jit_disasm.c b/tools/bpf/bpftool/jit_disasm.c index 70e480b59e9d..5937e134e408 100644 --- a/tools/bpf/bpftool/jit_disasm.c +++ b/tools/bpf/bpftool/jit_disasm.c | |||
@@ -10,6 +10,7 @@ | |||
10 | * Licensed under the GNU General Public License, version 2.0 (GPLv2) | 10 | * Licensed under the GNU General Public License, version 2.0 (GPLv2) |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <stdarg.h> | ||
13 | #include <stdint.h> | 14 | #include <stdint.h> |
14 | #include <stdio.h> | 15 | #include <stdio.h> |
15 | #include <stdlib.h> | 16 | #include <stdlib.h> |
@@ -21,6 +22,9 @@ | |||
21 | #include <sys/types.h> | 22 | #include <sys/types.h> |
22 | #include <sys/stat.h> | 23 | #include <sys/stat.h> |
23 | 24 | ||
25 | #include "json_writer.h" | ||
26 | #include "main.h" | ||
27 | |||
24 | static void get_exec_path(char *tpath, size_t size) | 28 | static void get_exec_path(char *tpath, size_t size) |
25 | { | 29 | { |
26 | ssize_t len; | 30 | ssize_t len; |
@@ -39,6 +43,38 @@ static void get_exec_path(char *tpath, size_t size) | |||
39 | free(path); | 43 | free(path); |
40 | } | 44 | } |
41 | 45 | ||
46 | static int oper_count; | ||
47 | static int fprintf_json(void *out, const char *fmt, ...) | ||
48 | { | ||
49 | va_list ap; | ||
50 | char *s; | ||
51 | |||
52 | va_start(ap, fmt); | ||
53 | if (!oper_count) { | ||
54 | int i; | ||
55 | |||
56 | s = va_arg(ap, char *); | ||
57 | |||
58 | /* Strip trailing spaces */ | ||
59 | i = strlen(s) - 1; | ||
60 | while (s[i] == ' ') | ||
61 | s[i--] = '\0'; | ||
62 | |||
63 | jsonw_string_field(json_wtr, "operation", s); | ||
64 | jsonw_name(json_wtr, "operands"); | ||
65 | jsonw_start_array(json_wtr); | ||
66 | oper_count++; | ||
67 | } else if (!strcmp(fmt, ",")) { | ||
68 | /* Skip */ | ||
69 | } else { | ||
70 | s = va_arg(ap, char *); | ||
71 | jsonw_string(json_wtr, s); | ||
72 | oper_count++; | ||
73 | } | ||
74 | va_end(ap); | ||
75 | return 0; | ||
76 | } | ||
77 | |||
42 | void disasm_print_insn(unsigned char *image, ssize_t len, int opcodes) | 78 | void disasm_print_insn(unsigned char *image, ssize_t len, int opcodes) |
43 | { | 79 | { |
44 | disassembler_ftype disassemble; | 80 | disassembler_ftype disassemble; |
@@ -57,7 +93,12 @@ void disasm_print_insn(unsigned char *image, ssize_t len, int opcodes) | |||
57 | assert(bfdf); | 93 | assert(bfdf); |
58 | assert(bfd_check_format(bfdf, bfd_object)); | 94 | assert(bfd_check_format(bfdf, bfd_object)); |
59 | 95 | ||
60 | init_disassemble_info(&info, stdout, (fprintf_ftype) fprintf); | 96 | if (json_output) |
97 | init_disassemble_info(&info, stdout, | ||
98 | (fprintf_ftype) fprintf_json); | ||
99 | else | ||
100 | init_disassemble_info(&info, stdout, | ||
101 | (fprintf_ftype) fprintf); | ||
61 | info.arch = bfd_get_arch(bfdf); | 102 | info.arch = bfd_get_arch(bfdf); |
62 | info.mach = bfd_get_mach(bfdf); | 103 | info.mach = bfd_get_mach(bfdf); |
63 | info.buffer = image; | 104 | info.buffer = image; |
@@ -68,20 +109,53 @@ void disasm_print_insn(unsigned char *image, ssize_t len, int opcodes) | |||
68 | disassemble = disassembler(bfdf); | 109 | disassemble = disassembler(bfdf); |
69 | assert(disassemble); | 110 | assert(disassemble); |
70 | 111 | ||
112 | if (json_output) | ||
113 | jsonw_start_array(json_wtr); | ||
71 | do { | 114 | do { |
72 | printf("%4x:\t", pc); | 115 | if (json_output) { |
116 | jsonw_start_object(json_wtr); | ||
117 | oper_count = 0; | ||
118 | jsonw_name(json_wtr, "pc"); | ||
119 | jsonw_printf(json_wtr, "\"0x%x\"", pc); | ||
120 | } else { | ||
121 | printf("%4x:\t", pc); | ||
122 | } | ||
73 | 123 | ||
74 | count = disassemble(pc, &info); | 124 | count = disassemble(pc, &info); |
125 | if (json_output) { | ||
126 | /* Operand array, was started in fprintf_json. Before | ||
127 | * that, make sure we have a _null_ value if no operand | ||
128 | * other than operation code was present. | ||
129 | */ | ||
130 | if (oper_count == 1) | ||
131 | jsonw_null(json_wtr); | ||
132 | jsonw_end_array(json_wtr); | ||
133 | } | ||
75 | 134 | ||
76 | if (opcodes) { | 135 | if (opcodes) { |
77 | printf("\n\t"); | 136 | if (json_output) { |
78 | for (i = 0; i < count; ++i) | 137 | jsonw_name(json_wtr, "opcodes"); |
79 | printf("%02x ", (uint8_t) image[pc + i]); | 138 | jsonw_start_array(json_wtr); |
139 | for (i = 0; i < count; ++i) | ||
140 | jsonw_printf(json_wtr, "\"0x%02hhx\"", | ||
141 | (uint8_t)image[pc + i]); | ||
142 | jsonw_end_array(json_wtr); | ||
143 | } else { | ||
144 | printf("\n\t"); | ||
145 | for (i = 0; i < count; ++i) | ||
146 | printf("%02x ", | ||
147 | (uint8_t)image[pc + i]); | ||
148 | } | ||
80 | } | 149 | } |
81 | printf("\n"); | 150 | if (json_output) |
151 | jsonw_end_object(json_wtr); | ||
152 | else | ||
153 | printf("\n"); | ||
82 | 154 | ||
83 | pc += count; | 155 | pc += count; |
84 | } while (count > 0 && pc < len); | 156 | } while (count > 0 && pc < len); |
157 | if (json_output) | ||
158 | jsonw_end_array(json_wtr); | ||
85 | 159 | ||
86 | bfd_close(bfdf); | 160 | bfd_close(bfdf); |
87 | } | 161 | } |