4 * Minimal BPF JIT image disassembler
6 * Disassembles BPF JIT compiler emitted opcodes back to asm insn's for
7 * debugging or verification purposes.
9 * Copyright 2013 Daniel Borkmann <daniel@iogearbox.net>
10 * Licensed under the GNU General Public License, version 2.0 (GPLv2)
24 #include <sys/types.h>
28 #include "json_writer.h"
31 static void get_exec_path(char *tpath, size_t size)
36 snprintf(tpath, size, "/proc/%d/exe", (int) getpid());
42 len = readlink(path, tpath, size - 1);
49 static int oper_count;
50 static int fprintf_json(void *out, const char *fmt, ...)
57 err = vasprintf(&s, fmt, ap);
65 /* Strip trailing spaces */
70 jsonw_string_field(json_wtr, "operation", s);
71 jsonw_name(json_wtr, "operands");
72 jsonw_start_array(json_wtr);
74 } else if (!strcmp(fmt, ",")) {
77 jsonw_string(json_wtr, s);
84 void disasm_print_insn(unsigned char *image, ssize_t len, int opcodes,
87 disassembler_ftype disassemble;
88 struct disassemble_info info;
96 memset(tpath, 0, sizeof(tpath));
97 get_exec_path(tpath, sizeof(tpath));
99 bfdf = bfd_openr(tpath, NULL);
101 assert(bfd_check_format(bfdf, bfd_object));
104 init_disassemble_info(&info, stdout,
105 (fprintf_ftype) fprintf_json);
107 init_disassemble_info(&info, stdout,
108 (fprintf_ftype) fprintf);
110 /* Update architecture info for offload. */
112 const bfd_arch_info_type *inf = bfd_scan_arch(arch);
115 bfdf->arch_info = inf;
117 p_err("No libfd support for %s", arch);
122 info.arch = bfd_get_arch(bfdf);
123 info.mach = bfd_get_mach(bfdf);
125 info.buffer_length = len;
127 disassemble_init_for_target(&info);
129 #ifdef DISASM_FOUR_ARGS_SIGNATURE
130 disassemble = disassembler(info.arch,
131 bfd_big_endian(bfdf),
135 disassemble = disassembler(bfdf);
140 jsonw_start_array(json_wtr);
143 jsonw_start_object(json_wtr);
145 jsonw_name(json_wtr, "pc");
146 jsonw_printf(json_wtr, "\"0x%x\"", pc);
148 printf("%4x:\t", pc);
151 count = disassemble(pc, &info);
153 /* Operand array, was started in fprintf_json. Before
154 * that, make sure we have a _null_ value if no operand
155 * other than operation code was present.
158 jsonw_null(json_wtr);
159 jsonw_end_array(json_wtr);
164 jsonw_name(json_wtr, "opcodes");
165 jsonw_start_array(json_wtr);
166 for (i = 0; i < count; ++i)
167 jsonw_printf(json_wtr, "\"0x%02hhx\"",
168 (uint8_t)image[pc + i]);
169 jsonw_end_array(json_wtr);
172 for (i = 0; i < count; ++i)
174 (uint8_t)image[pc + i]);
178 jsonw_end_object(json_wtr);
183 } while (count > 0 && pc < len);
185 jsonw_end_array(json_wtr);