Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

objtool: Store instruction disassembly result

When disassembling an instruction store the result instead of directly
printing it.

Signed-off-by: Alexandre Chartre <alexandre.chartre@oracle.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Josh Poimboeuf <jpoimboe@kernel.org>
Link: https://patch.msgid.link/20251121095340.464045-7-alexandre.chartre@oracle.com

authored by

Alexandre Chartre and committed by
Peter Zijlstra
d4e13c21 5d859dff

+71 -6
+71 -6
tools/objtool/disas.c
··· 12 12 #include <linux/string.h> 13 13 #include <tools/dis-asm-compat.h> 14 14 15 + /* 16 + * Size of the buffer for storing the result of disassembling 17 + * a single instruction. 18 + */ 19 + #define DISAS_RESULT_SIZE 1024 20 + 15 21 struct disas_context { 16 22 struct objtool_file *file; 17 23 struct instruction *insn; 24 + char result[DISAS_RESULT_SIZE]; 18 25 disassembler_ftype disassembler; 19 26 struct disassemble_info info; 20 27 }; ··· 40 33 41 34 #define DINFO_FPRINTF(dinfo, ...) \ 42 35 ((*(dinfo)->fprintf_func)((dinfo)->stream, __VA_ARGS__)) 36 + 37 + static int disas_result_fprintf(struct disas_context *dctx, 38 + const char *fmt, va_list ap) 39 + { 40 + char *buf = dctx->result; 41 + int avail, len; 42 + 43 + len = strlen(buf); 44 + if (len >= DISAS_RESULT_SIZE - 1) { 45 + WARN_FUNC(dctx->insn->sec, dctx->insn->offset, 46 + "disassembly buffer is full"); 47 + return -1; 48 + } 49 + avail = DISAS_RESULT_SIZE - len; 50 + 51 + len = vsnprintf(buf + len, avail, fmt, ap); 52 + if (len < 0 || len >= avail) { 53 + WARN_FUNC(dctx->insn->sec, dctx->insn->offset, 54 + "disassembly buffer is truncated"); 55 + return -1; 56 + } 57 + 58 + return 0; 59 + } 60 + 61 + static int disas_fprintf(void *stream, const char *fmt, ...) 62 + { 63 + va_list arg; 64 + int rv; 65 + 66 + va_start(arg, fmt); 67 + rv = disas_result_fprintf(stream, fmt, arg); 68 + va_end(arg); 69 + 70 + return rv; 71 + } 72 + 73 + /* 74 + * For init_disassemble_info_compat(). 75 + */ 76 + static int disas_fprintf_styled(void *stream, 77 + enum disassembler_style style, 78 + const char *fmt, ...) 79 + { 80 + va_list arg; 81 + int rv; 82 + 83 + va_start(arg, fmt); 84 + rv = disas_result_fprintf(stream, fmt, arg); 85 + va_end(arg); 86 + 87 + return rv; 88 + } 43 89 44 90 static void disas_print_addr_sym(struct section *sec, struct symbol *sym, 45 91 bfd_vma addr, struct disassemble_info *dinfo) ··· 255 195 dctx->file = file; 256 196 dinfo = &dctx->info; 257 197 258 - init_disassemble_info_compat(dinfo, stdout, 259 - (fprintf_ftype)fprintf, 260 - fprintf_styled); 198 + init_disassemble_info_compat(dinfo, dctx, 199 + disas_fprintf, disas_fprintf_styled); 261 200 262 201 dinfo->read_memory_func = buffer_read_memory; 263 202 dinfo->print_address_func = disas_print_address; ··· 303 244 free(dctx); 304 245 } 305 246 247 + static char *disas_result(struct disas_context *dctx) 248 + { 249 + return dctx->result; 250 + } 251 + 306 252 /* 307 253 * Disassemble a single instruction. Return the size of the instruction. 308 254 */ ··· 318 254 struct disassemble_info *dinfo = &dctx->info; 319 255 320 256 dctx->insn = insn; 257 + dctx->result[0] = '\0'; 321 258 322 259 if (insn->type == INSN_NOP) { 323 260 DINFO_FPRINTF(dinfo, "nop%d", insn->len); ··· 347 282 printf("%s:\n", func->name); 348 283 sym_for_each_insn(dctx->file, func, insn) { 349 284 addr = insn->offset; 350 - printf(" %6lx: %s+0x%-6lx ", 351 - addr, func->name, addr - func->offset); 352 285 disas_insn(dctx, insn); 353 - printf("\n"); 286 + printf(" %6lx: %s+0x%-6lx %s\n", 287 + addr, func->name, addr - func->offset, 288 + disas_result(dctx)); 354 289 } 355 290 printf("\n"); 356 291 }