[RFC][PATCH 04/16] objtool: Annotate identity_mapped()

Peter Zijlstra
2020-03-12T13:52:18Z

Normally identity_mapped is not visible to objtool, due to:

arch/x86/kernel/Makefile:OBJECT_FILES_NON_STANDARD_relocate_kernel_$(BITS).o := y

However, when we want to run objtool on vmlinux.o there is no hiding
it. Without the annotation we'll get complaints about the:

call 1f
1: popq %rB

construct from the add_call_destinations() pass. Because
identity_mapped() is a SYM_CODE_START_LOCAL_NOALIGN() it is STT_NOTYPE
and we need sym_for_each_insn() to iterate the actual instructions.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
arch/x86/kernel/relocate_kernel_64.S | 2 ++
include/linux/frame.h | 16 ++++++++++++++++
tools/objtool/check.c | 4 ++--
3 files changed, 20 insertions(+), 2 deletions(-)

--- a/arch/x86/kernel/relocate_kernel_64.S
+++ b/arch/x86/kernel/relocate_kernel_64.S
@@ -5,6 +5,7 @@
*/

#include <linux/linkage.h>
+#include <linux/frame.h>
#include <asm/page_types.h>
#include <asm/kexec.h>
#include <asm/processor-flags.h>
@@ -210,6 +211,7 @@ SYM_CODE_START_LOCAL_NOALIGN(identity_ma
pushq %rax
ret
SYM_CODE_END(identity_mapped)
+STACK_FRAME_NON_STANDARD(identity_mapped)

SYM_CODE_START_LOCAL_NOALIGN(virtual_mapped)
movq RSP(%r8), %rsp
--- a/include/linux/frame.h
+++ b/include/linux/frame.h
@@ -3,6 +3,9 @@
#define _LINUX_FRAME_H

#ifdef CONFIG_STACK_VALIDATION
+
+#ifndef __ASSEMBLY__
+
/*
* This macro marks the given function's stack frame as "non-standard", which
* tells objtool to ignore the function when doing stack metadata validation.
@@ -15,6 +18,19 @@
static void __used __section(.discard.func_stack_frame_non_standard) \
*__func_stack_frame_non_standard_##func = func

+#else /* __ASSEMBLY__ */
+
+#define STACK_FRAME_NON_STANDARD(func) \
+ .pushsection .discard.func_stack_frame_non_standard, "aw"; \
+ .align 8; \
+ .type __func_stack_frame_non_standard_##func, @object; \
+ .size __func_stack_frame_non_standard_##func, 8; \
+__func_stack_frame_non_standard_##func: \
+ .quad func; \
+ .popsection
+
+#endif /* __ASSEMBLY */
+
#else /* !CONFIG_STACK_VALIDATION */

#define STACK_FRAME_NON_STANDARD(func)
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -416,7 +416,7 @@ static void add_ignores(struct objtool_f

case STT_SECTION:
func = find_symbol_by_offset(rela->sym->sec, rela->addend);
- if (!func || func->type != STT_FUNC)
+ if (!func || (func->type != STT_FUNC && func->type != STT_NOTYPE))
continue;
break;

@@ -425,7 +425,7 @@ static void add_ignores(struct objtool_f
continue;
}

- func_for_each_insn(file, func, insn)
+ sym_for_each_insn(file, func, insn)
insn->ignore = true;
}
}