mirror of https://gitee.com/openkylin/linux.git
clang-lto for v5.12-rc1 (part2)
- Generate __mcount_loc in objtool (Peter Zijlstra) - Support running objtool against vmlinux.o (Sami Tolvanen) - Clang LTO enablement for x86 (Sami Tolvanen) -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEpcP2jyKd1g9yPm4TiXL039xtwCYFAmA1fn8ACgkQiXL039xt wCbswQ//Zmnq912Ubyn5uPe9SOS/kumGDoqtxGzlZwo/pSB3qFArhD6G07sJ49XD nu/05ZcOda760wubnhcuK91n2fY5i/eGLXMSjfgtdVcco4Q67nPQydc+LGdhuDco FlhL8TAIwqYN1f2nJK1IggZpZFxz5r/r1Pq8q1S0oQRqDenxDBQwNtBba4B1OIxw /FE/1Hp3xwRnuJEP2jREBeY1yQ+Y1n859pZcDgSOWlTArcp8EVUi5hIWJ9DwIe73 mqnx6PcFWEYB0zLNZmZz2gpEac+ncGyme6ChayeuQfInbL5dhx97jFGt3S6/+NSY mF2zyaR/+JsGGuM8dVqH3izKCJXCEAGirrdMO1ndb9HdwS3KnYEiag2ciNWL0wm3 UEM4r0i2B14sU3pkyotKgsJdOSgorMKkQUPb2wW+OUfnkZNEWKLqylMgNXBD80l4 WG5vYQRwwFN9jRBik6Z5YFGnwGsNIoGg1F1GRNMjh6h51adYQeBN/1QJE1FJ5L4D iKzmZYqimKUINXWfI6TNyqiv9TctOt65pxnRyq+MHxfTDzHGyc3MUeCeCiR1a1yI S5QhcgfSnC/NjDA0+oYC6yRlcBtfhjtUqFTGoZ4q4q/LF1BVU1bPyIXZrROLc05s LNMMBcWbJetJxFtm/gYfiVFuNitYtxbBV1krVtsWznCA2nKGJ9w= =htKJ -----END PGP SIGNATURE----- Merge tag 'clang-lto-v5.12-rc1-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux Pull more clang LTO updates from Kees Cook: "Clang LTO x86 enablement. Full disclosure: while this has _not_ been in linux-next (since it initially looked like the objtool dependencies weren't going to make v5.12), it has been under daily build and runtime testing by Sami for quite some time. These x86 portions have been discussed on lkml, with Peter, Josh, and others helping nail things down. The bulk of the changes are to get objtool working happily. The rest of the x86 enablement is very small. Summary: - Generate __mcount_loc in objtool (Peter Zijlstra) - Support running objtool against vmlinux.o (Sami Tolvanen) - Clang LTO enablement for x86 (Sami Tolvanen)" Link: https://lore.kernel.org/lkml/20201013003203.4168817-26-samitolvanen@google.com/ Link: https://lore.kernel.org/lkml/cover.1611263461.git.jpoimboe@redhat.com/ * tag 'clang-lto-v5.12-rc1-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux: kbuild: lto: force rebuilds when switching CONFIG_LTO x86, build: allow LTO to be selected x86, cpu: disable LTO for cpu.c x86, vdso: disable LTO only for vDSO kbuild: lto: postpone objtool objtool: Split noinstr validation from --vmlinux x86, build: use objtool mcount tracing: add support for objtool mcount objtool: Don't autodetect vmlinux.o objtool: Fix __mcount_loc generation with Clang's assembler objtool: Add a pass for generating __mcount_loc
This commit is contained in:
commit
414eece95b
10
Makefile
10
Makefile
|
@ -862,6 +862,9 @@ ifdef CONFIG_FTRACE_MCOUNT_USE_CC
|
|||
endif
|
||||
endif
|
||||
endif
|
||||
ifdef CONFIG_FTRACE_MCOUNT_USE_OBJTOOL
|
||||
CC_FLAGS_USING += -DCC_USING_NOP_MCOUNT
|
||||
endif
|
||||
ifdef CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT
|
||||
ifdef CONFIG_HAVE_C_RECORDMCOUNT
|
||||
BUILD_C_RECORDMCOUNT := y
|
||||
|
@ -909,7 +912,8 @@ KBUILD_LDFLAGS += -mllvm -import-instr-limit=5
|
|||
endif
|
||||
|
||||
ifdef CONFIG_LTO
|
||||
KBUILD_CFLAGS += $(CC_FLAGS_LTO)
|
||||
KBUILD_CFLAGS += -fno-lto $(CC_FLAGS_LTO)
|
||||
KBUILD_AFLAGS += -fno-lto
|
||||
export CC_FLAGS_LTO
|
||||
endif
|
||||
|
||||
|
@ -1243,6 +1247,10 @@ uapi-asm-generic:
|
|||
PHONY += prepare-objtool prepare-resolve_btfids
|
||||
prepare-objtool: $(objtool_target)
|
||||
ifeq ($(SKIP_STACK_VALIDATION),1)
|
||||
ifdef CONFIG_FTRACE_MCOUNT_USE_OBJTOOL
|
||||
@echo "error: Cannot generate __mcount_loc for CONFIG_DYNAMIC_FTRACE=y, please install libelf-dev, libelf-devel or elfutils-libelf-devel" >&2
|
||||
@false
|
||||
endif
|
||||
ifdef CONFIG_UNWINDER_ORC
|
||||
@echo "error: Cannot generate ORC metadata for CONFIG_UNWINDER_ORC=y, please install libelf-dev, libelf-devel or elfutils-libelf-devel" >&2
|
||||
@false
|
||||
|
|
|
@ -97,6 +97,8 @@ config X86
|
|||
select ARCH_SUPPORTS_DEBUG_PAGEALLOC
|
||||
select ARCH_SUPPORTS_NUMA_BALANCING if X86_64
|
||||
select ARCH_SUPPORTS_KMAP_LOCAL_FORCE_MAP if NR_CPUS <= 4096
|
||||
select ARCH_SUPPORTS_LTO_CLANG if X86_64
|
||||
select ARCH_SUPPORTS_LTO_CLANG_THIN if X86_64
|
||||
select ARCH_USE_BUILTIN_BSWAP
|
||||
select ARCH_USE_QUEUED_RWLOCKS
|
||||
select ARCH_USE_QUEUED_SPINLOCKS
|
||||
|
@ -169,6 +171,7 @@ config X86
|
|||
select HAVE_CONTEXT_TRACKING if X86_64
|
||||
select HAVE_CONTEXT_TRACKING_OFFSTACK if HAVE_CONTEXT_TRACKING
|
||||
select HAVE_C_RECORDMCOUNT
|
||||
select HAVE_OBJTOOL_MCOUNT if STACK_VALIDATION
|
||||
select HAVE_DEBUG_KMEMLEAK
|
||||
select HAVE_DMA_CONTIGUOUS
|
||||
select HAVE_DYNAMIC_FTRACE
|
||||
|
|
|
@ -169,6 +169,11 @@ ifeq ($(ACCUMULATE_OUTGOING_ARGS), 1)
|
|||
KBUILD_CFLAGS += $(call cc-option,-maccumulate-outgoing-args,)
|
||||
endif
|
||||
|
||||
ifdef CONFIG_LTO_CLANG
|
||||
KBUILD_LDFLAGS += -plugin-opt=-code-model=kernel \
|
||||
-plugin-opt=-stack-alignment=$(if $(CONFIG_X86_32),4,8)
|
||||
endif
|
||||
|
||||
# Workaround for a gcc prelease that unfortunately was shipped in a suse release
|
||||
KBUILD_CFLAGS += -Wno-sign-compare
|
||||
#
|
||||
|
|
|
@ -91,7 +91,7 @@ ifneq ($(RETPOLINE_VDSO_CFLAGS),)
|
|||
endif
|
||||
endif
|
||||
|
||||
$(vobjs): KBUILD_CFLAGS := $(filter-out $(GCC_PLUGINS_CFLAGS) $(RETPOLINE_CFLAGS),$(KBUILD_CFLAGS)) $(CFL)
|
||||
$(vobjs): KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_LTO) $(GCC_PLUGINS_CFLAGS) $(RETPOLINE_CFLAGS),$(KBUILD_CFLAGS)) $(CFL)
|
||||
|
||||
#
|
||||
# vDSO code runs in userspace and -pg doesn't help with profiling anyway.
|
||||
|
@ -150,6 +150,7 @@ KBUILD_CFLAGS_32 := $(filter-out -fno-pic,$(KBUILD_CFLAGS_32))
|
|||
KBUILD_CFLAGS_32 := $(filter-out -mfentry,$(KBUILD_CFLAGS_32))
|
||||
KBUILD_CFLAGS_32 := $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS_32))
|
||||
KBUILD_CFLAGS_32 := $(filter-out $(RETPOLINE_CFLAGS),$(KBUILD_CFLAGS_32))
|
||||
KBUILD_CFLAGS_32 := $(filter-out $(CC_FLAGS_LTO),$(KBUILD_CFLAGS_32))
|
||||
KBUILD_CFLAGS_32 += -m32 -msoft-float -mregparm=0 -fpic
|
||||
KBUILD_CFLAGS_32 += -fno-stack-protector
|
||||
KBUILD_CFLAGS_32 += $(call cc-option, -foptimize-sibling-calls)
|
||||
|
|
|
@ -4,5 +4,9 @@
|
|||
# itself be stack-protected
|
||||
CFLAGS_cpu.o := -fno-stack-protector
|
||||
|
||||
# Clang may incorrectly inline functions with stack protector enabled into
|
||||
# __restore_processor_state(): https://bugs.llvm.org/show_bug.cgi?id=47479
|
||||
CFLAGS_REMOVE_cpu.o := $(CC_FLAGS_LTO)
|
||||
|
||||
obj-$(CONFIG_PM_SLEEP) += cpu.o
|
||||
obj-$(CONFIG_HIBERNATION) += hibernate_$(BITS).o hibernate_asm_$(BITS).o hibernate.o
|
||||
|
|
|
@ -60,6 +60,11 @@ config HAVE_NOP_MCOUNT
|
|||
help
|
||||
Arch supports the gcc options -pg with -mrecord-mcount and -nop-mcount
|
||||
|
||||
config HAVE_OBJTOOL_MCOUNT
|
||||
bool
|
||||
help
|
||||
Arch supports objtool --mcount
|
||||
|
||||
config HAVE_C_RECORDMCOUNT
|
||||
bool
|
||||
help
|
||||
|
@ -612,10 +617,18 @@ config FTRACE_MCOUNT_USE_CC
|
|||
depends on !FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY
|
||||
depends on FTRACE_MCOUNT_RECORD
|
||||
|
||||
config FTRACE_MCOUNT_USE_OBJTOOL
|
||||
def_bool y
|
||||
depends on HAVE_OBJTOOL_MCOUNT
|
||||
depends on !FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY
|
||||
depends on !FTRACE_MCOUNT_USE_CC
|
||||
depends on FTRACE_MCOUNT_RECORD
|
||||
|
||||
config FTRACE_MCOUNT_USE_RECORDMCOUNT
|
||||
def_bool y
|
||||
depends on !FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY
|
||||
depends on !FTRACE_MCOUNT_USE_CC
|
||||
depends on !FTRACE_MCOUNT_USE_OBJTOOL
|
||||
depends on FTRACE_MCOUNT_RECORD
|
||||
|
||||
config TRACING_MAP
|
||||
|
|
|
@ -218,27 +218,11 @@ cmd_record_mcount = $(if $(findstring $(strip $(CC_FLAGS_FTRACE)),$(_c_flags)),
|
|||
endif # CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT
|
||||
|
||||
ifdef CONFIG_STACK_VALIDATION
|
||||
ifndef CONFIG_LTO_CLANG
|
||||
ifneq ($(SKIP_STACK_VALIDATION),1)
|
||||
|
||||
__objtool_obj := $(objtree)/tools/objtool/objtool
|
||||
|
||||
objtool_args = $(if $(CONFIG_UNWINDER_ORC),orc generate,check)
|
||||
|
||||
objtool_args += $(if $(part-of-module), --module,)
|
||||
|
||||
ifndef CONFIG_FRAME_POINTER
|
||||
objtool_args += --no-fp
|
||||
endif
|
||||
ifdef CONFIG_GCOV_KERNEL
|
||||
objtool_args += --no-unreachable
|
||||
endif
|
||||
ifdef CONFIG_RETPOLINE
|
||||
objtool_args += --retpoline
|
||||
endif
|
||||
ifdef CONFIG_X86_SMAP
|
||||
objtool_args += --uaccess
|
||||
endif
|
||||
|
||||
# 'OBJECT_FILES_NON_STANDARD := y': skip objtool checking for a directory
|
||||
# 'OBJECT_FILES_NON_STANDARD_foo.o := 'y': skip objtool checking for a file
|
||||
# 'OBJECT_FILES_NON_STANDARD_foo.o := 'n': override directory skip for a file
|
||||
|
@ -250,6 +234,7 @@ objtool_obj = $(if $(patsubst y%,, \
|
|||
$(__objtool_obj))
|
||||
|
||||
endif # SKIP_STACK_VALIDATION
|
||||
endif # CONFIG_LTO_CLANG
|
||||
endif # CONFIG_STACK_VALIDATION
|
||||
|
||||
# Rebuild all objects when objtool changes, or is enabled/disabled.
|
||||
|
|
|
@ -222,6 +222,18 @@ dtc_cpp_flags = -Wp,-MMD,$(depfile).pre.tmp -nostdinc \
|
|||
$(addprefix -I,$(DTC_INCLUDE)) \
|
||||
-undef -D__DTS__
|
||||
|
||||
# Objtool arguments are also needed for modfinal with LTO, so we define
|
||||
# then here to avoid duplication.
|
||||
objtool_args = \
|
||||
$(if $(CONFIG_UNWINDER_ORC),orc generate,check) \
|
||||
$(if $(part-of-module), --module,) \
|
||||
$(if $(CONFIG_FRAME_POINTER),, --no-fp) \
|
||||
$(if $(or $(CONFIG_GCOV_KERNEL),$(CONFIG_LTO_CLANG)), \
|
||||
--no-unreachable,) \
|
||||
$(if $(CONFIG_RETPOLINE), --retpoline,) \
|
||||
$(if $(CONFIG_X86_SMAP), --uaccess,) \
|
||||
$(if $(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL), --mcount,)
|
||||
|
||||
# Useful for describing the dependency of composite objects
|
||||
# Usage:
|
||||
# $(call multi_depend, multi_used_targets, suffix_to_remove, suffix_to_add)
|
||||
|
|
|
@ -9,7 +9,7 @@ __modfinal:
|
|||
include include/config/auto.conf
|
||||
include $(srctree)/scripts/Kbuild.include
|
||||
|
||||
# for c_flags
|
||||
# for c_flags and objtool_args
|
||||
include $(srctree)/scripts/Makefile.lib
|
||||
|
||||
# find all modules listed in modules.order
|
||||
|
@ -34,10 +34,23 @@ ifdef CONFIG_LTO_CLANG
|
|||
# With CONFIG_LTO_CLANG, reuse the object file we compiled for modpost to
|
||||
# avoid a second slow LTO link
|
||||
prelink-ext := .lto
|
||||
endif
|
||||
|
||||
# ELF processing was skipped earlier because we didn't have native code,
|
||||
# so let's now process the prelinked binary before we link the module.
|
||||
|
||||
ifdef CONFIG_STACK_VALIDATION
|
||||
ifneq ($(SKIP_STACK_VALIDATION),1)
|
||||
cmd_ld_ko_o += \
|
||||
$(objtree)/tools/objtool/objtool $(objtool_args) \
|
||||
$(@:.ko=$(prelink-ext).o);
|
||||
|
||||
endif # SKIP_STACK_VALIDATION
|
||||
endif # CONFIG_STACK_VALIDATION
|
||||
|
||||
endif # CONFIG_LTO_CLANG
|
||||
|
||||
quiet_cmd_ld_ko_o = LD [M] $@
|
||||
cmd_ld_ko_o = \
|
||||
cmd_ld_ko_o += \
|
||||
$(LD) -r $(KBUILD_LDFLAGS) \
|
||||
$(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \
|
||||
-T scripts/module.lds -o $@ $(filter %.o, $^); \
|
||||
|
|
|
@ -103,14 +103,36 @@ modpost_link()
|
|||
|
||||
objtool_link()
|
||||
{
|
||||
local objtoolcmd;
|
||||
local objtoolopt;
|
||||
|
||||
if [ "${CONFIG_LTO_CLANG} ${CONFIG_STACK_VALIDATION}" = "y y" ]; then
|
||||
# Don't perform vmlinux validation unless explicitly requested,
|
||||
# but run objtool on vmlinux.o now that we have an object file.
|
||||
if [ -n "${CONFIG_UNWINDER_ORC}" ]; then
|
||||
objtoolcmd="orc generate"
|
||||
fi
|
||||
|
||||
objtoolopt="${objtoolopt} --duplicate"
|
||||
|
||||
if [ -n "${CONFIG_FTRACE_MCOUNT_USE_OBJTOOL}" ]; then
|
||||
objtoolopt="${objtoolopt} --mcount"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "${CONFIG_VMLINUX_VALIDATION}" ]; then
|
||||
objtoolopt="check"
|
||||
objtoolopt="${objtoolopt} --noinstr"
|
||||
fi
|
||||
|
||||
if [ -n "${objtoolopt}" ]; then
|
||||
if [ -z "${objtoolcmd}" ]; then
|
||||
objtoolcmd="check"
|
||||
fi
|
||||
objtoolopt="${objtoolopt} --vmlinux"
|
||||
if [ -z "${CONFIG_FRAME_POINTER}" ]; then
|
||||
objtoolopt="${objtoolopt} --no-fp"
|
||||
fi
|
||||
if [ -n "${CONFIG_GCOV_KERNEL}" ]; then
|
||||
if [ -n "${CONFIG_GCOV_KERNEL}" ] || [ -n "${CONFIG_LTO_CLANG}" ]; then
|
||||
objtoolopt="${objtoolopt} --no-unreachable"
|
||||
fi
|
||||
if [ -n "${CONFIG_RETPOLINE}" ]; then
|
||||
|
@ -120,7 +142,7 @@ objtool_link()
|
|||
objtoolopt="${objtoolopt} --uaccess"
|
||||
fi
|
||||
info OBJTOOL ${1}
|
||||
tools/objtool/objtool ${objtoolopt} ${1}
|
||||
tools/objtool/objtool ${objtoolcmd} ${objtoolopt} ${1}
|
||||
fi
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include <objtool/builtin.h>
|
||||
#include <objtool/objtool.h>
|
||||
|
||||
bool no_fp, no_unreachable, retpoline, module, backtrace, uaccess, stats, validate_dup, vmlinux;
|
||||
bool no_fp, no_unreachable, retpoline, module, backtrace, uaccess, stats, validate_dup, vmlinux, mcount, noinstr;
|
||||
|
||||
static const char * const check_usage[] = {
|
||||
"objtool check [<options>] file.o",
|
||||
|
@ -34,13 +34,15 @@ const struct option check_options[] = {
|
|||
OPT_BOOLEAN('a', "uaccess", &uaccess, "enable uaccess checking"),
|
||||
OPT_BOOLEAN('s', "stats", &stats, "print statistics"),
|
||||
OPT_BOOLEAN('d', "duplicate", &validate_dup, "duplicate validation for vmlinux.o"),
|
||||
OPT_BOOLEAN('n', "noinstr", &noinstr, "noinstr validation for vmlinux.o"),
|
||||
OPT_BOOLEAN('l', "vmlinux", &vmlinux, "vmlinux.o validation"),
|
||||
OPT_BOOLEAN('M', "mcount", &mcount, "generate __mcount_loc"),
|
||||
OPT_END(),
|
||||
};
|
||||
|
||||
int cmd_check(int argc, const char **argv)
|
||||
{
|
||||
const char *objname, *s;
|
||||
const char *objname;
|
||||
struct objtool_file *file;
|
||||
int ret;
|
||||
|
||||
|
@ -51,10 +53,6 @@ int cmd_check(int argc, const char **argv)
|
|||
|
||||
objname = argv[0];
|
||||
|
||||
s = strstr(objname, "vmlinux.o");
|
||||
if (s && !s[9])
|
||||
vmlinux = true;
|
||||
|
||||
file = objtool_open_read(objname);
|
||||
if (!file)
|
||||
return 1;
|
||||
|
|
|
@ -249,7 +249,7 @@ static void init_insn_state(struct insn_state *state, struct section *sec)
|
|||
* not correctly determine insn->call_dest->sec (external symbols do
|
||||
* not have a section).
|
||||
*/
|
||||
if (vmlinux && sec)
|
||||
if (vmlinux && noinstr && sec)
|
||||
state->noinstr = sec->noinstr;
|
||||
}
|
||||
|
||||
|
@ -548,6 +548,78 @@ static int create_static_call_sections(struct objtool_file *file)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int create_mcount_loc_sections(struct objtool_file *file)
|
||||
{
|
||||
struct section *sec, *reloc_sec;
|
||||
struct reloc *reloc;
|
||||
unsigned long *loc;
|
||||
struct instruction *insn;
|
||||
int idx;
|
||||
|
||||
sec = find_section_by_name(file->elf, "__mcount_loc");
|
||||
if (sec) {
|
||||
INIT_LIST_HEAD(&file->mcount_loc_list);
|
||||
WARN("file already has __mcount_loc section, skipping");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (list_empty(&file->mcount_loc_list))
|
||||
return 0;
|
||||
|
||||
idx = 0;
|
||||
list_for_each_entry(insn, &file->mcount_loc_list, mcount_loc_node)
|
||||
idx++;
|
||||
|
||||
sec = elf_create_section(file->elf, "__mcount_loc", 0, sizeof(unsigned long), idx);
|
||||
if (!sec)
|
||||
return -1;
|
||||
|
||||
reloc_sec = elf_create_reloc_section(file->elf, sec, SHT_RELA);
|
||||
if (!reloc_sec)
|
||||
return -1;
|
||||
|
||||
idx = 0;
|
||||
list_for_each_entry(insn, &file->mcount_loc_list, mcount_loc_node) {
|
||||
|
||||
loc = (unsigned long *)sec->data->d_buf + idx;
|
||||
memset(loc, 0, sizeof(unsigned long));
|
||||
|
||||
reloc = malloc(sizeof(*reloc));
|
||||
if (!reloc) {
|
||||
perror("malloc");
|
||||
return -1;
|
||||
}
|
||||
memset(reloc, 0, sizeof(*reloc));
|
||||
|
||||
if (insn->sec->sym) {
|
||||
reloc->sym = insn->sec->sym;
|
||||
reloc->addend = insn->offset;
|
||||
} else {
|
||||
reloc->sym = find_symbol_containing(insn->sec, insn->offset);
|
||||
|
||||
if (!reloc->sym) {
|
||||
WARN("missing symbol for insn at offset 0x%lx\n",
|
||||
insn->offset);
|
||||
return -1;
|
||||
}
|
||||
|
||||
reloc->addend = insn->offset - reloc->sym->offset;
|
||||
}
|
||||
|
||||
reloc->type = R_X86_64_64;
|
||||
reloc->offset = idx * sizeof(unsigned long);
|
||||
reloc->sec = reloc_sec;
|
||||
elf_add_reloc(file->elf, reloc);
|
||||
|
||||
idx++;
|
||||
}
|
||||
|
||||
if (elf_rebuild_reloc_section(file->elf, reloc_sec))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Warnings shouldn't be reported for ignored functions.
|
||||
*/
|
||||
|
@ -975,6 +1047,22 @@ static int add_call_destinations(struct objtool_file *file)
|
|||
insn->type = INSN_NOP;
|
||||
}
|
||||
|
||||
if (mcount && !strcmp(insn->call_dest->name, "__fentry__")) {
|
||||
if (reloc) {
|
||||
reloc->type = R_NONE;
|
||||
elf_write_reloc(file->elf, reloc);
|
||||
}
|
||||
|
||||
elf_write_insn(file->elf, insn->sec,
|
||||
insn->offset, insn->len,
|
||||
arch_nop_insn(insn->len));
|
||||
|
||||
insn->type = INSN_NOP;
|
||||
|
||||
list_add_tail(&insn->mcount_loc_node,
|
||||
&file->mcount_loc_list);
|
||||
}
|
||||
|
||||
/*
|
||||
* Whatever stack impact regular CALLs have, should be undone
|
||||
* by the RETURN of the called function.
|
||||
|
@ -3048,6 +3136,13 @@ int check(struct objtool_file *file)
|
|||
goto out;
|
||||
warnings += ret;
|
||||
|
||||
if (mcount) {
|
||||
ret = create_mcount_loc_sections(file);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
warnings += ret;
|
||||
}
|
||||
|
||||
out:
|
||||
/*
|
||||
* For now, don't fail the kernel build on fatal warnings. These
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#include <subcmd/parse-options.h>
|
||||
|
||||
extern const struct option check_options[];
|
||||
extern bool no_fp, no_unreachable, retpoline, module, backtrace, uaccess, stats, validate_dup, vmlinux;
|
||||
extern bool no_fp, no_unreachable, retpoline, module, backtrace, uaccess, stats, validate_dup, vmlinux, mcount, noinstr;
|
||||
|
||||
extern int cmd_check(int argc, const char **argv);
|
||||
extern int cmd_orc(int argc, const char **argv);
|
||||
|
|
|
@ -40,6 +40,7 @@ struct instruction {
|
|||
struct list_head list;
|
||||
struct hlist_node hash;
|
||||
struct list_head static_call_node;
|
||||
struct list_head mcount_loc_node;
|
||||
struct section *sec;
|
||||
unsigned long offset;
|
||||
unsigned int len;
|
||||
|
|
|
@ -19,6 +19,7 @@ struct objtool_file {
|
|||
struct list_head insn_list;
|
||||
DECLARE_HASHTABLE(insn_hash, 20);
|
||||
struct list_head static_call_list;
|
||||
struct list_head mcount_loc_list;
|
||||
bool ignore_unreachables, c_file, hints, rodata;
|
||||
};
|
||||
|
||||
|
|
|
@ -62,6 +62,7 @@ struct objtool_file *objtool_open_read(const char *_objname)
|
|||
INIT_LIST_HEAD(&file.insn_list);
|
||||
hash_init(file.insn_hash);
|
||||
INIT_LIST_HEAD(&file.static_call_list);
|
||||
INIT_LIST_HEAD(&file.mcount_loc_list);
|
||||
file.c_file = !vmlinux && find_section_by_name(file.elf, ".comment");
|
||||
file.ignore_unreachables = no_unreachable;
|
||||
file.hints = false;
|
||||
|
|
Loading…
Reference in New Issue