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: Add functions to better name alternatives

Add the disas_alt_name() and disas_alt_type_name() to provide a
name and a type name for an alternative. This will be used to
better name alternatives when tracing their execution.

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-15-alexandre.chartre@oracle.com

authored by

Alexandre Chartre and committed by
Peter Zijlstra
9b580acc d490aa21

+84
+72
tools/objtool/disas.c
··· 3 3 * Copyright (C) 2015-2017 Josh Poimboeuf <jpoimboe@redhat.com> 4 4 */ 5 5 6 + #define _GNU_SOURCE 7 + 6 8 #include <objtool/arch.h> 7 9 #include <objtool/check.h> 8 10 #include <objtool/disas.h> ··· 450 448 dinfo->buffer_length = insn->sec->sh.sh_size; 451 449 452 450 return disasm(insn->offset, &dctx->info); 451 + } 452 + 453 + /* 454 + * Provide a name for the type of alternatives present at the 455 + * specified instruction. 456 + * 457 + * An instruction can have alternatives with different types, for 458 + * example alternative instructions and an exception table. In that 459 + * case the name for the alternative instructions type is used. 460 + * 461 + * Return NULL if the instruction as no alternative. 462 + */ 463 + const char *disas_alt_type_name(struct instruction *insn) 464 + { 465 + struct alternative *alt; 466 + const char *name; 467 + 468 + name = NULL; 469 + for (alt = insn->alts; alt; alt = alt->next) { 470 + if (alt->type == ALT_TYPE_INSTRUCTIONS) { 471 + name = "alternative"; 472 + break; 473 + } 474 + 475 + switch (alt->type) { 476 + case ALT_TYPE_EX_TABLE: 477 + name = "ex_table"; 478 + break; 479 + case ALT_TYPE_JUMP_TABLE: 480 + name = "jump_table"; 481 + break; 482 + default: 483 + name = "unknown"; 484 + break; 485 + } 486 + } 487 + 488 + return name; 489 + } 490 + 491 + /* 492 + * Provide a name for an alternative. 493 + */ 494 + char *disas_alt_name(struct alternative *alt) 495 + { 496 + char *str = NULL; 497 + 498 + switch (alt->type) { 499 + 500 + case ALT_TYPE_EX_TABLE: 501 + str = strdup("EXCEPTION"); 502 + break; 503 + 504 + case ALT_TYPE_JUMP_TABLE: 505 + str = strdup("JUMP"); 506 + break; 507 + 508 + case ALT_TYPE_INSTRUCTIONS: 509 + /* 510 + * This is a non-default group alternative. Create a unique 511 + * name using the offset of the first original and alternative 512 + * instructions. 513 + */ 514 + asprintf(&str, "ALTERNATIVE %lx.%lx", 515 + alt->insn->alt_group->orig_group->first_insn->offset, 516 + alt->insn->alt_group->first_insn->offset); 517 + break; 518 + } 519 + 520 + return str; 453 521 } 454 522 455 523 /*
+12
tools/objtool/include/objtool/disas.h
··· 6 6 #ifndef _DISAS_H 7 7 #define _DISAS_H 8 8 9 + struct alternative; 9 10 struct disas_context; 10 11 struct disassemble_info; 11 12 ··· 25 24 void disas_print_insn(FILE *stream, struct disas_context *dctx, 26 25 struct instruction *insn, int depth, 27 26 const char *format, ...); 27 + char *disas_alt_name(struct alternative *alt); 28 + const char *disas_alt_type_name(struct instruction *insn); 28 29 29 30 #else /* DISAS */ 30 31 ··· 64 61 static inline void disas_print_insn(FILE *stream, struct disas_context *dctx, 65 62 struct instruction *insn, int depth, 66 63 const char *format, ...) {} 64 + static inline char *disas_alt_name(struct alternative *alt) 65 + { 66 + return NULL; 67 + } 68 + 69 + static inline const char *disas_alt_type_name(struct instruction *insn) 70 + { 71 + return NULL; 72 + } 67 73 68 74 #endif /* DISAS */ 69 75