mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-07 21:53:44 +00:00
x86,objtool: Introduce ORC_TYPE_*
Unwind hints and ORC entry types are two distinct things. Separate them out more explicitly. Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lore.kernel.org/r/cc879d38fff8a43f8f7beb2fd56e35a5a384d7cd.1677683419.git.jpoimboe@kernel.org
This commit is contained in:
parent
d88ebba45d
commit
f902cfdd46
@ -39,6 +39,10 @@
|
||||
#define ORC_REG_SP_INDIRECT 9
|
||||
#define ORC_REG_MAX 15
|
||||
|
||||
#define ORC_TYPE_CALL 0
|
||||
#define ORC_TYPE_REGS 1
|
||||
#define ORC_TYPE_REGS_PARTIAL 2
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
|
@ -133,7 +133,7 @@ static struct orc_entry null_orc_entry = {
|
||||
.sp_offset = sizeof(long),
|
||||
.sp_reg = ORC_REG_SP,
|
||||
.bp_reg = ORC_REG_UNDEFINED,
|
||||
.type = UNWIND_HINT_TYPE_CALL
|
||||
.type = ORC_TYPE_CALL
|
||||
};
|
||||
|
||||
#ifdef CONFIG_CALL_THUNKS
|
||||
@ -153,7 +153,7 @@ static struct orc_entry *orc_callthunk_find(unsigned long ip)
|
||||
|
||||
/* Fake frame pointer entry -- used as a fallback for generated code */
|
||||
static struct orc_entry orc_fp_entry = {
|
||||
.type = UNWIND_HINT_TYPE_CALL,
|
||||
.type = ORC_TYPE_CALL,
|
||||
.sp_reg = ORC_REG_BP,
|
||||
.sp_offset = 16,
|
||||
.bp_reg = ORC_REG_PREV_SP,
|
||||
@ -554,7 +554,7 @@ bool unwind_next_frame(struct unwind_state *state)
|
||||
|
||||
/* Find IP, SP and possibly regs: */
|
||||
switch (orc->type) {
|
||||
case UNWIND_HINT_TYPE_CALL:
|
||||
case ORC_TYPE_CALL:
|
||||
ip_p = sp - sizeof(long);
|
||||
|
||||
if (!deref_stack_reg(state, ip_p, &state->ip))
|
||||
@ -567,7 +567,7 @@ bool unwind_next_frame(struct unwind_state *state)
|
||||
state->prev_regs = NULL;
|
||||
break;
|
||||
|
||||
case UNWIND_HINT_TYPE_REGS:
|
||||
case ORC_TYPE_REGS:
|
||||
if (!deref_stack_regs(state, sp, &state->ip, &state->sp)) {
|
||||
orc_warn_current("can't access registers at %pB\n",
|
||||
(void *)orig_ip);
|
||||
@ -590,13 +590,13 @@ bool unwind_next_frame(struct unwind_state *state)
|
||||
state->full_regs = true;
|
||||
break;
|
||||
|
||||
case UNWIND_HINT_TYPE_REGS_PARTIAL:
|
||||
case ORC_TYPE_REGS_PARTIAL:
|
||||
if (!deref_stack_iret_regs(state, sp, &state->ip, &state->sp)) {
|
||||
orc_warn_current("can't access iret registers at %pB\n",
|
||||
(void *)orig_ip);
|
||||
goto err;
|
||||
}
|
||||
/* See UNWIND_HINT_TYPE_REGS case comment. */
|
||||
/* See ORC_TYPE_REGS case comment. */
|
||||
state->ip = unwind_recover_rethook(state, state->ip,
|
||||
(unsigned long *)(state->sp - sizeof(long)));
|
||||
|
||||
|
@ -40,6 +40,7 @@ struct unwind_hint {
|
||||
#define UNWIND_HINT_TYPE_CALL 0
|
||||
#define UNWIND_HINT_TYPE_REGS 1
|
||||
#define UNWIND_HINT_TYPE_REGS_PARTIAL 2
|
||||
/* The below hint types don't have corresponding ORC types */
|
||||
#define UNWIND_HINT_TYPE_FUNC 3
|
||||
#define UNWIND_HINT_TYPE_ENTRY 4
|
||||
#define UNWIND_HINT_TYPE_SAVE 5
|
||||
|
@ -39,6 +39,10 @@
|
||||
#define ORC_REG_SP_INDIRECT 9
|
||||
#define ORC_REG_MAX 15
|
||||
|
||||
#define ORC_TYPE_CALL 0
|
||||
#define ORC_TYPE_REGS 1
|
||||
#define ORC_TYPE_REGS_PARTIAL 2
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
|
@ -40,6 +40,7 @@ struct unwind_hint {
|
||||
#define UNWIND_HINT_TYPE_CALL 0
|
||||
#define UNWIND_HINT_TYPE_REGS 1
|
||||
#define UNWIND_HINT_TYPE_REGS_PARTIAL 2
|
||||
/* The below hint types don't have corresponding ORC types */
|
||||
#define UNWIND_HINT_TYPE_FUNC 3
|
||||
#define UNWIND_HINT_TYPE_ENTRY 4
|
||||
#define UNWIND_HINT_TYPE_SAVE 5
|
||||
|
@ -4,7 +4,6 @@
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <linux/objtool_types.h>
|
||||
#include <asm/orc_types.h>
|
||||
#include <objtool/objtool.h>
|
||||
#include <objtool/warn.h>
|
||||
@ -39,11 +38,11 @@ static const char *reg_name(unsigned int reg)
|
||||
static const char *orc_type_name(unsigned int type)
|
||||
{
|
||||
switch (type) {
|
||||
case UNWIND_HINT_TYPE_CALL:
|
||||
case ORC_TYPE_CALL:
|
||||
return "call";
|
||||
case UNWIND_HINT_TYPE_REGS:
|
||||
case ORC_TYPE_REGS:
|
||||
return "regs";
|
||||
case UNWIND_HINT_TYPE_REGS_PARTIAL:
|
||||
case ORC_TYPE_REGS_PARTIAL:
|
||||
return "regs (partial)";
|
||||
default:
|
||||
return "?";
|
||||
|
@ -26,6 +26,22 @@ static int init_orc_entry(struct orc_entry *orc, struct cfi_state *cfi,
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (cfi->type) {
|
||||
case UNWIND_HINT_TYPE_CALL:
|
||||
orc->type = ORC_TYPE_CALL;
|
||||
break;
|
||||
case UNWIND_HINT_TYPE_REGS:
|
||||
orc->type = ORC_TYPE_REGS;
|
||||
break;
|
||||
case UNWIND_HINT_TYPE_REGS_PARTIAL:
|
||||
orc->type = ORC_TYPE_REGS_PARTIAL;
|
||||
break;
|
||||
default:
|
||||
WARN_FUNC("unknown unwind hint type %d",
|
||||
insn->sec, insn->offset, cfi->type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
orc->end = cfi->end;
|
||||
orc->signal = cfi->signal;
|
||||
|
||||
@ -83,7 +99,6 @@ static int init_orc_entry(struct orc_entry *orc, struct cfi_state *cfi,
|
||||
|
||||
orc->sp_offset = cfi->cfa.offset;
|
||||
orc->bp_offset = bp->offset;
|
||||
orc->type = cfi->type;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -151,7 +166,7 @@ int orc_create(struct objtool_file *file)
|
||||
struct orc_entry null = {
|
||||
.sp_reg = ORC_REG_UNDEFINED,
|
||||
.bp_reg = ORC_REG_UNDEFINED,
|
||||
.type = UNWIND_HINT_TYPE_CALL,
|
||||
.type = ORC_TYPE_CALL,
|
||||
};
|
||||
|
||||
/* Build a deduplicated list of ORC entries: */
|
||||
|
Loading…
Reference in New Issue
Block a user