Skip to content

Commit e1947c7

Browse files
qmonnetAlexei Starovoitov
authored andcommitted
bpftool: Refactor disassembler for JIT-ed programs
Refactor disasm_print_insn() to extract the code specific to libbfd and move it to dedicated functions. There is no functional change. This is in preparation for supporting an alternative library for disassembling the instructions. Signed-off-by: Quentin Monnet <[email protected]> Tested-by: Niklas Söderlund <[email protected]> Acked-by: Song Liu <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 2ea4d86 commit e1947c7

File tree

1 file changed

+88
-45
lines changed

1 file changed

+88
-45
lines changed

tools/bpf/bpftool/jit_disasm.c

Lines changed: 88 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,14 @@
3030
#include "json_writer.h"
3131
#include "main.h"
3232

33+
static int oper_count;
34+
35+
typedef struct {
36+
struct disassemble_info *info;
37+
disassembler_ftype disassemble;
38+
bfd *bfdf;
39+
} disasm_ctx_t;
40+
3341
static int get_exec_path(char *tpath, size_t size)
3442
{
3543
const char *path = "/proc/self/exe";
@@ -44,7 +52,6 @@ static int get_exec_path(char *tpath, size_t size)
4452
return 0;
4553
}
4654

47-
static int oper_count;
4855
static int printf_json(void *out, const char *fmt, va_list ap)
4956
{
5057
char *s;
@@ -102,46 +109,44 @@ static int fprintf_json_styled(void *out,
102109
return r;
103110
}
104111

105-
int disasm_print_insn(unsigned char *image, ssize_t len, int opcodes,
106-
const char *arch, const char *disassembler_options,
107-
const struct btf *btf,
108-
const struct bpf_prog_linfo *prog_linfo,
109-
__u64 func_ksym, unsigned int func_idx,
110-
bool linum)
112+
static int init_context(disasm_ctx_t *ctx, const char *arch,
113+
const char *disassembler_options,
114+
unsigned char *image, ssize_t len)
111115
{
112-
const struct bpf_line_info *linfo = NULL;
113-
disassembler_ftype disassemble;
114-
int count, i, pc = 0, err = -1;
115-
struct disassemble_info info;
116-
unsigned int nr_skip = 0;
116+
struct disassemble_info *info;
117117
char tpath[PATH_MAX];
118118
bfd *bfdf;
119119

120-
if (!len)
121-
return -1;
122-
123120
memset(tpath, 0, sizeof(tpath));
124121
if (get_exec_path(tpath, sizeof(tpath))) {
125122
p_err("failed to create disasembler (get_exec_path)");
126123
return -1;
127124
}
128125

129-
bfdf = bfd_openr(tpath, NULL);
130-
if (!bfdf) {
126+
ctx->bfdf = bfd_openr(tpath, NULL);
127+
if (!ctx->bfdf) {
131128
p_err("failed to create disassembler (bfd_openr)");
132129
return -1;
133130
}
134-
if (!bfd_check_format(bfdf, bfd_object)) {
131+
if (!bfd_check_format(ctx->bfdf, bfd_object)) {
135132
p_err("failed to create disassembler (bfd_check_format)");
136-
goto exit_close;
133+
goto err_close;
137134
}
135+
bfdf = ctx->bfdf;
136+
137+
ctx->info = malloc(sizeof(struct disassemble_info));
138+
if (!ctx->info) {
139+
p_err("mem alloc failed");
140+
goto err_close;
141+
}
142+
info = ctx->info;
138143

139144
if (json_output)
140-
init_disassemble_info_compat(&info, stdout,
145+
init_disassemble_info_compat(info, stdout,
141146
(fprintf_ftype) fprintf_json,
142147
fprintf_json_styled);
143148
else
144-
init_disassemble_info_compat(&info, stdout,
149+
init_disassemble_info_compat(info, stdout,
145150
(fprintf_ftype) fprintf,
146151
fprintf_styled);
147152

@@ -153,31 +158,76 @@ int disasm_print_insn(unsigned char *image, ssize_t len, int opcodes,
153158
bfdf->arch_info = inf;
154159
} else {
155160
p_err("No libbfd support for %s", arch);
156-
goto exit_close;
161+
goto err_free;
157162
}
158163
}
159164

160-
info.arch = bfd_get_arch(bfdf);
161-
info.mach = bfd_get_mach(bfdf);
165+
info->arch = bfd_get_arch(bfdf);
166+
info->mach = bfd_get_mach(bfdf);
162167
if (disassembler_options)
163-
info.disassembler_options = disassembler_options;
164-
info.buffer = image;
165-
info.buffer_length = len;
168+
info->disassembler_options = disassembler_options;
169+
info->buffer = image;
170+
info->buffer_length = len;
166171

167-
disassemble_init_for_target(&info);
172+
disassemble_init_for_target(info);
168173

169174
#ifdef DISASM_FOUR_ARGS_SIGNATURE
170-
disassemble = disassembler(info.arch,
171-
bfd_big_endian(bfdf),
172-
info.mach,
173-
bfdf);
175+
ctx->disassemble = disassembler(info->arch,
176+
bfd_big_endian(bfdf),
177+
info->mach,
178+
bfdf);
174179
#else
175-
disassemble = disassembler(bfdf);
180+
ctx->disassemble = disassembler(bfdf);
176181
#endif
177-
if (!disassemble) {
182+
if (!ctx->disassemble) {
178183
p_err("failed to create disassembler");
179-
goto exit_close;
184+
goto err_free;
180185
}
186+
return 0;
187+
188+
err_free:
189+
free(info);
190+
err_close:
191+
bfd_close(ctx->bfdf);
192+
return -1;
193+
}
194+
195+
static void destroy_context(disasm_ctx_t *ctx)
196+
{
197+
free(ctx->info);
198+
bfd_close(ctx->bfdf);
199+
}
200+
201+
static int
202+
disassemble_insn(disasm_ctx_t *ctx, __maybe_unused unsigned char *image,
203+
__maybe_unused ssize_t len, int pc)
204+
{
205+
return ctx->disassemble(pc, ctx->info);
206+
}
207+
208+
int disasm_init(void)
209+
{
210+
bfd_init();
211+
return 0;
212+
}
213+
214+
int disasm_print_insn(unsigned char *image, ssize_t len, int opcodes,
215+
const char *arch, const char *disassembler_options,
216+
const struct btf *btf,
217+
const struct bpf_prog_linfo *prog_linfo,
218+
__u64 func_ksym, unsigned int func_idx,
219+
bool linum)
220+
{
221+
const struct bpf_line_info *linfo = NULL;
222+
unsigned int nr_skip = 0;
223+
int count, i, pc = 0;
224+
disasm_ctx_t ctx;
225+
226+
if (!len)
227+
return -1;
228+
229+
if (init_context(&ctx, arch, disassembler_options, image, len))
230+
return -1;
181231

182232
if (json_output)
183233
jsonw_start_array(json_wtr);
@@ -205,7 +255,8 @@ int disasm_print_insn(unsigned char *image, ssize_t len, int opcodes,
205255
printf("%4x:\t", pc);
206256
}
207257

208-
count = disassemble(pc, &info);
258+
count = disassemble_insn(&ctx, image, len, pc);
259+
209260
if (json_output) {
210261
/* Operand array, was started in fprintf_json. Before
211262
* that, make sure we have a _null_ value if no operand
@@ -241,15 +292,7 @@ int disasm_print_insn(unsigned char *image, ssize_t len, int opcodes,
241292
if (json_output)
242293
jsonw_end_array(json_wtr);
243294

244-
err = 0;
245-
246-
exit_close:
247-
bfd_close(bfdf);
248-
return err;
249-
}
295+
destroy_context(&ctx);
250296

251-
int disasm_init(void)
252-
{
253-
bfd_init();
254297
return 0;
255298
}

0 commit comments

Comments
 (0)