Skip to content

Commit e4fbb51

Browse files
Asphalttqmonnet
authored andcommitted
bpf, bpftool: Fix incorrect disasm pc
This patch addresses the bpftool issue "Wrong callq address displayed"[0]. The issue stemmed from an incorrect program counter (PC) value used during disassembly with LLVM or libbfd. For LLVM: The PC argument must represent the actual address in the kernel to compute the correct relative address. For libbfd: The relative address can be adjusted by adding func_ksym within the custom info->print_address_func to yield the correct address. Links: [0] #109 Changes: v2 -> v3: * Address comment from Quentin: * Remove the typedef. v1 -> v2: * Fix the broken libbfd disassembler. Fixes: e1947c750ffe ("bpftool: Refactor disassembler for JIT-ed programs") Signed-off-by: Leon Hwang <[email protected]> Signed-off-by: Andrii Nakryiko <[email protected]> Tested-by: Quentin Monnet <[email protected]> Reviewed-by: Quentin Monnet <[email protected]> Acked-by: Yonghong Song <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent 8cc215e commit e4fbb51

File tree

1 file changed

+29
-11
lines changed

1 file changed

+29
-11
lines changed

src/jit_disasm.c

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ symbol_lookup_callback(__maybe_unused void *disasm_info,
8080
static int
8181
init_context(disasm_ctx_t *ctx, const char *arch,
8282
__maybe_unused const char *disassembler_options,
83-
__maybe_unused unsigned char *image, __maybe_unused ssize_t len)
83+
__maybe_unused unsigned char *image, __maybe_unused ssize_t len,
84+
__maybe_unused __u64 func_ksym)
8485
{
8586
char *triple;
8687

@@ -109,12 +110,13 @@ static void destroy_context(disasm_ctx_t *ctx)
109110
}
110111

111112
static int
112-
disassemble_insn(disasm_ctx_t *ctx, unsigned char *image, ssize_t len, int pc)
113+
disassemble_insn(disasm_ctx_t *ctx, unsigned char *image, ssize_t len, int pc,
114+
__u64 func_ksym)
113115
{
114116
char buf[256];
115117
int count;
116118

117-
count = LLVMDisasmInstruction(*ctx, image + pc, len - pc, pc,
119+
count = LLVMDisasmInstruction(*ctx, image + pc, len - pc, func_ksym + pc,
118120
buf, sizeof(buf));
119121
if (json_output)
120122
printf_json(buf);
@@ -136,8 +138,21 @@ int disasm_init(void)
136138
#ifdef HAVE_LIBBFD_SUPPORT
137139
#define DISASM_SPACER "\t"
138140

141+
struct disasm_info {
142+
struct disassemble_info info;
143+
__u64 func_ksym;
144+
};
145+
146+
static void disasm_print_addr(bfd_vma addr, struct disassemble_info *info)
147+
{
148+
struct disasm_info *dinfo = container_of(info, struct disasm_info, info);
149+
150+
addr += dinfo->func_ksym;
151+
generic_print_address(addr, info);
152+
}
153+
139154
typedef struct {
140-
struct disassemble_info *info;
155+
struct disasm_info *info;
141156
disassembler_ftype disassemble;
142157
bfd *bfdf;
143158
} disasm_ctx_t;
@@ -215,7 +230,7 @@ static int fprintf_json_styled(void *out,
215230

216231
static int init_context(disasm_ctx_t *ctx, const char *arch,
217232
const char *disassembler_options,
218-
unsigned char *image, ssize_t len)
233+
unsigned char *image, ssize_t len, __u64 func_ksym)
219234
{
220235
struct disassemble_info *info;
221236
char tpath[PATH_MAX];
@@ -238,12 +253,13 @@ static int init_context(disasm_ctx_t *ctx, const char *arch,
238253
}
239254
bfdf = ctx->bfdf;
240255

241-
ctx->info = malloc(sizeof(struct disassemble_info));
256+
ctx->info = malloc(sizeof(struct disasm_info));
242257
if (!ctx->info) {
243258
p_err("mem alloc failed");
244259
goto err_close;
245260
}
246-
info = ctx->info;
261+
ctx->info->func_ksym = func_ksym;
262+
info = &ctx->info->info;
247263

248264
if (json_output)
249265
init_disassemble_info_compat(info, stdout,
@@ -272,6 +288,7 @@ static int init_context(disasm_ctx_t *ctx, const char *arch,
272288
info->disassembler_options = disassembler_options;
273289
info->buffer = image;
274290
info->buffer_length = len;
291+
info->print_address_func = disasm_print_addr;
275292

276293
disassemble_init_for_target(info);
277294

@@ -304,9 +321,10 @@ static void destroy_context(disasm_ctx_t *ctx)
304321

305322
static int
306323
disassemble_insn(disasm_ctx_t *ctx, __maybe_unused unsigned char *image,
307-
__maybe_unused ssize_t len, int pc)
324+
__maybe_unused ssize_t len, int pc,
325+
__maybe_unused __u64 func_ksym)
308326
{
309-
return ctx->disassemble(pc, ctx->info);
327+
return ctx->disassemble(pc, &ctx->info->info);
310328
}
311329

312330
int disasm_init(void)
@@ -331,7 +349,7 @@ int disasm_print_insn(unsigned char *image, ssize_t len, int opcodes,
331349
if (!len)
332350
return -1;
333351

334-
if (init_context(&ctx, arch, disassembler_options, image, len))
352+
if (init_context(&ctx, arch, disassembler_options, image, len, func_ksym))
335353
return -1;
336354

337355
if (json_output)
@@ -360,7 +378,7 @@ int disasm_print_insn(unsigned char *image, ssize_t len, int opcodes,
360378
printf("%4x:" DISASM_SPACER, pc);
361379
}
362380

363-
count = disassemble_insn(&ctx, image, len, pc);
381+
count = disassemble_insn(&ctx, image, len, pc, func_ksym);
364382

365383
if (json_output) {
366384
/* Operand array, was started in fprintf_json. Before

0 commit comments

Comments
 (0)