mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2024-12-28 16:52:18 +00:00
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
This commit is contained in:
parent
06e2474598
commit
e7a174fb43
@ -45,7 +45,7 @@
|
||||
#define __WARN_FLAGS(flags) \
|
||||
do { \
|
||||
instrumentation_begin(); \
|
||||
__BUG_FLAGS(BUGFLAG_WARNING|(flags), ASM_REACHABLE); \
|
||||
__BUG_FLAGS(BUGFLAG_WARNING|(flags), ANNOTATE_REACHABLE);\
|
||||
instrumentation_end(); \
|
||||
} while (0)
|
||||
|
||||
|
@ -311,7 +311,7 @@ SYM_CODE_END(xen_error_entry)
|
||||
call \cfunc
|
||||
|
||||
/* For some configurations \cfunc ends up being a noreturn. */
|
||||
REACHABLE
|
||||
ANNOTATE_REACHABLE
|
||||
|
||||
jmp error_return
|
||||
.endm
|
||||
@ -532,7 +532,7 @@ SYM_CODE_START(\asmsym)
|
||||
call \cfunc
|
||||
|
||||
/* For some configurations \cfunc ends up being a noreturn. */
|
||||
REACHABLE
|
||||
ANNOTATE_REACHABLE
|
||||
|
||||
jmp paranoid_exit
|
||||
|
||||
|
@ -92,7 +92,7 @@ do { \
|
||||
do { \
|
||||
__auto_type __flags = BUGFLAG_WARNING|(flags); \
|
||||
instrumentation_begin(); \
|
||||
_BUG_FLAGS(ASM_UD2, __flags, ASM_REACHABLE); \
|
||||
_BUG_FLAGS(ASM_UD2, __flags, ANNOTATE_REACHABLE); \
|
||||
instrumentation_end(); \
|
||||
} while (0)
|
||||
|
||||
|
@ -101,7 +101,7 @@
|
||||
|
||||
#define ASM_CALL_ARG0 \
|
||||
"call %c[__func] \n" \
|
||||
ASM_REACHABLE
|
||||
ANNOTATE_REACHABLE
|
||||
|
||||
#define ASM_CALL_ARG1 \
|
||||
"movq %[arg1], %%rdi \n" \
|
||||
|
@ -111,14 +111,6 @@
|
||||
#endif
|
||||
.endm
|
||||
|
||||
|
||||
.macro REACHABLE
|
||||
.Lhere_\@:
|
||||
.pushsection .discard.reachable
|
||||
.long .Lhere_\@
|
||||
.popsection
|
||||
.endm
|
||||
|
||||
.macro ANNOTATE type:req
|
||||
.Lhere_\@:
|
||||
.pushsection .discard.annotate_insn,"M",@progbits,8
|
||||
@ -138,14 +130,11 @@
|
||||
#define STACK_FRAME_NON_STANDARD_FP(func)
|
||||
#define __ASM_ANNOTATE(label, type)
|
||||
#define ASM_ANNOTATE(type)
|
||||
#define ASM_REACHABLE
|
||||
#else
|
||||
.macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 signal=0
|
||||
.endm
|
||||
.macro STACK_FRAME_NON_STANDARD func:req
|
||||
.endm
|
||||
.macro REACHABLE
|
||||
.endm
|
||||
.macro ANNOTATE type:req
|
||||
.endm
|
||||
#endif
|
||||
@ -187,6 +176,12 @@
|
||||
* it will be ignored.
|
||||
*/
|
||||
#define ANNOTATE_UNRET_BEGIN ASM_ANNOTATE(ANNOTYPE_UNRET_BEGIN)
|
||||
/*
|
||||
* This should be used directly after an instruction that is considered
|
||||
* terminating, like a noreturn CALL or UD2 when we know they are not -- eg
|
||||
* WARN using UD2.
|
||||
*/
|
||||
#define ANNOTATE_REACHABLE ASM_ANNOTATE(ANNOTYPE_REACHABLE)
|
||||
|
||||
#else
|
||||
#define ANNOTATE_NOENDBR ANNOTATE type=ANNOTYPE_NOENDBR
|
||||
@ -196,6 +191,7 @@
|
||||
#define ANNOTATE_IGNORE_ALTERNATIVE ANNOTATE type=ANNOTYPE_IGNORE_ALTS
|
||||
#define ANNOTATE_INTRA_FUNCTION_CALL ANNOTATE type=ANNOTYPE_INTRA_FUNCTION_CALL
|
||||
#define ANNOTATE_UNRET_BEGIN ANNOTATE type=ANNOTYPE_UNRET_BEGIN
|
||||
#define ANNOTATE_REACHABLE ANNOTATE type=ANNOTYPE_REACHABLE
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_NOINSTR_VALIDATION) && \
|
||||
|
@ -64,5 +64,6 @@ struct unwind_hint {
|
||||
#define ANNOTYPE_UNRET_BEGIN 5
|
||||
#define ANNOTYPE_IGNORE_ALTS 6
|
||||
#define ANNOTYPE_INTRA_FUNCTION_CALL 7
|
||||
#define ANNOTYPE_REACHABLE 8
|
||||
|
||||
#endif /* _LINUX_OBJTOOL_TYPES_H */
|
||||
|
@ -64,5 +64,6 @@ struct unwind_hint {
|
||||
#define ANNOTYPE_UNRET_BEGIN 5
|
||||
#define ANNOTYPE_IGNORE_ALTS 6
|
||||
#define ANNOTYPE_INTRA_FUNCTION_CALL 7
|
||||
#define ANNOTYPE_REACHABLE 8
|
||||
|
||||
#endif /* _LINUX_OBJTOOL_TYPES_H */
|
||||
|
@ -627,56 +627,6 @@ static struct instruction *find_last_insn(struct objtool_file *file,
|
||||
return insn;
|
||||
}
|
||||
|
||||
/*
|
||||
* Mark "ud2" instructions and manually annotated dead ends.
|
||||
*/
|
||||
static int add_dead_ends(struct objtool_file *file)
|
||||
{
|
||||
struct section *rsec;
|
||||
struct reloc *reloc;
|
||||
struct instruction *insn;
|
||||
uint64_t offset;
|
||||
|
||||
/*
|
||||
* UD2 defaults to being a dead-end, allow them to be annotated for
|
||||
* non-fatal, eg WARN.
|
||||
*/
|
||||
rsec = find_section_by_name(file->elf, ".rela.discard.reachable");
|
||||
if (!rsec)
|
||||
return 0;
|
||||
|
||||
for_each_reloc(rsec, reloc) {
|
||||
if (reloc->sym->type == STT_SECTION) {
|
||||
offset = reloc_addend(reloc);
|
||||
} else if (reloc->sym->local_label) {
|
||||
offset = reloc->sym->offset;
|
||||
} else {
|
||||
WARN("unexpected relocation symbol type in %s", rsec->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
insn = find_insn(file, reloc->sym->sec, offset);
|
||||
if (insn)
|
||||
insn = prev_insn_same_sec(file, insn);
|
||||
else if (offset == reloc->sym->sec->sh.sh_size) {
|
||||
insn = find_last_insn(file, reloc->sym->sec);
|
||||
if (!insn) {
|
||||
WARN("can't find reachable insn at %s+0x%" PRIx64,
|
||||
reloc->sym->sec->name, offset);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
WARN("can't find reachable insn at %s+0x%" PRIx64,
|
||||
reloc->sym->sec->name, offset);
|
||||
return -1;
|
||||
}
|
||||
|
||||
insn->dead_end = false;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int create_static_call_sections(struct objtool_file *file)
|
||||
{
|
||||
struct static_call_site *site;
|
||||
@ -2306,6 +2256,7 @@ static int read_annotate(struct objtool_file *file,
|
||||
struct section *sec;
|
||||
struct instruction *insn;
|
||||
struct reloc *reloc;
|
||||
uint64_t offset;
|
||||
int type, ret;
|
||||
|
||||
sec = find_section_by_name(file->elf, ".discard.annotate_insn");
|
||||
@ -2327,8 +2278,19 @@ static int read_annotate(struct objtool_file *file,
|
||||
for_each_reloc(sec->rsec, reloc) {
|
||||
type = *(u32 *)(sec->data->d_buf + (reloc_idx(reloc) * sec->sh.sh_entsize) + 4);
|
||||
|
||||
insn = find_insn(file, reloc->sym->sec,
|
||||
reloc->sym->offset + reloc_addend(reloc));
|
||||
offset = reloc->sym->offset + reloc_addend(reloc);
|
||||
insn = find_insn(file, reloc->sym->sec, offset);
|
||||
|
||||
/*
|
||||
* Reachable annotations are 'funneh' and act on the previous instruction :/
|
||||
*/
|
||||
if (type == ANNOTYPE_REACHABLE) {
|
||||
if (insn)
|
||||
insn = prev_insn_same_sec(file, insn);
|
||||
else if (offset == reloc->sym->sec->sh.sh_size)
|
||||
insn = find_last_insn(file, reloc->sym->sec);
|
||||
}
|
||||
|
||||
if (!insn) {
|
||||
WARN("bad .discard.annotate_insn entry: %d of type %d", reloc_idx(reloc), type);
|
||||
return -1;
|
||||
@ -2420,6 +2382,10 @@ static int __annotate_late(struct objtool_file *file, int type, struct instructi
|
||||
insn->unret = 1;
|
||||
break;
|
||||
|
||||
case ANNOTYPE_REACHABLE:
|
||||
insn->dead_end = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -2566,14 +2532,6 @@ static int decode_sections(struct objtool_file *file)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Must be after add_call_destinations() such that it can override
|
||||
* dead_end_function() marks.
|
||||
*/
|
||||
ret = add_dead_ends(file);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = add_jump_table_alts(file);
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -2582,6 +2540,10 @@ static int decode_sections(struct objtool_file *file)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Must be after add_call_destinations() such that it can override
|
||||
* dead_end_function() marks.
|
||||
*/
|
||||
ret = read_annotate(file, __annotate_late);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
Loading…
Reference in New Issue
Block a user