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>
This commit is contained in:
Josh Poimboeuf 2026-03-18 09:38:38 +01:00 committed by Peter Zijlstra
commit 1735858caa
5 changed files with 58 additions and 49 deletions

View file

@ -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

View file

@ -546,25 +546,15 @@ 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",
(void *)state->ip);
goto err;
}
break;
/*
* 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_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;
}
break;
case ORC_REG_DI:
if (!get_reg(state, offsetof(struct pt_regs, di), &sp)) {
orc_warn_current("missing RDI value at %pB\n",
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;
}
@ -578,9 +568,25 @@ bool unwind_next_frame(struct unwind_state *state)
}
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_DI:
if (!get_reg(state, offsetof(struct pt_regs, di), &sp)) {
orc_warn_current("missing RDI value at %pB\n",
(void *)state->ip);
goto err;
}
break;
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_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;
}

View file

@ -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

View 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;
case ORC_REG_SP_INDIRECT:
*base = CFI_SP_INDIRECT;
break;
case ORC_REG_DX:
*base = CFI_DX;
break;
case ORC_REG_AX:
*base = CFI_AX;
case ORC_REG_BP_INDIRECT:
*base = CFI_BP_INDIRECT;
break;
default:
return -1;

View 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;
case CFI_SP_INDIRECT:
orc->sp_reg = ORC_REG_SP_INDIRECT;
break;
case CFI_DX:
orc->sp_reg = ORC_REG_DX;
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 "?";
}