Skip to content

Commit 8faea26

Browse files
jpoimboesuryasaimadhu
authored andcommitted
objtool: Re-add UNWIND_HINT_{SAVE_RESTORE}
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]>
1 parent acac5e9 commit 8faea26

File tree

5 files changed

+68
-15
lines changed

5 files changed

+68
-15
lines changed

arch/x86/include/asm/unwind_hints.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@
88
#ifdef __ASSEMBLY__
99

1010
.macro UNWIND_HINT_EMPTY
11-
UNWIND_HINT sp_reg=ORC_REG_UNDEFINED type=UNWIND_HINT_TYPE_CALL end=1
11+
UNWIND_HINT type=UNWIND_HINT_TYPE_CALL end=1
1212
.endm
1313

1414
.macro UNWIND_HINT_ENTRY
15-
UNWIND_HINT sp_reg=ORC_REG_UNDEFINED type=UNWIND_HINT_TYPE_ENTRY end=1
15+
UNWIND_HINT type=UNWIND_HINT_TYPE_ENTRY end=1
1616
.endm
1717

1818
.macro UNWIND_HINT_REGS base=%rsp offset=0 indirect=0 extra=1 partial=0
@@ -56,6 +56,14 @@
5656
UNWIND_HINT sp_reg=ORC_REG_SP sp_offset=8 type=UNWIND_HINT_TYPE_FUNC
5757
.endm
5858

59+
.macro UNWIND_HINT_SAVE
60+
UNWIND_HINT type=UNWIND_HINT_TYPE_SAVE
61+
.endm
62+
63+
.macro UNWIND_HINT_RESTORE
64+
UNWIND_HINT type=UNWIND_HINT_TYPE_RESTORE
65+
.endm
66+
5967
#else
6068

6169
#define UNWIND_HINT_FUNC \

include/linux/objtool.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ struct unwind_hint {
4040
#define UNWIND_HINT_TYPE_REGS_PARTIAL 2
4141
#define UNWIND_HINT_TYPE_FUNC 3
4242
#define UNWIND_HINT_TYPE_ENTRY 4
43+
#define UNWIND_HINT_TYPE_SAVE 5
44+
#define UNWIND_HINT_TYPE_RESTORE 6
4345

4446
#ifdef CONFIG_OBJTOOL
4547

@@ -127,7 +129,7 @@ struct unwind_hint {
127129
* the debuginfo as necessary. It will also warn if it sees any
128130
* inconsistencies.
129131
*/
130-
.macro UNWIND_HINT sp_reg:req sp_offset=0 type:req end=0
132+
.macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 end=0
131133
.Lunwind_hint_ip_\@:
132134
.pushsection .discard.unwind_hints
133135
/* struct unwind_hint */
@@ -180,7 +182,7 @@ struct unwind_hint {
180182
#define ASM_REACHABLE
181183
#else
182184
#define ANNOTATE_INTRA_FUNCTION_CALL
183-
.macro UNWIND_HINT sp_reg:req sp_offset=0 type:req end=0
185+
.macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 end=0
184186
.endm
185187
.macro STACK_FRAME_NON_STANDARD func:req
186188
.endm

tools/include/linux/objtool.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ struct unwind_hint {
4040
#define UNWIND_HINT_TYPE_REGS_PARTIAL 2
4141
#define UNWIND_HINT_TYPE_FUNC 3
4242
#define UNWIND_HINT_TYPE_ENTRY 4
43+
#define UNWIND_HINT_TYPE_SAVE 5
44+
#define UNWIND_HINT_TYPE_RESTORE 6
4345

4446
#ifdef CONFIG_OBJTOOL
4547

@@ -127,7 +129,7 @@ struct unwind_hint {
127129
* the debuginfo as necessary. It will also warn if it sees any
128130
* inconsistencies.
129131
*/
130-
.macro UNWIND_HINT sp_reg:req sp_offset=0 type:req end=0
132+
.macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 end=0
131133
.Lunwind_hint_ip_\@:
132134
.pushsection .discard.unwind_hints
133135
/* struct unwind_hint */
@@ -180,7 +182,7 @@ struct unwind_hint {
180182
#define ASM_REACHABLE
181183
#else
182184
#define ANNOTATE_INTRA_FUNCTION_CALL
183-
.macro UNWIND_HINT sp_reg:req sp_offset=0 type:req end=0
185+
.macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 end=0
184186
.endm
185187
.macro STACK_FRAME_NON_STANDARD func:req
186188
.endm

tools/objtool/check.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2032,6 +2032,17 @@ static int read_unwind_hints(struct objtool_file *file)
20322032

20332033
insn->hint = true;
20342034

2035+
if (hint->type == UNWIND_HINT_TYPE_SAVE) {
2036+
insn->hint = false;
2037+
insn->save = true;
2038+
continue;
2039+
}
2040+
2041+
if (hint->type == UNWIND_HINT_TYPE_RESTORE) {
2042+
insn->restore = true;
2043+
continue;
2044+
}
2045+
20352046
if (hint->type == UNWIND_HINT_TYPE_REGS_PARTIAL) {
20362047
struct symbol *sym = find_symbol_by_offset(insn->sec, insn->offset);
20372048

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

33313342
if (insn->hint) {
3343+
if (insn->restore) {
3344+
struct instruction *save_insn, *i;
3345+
3346+
i = insn;
3347+
save_insn = NULL;
3348+
3349+
sym_for_each_insn_continue_reverse(file, func, i) {
3350+
if (i->save) {
3351+
save_insn = i;
3352+
break;
3353+
}
3354+
}
3355+
3356+
if (!save_insn) {
3357+
WARN_FUNC("no corresponding CFI save for CFI restore",
3358+
sec, insn->offset);
3359+
return 1;
3360+
}
3361+
3362+
if (!save_insn->visited) {
3363+
WARN_FUNC("objtool isn't smart enough to handle this CFI save/restore combo",
3364+
sec, insn->offset);
3365+
return 1;
3366+
}
3367+
3368+
insn->cfi = save_insn->cfi;
3369+
nr_cfi_reused++;
3370+
}
3371+
33323372
state.cfi = *insn->cfi;
33333373
} else {
33343374
/* XXX track if we actually changed state.cfi */

tools/objtool/include/objtool/check.h

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,18 +46,19 @@ struct instruction {
4646
enum insn_type type;
4747
unsigned long immediate;
4848

49-
u8 dead_end : 1,
50-
ignore : 1,
51-
ignore_alts : 1,
52-
hint : 1,
53-
retpoline_safe : 1,
54-
noendbr : 1,
55-
entry : 1;
56-
/* 1 bit hole */
49+
u16 dead_end : 1,
50+
ignore : 1,
51+
ignore_alts : 1,
52+
hint : 1,
53+
save : 1,
54+
restore : 1,
55+
retpoline_safe : 1,
56+
noendbr : 1,
57+
entry : 1;
58+
/* 7 bit hole */
5759

5860
s8 instr;
5961
u8 visited;
60-
/* u8 hole */
6162

6263
struct alt_group *alt_group;
6364
struct symbol *call_dest;

0 commit comments

Comments
 (0)