From: Josh Poimboeuf Date: Wed, 18 Mar 2026 08:38:38 +0000 (+0100) Subject: objtool/x86: Reorder ORC register numbering X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=1735858caa4bbb8b923860c0833d463b5d9c5f79;p=thirdparty%2Fkernel%2Flinux.git 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) --- diff --git a/arch/x86/include/asm/orc_types.h b/arch/x86/include/asm/orc_types.h index b3cc7970fa548..5837c2bb277fd 100644 --- a/arch/x86/include/asm/orc_types.h +++ b/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/arch/x86/kernel/unwind_orc.c b/arch/x86/kernel/unwind_orc.c index 32f7e918d3d9f..6407bc9256bfb 100644 --- a/arch/x86/kernel/unwind_orc.c +++ b/arch/x86/kernel/unwind_orc.c @@ -546,17 +546,23 @@ bool unwind_next_frame(struct unwind_state *state) indirect = true; break; - case ORC_REG_R10: - if (!get_reg(state, offsetof(struct pt_regs, r10), &sp)) { - orc_warn_current("missing R10 value at %pB\n", + /* + * Any of the below registers may temporarily hold the stack pointer, + * typically during a DRAP stack realignment sequence or some other + * stack swizzle. + */ + + case ORC_REG_AX: + if (!get_reg(state, offsetof(struct pt_regs, ax), &sp)) { + orc_warn_current("missing AX value at %pB\n", (void *)state->ip); goto err; } break; - case ORC_REG_R13: - if (!get_reg(state, offsetof(struct pt_regs, r13), &sp)) { - orc_warn_current("missing R13 value at %pB\n", + case ORC_REG_DX: + if (!get_reg(state, offsetof(struct pt_regs, dx), &sp)) { + orc_warn_current("missing DX value at %pB\n", (void *)state->ip); goto err; } @@ -570,17 +576,17 @@ bool unwind_next_frame(struct unwind_state *state) } break; - case ORC_REG_DX: - if (!get_reg(state, offsetof(struct pt_regs, dx), &sp)) { - orc_warn_current("missing DX value at %pB\n", + case ORC_REG_R10: + if (!get_reg(state, offsetof(struct pt_regs, r10), &sp)) { + orc_warn_current("missing R10 value at %pB\n", (void *)state->ip); goto err; } break; - case ORC_REG_AX: - if (!get_reg(state, offsetof(struct pt_regs, ax), &sp)) { - orc_warn_current("missing AX value at %pB\n", + case ORC_REG_R13: + if (!get_reg(state, offsetof(struct pt_regs, r13), &sp)) { + orc_warn_current("missing R13 value at %pB\n", (void *)state->ip); goto err; } diff --git a/tools/arch/x86/include/asm/orc_types.h b/tools/arch/x86/include/asm/orc_types.h index b3cc7970fa548..5837c2bb277fd 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 c3a10f3c72d99..23e48ea9d94e1 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 5494bb450ab55..eff078ecc945b 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 "?"; }