objtool: Fix ANNOTATE_REACHABLE to be a normal annotation

Currently REACHABLE is weird for being on the instruction after the
instruction it modifies.

Since all REACHABLE annotations have an explicit instruction, flip
them around.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Josh Poimboeuf <jpoimboe@kernel.org>
Link: https://lore.kernel.org/r/20241128094312.494176035@infradead.org
This commit is contained in:
Peter Zijlstra 2024-11-28 10:39:06 +01:00
parent e7a174fb43
commit 87116ae6da
6 changed files with 8 additions and 32 deletions

View File

@ -45,7 +45,7 @@
#define __WARN_FLAGS(flags) \ #define __WARN_FLAGS(flags) \
do { \ do { \
instrumentation_begin(); \ instrumentation_begin(); \
__BUG_FLAGS(BUGFLAG_WARNING|(flags), ANNOTATE_REACHABLE);\ __BUG_FLAGS(BUGFLAG_WARNING|(flags), ANNOTATE_REACHABLE(10001b));\
instrumentation_end(); \ instrumentation_end(); \
} while (0) } while (0)

View File

@ -308,10 +308,9 @@ SYM_CODE_END(xen_error_entry)
movq $-1, ORIG_RAX(%rsp) /* no syscall to restart */ movq $-1, ORIG_RAX(%rsp) /* no syscall to restart */
.endif .endif
call \cfunc
/* For some configurations \cfunc ends up being a noreturn. */ /* For some configurations \cfunc ends up being a noreturn. */
ANNOTATE_REACHABLE ANNOTATE_REACHABLE
call \cfunc
jmp error_return jmp error_return
.endm .endm
@ -529,10 +528,10 @@ SYM_CODE_START(\asmsym)
movq %rsp, %rdi /* pt_regs pointer into first argument */ movq %rsp, %rdi /* pt_regs pointer into first argument */
movq ORIG_RAX(%rsp), %rsi /* get error code into 2nd argument*/ movq ORIG_RAX(%rsp), %rsi /* get error code into 2nd argument*/
movq $-1, ORIG_RAX(%rsp) /* no syscall to restart */ movq $-1, ORIG_RAX(%rsp) /* no syscall to restart */
call \cfunc
/* For some configurations \cfunc ends up being a noreturn. */ /* For some configurations \cfunc ends up being a noreturn. */
ANNOTATE_REACHABLE ANNOTATE_REACHABLE
call \cfunc
jmp paranoid_exit jmp paranoid_exit

View File

@ -92,7 +92,7 @@ do { \
do { \ do { \
__auto_type __flags = BUGFLAG_WARNING|(flags); \ __auto_type __flags = BUGFLAG_WARNING|(flags); \
instrumentation_begin(); \ instrumentation_begin(); \
_BUG_FLAGS(ASM_UD2, __flags, ANNOTATE_REACHABLE); \ _BUG_FLAGS(ASM_UD2, __flags, ANNOTATE_REACHABLE(1b)); \
instrumentation_end(); \ instrumentation_end(); \
} while (0) } while (0)

View File

@ -100,8 +100,8 @@
} }
#define ASM_CALL_ARG0 \ #define ASM_CALL_ARG0 \
"call %c[__func] \n" \ "1: call %c[__func] \n" \
ANNOTATE_REACHABLE ANNOTATE_REACHABLE(1b)
#define ASM_CALL_ARG1 \ #define ASM_CALL_ARG1 \
"movq %[arg1], %%rdi \n" \ "movq %[arg1], %%rdi \n" \

View File

@ -177,11 +177,11 @@
*/ */
#define ANNOTATE_UNRET_BEGIN ASM_ANNOTATE(ANNOTYPE_UNRET_BEGIN) #define ANNOTATE_UNRET_BEGIN ASM_ANNOTATE(ANNOTYPE_UNRET_BEGIN)
/* /*
* This should be used directly after an instruction that is considered * This should be used to refer to an instruction that is considered
* terminating, like a noreturn CALL or UD2 when we know they are not -- eg * terminating, like a noreturn CALL or UD2 when we know they are not -- eg
* WARN using UD2. * WARN using UD2.
*/ */
#define ANNOTATE_REACHABLE ASM_ANNOTATE(ANNOTYPE_REACHABLE) #define ANNOTATE_REACHABLE(label) __ASM_ANNOTATE(label, ANNOTYPE_REACHABLE)
#else #else
#define ANNOTATE_NOENDBR ANNOTATE type=ANNOTYPE_NOENDBR #define ANNOTATE_NOENDBR ANNOTATE type=ANNOTYPE_NOENDBR

View File

@ -614,19 +614,6 @@ static int init_pv_ops(struct objtool_file *file)
return 0; return 0;
} }
static struct instruction *find_last_insn(struct objtool_file *file,
struct section *sec)
{
struct instruction *insn = NULL;
unsigned int offset;
unsigned int end = (sec->sh.sh_size > 10) ? sec->sh.sh_size - 10 : 0;
for (offset = sec->sh.sh_size - 1; offset >= end && !insn; offset--)
insn = find_insn(file, sec, offset);
return insn;
}
static int create_static_call_sections(struct objtool_file *file) static int create_static_call_sections(struct objtool_file *file)
{ {
struct static_call_site *site; struct static_call_site *site;
@ -2281,16 +2268,6 @@ static int read_annotate(struct objtool_file *file,
offset = reloc->sym->offset + reloc_addend(reloc); offset = reloc->sym->offset + reloc_addend(reloc);
insn = find_insn(file, reloc->sym->sec, offset); 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) { if (!insn) {
WARN("bad .discard.annotate_insn entry: %d of type %d", reloc_idx(reloc), type); WARN("bad .discard.annotate_insn entry: %d of type %d", reloc_idx(reloc), type);
return -1; return -1;