From c19c854b307424c745dd6de73eea8db099c79408 Mon Sep 17 00:00:00 2001 From: Wentong Tian Date: Thu, 22 Jan 2026 22:44:04 +0800 Subject: objtool: Use section/symbol type helpers Commit 25eac74b6bdb ("objtool: Add section/symbol type helpers") introduced several helper macros to improve code readability. Update the remaining open-coded checks in check.c, disas.c, elf.c, and klp-diff.c to use these new helpers. Signed-off-by: Wentong Tian Link: https://patch.msgid.link/20260122144404.40602-1-tianwentong2000@gmail.com Signed-off-by: Josh Poimboeuf --- tools/objtool/check.c | 4 ++-- tools/objtool/disas.c | 6 +++--- tools/objtool/elf.c | 6 +++--- tools/objtool/klp-diff.c | 8 ++++---- 4 files changed, 12 insertions(+), 12 deletions(-) (limited to 'tools') diff --git a/tools/objtool/check.c b/tools/objtool/check.c index a30379e4ff97..efd4b9ce0560 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -4293,8 +4293,8 @@ static int validate_retpoline(struct objtool_file *file) list_for_each_entry(insn, &file->retpoline_call_list, call_node) { struct symbol *sym = insn->sym; - if (sym && (sym->type == STT_NOTYPE || - sym->type == STT_FUNC) && !sym->nocfi) { + if (sym && (is_notype_sym(sym) || + is_func_sym(sym)) && !sym->nocfi) { struct instruction *prev = prev_insn_same_sym(file, insn); diff --git a/tools/objtool/disas.c b/tools/objtool/disas.c index 26f08d41f2b1..59090234af19 100644 --- a/tools/objtool/disas.c +++ b/tools/objtool/disas.c @@ -264,7 +264,7 @@ static void disas_print_addr_reloc(bfd_vma addr, struct disassemble_info *dinfo) * If the relocation symbol is a section name (for example ".bss") * then we try to further resolve the name. */ - if (reloc->sym->type == STT_SECTION) { + if (is_sec_sym(reloc->sym)) { str = offstr(reloc->sym->sec, reloc->sym->offset + offset); DINFO_FPRINTF(dinfo, bfd_vma_fmt, addr, str); free(str); @@ -580,7 +580,7 @@ static size_t disas_insn_common(struct disas_context *dctx, */ dinfo->buffer = insn->sec->data->d_buf; dinfo->buffer_vma = 0; - dinfo->buffer_length = insn->sec->sh.sh_size; + dinfo->buffer_length = sec_size(insn->sec); return disasm(insn->offset, &dctx->info); } @@ -1231,7 +1231,7 @@ void disas_funcs(struct disas_context *dctx) for_each_sec(dctx->file->elf, sec) { - if (!(sec->sh.sh_flags & SHF_EXECINSTR)) + if (!is_text_sec(sec)) continue; sec_for_each_sym(sec, sym) { diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index 2c02c7b49265..a634b227d627 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -614,7 +614,7 @@ static int read_symbols(struct elf *elf) if (elf_add_symbol(elf, sym)) return -1; - if (sym->type == STT_FILE) + if (is_file_sym(sym)) file = sym; else if (sym->bind == STB_LOCAL) sym->file = file; @@ -1335,7 +1335,7 @@ unsigned int elf_add_string(struct elf *elf, struct section *strtab, const char return -1; } - offset = ALIGN(strtab->sh.sh_size, strtab->sh.sh_addralign); + offset = ALIGN(sec_size(strtab), strtab->sh.sh_addralign); if (!elf_add_data(elf, strtab, str, strlen(str) + 1)) return -1; @@ -1377,7 +1377,7 @@ void *elf_add_data(struct elf *elf, struct section *sec, const void *data, size_ sec->data->d_size = size; sec->data->d_align = 1; - offset = ALIGN(sec->sh.sh_size, sec->sh.sh_addralign); + offset = ALIGN(sec_size(sec), sec->sh.sh_addralign); sec->sh.sh_size = offset + size; mark_sec_changed(elf, sec, true); diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c index 9f1f4011eb9c..885775f6072e 100644 --- a/tools/objtool/klp-diff.c +++ b/tools/objtool/klp-diff.c @@ -271,7 +271,7 @@ static bool is_uncorrelated_static_local(struct symbol *sym) */ static bool is_clang_tmp_label(struct symbol *sym) { - return sym->type == STT_NOTYPE && + return is_notype_sym(sym) && is_text_sec(sym->sec) && strstarts(sym->name, ".Ltmp") && isdigit(sym->name[5]); @@ -480,7 +480,7 @@ static unsigned long find_sympos(struct elf *elf, struct symbol *sym) if (sym->bind != STB_LOCAL) return 0; - if (vmlinux && sym->type == STT_FUNC) { + if (vmlinux && is_func_sym(sym)) { /* * HACK: Unfortunately, symbol ordering can differ between * vmlinux.o and vmlinux due to the linker script emitting @@ -1046,8 +1046,8 @@ static int clone_reloc_klp(struct elfs *e, struct reloc *patched_reloc, sec->name, offset, patched_sym->name, \ addend >= 0 ? "+" : "-", labs(addend), \ sym_type(patched_sym), \ - patched_sym->type == STT_SECTION ? "" : " ", \ - patched_sym->type == STT_SECTION ? "" : sym_bind(patched_sym), \ + is_sec_sym(patched_sym) ? "" : " ", \ + is_sec_sym(patched_sym) ? "" : sym_bind(patched_sym), \ is_undef_sym(patched_sym) ? " UNDEF" : "", \ export ? " EXPORTED" : "", \ klp ? " KLP" : "") -- cgit v1.2.3 From a1cbaff2ea23645f0a94fdfa721aef202aebdf86 Mon Sep 17 00:00:00 2001 From: Song Liu Date: Thu, 5 Mar 2026 15:15:25 -0800 Subject: objtool/klp: Remove redundant strcmp() in correlate_symbols() find_global_symbol_by_name() already compares names of the two symbols, so there is no need to compare them again. Signed-off-by: Song Liu Link: https://patch.msgid.link/20260305231531.3847295-2-song@kernel.org Signed-off-by: Josh Poimboeuf --- tools/objtool/klp-diff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c index 885775f6072e..639bdd3ad5eb 100644 --- a/tools/objtool/klp-diff.c +++ b/tools/objtool/klp-diff.c @@ -454,7 +454,7 @@ static int correlate_symbols(struct elfs *e) sym2 = find_global_symbol_by_name(e->patched, sym1->name); - if (sym2 && !sym2->twin && !strcmp(sym1->name, sym2->name)) { + if (sym2 && !sym2->twin) { sym1->twin = sym2; sym2->twin = sym1; } -- cgit v1.2.3 From a3f28d2072452edb377eaad01375445dbace6771 Mon Sep 17 00:00:00 2001 From: Song Liu Date: Thu, 5 Mar 2026 15:15:26 -0800 Subject: objtool/klp: Remove trailing '_' in demangle_name() With CONFIG_LTO_CLANG_THIN, it is possible to have nested __UNIQUE_ID_, such as: __UNIQUE_ID_addressable___UNIQUE_ID_pci_invalid_bar_694_695 To remove both trailing numbers, also remove trailing '_'. Also add comments to demangle_name(). Signed-off-by: Song Liu Link: https://patch.msgid.link/20260305231531.3847295-3-song@kernel.org Signed-off-by: Josh Poimboeuf --- tools/objtool/elf.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index a634b227d627..fe6e66dd5422 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -441,6 +441,19 @@ static int read_sections(struct elf *elf) return 0; } +/* + * Remove number suffix of a symbol. + * + * Specifically, remove trailing numbers for "__UNIQUE_ID_" symbols and + * symbols with '.'. + * + * With CONFIG_LTO_CLANG_THIN, it is possible to have nested __UNIQUE_ID_, + * such as + * + * __UNIQUE_ID_addressable___UNIQUE_ID_pci_invalid_bar_694_695 + * + * to remove both trailing numbers, also remove trailing '_'. + */ static const char *demangle_name(struct symbol *sym) { char *str; @@ -463,7 +476,7 @@ static const char *demangle_name(struct symbol *sym) for (int i = strlen(str) - 1; i >= 0; i--) { char c = str[i]; - if (!isdigit(c) && c != '.') { + if (!isdigit(c) && c != '.' && c != '_') { str[i + 1] = '\0'; break; } -- cgit v1.2.3 From 0b8fc6adc3d9bdf161fc8ad0a1de191dba293b39 Mon Sep 17 00:00:00 2001 From: Song Liu Date: Thu, 5 Mar 2026 15:15:27 -0800 Subject: objtool/klp: Use sym->demangled_name for symbol_name hash For klp-build with LTO, it is necessary to correlate demangled symbols, e.g., correlate foo.llvm. and foo.llvm.. However, these two symbols do not have the same str_hash(name). To be able to correlate the two symbols, calculate hash based on demanged_name, so that these two symbols have the same hash. No functional changes intended. Signed-off-by: Song Liu Link: https://patch.msgid.link/20260305231531.3847295-4-song@kernel.org Signed-off-by: Josh Poimboeuf --- tools/objtool/elf.c | 58 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 18 deletions(-) (limited to 'tools') diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index fe6e66dd5422..b2d73c4c6cf1 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -26,11 +26,18 @@ #include #include +static ssize_t demangled_name_len(const char *name); + static inline u32 str_hash(const char *str) { return jhash(str, strlen(str), 0); } +static inline u32 str_hash_demangled(const char *str) +{ + return jhash(str, demangled_name_len(str), 0); +} + #define __elf_table(name) (elf->name##_hash) #define __elf_bits(name) (elf->name##_bits) @@ -294,7 +301,7 @@ static struct symbol *find_local_symbol_by_file_and_name(const struct elf *elf, { struct symbol *sym; - elf_hash_for_each_possible(symbol_name, sym, name_hash, str_hash(name)) { + elf_hash_for_each_possible(symbol_name, sym, name_hash, str_hash_demangled(name)) { if (sym->bind == STB_LOCAL && sym->file == file && !strcmp(sym->name, name)) { return sym; @@ -308,7 +315,7 @@ struct symbol *find_global_symbol_by_name(const struct elf *elf, const char *nam { struct symbol *sym; - elf_hash_for_each_possible(symbol_name, sym, name_hash, str_hash(name)) { + elf_hash_for_each_possible(symbol_name, sym, name_hash, str_hash_demangled(name)) { if (!strcmp(sym->name, name) && !is_local_sym(sym)) return sym; } @@ -441,6 +448,28 @@ static int read_sections(struct elf *elf) return 0; } +/* + * Returns desired length of the demangled name. + * If name doesn't need demangling, return strlen(name). + */ +static ssize_t demangled_name_len(const char *name) +{ + ssize_t idx; + + if (!strstarts(name, "__UNIQUE_ID_") && !strchr(name, '.')) + return strlen(name); + + for (idx = strlen(name) - 1; idx >= 0; idx--) { + char c = name[idx]; + + if (!isdigit(c) && c != '.' && c != '_') + break; + } + if (idx <= 0) + return strlen(name); + return idx + 1; +} + /* * Remove number suffix of a symbol. * @@ -457,6 +486,7 @@ static int read_sections(struct elf *elf) static const char *demangle_name(struct symbol *sym) { char *str; + ssize_t len; if (!is_local_sym(sym)) return sym->name; @@ -464,24 +494,16 @@ static const char *demangle_name(struct symbol *sym) if (!is_func_sym(sym) && !is_object_sym(sym)) return sym->name; - if (!strstarts(sym->name, "__UNIQUE_ID_") && !strchr(sym->name, '.')) + len = demangled_name_len(sym->name); + if (len == strlen(sym->name)) return sym->name; - str = strdup(sym->name); + str = strndup(sym->name, len); if (!str) { ERROR_GLIBC("strdup"); return NULL; } - for (int i = strlen(str) - 1; i >= 0; i--) { - char c = str[i]; - - if (!isdigit(c) && c != '.' && c != '_') { - str[i + 1] = '\0'; - break; - } - } - return str; } @@ -517,9 +539,13 @@ static int elf_add_symbol(struct elf *elf, struct symbol *sym) entry = &sym->sec->symbol_list; list_add(&sym->list, entry); + sym->demangled_name = demangle_name(sym); + if (!sym->demangled_name) + return -1; + list_add_tail(&sym->global_list, &elf->symbols); elf_hash_add(symbol, &sym->hash, sym->idx); - elf_hash_add(symbol_name, &sym->name_hash, str_hash(sym->name)); + elf_hash_add(symbol_name, &sym->name_hash, str_hash(sym->demangled_name)); if (is_func_sym(sym) && (strstarts(sym->name, "__pfx_") || @@ -543,10 +569,6 @@ static int elf_add_symbol(struct elf *elf, struct symbol *sym) sym->pfunc = sym->cfunc = sym; - sym->demangled_name = demangle_name(sym); - if (!sym->demangled_name) - return -1; - return 0; } -- cgit v1.2.3 From 8206277746d5c6ae300e7e062a0d9238ed59cc7f Mon Sep 17 00:00:00 2001 From: Song Liu Date: Thu, 5 Mar 2026 15:15:28 -0800 Subject: objtool/klp: Also demangle global objects With CONFIG_LTO_CLANG_THIN, it is possible to have global __UNIQUE_ID, such as: FUNC GLOBAL HIDDEN 19745 __UNIQUE_ID_quirk_amd_nb_node_458 Also demangle global objects. Signed-off-by: Song Liu Link: https://patch.msgid.link/20260305231531.3847295-5-song@kernel.org Signed-off-by: Josh Poimboeuf --- tools/objtool/elf.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'tools') diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index b2d73c4c6cf1..7e019f15aac5 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -488,9 +488,6 @@ static const char *demangle_name(struct symbol *sym) char *str; ssize_t len; - if (!is_local_sym(sym)) - return sym->name; - if (!is_func_sym(sym) && !is_object_sym(sym)) return sym->name; -- cgit v1.2.3 From 020b71dcafeeececb78d9ee9e5a2e68e8e05e922 Mon Sep 17 00:00:00 2001 From: Song Liu Date: Thu, 5 Mar 2026 15:15:29 -0800 Subject: objtool/klp: Remove .llvm suffix in demangle_name() Remove .llvm suffix, so that we can correlate foo.llvm. and foo.llvm.. Signed-off-by: Song Liu Link: https://patch.msgid.link/20260305231531.3847295-6-song@kernel.org Signed-off-by: Josh Poimboeuf --- tools/objtool/elf.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'tools') diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index 7e019f15aac5..feaec45a14a0 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -455,6 +455,11 @@ static int read_sections(struct elf *elf) static ssize_t demangled_name_len(const char *name) { ssize_t idx; + const char *p; + + p = strstr(name, ".llvm."); + if (p) + return p - name; if (!strstarts(name, "__UNIQUE_ID_") && !strchr(name, '.')) return strlen(name); @@ -482,6 +487,9 @@ static ssize_t demangled_name_len(const char *name) * __UNIQUE_ID_addressable___UNIQUE_ID_pci_invalid_bar_694_695 * * to remove both trailing numbers, also remove trailing '_'. + * + * For symbols with llvm suffix, i.e., foo.llvm., remove the + * .llvm. part. */ static const char *demangle_name(struct symbol *sym) { -- cgit v1.2.3 From cdea5cadb0ca403b1929f8d29929c0eda0f715d6 Mon Sep 17 00:00:00 2001 From: Song Liu Date: Thu, 5 Mar 2026 15:15:30 -0800 Subject: objtool/klp: Match symbols based on demangled_name for global variables correlate_symbols() will always try to match full name first. If there is no match, try match only demangled_name. In very rare cases, it is possible to have multiple foo.llvm. in the same kernel. Whenever there is ambiguity like this, fail the klp diff. Signed-off-by: Song Liu Link: https://patch.msgid.link/20260305231531.3847295-7-song@kernel.org Signed-off-by: Josh Poimboeuf --- tools/objtool/elf.c | 13 +++++++++ tools/objtool/include/objtool/elf.h | 3 ++ tools/objtool/klp-diff.c | 57 +++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+) (limited to 'tools') diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index feaec45a14a0..8122c5f5141c 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -323,6 +323,19 @@ struct symbol *find_global_symbol_by_name(const struct elf *elf, const char *nam return NULL; } +void iterate_global_symbol_by_demangled_name(const struct elf *elf, + const char *demangled_name, + void (*process)(struct symbol *sym, void *data), + void *data) +{ + struct symbol *sym; + + elf_hash_for_each_possible(symbol_name, sym, name_hash, str_hash(demangled_name)) { + if (!strcmp(sym->demangled_name, demangled_name) && !is_local_sym(sym)) + process(sym, data); + } +} + struct reloc *find_reloc_by_dest_range(const struct elf *elf, struct section *sec, unsigned long offset, unsigned int len) { diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/objtool/elf.h index e12c516bd320..25573e5af76e 100644 --- a/tools/objtool/include/objtool/elf.h +++ b/tools/objtool/include/objtool/elf.h @@ -186,6 +186,9 @@ struct symbol *find_func_by_offset(struct section *sec, unsigned long offset); struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset); struct symbol *find_symbol_by_name(const struct elf *elf, const char *name); struct symbol *find_global_symbol_by_name(const struct elf *elf, const char *name); +void iterate_global_symbol_by_demangled_name(const struct elf *elf, const char *demangled_name, + void (*process)(struct symbol *sym, void *data), + void *data); struct symbol *find_symbol_containing(const struct section *sec, unsigned long offset); int find_symbol_hole_containing(const struct section *sec, unsigned long offset); struct reloc *find_reloc_by_dest(const struct elf *elf, struct section *sec, unsigned long offset); diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c index 639bdd3ad5eb..46afbf4a03b9 100644 --- a/tools/objtool/klp-diff.c +++ b/tools/objtool/klp-diff.c @@ -355,6 +355,46 @@ static bool dont_correlate(struct symbol *sym) strstarts(sym->name, "__initcall__"); } +struct process_demangled_name_data { + struct symbol *ret; + int count; +}; + +static void process_demangled_name(struct symbol *sym, void *d) +{ + struct process_demangled_name_data *data = d; + + if (sym->twin) + return; + + data->count++; + data->ret = sym; +} + +/* + * When there is no full name match, try match demangled_name. This would + * match original foo.llvm.123 to patched foo.llvm.456. + * + * Note that, in very rare cases, it is possible to have multiple + * foo.llvm. in the same kernel. When this happens, report error and + * fail the diff. + */ +static int find_global_symbol_by_demangled_name(struct elf *elf, struct symbol *sym, + struct symbol **out_sym) +{ + struct process_demangled_name_data data = {}; + + iterate_global_symbol_by_demangled_name(elf, sym->demangled_name, + process_demangled_name, + &data); + if (data.count > 1) { + ERROR("Multiple (%d) correlation candidates for %s", data.count, sym->name); + return -1; + } + *out_sym = data.ret; + return 0; +} + /* * For each symbol in the original kernel, find its corresponding "twin" in the * patched kernel. @@ -453,6 +493,23 @@ static int correlate_symbols(struct elfs *e) continue; sym2 = find_global_symbol_by_name(e->patched, sym1->name); + if (sym2 && !sym2->twin) { + sym1->twin = sym2; + sym2->twin = sym1; + } + } + + /* + * Correlate globals with demangled_name. + * A separate loop is needed because we want to finish all the + * full name correlations first. + */ + for_each_sym(e->orig, sym1) { + if (sym1->bind == STB_LOCAL || sym1->twin) + continue; + + if (find_global_symbol_by_demangled_name(e->patched, sym1, &sym2)) + return -1; if (sym2 && !sym2->twin) { sym1->twin = sym2; -- cgit v1.2.3 From 4b57e97be22fb8332d05ee1d0fe3c0dd43c828bf Mon Sep 17 00:00:00 2001 From: Song Liu Date: Thu, 5 Mar 2026 15:15:31 -0800 Subject: objtool/klp: Correlate locals to globals Allow correlating original locals to patched globals, and vice versa. This is needed when: 1. User adds/removes "static" for a function. 2. CONFIG_LTO_CLANG_THIN promotes local functions and objects to global and add .llvm. suffix. Signed-off-by: Song Liu Link: https://patch.msgid.link/20260305231531.3847295-8-song@kernel.org Signed-off-by: Josh Poimboeuf --- tools/objtool/klp-diff.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'tools') diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c index 46afbf4a03b9..85281b3b021f 100644 --- a/tools/objtool/klp-diff.c +++ b/tools/objtool/klp-diff.c @@ -517,6 +517,36 @@ static int correlate_symbols(struct elfs *e) } } + /* Correlate original locals with patched globals */ + for_each_sym(e->orig, sym1) { + if (sym1->twin || dont_correlate(sym1) || !is_local_sym(sym1)) + continue; + + sym2 = find_global_symbol_by_name(e->patched, sym1->name); + if (!sym2 && find_global_symbol_by_demangled_name(e->patched, sym1, &sym2)) + return -1; + + if (sym2 && !sym2->twin) { + sym1->twin = sym2; + sym2->twin = sym1; + } + } + + /* Correlate original globals with patched locals */ + for_each_sym(e->patched, sym2) { + if (sym2->twin || dont_correlate(sym2) || !is_local_sym(sym2)) + continue; + + sym1 = find_global_symbol_by_name(e->orig, sym2->name); + if (!sym1 && find_global_symbol_by_demangled_name(e->orig, sym2, &sym1)) + return -1; + + if (sym1 && !sym1->twin) { + sym2->twin = sym1; + sym1->twin = sym2; + } + } + for_each_sym(e->orig, sym1) { if (sym1->twin || dont_correlate(sym1)) continue; -- cgit v1.2.3 From 96f3b16a9de552538b810f773645d43f3b661b50 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Mon, 16 Mar 2026 17:47:56 -0700 Subject: objtool: Support Clang RAX DRAP sequence Recent Clang can use RAX as a temporary register for the DRAP stack alignment sequence. Add support for that. Fixes the following warning: vmlinux.o: error: objtool: vmw_host_printf+0xd: unknown CFA base reg 0 Closes: https://lore.kernel.org/cefefdd1-7b82-406d-8ff4-e4b167e45ee6@app.fastmail.com Reported-by: Arnd Bergmann Signed-off-by: Josh Poimboeuf Signed-off-by: Peter Zijlstra (Intel) Link: https://patch.msgid.link/3f33dc720b83dc6d3a2b7094f75a5c90a0b1cbc5.1773708458.git.jpoimboe@kernel.org --- tools/arch/x86/include/asm/orc_types.h | 1 + tools/objtool/arch/x86/decode.c | 3 +++ tools/objtool/arch/x86/orc.c | 5 +++++ 3 files changed, 9 insertions(+) (limited to 'tools') diff --git a/tools/arch/x86/include/asm/orc_types.h b/tools/arch/x86/include/asm/orc_types.h index e0125afa53fb..b3cc7970fa54 100644 --- a/tools/arch/x86/include/asm/orc_types.h +++ b/tools/arch/x86/include/asm/orc_types.h @@ -37,6 +37,7 @@ #define ORC_REG_R13 7 #define ORC_REG_BP_INDIRECT 8 #define ORC_REG_SP_INDIRECT 9 +#define ORC_REG_AX 10 #define ORC_REG_MAX 15 #define ORC_TYPE_UNDEFINED 0 diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c index 73bfea220d1b..c3a10f3c72d9 100644 --- a/tools/objtool/arch/x86/decode.c +++ b/tools/objtool/arch/x86/decode.c @@ -912,6 +912,9 @@ int arch_decode_hint_reg(u8 sp_reg, int *base) case ORC_REG_DX: *base = CFI_DX; break; + case ORC_REG_AX: + *base = CFI_AX; + break; default: return -1; } diff --git a/tools/objtool/arch/x86/orc.c b/tools/objtool/arch/x86/orc.c index 735e150ca6b7..5494bb450ab5 100644 --- a/tools/objtool/arch/x86/orc.c +++ b/tools/objtool/arch/x86/orc.c @@ -70,6 +70,9 @@ int init_orc_entry(struct orc_entry *orc, struct cfi_state *cfi, struct instruct case CFI_DX: orc->sp_reg = ORC_REG_DX; break; + case CFI_AX: + orc->sp_reg = ORC_REG_AX; + break; default: ERROR_INSN(insn, "unknown CFA base reg %d", cfi->cfa.base); return -1; @@ -138,6 +141,8 @@ static const char *reg_name(unsigned int reg) return "bp(ind)"; case ORC_REG_SP_INDIRECT: return "sp(ind)"; + case ORC_REG_AX: + return "ax"; default: return "?"; } -- cgit v1.2.3 From 1735858caa4bbb8b923860c0833d463b5d9c5f79 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Wed, 18 Mar 2026 09:38:38 +0100 Subject: objtool/x86: Reorder ORC register numbering Reorder the ORC register values so their ordering matches the x86 instruction set register encodings. No functional change intended. Suggested-by: Peter Zijlstra Signed-off-by: Josh Poimboeuf Signed-off-by: Peter Zijlstra (Intel) --- tools/arch/x86/include/asm/orc_types.h | 10 +++++----- tools/objtool/arch/x86/decode.c | 21 +++++++++++--------- tools/objtool/arch/x86/orc.c | 36 +++++++++++++++++----------------- 3 files changed, 35 insertions(+), 32 deletions(-) (limited to 'tools') diff --git a/tools/arch/x86/include/asm/orc_types.h b/tools/arch/x86/include/asm/orc_types.h index b3cc7970fa54..5837c2bb277f 100644 --- a/tools/arch/x86/include/asm/orc_types.h +++ b/tools/arch/x86/include/asm/orc_types.h @@ -28,16 +28,16 @@ * and GCC realigned stacks. */ #define ORC_REG_UNDEFINED 0 -#define ORC_REG_PREV_SP 1 +#define ORC_REG_AX 1 #define ORC_REG_DX 2 -#define ORC_REG_DI 3 +#define ORC_REG_SP 3 #define ORC_REG_BP 4 -#define ORC_REG_SP 5 +#define ORC_REG_DI 5 #define ORC_REG_R10 6 #define ORC_REG_R13 7 -#define ORC_REG_BP_INDIRECT 8 +#define ORC_REG_PREV_SP 8 #define ORC_REG_SP_INDIRECT 9 -#define ORC_REG_AX 10 +#define ORC_REG_BP_INDIRECT 10 #define ORC_REG_MAX 15 #define ORC_TYPE_UNDEFINED 0 diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c index c3a10f3c72d9..23e48ea9d94e 100644 --- a/tools/objtool/arch/x86/decode.c +++ b/tools/objtool/arch/x86/decode.c @@ -891,14 +891,20 @@ int arch_decode_hint_reg(u8 sp_reg, int *base) case ORC_REG_UNDEFINED: *base = CFI_UNDEFINED; break; + case ORC_REG_AX: + *base = CFI_AX; + break; + case ORC_REG_DX: + *base = CFI_DX; + break; case ORC_REG_SP: *base = CFI_SP; break; case ORC_REG_BP: *base = CFI_BP; break; - case ORC_REG_SP_INDIRECT: - *base = CFI_SP_INDIRECT; + case ORC_REG_DI: + *base = CFI_DI; break; case ORC_REG_R10: *base = CFI_R10; @@ -906,14 +912,11 @@ int arch_decode_hint_reg(u8 sp_reg, int *base) case ORC_REG_R13: *base = CFI_R13; break; - case ORC_REG_DI: - *base = CFI_DI; - break; - case ORC_REG_DX: - *base = CFI_DX; + case ORC_REG_SP_INDIRECT: + *base = CFI_SP_INDIRECT; break; - case ORC_REG_AX: - *base = CFI_AX; + case ORC_REG_BP_INDIRECT: + *base = CFI_BP_INDIRECT; break; default: return -1; diff --git a/tools/objtool/arch/x86/orc.c b/tools/objtool/arch/x86/orc.c index 5494bb450ab5..eff078ecc945 100644 --- a/tools/objtool/arch/x86/orc.c +++ b/tools/objtool/arch/x86/orc.c @@ -46,17 +46,20 @@ int init_orc_entry(struct orc_entry *orc, struct cfi_state *cfi, struct instruct orc->signal = cfi->signal; switch (cfi->cfa.base) { + case CFI_AX: + orc->sp_reg = ORC_REG_AX; + break; + case CFI_DX: + orc->sp_reg = ORC_REG_DX; + break; case CFI_SP: orc->sp_reg = ORC_REG_SP; break; - case CFI_SP_INDIRECT: - orc->sp_reg = ORC_REG_SP_INDIRECT; - break; case CFI_BP: orc->sp_reg = ORC_REG_BP; break; - case CFI_BP_INDIRECT: - orc->sp_reg = ORC_REG_BP_INDIRECT; + case CFI_DI: + orc->sp_reg = ORC_REG_DI; break; case CFI_R10: orc->sp_reg = ORC_REG_R10; @@ -64,14 +67,11 @@ int init_orc_entry(struct orc_entry *orc, struct cfi_state *cfi, struct instruct case CFI_R13: orc->sp_reg = ORC_REG_R13; break; - case CFI_DI: - orc->sp_reg = ORC_REG_DI; - break; - case CFI_DX: - orc->sp_reg = ORC_REG_DX; + case CFI_SP_INDIRECT: + orc->sp_reg = ORC_REG_SP_INDIRECT; break; - case CFI_AX: - orc->sp_reg = ORC_REG_AX; + case CFI_BP_INDIRECT: + orc->sp_reg = ORC_REG_BP_INDIRECT; break; default: ERROR_INSN(insn, "unknown CFA base reg %d", cfi->cfa.base); @@ -125,24 +125,24 @@ static const char *reg_name(unsigned int reg) switch (reg) { case ORC_REG_PREV_SP: return "prevsp"; + case ORC_REG_AX: + return "ax"; case ORC_REG_DX: return "dx"; - case ORC_REG_DI: - return "di"; case ORC_REG_BP: return "bp"; case ORC_REG_SP: return "sp"; + case ORC_REG_DI: + return "di"; case ORC_REG_R10: return "r10"; case ORC_REG_R13: return "r13"; - case ORC_REG_BP_INDIRECT: - return "bp(ind)"; case ORC_REG_SP_INDIRECT: return "sp(ind)"; - case ORC_REG_AX: - return "ax"; + case ORC_REG_BP_INDIRECT: + return "bp(ind)"; default: return "?"; } -- cgit v1.2.3