Skip to content

Commit e7a174f

Browse files
author
Peter Zijlstra
committed
objtool: Convert {.UN}REACHABLE to ANNOTATE
Suggested-by: Josh Poimboeuf <jpoimboe@redhat.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Acked-by: Josh Poimboeuf <jpoimboe@kernel.org> Link: https://lore.kernel.org/r/20241128094312.353431347@infradead.org
1 parent 06e2474 commit e7a174f

File tree

8 files changed

+36
-76
lines changed

8 files changed

+36
-76
lines changed

arch/loongarch/include/asm/bug.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
#define __WARN_FLAGS(flags) \
4646
do { \
4747
instrumentation_begin(); \
48-
__BUG_FLAGS(BUGFLAG_WARNING|(flags), ASM_REACHABLE); \
48+
__BUG_FLAGS(BUGFLAG_WARNING|(flags), ANNOTATE_REACHABLE);\
4949
instrumentation_end(); \
5050
} while (0)
5151

arch/x86/entry/entry_64.S

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ SYM_CODE_END(xen_error_entry)
311311
call \cfunc
312312

313313
/* For some configurations \cfunc ends up being a noreturn. */
314-
REACHABLE
314+
ANNOTATE_REACHABLE
315315

316316
jmp error_return
317317
.endm
@@ -532,7 +532,7 @@ SYM_CODE_START(\asmsym)
532532
call \cfunc
533533

534534
/* For some configurations \cfunc ends up being a noreturn. */
535-
REACHABLE
535+
ANNOTATE_REACHABLE
536536

537537
jmp paranoid_exit
538538

arch/x86/include/asm/bug.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ do { \
9292
do { \
9393
__auto_type __flags = BUGFLAG_WARNING|(flags); \
9494
instrumentation_begin(); \
95-
_BUG_FLAGS(ASM_UD2, __flags, ASM_REACHABLE); \
95+
_BUG_FLAGS(ASM_UD2, __flags, ANNOTATE_REACHABLE); \
9696
instrumentation_end(); \
9797
} while (0)
9898

arch/x86/include/asm/irq_stack.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@
101101

102102
#define ASM_CALL_ARG0 \
103103
"call %c[__func] \n" \
104-
ASM_REACHABLE
104+
ANNOTATE_REACHABLE
105105

106106
#define ASM_CALL_ARG1 \
107107
"movq %[arg1], %%rdi \n" \

include/linux/objtool.h

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -111,14 +111,6 @@
111111
#endif
112112
.endm
113113

114-
115-
.macro REACHABLE
116-
.Lhere_\@:
117-
.pushsection .discard.reachable
118-
.long .Lhere_\@
119-
.popsection
120-
.endm
121-
122114
.macro ANNOTATE type:req
123115
.Lhere_\@:
124116
.pushsection .discard.annotate_insn,"M",@progbits,8
@@ -138,14 +130,11 @@
138130
#define STACK_FRAME_NON_STANDARD_FP(func)
139131
#define __ASM_ANNOTATE(label, type)
140132
#define ASM_ANNOTATE(type)
141-
#define ASM_REACHABLE
142133
#else
143134
.macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 signal=0
144135
.endm
145136
.macro STACK_FRAME_NON_STANDARD func:req
146137
.endm
147-
.macro REACHABLE
148-
.endm
149138
.macro ANNOTATE type:req
150139
.endm
151140
#endif
@@ -187,6 +176,12 @@
187176
* it will be ignored.
188177
*/
189178
#define ANNOTATE_UNRET_BEGIN ASM_ANNOTATE(ANNOTYPE_UNRET_BEGIN)
179+
/*
180+
* This should be used directly after an instruction that is considered
181+
* terminating, like a noreturn CALL or UD2 when we know they are not -- eg
182+
* WARN using UD2.
183+
*/
184+
#define ANNOTATE_REACHABLE ASM_ANNOTATE(ANNOTYPE_REACHABLE)
190185

191186
#else
192187
#define ANNOTATE_NOENDBR ANNOTATE type=ANNOTYPE_NOENDBR
@@ -196,6 +191,7 @@
196191
#define ANNOTATE_IGNORE_ALTERNATIVE ANNOTATE type=ANNOTYPE_IGNORE_ALTS
197192
#define ANNOTATE_INTRA_FUNCTION_CALL ANNOTATE type=ANNOTYPE_INTRA_FUNCTION_CALL
198193
#define ANNOTATE_UNRET_BEGIN ANNOTATE type=ANNOTYPE_UNRET_BEGIN
194+
#define ANNOTATE_REACHABLE ANNOTATE type=ANNOTYPE_REACHABLE
199195
#endif
200196

201197
#if defined(CONFIG_NOINSTR_VALIDATION) && \

include/linux/objtool_types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,5 +64,6 @@ struct unwind_hint {
6464
#define ANNOTYPE_UNRET_BEGIN 5
6565
#define ANNOTYPE_IGNORE_ALTS 6
6666
#define ANNOTYPE_INTRA_FUNCTION_CALL 7
67+
#define ANNOTYPE_REACHABLE 8
6768

6869
#endif /* _LINUX_OBJTOOL_TYPES_H */

tools/include/linux/objtool_types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,5 +64,6 @@ struct unwind_hint {
6464
#define ANNOTYPE_UNRET_BEGIN 5
6565
#define ANNOTYPE_IGNORE_ALTS 6
6666
#define ANNOTYPE_INTRA_FUNCTION_CALL 7
67+
#define ANNOTYPE_REACHABLE 8
6768

6869
#endif /* _LINUX_OBJTOOL_TYPES_H */

tools/objtool/check.c

Lines changed: 22 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -627,56 +627,6 @@ static struct instruction *find_last_insn(struct objtool_file *file,
627627
return insn;
628628
}
629629

630-
/*
631-
* Mark "ud2" instructions and manually annotated dead ends.
632-
*/
633-
static int add_dead_ends(struct objtool_file *file)
634-
{
635-
struct section *rsec;
636-
struct reloc *reloc;
637-
struct instruction *insn;
638-
uint64_t offset;
639-
640-
/*
641-
* UD2 defaults to being a dead-end, allow them to be annotated for
642-
* non-fatal, eg WARN.
643-
*/
644-
rsec = find_section_by_name(file->elf, ".rela.discard.reachable");
645-
if (!rsec)
646-
return 0;
647-
648-
for_each_reloc(rsec, reloc) {
649-
if (reloc->sym->type == STT_SECTION) {
650-
offset = reloc_addend(reloc);
651-
} else if (reloc->sym->local_label) {
652-
offset = reloc->sym->offset;
653-
} else {
654-
WARN("unexpected relocation symbol type in %s", rsec->name);
655-
return -1;
656-
}
657-
658-
insn = find_insn(file, reloc->sym->sec, offset);
659-
if (insn)
660-
insn = prev_insn_same_sec(file, insn);
661-
else if (offset == reloc->sym->sec->sh.sh_size) {
662-
insn = find_last_insn(file, reloc->sym->sec);
663-
if (!insn) {
664-
WARN("can't find reachable insn at %s+0x%" PRIx64,
665-
reloc->sym->sec->name, offset);
666-
return -1;
667-
}
668-
} else {
669-
WARN("can't find reachable insn at %s+0x%" PRIx64,
670-
reloc->sym->sec->name, offset);
671-
return -1;
672-
}
673-
674-
insn->dead_end = false;
675-
}
676-
677-
return 0;
678-
}
679-
680630
static int create_static_call_sections(struct objtool_file *file)
681631
{
682632
struct static_call_site *site;
@@ -2306,6 +2256,7 @@ static int read_annotate(struct objtool_file *file,
23062256
struct section *sec;
23072257
struct instruction *insn;
23082258
struct reloc *reloc;
2259+
uint64_t offset;
23092260
int type, ret;
23102261

23112262
sec = find_section_by_name(file->elf, ".discard.annotate_insn");
@@ -2327,8 +2278,19 @@ static int read_annotate(struct objtool_file *file,
23272278
for_each_reloc(sec->rsec, reloc) {
23282279
type = *(u32 *)(sec->data->d_buf + (reloc_idx(reloc) * sec->sh.sh_entsize) + 4);
23292280

2330-
insn = find_insn(file, reloc->sym->sec,
2331-
reloc->sym->offset + reloc_addend(reloc));
2281+
offset = reloc->sym->offset + reloc_addend(reloc);
2282+
insn = find_insn(file, reloc->sym->sec, offset);
2283+
2284+
/*
2285+
* Reachable annotations are 'funneh' and act on the previous instruction :/
2286+
*/
2287+
if (type == ANNOTYPE_REACHABLE) {
2288+
if (insn)
2289+
insn = prev_insn_same_sec(file, insn);
2290+
else if (offset == reloc->sym->sec->sh.sh_size)
2291+
insn = find_last_insn(file, reloc->sym->sec);
2292+
}
2293+
23322294
if (!insn) {
23332295
WARN("bad .discard.annotate_insn entry: %d of type %d", reloc_idx(reloc), type);
23342296
return -1;
@@ -2420,6 +2382,10 @@ static int __annotate_late(struct objtool_file *file, int type, struct instructi
24202382
insn->unret = 1;
24212383
break;
24222384

2385+
case ANNOTYPE_REACHABLE:
2386+
insn->dead_end = false;
2387+
break;
2388+
24232389
default:
24242390
break;
24252391
}
@@ -2566,14 +2532,6 @@ static int decode_sections(struct objtool_file *file)
25662532
if (ret)
25672533
return ret;
25682534

2569-
/*
2570-
* Must be after add_call_destinations() such that it can override
2571-
* dead_end_function() marks.
2572-
*/
2573-
ret = add_dead_ends(file);
2574-
if (ret)
2575-
return ret;
2576-
25772535
ret = add_jump_table_alts(file);
25782536
if (ret)
25792537
return ret;
@@ -2582,6 +2540,10 @@ static int decode_sections(struct objtool_file *file)
25822540
if (ret)
25832541
return ret;
25842542

2543+
/*
2544+
* Must be after add_call_destinations() such that it can override
2545+
* dead_end_function() marks.
2546+
*/
25852547
ret = read_annotate(file, __annotate_late);
25862548
if (ret)
25872549
return ret;

0 commit comments

Comments
 (0)