[tip: objtool/core] objtool/x86: Reorder ORC register numbering

tip-bot2 for Josh Poimboeuf posted 1 patch 2 weeks, 5 days ago
arch/x86/include/asm/orc_types.h       | 10 +++----
arch/x86/kernel/unwind_orc.c           | 30 ++++++++++++---------
tools/arch/x86/include/asm/orc_types.h | 10 +++----
tools/objtool/arch/x86/decode.c        | 21 ++++++++-------
tools/objtool/arch/x86/orc.c           | 36 ++++++++++++-------------
5 files changed, 58 insertions(+), 49 deletions(-)
[tip: objtool/core] objtool/x86: Reorder ORC register numbering
Posted by tip-bot2 for Josh Poimboeuf 2 weeks, 5 days ago
The following commit has been merged into the objtool/core branch of tip:

Commit-ID:     1735858caa4bbb8b923860c0833d463b5d9c5f79
Gitweb:        https://git.kernel.org/tip/1735858caa4bbb8b923860c0833d463b5d9c5f79
Author:        Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate:    Wed, 18 Mar 2026 09:38:38 +01:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Wed, 18 Mar 2026 09:38:52 +01:00

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 <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       | 10 +++----
 arch/x86/kernel/unwind_orc.c           | 30 ++++++++++++---------
 tools/arch/x86/include/asm/orc_types.h | 10 +++----
 tools/objtool/arch/x86/decode.c        | 21 ++++++++-------
 tools/objtool/arch/x86/orc.c           | 36 ++++++++++++-------------
 5 files changed, 58 insertions(+), 49 deletions(-)

diff --git a/arch/x86/include/asm/orc_types.h b/arch/x86/include/asm/orc_types.h
index b3cc797..5837c2b 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 32f7e91..6407bc9 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 b3cc797..5837c2b 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 c3a10f3..23e48ea 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 5494bb4..eff078e 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 "?";
 	}