Commit 58c3862b authored by Josh Poimboeuf's avatar Josh Poimboeuf Committed by Ingo Molnar

x86/unwind: Show function name+offset in ORC error messages

Improve the warning messages to show the relevant function name+offset.
This makes it much easier to diagnose problems with the ORC metadata.

Before:

  WARNING: can't dereference iret registers at ffff8801c5f17fe0 for ip ffffffff95f0d94b

After:

  WARNING: can't dereference iret registers at ffff880178f5ffe0 for ip int3+0x5b/0x60
Reported-by: default avatarAndrei Vagin <avagin@virtuozzo.com>
Signed-off-by: default avatarJosh Poimboeuf <jpoimboe@redhat.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Fixes: ee9f8fce ("x86/unwind: Add the ORC unwinder")
Link: http://lkml.kernel.org/r/6bada6b9eac86017e16bd79e1e77877935cb50bb.1508516398.git.jpoimboe@redhat.comSigned-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent 98990a33
...@@ -86,8 +86,8 @@ static struct orc_entry *orc_find(unsigned long ip) ...@@ -86,8 +86,8 @@ static struct orc_entry *orc_find(unsigned long ip)
idx = (ip - LOOKUP_START_IP) / LOOKUP_BLOCK_SIZE; idx = (ip - LOOKUP_START_IP) / LOOKUP_BLOCK_SIZE;
if (unlikely((idx >= lookup_num_blocks-1))) { if (unlikely((idx >= lookup_num_blocks-1))) {
orc_warn("WARNING: bad lookup idx: idx=%u num=%u ip=%lx\n", orc_warn("WARNING: bad lookup idx: idx=%u num=%u ip=%pB\n",
idx, lookup_num_blocks, ip); idx, lookup_num_blocks, (void *)ip);
return NULL; return NULL;
} }
...@@ -96,8 +96,8 @@ static struct orc_entry *orc_find(unsigned long ip) ...@@ -96,8 +96,8 @@ static struct orc_entry *orc_find(unsigned long ip)
if (unlikely((__start_orc_unwind + start >= __stop_orc_unwind) || if (unlikely((__start_orc_unwind + start >= __stop_orc_unwind) ||
(__start_orc_unwind + stop > __stop_orc_unwind))) { (__start_orc_unwind + stop > __stop_orc_unwind))) {
orc_warn("WARNING: bad lookup value: idx=%u num=%u start=%u stop=%u ip=%lx\n", orc_warn("WARNING: bad lookup value: idx=%u num=%u start=%u stop=%u ip=%pB\n",
idx, lookup_num_blocks, start, stop, ip); idx, lookup_num_blocks, start, stop, (void *)ip);
return NULL; return NULL;
} }
...@@ -373,7 +373,7 @@ bool unwind_next_frame(struct unwind_state *state) ...@@ -373,7 +373,7 @@ bool unwind_next_frame(struct unwind_state *state)
case ORC_REG_R10: case ORC_REG_R10:
if (!state->regs || !state->full_regs) { if (!state->regs || !state->full_regs) {
orc_warn("missing regs for base reg R10 at ip %p\n", orc_warn("missing regs for base reg R10 at ip %pB\n",
(void *)state->ip); (void *)state->ip);
goto done; goto done;
} }
...@@ -382,7 +382,7 @@ bool unwind_next_frame(struct unwind_state *state) ...@@ -382,7 +382,7 @@ bool unwind_next_frame(struct unwind_state *state)
case ORC_REG_R13: case ORC_REG_R13:
if (!state->regs || !state->full_regs) { if (!state->regs || !state->full_regs) {
orc_warn("missing regs for base reg R13 at ip %p\n", orc_warn("missing regs for base reg R13 at ip %pB\n",
(void *)state->ip); (void *)state->ip);
goto done; goto done;
} }
...@@ -391,7 +391,7 @@ bool unwind_next_frame(struct unwind_state *state) ...@@ -391,7 +391,7 @@ bool unwind_next_frame(struct unwind_state *state)
case ORC_REG_DI: case ORC_REG_DI:
if (!state->regs || !state->full_regs) { if (!state->regs || !state->full_regs) {
orc_warn("missing regs for base reg DI at ip %p\n", orc_warn("missing regs for base reg DI at ip %pB\n",
(void *)state->ip); (void *)state->ip);
goto done; goto done;
} }
...@@ -400,7 +400,7 @@ bool unwind_next_frame(struct unwind_state *state) ...@@ -400,7 +400,7 @@ bool unwind_next_frame(struct unwind_state *state)
case ORC_REG_DX: case ORC_REG_DX:
if (!state->regs || !state->full_regs) { if (!state->regs || !state->full_regs) {
orc_warn("missing regs for base reg DX at ip %p\n", orc_warn("missing regs for base reg DX at ip %pB\n",
(void *)state->ip); (void *)state->ip);
goto done; goto done;
} }
...@@ -408,7 +408,7 @@ bool unwind_next_frame(struct unwind_state *state) ...@@ -408,7 +408,7 @@ bool unwind_next_frame(struct unwind_state *state)
break; break;
default: default:
orc_warn("unknown SP base reg %d for ip %p\n", orc_warn("unknown SP base reg %d for ip %pB\n",
orc->sp_reg, (void *)state->ip); orc->sp_reg, (void *)state->ip);
goto done; goto done;
} }
...@@ -436,7 +436,7 @@ bool unwind_next_frame(struct unwind_state *state) ...@@ -436,7 +436,7 @@ bool unwind_next_frame(struct unwind_state *state)
case ORC_TYPE_REGS: case ORC_TYPE_REGS:
if (!deref_stack_regs(state, sp, &state->ip, &state->sp, true)) { if (!deref_stack_regs(state, sp, &state->ip, &state->sp, true)) {
orc_warn("can't dereference registers at %p for ip %p\n", orc_warn("can't dereference registers at %p for ip %pB\n",
(void *)sp, (void *)orig_ip); (void *)sp, (void *)orig_ip);
goto done; goto done;
} }
...@@ -448,7 +448,7 @@ bool unwind_next_frame(struct unwind_state *state) ...@@ -448,7 +448,7 @@ bool unwind_next_frame(struct unwind_state *state)
case ORC_TYPE_REGS_IRET: case ORC_TYPE_REGS_IRET:
if (!deref_stack_regs(state, sp, &state->ip, &state->sp, false)) { if (!deref_stack_regs(state, sp, &state->ip, &state->sp, false)) {
orc_warn("can't dereference iret registers at %p for ip %p\n", orc_warn("can't dereference iret registers at %p for ip %pB\n",
(void *)sp, (void *)orig_ip); (void *)sp, (void *)orig_ip);
goto done; goto done;
} }
...@@ -465,7 +465,8 @@ bool unwind_next_frame(struct unwind_state *state) ...@@ -465,7 +465,8 @@ bool unwind_next_frame(struct unwind_state *state)
break; break;
default: default:
orc_warn("unknown .orc_unwind entry type %d\n", orc->type); orc_warn("unknown .orc_unwind entry type %d for ip %pB\n",
orc->type, (void *)orig_ip);
break; break;
} }
...@@ -487,7 +488,7 @@ bool unwind_next_frame(struct unwind_state *state) ...@@ -487,7 +488,7 @@ bool unwind_next_frame(struct unwind_state *state)
break; break;
default: default:
orc_warn("unknown BP base reg %d for ip %p\n", orc_warn("unknown BP base reg %d for ip %pB\n",
orc->bp_reg, (void *)orig_ip); orc->bp_reg, (void *)orig_ip);
goto done; goto done;
} }
...@@ -496,7 +497,7 @@ bool unwind_next_frame(struct unwind_state *state) ...@@ -496,7 +497,7 @@ bool unwind_next_frame(struct unwind_state *state)
if (state->stack_info.type == prev_type && if (state->stack_info.type == prev_type &&
on_stack(&state->stack_info, (void *)state->sp, sizeof(long)) && on_stack(&state->stack_info, (void *)state->sp, sizeof(long)) &&
state->sp <= prev_sp) { state->sp <= prev_sp) {
orc_warn("stack going in the wrong direction? ip=%p\n", orc_warn("stack going in the wrong direction? ip=%pB\n",
(void *)orig_ip); (void *)orig_ip);
goto done; goto done;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment