mirror of
https://gitee.com/bianbu-linux/linux-6.6
synced 2025-04-24 14:07:52 -04:00
objtool: Re-add UNWIND_HINT_{SAVE_RESTORE}
Commit
c536ed2fff
("objtool: Remove SAVE/RESTORE hints")
removed the save/restore unwind hints because they were no longer
needed. Now they're going to be needed again so re-add them.
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Borislav Petkov <bp@suse.de>
This commit is contained in:
parent
acac5e98ef
commit
8faea26e61
5 changed files with 68 additions and 15 deletions
|
@ -8,11 +8,11 @@
|
||||||
#ifdef __ASSEMBLY__
|
#ifdef __ASSEMBLY__
|
||||||
|
|
||||||
.macro UNWIND_HINT_EMPTY
|
.macro UNWIND_HINT_EMPTY
|
||||||
UNWIND_HINT sp_reg=ORC_REG_UNDEFINED type=UNWIND_HINT_TYPE_CALL end=1
|
UNWIND_HINT type=UNWIND_HINT_TYPE_CALL end=1
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro UNWIND_HINT_ENTRY
|
.macro UNWIND_HINT_ENTRY
|
||||||
UNWIND_HINT sp_reg=ORC_REG_UNDEFINED type=UNWIND_HINT_TYPE_ENTRY end=1
|
UNWIND_HINT type=UNWIND_HINT_TYPE_ENTRY end=1
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro UNWIND_HINT_REGS base=%rsp offset=0 indirect=0 extra=1 partial=0
|
.macro UNWIND_HINT_REGS base=%rsp offset=0 indirect=0 extra=1 partial=0
|
||||||
|
@ -56,6 +56,14 @@
|
||||||
UNWIND_HINT sp_reg=ORC_REG_SP sp_offset=8 type=UNWIND_HINT_TYPE_FUNC
|
UNWIND_HINT sp_reg=ORC_REG_SP sp_offset=8 type=UNWIND_HINT_TYPE_FUNC
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
.macro UNWIND_HINT_SAVE
|
||||||
|
UNWIND_HINT type=UNWIND_HINT_TYPE_SAVE
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro UNWIND_HINT_RESTORE
|
||||||
|
UNWIND_HINT type=UNWIND_HINT_TYPE_RESTORE
|
||||||
|
.endm
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define UNWIND_HINT_FUNC \
|
#define UNWIND_HINT_FUNC \
|
||||||
|
|
|
@ -40,6 +40,8 @@ struct unwind_hint {
|
||||||
#define UNWIND_HINT_TYPE_REGS_PARTIAL 2
|
#define UNWIND_HINT_TYPE_REGS_PARTIAL 2
|
||||||
#define UNWIND_HINT_TYPE_FUNC 3
|
#define UNWIND_HINT_TYPE_FUNC 3
|
||||||
#define UNWIND_HINT_TYPE_ENTRY 4
|
#define UNWIND_HINT_TYPE_ENTRY 4
|
||||||
|
#define UNWIND_HINT_TYPE_SAVE 5
|
||||||
|
#define UNWIND_HINT_TYPE_RESTORE 6
|
||||||
|
|
||||||
#ifdef CONFIG_OBJTOOL
|
#ifdef CONFIG_OBJTOOL
|
||||||
|
|
||||||
|
@ -127,7 +129,7 @@ struct unwind_hint {
|
||||||
* the debuginfo as necessary. It will also warn if it sees any
|
* the debuginfo as necessary. It will also warn if it sees any
|
||||||
* inconsistencies.
|
* inconsistencies.
|
||||||
*/
|
*/
|
||||||
.macro UNWIND_HINT sp_reg:req sp_offset=0 type:req end=0
|
.macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 end=0
|
||||||
.Lunwind_hint_ip_\@:
|
.Lunwind_hint_ip_\@:
|
||||||
.pushsection .discard.unwind_hints
|
.pushsection .discard.unwind_hints
|
||||||
/* struct unwind_hint */
|
/* struct unwind_hint */
|
||||||
|
@ -180,7 +182,7 @@ struct unwind_hint {
|
||||||
#define ASM_REACHABLE
|
#define ASM_REACHABLE
|
||||||
#else
|
#else
|
||||||
#define ANNOTATE_INTRA_FUNCTION_CALL
|
#define ANNOTATE_INTRA_FUNCTION_CALL
|
||||||
.macro UNWIND_HINT sp_reg:req sp_offset=0 type:req end=0
|
.macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 end=0
|
||||||
.endm
|
.endm
|
||||||
.macro STACK_FRAME_NON_STANDARD func:req
|
.macro STACK_FRAME_NON_STANDARD func:req
|
||||||
.endm
|
.endm
|
||||||
|
|
|
@ -40,6 +40,8 @@ struct unwind_hint {
|
||||||
#define UNWIND_HINT_TYPE_REGS_PARTIAL 2
|
#define UNWIND_HINT_TYPE_REGS_PARTIAL 2
|
||||||
#define UNWIND_HINT_TYPE_FUNC 3
|
#define UNWIND_HINT_TYPE_FUNC 3
|
||||||
#define UNWIND_HINT_TYPE_ENTRY 4
|
#define UNWIND_HINT_TYPE_ENTRY 4
|
||||||
|
#define UNWIND_HINT_TYPE_SAVE 5
|
||||||
|
#define UNWIND_HINT_TYPE_RESTORE 6
|
||||||
|
|
||||||
#ifdef CONFIG_OBJTOOL
|
#ifdef CONFIG_OBJTOOL
|
||||||
|
|
||||||
|
@ -127,7 +129,7 @@ struct unwind_hint {
|
||||||
* the debuginfo as necessary. It will also warn if it sees any
|
* the debuginfo as necessary. It will also warn if it sees any
|
||||||
* inconsistencies.
|
* inconsistencies.
|
||||||
*/
|
*/
|
||||||
.macro UNWIND_HINT sp_reg:req sp_offset=0 type:req end=0
|
.macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 end=0
|
||||||
.Lunwind_hint_ip_\@:
|
.Lunwind_hint_ip_\@:
|
||||||
.pushsection .discard.unwind_hints
|
.pushsection .discard.unwind_hints
|
||||||
/* struct unwind_hint */
|
/* struct unwind_hint */
|
||||||
|
@ -180,7 +182,7 @@ struct unwind_hint {
|
||||||
#define ASM_REACHABLE
|
#define ASM_REACHABLE
|
||||||
#else
|
#else
|
||||||
#define ANNOTATE_INTRA_FUNCTION_CALL
|
#define ANNOTATE_INTRA_FUNCTION_CALL
|
||||||
.macro UNWIND_HINT sp_reg:req sp_offset=0 type:req end=0
|
.macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 end=0
|
||||||
.endm
|
.endm
|
||||||
.macro STACK_FRAME_NON_STANDARD func:req
|
.macro STACK_FRAME_NON_STANDARD func:req
|
||||||
.endm
|
.endm
|
||||||
|
|
|
@ -2032,6 +2032,17 @@ static int read_unwind_hints(struct objtool_file *file)
|
||||||
|
|
||||||
insn->hint = true;
|
insn->hint = true;
|
||||||
|
|
||||||
|
if (hint->type == UNWIND_HINT_TYPE_SAVE) {
|
||||||
|
insn->hint = false;
|
||||||
|
insn->save = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hint->type == UNWIND_HINT_TYPE_RESTORE) {
|
||||||
|
insn->restore = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (hint->type == UNWIND_HINT_TYPE_REGS_PARTIAL) {
|
if (hint->type == UNWIND_HINT_TYPE_REGS_PARTIAL) {
|
||||||
struct symbol *sym = find_symbol_by_offset(insn->sec, insn->offset);
|
struct symbol *sym = find_symbol_by_offset(insn->sec, insn->offset);
|
||||||
|
|
||||||
|
@ -3329,6 +3340,35 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
|
||||||
state.instr += insn->instr;
|
state.instr += insn->instr;
|
||||||
|
|
||||||
if (insn->hint) {
|
if (insn->hint) {
|
||||||
|
if (insn->restore) {
|
||||||
|
struct instruction *save_insn, *i;
|
||||||
|
|
||||||
|
i = insn;
|
||||||
|
save_insn = NULL;
|
||||||
|
|
||||||
|
sym_for_each_insn_continue_reverse(file, func, i) {
|
||||||
|
if (i->save) {
|
||||||
|
save_insn = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!save_insn) {
|
||||||
|
WARN_FUNC("no corresponding CFI save for CFI restore",
|
||||||
|
sec, insn->offset);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!save_insn->visited) {
|
||||||
|
WARN_FUNC("objtool isn't smart enough to handle this CFI save/restore combo",
|
||||||
|
sec, insn->offset);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
insn->cfi = save_insn->cfi;
|
||||||
|
nr_cfi_reused++;
|
||||||
|
}
|
||||||
|
|
||||||
state.cfi = *insn->cfi;
|
state.cfi = *insn->cfi;
|
||||||
} else {
|
} else {
|
||||||
/* XXX track if we actually changed state.cfi */
|
/* XXX track if we actually changed state.cfi */
|
||||||
|
|
|
@ -46,18 +46,19 @@ struct instruction {
|
||||||
enum insn_type type;
|
enum insn_type type;
|
||||||
unsigned long immediate;
|
unsigned long immediate;
|
||||||
|
|
||||||
u8 dead_end : 1,
|
u16 dead_end : 1,
|
||||||
ignore : 1,
|
ignore : 1,
|
||||||
ignore_alts : 1,
|
ignore_alts : 1,
|
||||||
hint : 1,
|
hint : 1,
|
||||||
retpoline_safe : 1,
|
save : 1,
|
||||||
noendbr : 1,
|
restore : 1,
|
||||||
entry : 1;
|
retpoline_safe : 1,
|
||||||
/* 1 bit hole */
|
noendbr : 1,
|
||||||
|
entry : 1;
|
||||||
|
/* 7 bit hole */
|
||||||
|
|
||||||
s8 instr;
|
s8 instr;
|
||||||
u8 visited;
|
u8 visited;
|
||||||
/* u8 hole */
|
|
||||||
|
|
||||||
struct alt_group *alt_group;
|
struct alt_group *alt_group;
|
||||||
struct symbol *call_dest;
|
struct symbol *call_dest;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue