forked from Minki/linux
objtool: Make noinstr hacks optional
Objtool has some hacks in place to workaround toolchain limitations which otherwise would break no-instrumentation rules. Make the hacks explicit (and optional for other arches) by turning it into a cmdline option and kernel config option. Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Reviewed-by: Miroslav Benes <mbenes@suse.cz> Link: https://lkml.kernel.org/r/b326eeb9c33231b9dfbb925f194ed7ee40edcd7c.1650300597.git.jpoimboe@redhat.com
This commit is contained in:
parent
4ab7674f59
commit
22102f4559
@ -1035,6 +1035,9 @@ config HAVE_OBJTOOL
|
|||||||
config HAVE_JUMP_LABEL_HACK
|
config HAVE_JUMP_LABEL_HACK
|
||||||
bool
|
bool
|
||||||
|
|
||||||
|
config HAVE_NOINSTR_HACK
|
||||||
|
bool
|
||||||
|
|
||||||
config HAVE_STACK_VALIDATION
|
config HAVE_STACK_VALIDATION
|
||||||
bool
|
bool
|
||||||
help
|
help
|
||||||
|
@ -231,6 +231,7 @@ config X86
|
|||||||
select HAVE_MOD_ARCH_SPECIFIC
|
select HAVE_MOD_ARCH_SPECIFIC
|
||||||
select HAVE_MOVE_PMD
|
select HAVE_MOVE_PMD
|
||||||
select HAVE_MOVE_PUD
|
select HAVE_MOVE_PUD
|
||||||
|
select HAVE_NOINSTR_HACK if HAVE_OBJTOOL
|
||||||
select HAVE_NMI
|
select HAVE_NMI
|
||||||
select HAVE_OBJTOOL if X86_64
|
select HAVE_OBJTOOL if X86_64
|
||||||
select HAVE_OPTPROBES
|
select HAVE_OPTPROBES
|
||||||
|
@ -2036,11 +2036,11 @@ config KCOV
|
|||||||
bool "Code coverage for fuzzing"
|
bool "Code coverage for fuzzing"
|
||||||
depends on ARCH_HAS_KCOV
|
depends on ARCH_HAS_KCOV
|
||||||
depends on CC_HAS_SANCOV_TRACE_PC || GCC_PLUGINS
|
depends on CC_HAS_SANCOV_TRACE_PC || GCC_PLUGINS
|
||||||
depends on !ARCH_WANTS_NO_INSTR || HAVE_OBJTOOL || \
|
depends on !ARCH_WANTS_NO_INSTR || HAVE_NOINSTR_HACK || \
|
||||||
GCC_VERSION >= 120000 || CLANG_VERSION >= 130000
|
GCC_VERSION >= 120000 || CLANG_VERSION >= 130000
|
||||||
select DEBUG_FS
|
select DEBUG_FS
|
||||||
select GCC_PLUGIN_SANCOV if !CC_HAS_SANCOV_TRACE_PC
|
select GCC_PLUGIN_SANCOV if !CC_HAS_SANCOV_TRACE_PC
|
||||||
select OBJTOOL if HAVE_OBJTOOL
|
select OBJTOOL if HAVE_NOINSTR_HACK
|
||||||
help
|
help
|
||||||
KCOV exposes kernel code coverage information in a form suitable
|
KCOV exposes kernel code coverage information in a form suitable
|
||||||
for coverage-guided fuzzing (randomized testing).
|
for coverage-guided fuzzing (randomized testing).
|
||||||
|
@ -187,8 +187,9 @@ config KCSAN_WEAK_MEMORY
|
|||||||
# We can either let objtool nop __tsan_func_{entry,exit}() and builtin
|
# We can either let objtool nop __tsan_func_{entry,exit}() and builtin
|
||||||
# atomics instrumentation in .noinstr.text, or use a compiler that can
|
# atomics instrumentation in .noinstr.text, or use a compiler that can
|
||||||
# implement __no_kcsan to really remove all instrumentation.
|
# implement __no_kcsan to really remove all instrumentation.
|
||||||
depends on HAVE_OBJTOOL || CC_IS_GCC || CLANG_VERSION >= 140000
|
depends on !ARCH_WANTS_NO_INSTR || HAVE_NOINSTR_HACK || \
|
||||||
select OBJTOOL if HAVE_OBJTOOL
|
CC_IS_GCC || CLANG_VERSION >= 140000
|
||||||
|
select OBJTOOL if HAVE_NOINSTR_HACK
|
||||||
help
|
help
|
||||||
Enable support for modeling a subset of weak memory, which allows
|
Enable support for modeling a subset of weak memory, which allows
|
||||||
detecting a subset of data races due to missing memory barriers.
|
detecting a subset of data races due to missing memory barriers.
|
||||||
|
@ -228,6 +228,7 @@ objtool := $(objtree)/tools/objtool/objtool
|
|||||||
|
|
||||||
objtool_args = \
|
objtool_args = \
|
||||||
$(if $(CONFIG_HAVE_JUMP_LABEL_HACK), --hacks=jump_label) \
|
$(if $(CONFIG_HAVE_JUMP_LABEL_HACK), --hacks=jump_label) \
|
||||||
|
$(if $(CONFIG_HAVE_NOINSTR_HACK), --hacks=noinstr) \
|
||||||
$(if $(CONFIG_X86_KERNEL_IBT), --lto --ibt) \
|
$(if $(CONFIG_X86_KERNEL_IBT), --lto --ibt) \
|
||||||
$(if $(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL), --mcount) \
|
$(if $(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL), --mcount) \
|
||||||
$(if $(CONFIG_UNWINDER_ORC), --orc) \
|
$(if $(CONFIG_UNWINDER_ORC), --orc) \
|
||||||
|
@ -121,6 +121,10 @@ objtool_link()
|
|||||||
objtoolopt="${objtoolopt} --hacks=jump_label"
|
objtoolopt="${objtoolopt} --hacks=jump_label"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if is_enabled CONFIG_HAVE_NOINSTR_HACK; then
|
||||||
|
objtoolopt="${objtoolopt} --hacks=noinstr"
|
||||||
|
fi
|
||||||
|
|
||||||
if is_enabled CONFIG_X86_KERNEL_IBT; then
|
if is_enabled CONFIG_X86_KERNEL_IBT; then
|
||||||
objtoolopt="${objtoolopt} --ibt"
|
objtoolopt="${objtoolopt} --ibt"
|
||||||
fi
|
fi
|
||||||
|
@ -47,12 +47,17 @@ static int parse_hacks(const struct option *opt, const char *str, int unset)
|
|||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!str || strstr(str, "noinstr")) {
|
||||||
|
opts.hack_noinstr = true;
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
|
||||||
return found ? 0 : -1;
|
return found ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct option check_options[] = {
|
const struct option check_options[] = {
|
||||||
OPT_GROUP("Actions:"),
|
OPT_GROUP("Actions:"),
|
||||||
OPT_CALLBACK_OPTARG('h', "hacks", NULL, NULL, "jump_label", "patch toolchain bugs/limitations", parse_hacks),
|
OPT_CALLBACK_OPTARG('h', "hacks", NULL, NULL, "jump_label,noinstr", "patch toolchain bugs/limitations", parse_hacks),
|
||||||
OPT_BOOLEAN('i', "ibt", &opts.ibt, "validate and annotate IBT"),
|
OPT_BOOLEAN('i', "ibt", &opts.ibt, "validate and annotate IBT"),
|
||||||
OPT_BOOLEAN('m', "mcount", &opts.mcount, "annotate mcount/fentry calls for ftrace"),
|
OPT_BOOLEAN('m', "mcount", &opts.mcount, "annotate mcount/fentry calls for ftrace"),
|
||||||
OPT_BOOLEAN('n', "noinstr", &opts.noinstr, "validate noinstr rules"),
|
OPT_BOOLEAN('n', "noinstr", &opts.noinstr, "validate noinstr rules"),
|
||||||
@ -108,6 +113,7 @@ int cmd_parse_options(int argc, const char **argv, const char * const usage[])
|
|||||||
static bool opts_valid(void)
|
static bool opts_valid(void)
|
||||||
{
|
{
|
||||||
if (opts.hack_jump_label ||
|
if (opts.hack_jump_label ||
|
||||||
|
opts.hack_noinstr ||
|
||||||
opts.ibt ||
|
opts.ibt ||
|
||||||
opts.mcount ||
|
opts.mcount ||
|
||||||
opts.noinstr ||
|
opts.noinstr ||
|
||||||
|
@ -1144,7 +1144,7 @@ static void annotate_call_site(struct objtool_file *file,
|
|||||||
* attribute so they need a little help, NOP out any such calls from
|
* attribute so they need a little help, NOP out any such calls from
|
||||||
* noinstr text.
|
* noinstr text.
|
||||||
*/
|
*/
|
||||||
if (insn->sec->noinstr && sym->profiling_func) {
|
if (opts.hack_noinstr && insn->sec->noinstr && sym->profiling_func) {
|
||||||
if (reloc) {
|
if (reloc) {
|
||||||
reloc->type = R_NONE;
|
reloc->type = R_NONE;
|
||||||
elf_write_reloc(file->elf, reloc);
|
elf_write_reloc(file->elf, reloc);
|
||||||
|
@ -13,6 +13,7 @@ struct opts {
|
|||||||
/* actions: */
|
/* actions: */
|
||||||
bool dump_orc;
|
bool dump_orc;
|
||||||
bool hack_jump_label;
|
bool hack_jump_label;
|
||||||
|
bool hack_noinstr;
|
||||||
bool ibt;
|
bool ibt;
|
||||||
bool mcount;
|
bool mcount;
|
||||||
bool noinstr;
|
bool noinstr;
|
||||||
|
Loading…
Reference in New Issue
Block a user