]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
objtool/x86: Reorder ORC register numbering
authorJosh Poimboeuf <jpoimboe@kernel.org>
Wed, 18 Mar 2026 08:38:38 +0000 (09:38 +0100)
committerPeter Zijlstra <peterz@infradead.org>
Wed, 18 Mar 2026 08:38:52 +0000 (09:38 +0100)
Reorder the ORC register values so their ordering matches the x86
instruction set register encodings.

No functional change intended.

Suggested-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
arch/x86/include/asm/orc_types.h
arch/x86/kernel/unwind_orc.c
tools/arch/x86/include/asm/orc_types.h
tools/objtool/arch/x86/decode.c
tools/objtool/arch/x86/orc.c

index b3cc7970fa548f39c8c4c4702a8b20b028d3cba2..5837c2bb277fdc47abacd4ffc000764de7461f2e 100644 (file)
  * 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
index 32f7e918d3d9f9013284ab3fa31161501e20edf6..6407bc9256bfb78448e1cfa3e9a1755168670e7c 100644 (file)
@@ -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;
                }
index b3cc7970fa548f39c8c4c4702a8b20b028d3cba2..5837c2bb277fdc47abacd4ffc000764de7461f2e 100644 (file)
  * 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
index c3a10f3c72d996daf00a111d45dee7dc464f2748..23e48ea9d94e19a9fc16599c40d9e04b10e7e1c1 100644 (file)
@@ -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;
index 5494bb450ab552d048e357c61f47667df5131bc6..eff078ecc945b0eda52703194962ffbf2852e381 100644 (file)
@@ -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 "?";
        }