Skip to content

Commit

Permalink
kbuild: lto: postpone objtool
Browse files Browse the repository at this point in the history
With LTO, LLVM bitcode won't be compiled into native code until
modpost_link, or modfinal for modules. This change postpones calls
to objtool until after these steps, and moves objtool_args to
Makefile.lib, so the arguments can be reused in Makefile.modfinal.

As we didn't have objects to process earlier, we use --duplicate
when processing vmlinux.o. This change also disables unreachable
instruction warnings with LTO to avoid warnings about the int3
padding between functions.

Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
  • Loading branch information
samitolvanen authored and kees committed Feb 23, 2021
1 parent 41425eb commit b1a1a1a
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 26 deletions.
22 changes: 2 additions & 20 deletions scripts/Makefile.build
Original file line number Diff line number Diff line change
Expand Up @@ -218,30 +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
ifdef CONFIG_FTRACE_MCOUNT_USE_OBJTOOL
objtool_args += --mcount
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
Expand All @@ -253,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.
Expand Down
12 changes: 12 additions & 0 deletions scripts/Makefile.lib
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,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)
Expand Down
19 changes: 16 additions & 3 deletions scripts/Makefile.modfinal
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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, $^); \
Expand Down
28 changes: 25 additions & 3 deletions scripts/link-vmlinux.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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 --vmlinux --noinstr"
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
Expand All @@ -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
}

Expand Down

0 comments on commit b1a1a1a

Please sign in to comment.