Skip to content

Commit

Permalink
objtool: Re-add UNWIND_HINT_{SAVE_RESTORE}
Browse files Browse the repository at this point in the history
Commit

  c536ed2 ("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 <[email protected]>
Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
Signed-off-by: Borislav Petkov <[email protected]>
  • Loading branch information
jpoimboe authored and suryasaimadhu committed Jun 27, 2022
1 parent acac5e9 commit 8faea26
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 15 deletions.
12 changes: 10 additions & 2 deletions arch/x86/include/asm/unwind_hints.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
#ifdef __ASSEMBLY__

.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

.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

.macro UNWIND_HINT_REGS base=%rsp offset=0 indirect=0 extra=1 partial=0
Expand Down Expand Up @@ -56,6 +56,14 @@
UNWIND_HINT sp_reg=ORC_REG_SP sp_offset=8 type=UNWIND_HINT_TYPE_FUNC
.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

#define UNWIND_HINT_FUNC \
Expand Down
6 changes: 4 additions & 2 deletions include/linux/objtool.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ struct unwind_hint {
#define UNWIND_HINT_TYPE_REGS_PARTIAL 2
#define UNWIND_HINT_TYPE_FUNC 3
#define UNWIND_HINT_TYPE_ENTRY 4
#define UNWIND_HINT_TYPE_SAVE 5
#define UNWIND_HINT_TYPE_RESTORE 6

#ifdef CONFIG_OBJTOOL

Expand Down Expand Up @@ -127,7 +129,7 @@ struct unwind_hint {
* the debuginfo as necessary. It will also warn if it sees any
* 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_\@:
.pushsection .discard.unwind_hints
/* struct unwind_hint */
Expand Down Expand Up @@ -180,7 +182,7 @@ struct unwind_hint {
#define ASM_REACHABLE
#else
#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
.macro STACK_FRAME_NON_STANDARD func:req
.endm
Expand Down
6 changes: 4 additions & 2 deletions tools/include/linux/objtool.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ struct unwind_hint {
#define UNWIND_HINT_TYPE_REGS_PARTIAL 2
#define UNWIND_HINT_TYPE_FUNC 3
#define UNWIND_HINT_TYPE_ENTRY 4
#define UNWIND_HINT_TYPE_SAVE 5
#define UNWIND_HINT_TYPE_RESTORE 6

#ifdef CONFIG_OBJTOOL

Expand Down Expand Up @@ -127,7 +129,7 @@ struct unwind_hint {
* the debuginfo as necessary. It will also warn if it sees any
* 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_\@:
.pushsection .discard.unwind_hints
/* struct unwind_hint */
Expand Down Expand Up @@ -180,7 +182,7 @@ struct unwind_hint {
#define ASM_REACHABLE
#else
#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
.macro STACK_FRAME_NON_STANDARD func:req
.endm
Expand Down
40 changes: 40 additions & 0 deletions tools/objtool/check.c
Original file line number Diff line number Diff line change
Expand Up @@ -2032,6 +2032,17 @@ static int read_unwind_hints(struct objtool_file *file)

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) {
struct symbol *sym = find_symbol_by_offset(insn->sec, insn->offset);

Expand Down Expand Up @@ -3329,6 +3340,35 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
state.instr += insn->instr;

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;
} else {
/* XXX track if we actually changed state.cfi */
Expand Down
19 changes: 10 additions & 9 deletions tools/objtool/include/objtool/check.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,18 +46,19 @@ struct instruction {
enum insn_type type;
unsigned long immediate;

u8 dead_end : 1,
ignore : 1,
ignore_alts : 1,
hint : 1,
retpoline_safe : 1,
noendbr : 1,
entry : 1;
/* 1 bit hole */
u16 dead_end : 1,
ignore : 1,
ignore_alts : 1,
hint : 1,
save : 1,
restore : 1,
retpoline_safe : 1,
noendbr : 1,
entry : 1;
/* 7 bit hole */

s8 instr;
u8 visited;
/* u8 hole */

struct alt_group *alt_group;
struct symbol *call_dest;
Expand Down

0 comments on commit 8faea26

Please sign in to comment.