mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2024-12-29 01:02:08 +00:00
objtool: Convert ANNOTATE_INTRA_FUNCTION_CALL to ANNOTATE
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Acked-by: Josh Poimboeuf <jpoimboe@kernel.org> Link: https://lore.kernel.org/r/20241128094311.584892071@infradead.org
This commit is contained in:
parent
f0cd57c35a
commit
112765ca1c
@ -67,16 +67,6 @@
|
||||
|
||||
#else /* __ASSEMBLY__ */
|
||||
|
||||
/*
|
||||
* This macro indicates that the following intra-function call is valid.
|
||||
* Any non-annotated intra-function call will cause objtool to issue a warning.
|
||||
*/
|
||||
#define ANNOTATE_INTRA_FUNCTION_CALL \
|
||||
999: \
|
||||
.pushsection .discard.intra_function_calls; \
|
||||
.long 999b; \
|
||||
.popsection;
|
||||
|
||||
/*
|
||||
* In asm, there are two kinds of code: normal C-type callable functions and
|
||||
* the rest. The normal callable functions can be called by other code, and
|
||||
@ -154,6 +144,12 @@
|
||||
|
||||
#define ANNOTATE_NOENDBR ANNOTATE type=ANNOTYPE_NOENDBR
|
||||
|
||||
/*
|
||||
* This macro indicates that the following intra-function call is valid.
|
||||
* Any non-annotated intra-function call will cause objtool to issue a warning.
|
||||
*/
|
||||
#define ANNOTATE_INTRA_FUNCTION_CALL ANNOTATE type=ANNOTYPE_INTRA_FUNCTION_CALL
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#else /* !CONFIG_OBJTOOL */
|
||||
|
@ -63,5 +63,6 @@ struct unwind_hint {
|
||||
#define ANNOTYPE_INSTR_END 4
|
||||
#define ANNOTYPE_UNRET_BEGIN 5
|
||||
#define ANNOTYPE_IGNORE_ALTS 6
|
||||
#define ANNOTYPE_INTRA_FUNCTION_CALL 7
|
||||
|
||||
#endif /* _LINUX_OBJTOOL_TYPES_H */
|
||||
|
@ -63,5 +63,6 @@ struct unwind_hint {
|
||||
#define ANNOTYPE_INSTR_END 4
|
||||
#define ANNOTYPE_UNRET_BEGIN 5
|
||||
#define ANNOTYPE_IGNORE_ALTS 6
|
||||
#define ANNOTYPE_INTRA_FUNCTION_CALL 7
|
||||
|
||||
#endif /* _LINUX_OBJTOOL_TYPES_H */
|
||||
|
@ -2339,7 +2339,8 @@ static int read_unwind_hints(struct objtool_file *file)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_annotate(struct objtool_file *file, int (*func)(int type, struct instruction *insn))
|
||||
static int read_annotate(struct objtool_file *file,
|
||||
int (*func)(struct objtool_file *file, int type, struct instruction *insn))
|
||||
{
|
||||
struct section *sec;
|
||||
struct instruction *insn;
|
||||
@ -2372,7 +2373,7 @@ static int read_annotate(struct objtool_file *file, int (*func)(int type, struct
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = func(type, insn);
|
||||
ret = func(file, type, insn);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
@ -2380,7 +2381,7 @@ static int read_annotate(struct objtool_file *file, int (*func)(int type, struct
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __annotate_ignore_alts(int type, struct instruction *insn)
|
||||
static int __annotate_ignore_alts(struct objtool_file *file, int type, struct instruction *insn)
|
||||
{
|
||||
if (type != ANNOTYPE_IGNORE_ALTS)
|
||||
return 0;
|
||||
@ -2389,7 +2390,7 @@ static int __annotate_ignore_alts(int type, struct instruction *insn)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __annotate_noendbr(int type, struct instruction *insn)
|
||||
static int __annotate_noendbr(struct objtool_file *file, int type, struct instruction *insn)
|
||||
{
|
||||
if (type != ANNOTYPE_NOENDBR)
|
||||
return 0;
|
||||
@ -2398,7 +2399,37 @@ static int __annotate_noendbr(int type, struct instruction *insn)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __annotate_retpoline_safe(int type, struct instruction *insn)
|
||||
static int __annotate_ifc(struct objtool_file *file, int type, struct instruction *insn)
|
||||
{
|
||||
unsigned long dest_off;
|
||||
|
||||
if (type != ANNOTYPE_INTRA_FUNCTION_CALL)
|
||||
return 0;
|
||||
|
||||
if (insn->type != INSN_CALL) {
|
||||
WARN_INSN(insn, "intra_function_call not a direct call");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Treat intra-function CALLs as JMPs, but with a stack_op.
|
||||
* See add_call_destinations(), which strips stack_ops from
|
||||
* normal CALLs.
|
||||
*/
|
||||
insn->type = INSN_JUMP_UNCONDITIONAL;
|
||||
|
||||
dest_off = arch_jump_destination(insn);
|
||||
insn->jump_dest = find_insn(file, insn->sec, dest_off);
|
||||
if (!insn->jump_dest) {
|
||||
WARN_INSN(insn, "can't find call dest at %s+0x%lx",
|
||||
insn->sec->name, dest_off);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __annotate_retpoline_safe(struct objtool_file *file, int type, struct instruction *insn)
|
||||
{
|
||||
if (type != ANNOTYPE_RETPOLINE_SAFE)
|
||||
return 0;
|
||||
@ -2415,7 +2446,7 @@ static int __annotate_retpoline_safe(int type, struct instruction *insn)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __annotate_instr(int type, struct instruction *insn)
|
||||
static int __annotate_instr(struct objtool_file *file, int type, struct instruction *insn)
|
||||
{
|
||||
switch (type) {
|
||||
case ANNOTYPE_INSTR_BEGIN:
|
||||
@ -2433,7 +2464,7 @@ static int __annotate_instr(int type, struct instruction *insn)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __annotate_unret(int type, struct instruction *insn)
|
||||
static int __annotate_unret(struct objtool_file *file, int type, struct instruction *insn)
|
||||
{
|
||||
if (type != ANNOTYPE_UNRET_BEGIN)
|
||||
return 0;
|
||||
@ -2443,55 +2474,6 @@ static int __annotate_unret(int type, struct instruction *insn)
|
||||
|
||||
}
|
||||
|
||||
static int read_intra_function_calls(struct objtool_file *file)
|
||||
{
|
||||
struct instruction *insn;
|
||||
struct section *rsec;
|
||||
struct reloc *reloc;
|
||||
|
||||
rsec = find_section_by_name(file->elf, ".rela.discard.intra_function_calls");
|
||||
if (!rsec)
|
||||
return 0;
|
||||
|
||||
for_each_reloc(rsec, reloc) {
|
||||
unsigned long dest_off;
|
||||
|
||||
if (reloc->sym->type != STT_SECTION) {
|
||||
WARN("unexpected relocation symbol type in %s",
|
||||
rsec->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
insn = find_insn(file, reloc->sym->sec, reloc_addend(reloc));
|
||||
if (!insn) {
|
||||
WARN("bad .discard.intra_function_call entry");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (insn->type != INSN_CALL) {
|
||||
WARN_INSN(insn, "intra_function_call not a direct call");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Treat intra-function CALLs as JMPs, but with a stack_op.
|
||||
* See add_call_destinations(), which strips stack_ops from
|
||||
* normal CALLs.
|
||||
*/
|
||||
insn->type = INSN_JUMP_UNCONDITIONAL;
|
||||
|
||||
dest_off = arch_jump_destination(insn);
|
||||
insn->jump_dest = find_insn(file, insn->sec, dest_off);
|
||||
if (!insn->jump_dest) {
|
||||
WARN_INSN(insn, "can't find call dest at %s+0x%lx",
|
||||
insn->sec->name, dest_off);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return true if name matches an instrumentation function, where calls to that
|
||||
* function from noinstr code can safely be removed, but compilers won't do so.
|
||||
@ -2630,7 +2612,7 @@ static int decode_sections(struct objtool_file *file)
|
||||
* Must be before add_call_destination(); it changes INSN_CALL to
|
||||
* INSN_JUMP.
|
||||
*/
|
||||
ret = read_intra_function_calls(file);
|
||||
ret = read_annotate(file, __annotate_ifc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user