#!/bin/sh## link vmlinux## vmlinux is linked from the objects selected by $(KBUILD_VMLINUX_INIT) and# $(KBUILD_VMLINUX_MAIN). Most are built-in.o files from top-level directories# in the kernel tree, others are specified in arch/$(ARCH)/Makefile.# Ordering when linking is important, and $(KBUILD_VMLINUX_INIT) must be first.## vmlinux# ^# |# +-< $(KBUILD_VMLINUX_INIT)# | +--< init/version.o + more# |# +--< $(KBUILD_VMLINUX_MAIN)# | +--< drivers/built-in.o mm/built-in.o + more# |# +-< ${kallsymso} (see description in KALLSYMS section)## vmlinux version (uname -v) cannot be updated during normal# descending-into-subdirs phase since we do not yet know if we need to# update vmlinux.# Therefore this step is delayed until just before final link of vmlinux.## System.map is generated to document addresses of all kernel symbols# Error out on errorset -e# Nice output in kbuild format# Will be supressed by "make -s"info(){ if [ "${quiet}" != "silent_" ]; then printf " %-7s %s\n" ${1} ${2} fi}# Thin archive build here makes a final archive with# symbol table and indexes from vmlinux objects, which can be# used as input to linker.## Traditional incremental style of link does not require this step## built-in.o output file#archive_builtin(){ if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then info AR built-in.o rm -f built-in.o; ${AR} rcsT${KBUILD_ARFLAGS} built-in.o \ ${KBUILD_VMLINUX_INIT} \ ${KBUILD_VMLINUX_MAIN} fi}# Link of vmlinux.o used for section mismatch analysis# ${1} output filemodpost_link(){ local objects if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then objects="--whole-archive built-in.o" else objects="${KBUILD_VMLINUX_INIT} \ --start-group \ ${KBUILD_VMLINUX_MAIN} \ --end-group" fi ${LD} ${LDFLAGS} -r -o ${1} ${objects}}# Link of vmlinux# ${1} - optional extra .o files# ${2} - output filevmlinux_link(){ local lds="${objtree}/${KBUILD_LDS}" local objects if [ "${SRCARCH}" != "um" ]; then if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then objects="--whole-archive built-in.o ${1}" else objects="${KBUILD_VMLINUX_INIT} \ --start-group \ ${KBUILD_VMLINUX_MAIN} \ --end-group \ ${1}" fi ${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} -o ${2} \ -T ${lds} ${objects} else if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then objects="-Wl,--whole-archive built-in.o ${1}" else objects="${KBUILD_VMLINUX_INIT} \ -Wl,--start-group \ ${KBUILD_VMLINUX_MAIN} \ -Wl,--end-group \ ${1}" fi ${CC} ${CFLAGS_vmlinux} -o ${2} \ -Wl,-T,${lds} \ ${objects} \ -lutil -lrt -lpthread rm -f linux fi}# Create ${2} .o file with all symbols from the ${1} object filekallsyms(){ info KSYM ${2} local kallsymopt; if [ -n "${CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX}" ]; then kallsymopt="${kallsymopt} --symbol-prefix=_" fi if [ -n "${CONFIG_KALLSYMS_ALL}" ]; then kallsymopt="${kallsymopt} --all-symbols" fi if [ -n "${CONFIG_KALLSYMS_ABSOLUTE_PERCPU}" ]; then kallsymopt="${kallsymopt} --absolute-percpu" fi if [ -n "${CONFIG_KALLSYMS_BASE_RELATIVE}" ]; then kallsymopt="${kallsymopt} --base-relative" fi local aflags="${KBUILD_AFLAGS} ${KBUILD_AFLAGS_KERNEL} \ ${NOSTDINC_FLAGS} ${LINUXINCLUDE} ${KBUILD_CPPFLAGS}" local afile="`basename ${2} .o`.S" ${NM} -n ${1} | scripts/kallsyms ${kallsymopt} > ${afile} ${CC} ${aflags} -c -o ${2} ${afile}}# Create map file with all symbols from ${1}# See mksymap for additional detailsmksysmap(){ ${CONFIG_SHELL} "${srctree}/scripts/mksysmap" ${1} ${2}}sortextable(){ ${objtree}/scripts/sortextable ${1}}# Delete output files in case of errorcleanup(){ rm -f .old_version rm -f .tmp_System.map rm -f .tmp_kallsyms* rm -f .tmp_version rm -f .tmp_vmlinux* rm -f built-in.o rm -f System.map rm -f vmlinux rm -f vmlinux.o}on_exit(){ if [ $? -ne 0 ]; then cleanup fi}trap on_exit EXITon_signals(){ exit 1}trap on_signals HUP INT QUIT TERM### Use "make V=1" to debug this scriptcase "${KBUILD_VERBOSE}" in*1*) set -x ;;esacif [ "$1" = "clean" ]; then cleanup exit 0fi# We need access to CONFIG_ symbolscase "${KCONFIG_CONFIG}" in*/*) . "${KCONFIG_CONFIG}" ;;*) # Force using a file from the current directory . "./${KCONFIG_CONFIG}"esac# Update versioninfo GEN .versionif [ ! -r .version ]; then rm -f .version; echo 1 >.version;else mv .version .old_version; expr 0$(cat .old_version) + 1 >.version;fi;# final build of init/${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init GCC_PLUGINS_CFLAGS="${GCC_PLUGINS_CFLAGS}"archive_builtin#link vmlinux.oinfo LD vmlinux.omodpost_link vmlinux.o# modpost vmlinux.o to check for section mismatches${MAKE} -f "${srctree}/scripts/Makefile.modpost" vmlinux.okallsymso=""kallsyms_vmlinux=""if [ -n "${CONFIG_KALLSYMS}" ]; then # kallsyms support # Generate section listing all symbols and add it into vmlinux # It's a three step process: # 1) Link .tmp_vmlinux1 so it has all symbols and sections, # but __kallsyms is empty. # Running kallsyms on that gives us .tmp_kallsyms1.o with # the right size # 2) Link .tmp_vmlinux2 so it now has a __kallsyms section of # the right size, but due to the added section, some # addresses have shifted. # From here, we generate a correct .tmp_kallsyms2.o # 3) That link may have expanded the kernel image enough that # more linker branch stubs / trampolines had to be added, which # introduces new names, which further expands kallsyms. Do another # pass if that is the case. In theory it's possible this results # in even more stubs, but unlikely. # KALLSYMS_EXTRA_PASS=1 may also used to debug or work around # other bugs. # 4) The correct ${kallsymso} is linked into the final vmlinux. # # a) Verify that the System.map from vmlinux matches the map from # ${kallsymso}. kallsymso=.tmp_kallsyms2.o kallsyms_vmlinux=.tmp_vmlinux2 # step 1 vmlinux_link "" .tmp_vmlinux1 kallsyms .tmp_vmlinux1 .tmp_kallsyms1.o # step 2 vmlinux_link .tmp_kallsyms1.o .tmp_vmlinux2 kallsyms .tmp_vmlinux2 .tmp_kallsyms2.o # step 3 size1=$(stat -c "%s" .tmp_kallsyms1.o) size2=$(stat -c "%s" .tmp_kallsyms2.o) if [ $size1 -ne $size2 ] || [ -n "${KALLSYMS_EXTRA_PASS}" ]; then kallsymso=.tmp_kallsyms3.o kallsyms_vmlinux=.tmp_vmlinux3 vmlinux_link .tmp_kallsyms2.o .tmp_vmlinux3 kallsyms .tmp_vmlinux3 .tmp_kallsyms3.o fifiinfo LD vmlinuxvmlinux_link "${kallsymso}" vmlinuxif [ -n "${CONFIG_BUILDTIME_EXTABLE_SORT}" ]; then info SORTEX vmlinux sortextable vmlinuxfiinfo SYSMAP System.mapmksysmap vmlinux System.map# step a (see comment above)if [ -n "${CONFIG_KALLSYMS}" ]; then mksysmap ${kallsyms_vmlinux} .tmp_System.map if ! cmp -s System.map .tmp_System.map; then echo >&2 Inconsistent kallsyms data echo >&2 Try "make KALLSYMS_EXTRA_PASS=1" as a workaround exit 1 fifi# We made a new kernel - delete old version filerm -f .old_version
#!/bin/sh
#
# link vmlinux
#
# vmlinux is linked from the objects selected by $(KBUILD_VMLINUX_INIT) and
# $(KBUILD_VMLINUX_MAIN). Most are built-in.o files from top-level directories
# in the kernel tree, others are specified in arch/$(ARCH)/Makefile.
# Ordering when linking is important, and $(KBUILD_VMLINUX_INIT) must be first.
#
# vmlinux
# ^
# |
# +-< $(KBUILD_VMLINUX_INIT)
# | +--< init/version.o + more
# |
# +--< $(KBUILD_VMLINUX_MAIN)
# | +--< drivers/built-in.o mm/built-in.o + more
# |
# +-< ${kallsymso} (see description in KALLSYMS section)
#
# vmlinux version (uname -v) cannot be updated during normal
# descending-into-subdirs phase since we do not yet know if we need to
# update vmlinux.
# Therefore this step is delayed until just before final link of vmlinux.
#
# System.map is generated to document addresses of all kernel symbols
# Error out on error
set -e
# Nice output in kbuild format
# Will be supressed by "make -s"
info()
{
if [ "${quiet}" != "silent_" ]; then
printf " %-7s %s\n" ${1} ${2}
fi
}
# Thin archive build here makes a final archive with
# symbol table and indexes from vmlinux objects, which can be
# used as input to linker.
#
# Traditional incremental style of link does not require this step
#
# built-in.o output file
#
archive_builtin()
{
if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then
info AR built-in.o
rm -f built-in.o;
${AR} rcsT${KBUILD_ARFLAGS} built-in.o \
${KBUILD_VMLINUX_INIT} \
${KBUILD_VMLINUX_MAIN}
fi
}
# Link of vmlinux.o used for section mismatch analysis
# ${1} output file
modpost_link()
{
local objects
if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then
objects="--whole-archive built-in.o"
else
objects="${KBUILD_VMLINUX_INIT} \
--start-group \
${KBUILD_VMLINUX_MAIN} \
--end-group"
fi
${LD} ${LDFLAGS} -r -o ${1} ${objects}
}
# Link of vmlinux
# ${1} - optional extra .o files
# ${2} - output file
vmlinux_link()
{
local lds="${objtree}/${KBUILD_LDS}"
local objects
if [ "${SRCARCH}" != "um" ]; then
if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then
objects="--whole-archive built-in.o ${1}"
else
objects="${KBUILD_VMLINUX_INIT} \
--start-group \
${KBUILD_VMLINUX_MAIN} \
--end-group \
${1}"
fi
${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} -o ${2} \
-T ${lds} ${objects}
else
if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then
objects="-Wl,--whole-archive built-in.o ${1}"
else
objects="${KBUILD_VMLINUX_INIT} \
-Wl,--start-group \
${KBUILD_VMLINUX_MAIN} \
-Wl,--end-group \
${1}"
fi
${CC} ${CFLAGS_vmlinux} -o ${2} \
-Wl,-T,${lds} \
${objects} \
-lutil -lrt -lpthread
rm -f linux
fi
}
# Create ${2} .o file with all symbols from the ${1} object file
kallsyms()
{
info KSYM ${2}
local kallsymopt;
if [ -n "${CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX}" ]; then
kallsymopt="${kallsymopt} --symbol-prefix=_"
fi
if [ -n "${CONFIG_KALLSYMS_ALL}" ]; then
kallsymopt="${kallsymopt} --all-symbols"
fi
if [ -n "${CONFIG_KALLSYMS_ABSOLUTE_PERCPU}" ]; then
kallsymopt="${kallsymopt} --absolute-percpu"
fi
if [ -n "${CONFIG_KALLSYMS_BASE_RELATIVE}" ]; then
kallsymopt="${kallsymopt} --base-relative"
fi
local aflags="${KBUILD_AFLAGS} ${KBUILD_AFLAGS_KERNEL} \
${NOSTDINC_FLAGS} ${LINUXINCLUDE} ${KBUILD_CPPFLAGS}"
local afile="`basename ${2} .o`.S"
${NM} -n ${1} | scripts/kallsyms ${kallsymopt} > ${afile}
${CC} ${aflags} -c -o ${2} ${afile}
}
# Create map file with all symbols from ${1}
# See mksymap for additional details
mksysmap()
{
${CONFIG_SHELL} "${srctree}/scripts/mksysmap" ${1} ${2}
}
sortextable()
{
${objtree}/scripts/sortextable ${1}
}
# Delete output files in case of error
cleanup()
{
rm -f .old_version
rm -f .tmp_System.map
rm -f .tmp_kallsyms*
rm -f .tmp_version
rm -f .tmp_vmlinux*
rm -f built-in.o
rm -f System.map
rm -f vmlinux
rm -f vmlinux.o
}
on_exit()
{
if [ $? -ne 0 ]; then
cleanup
fi
}
trap on_exit EXIT
on_signals()
{
exit 1
}
trap on_signals HUP INT QUIT TERM
#
#
# Use "make V=1" to debug this script
case "${KBUILD_VERBOSE}" in
*1*)
set -x
;;
esac
if [ "$1" = "clean" ]; then
cleanup
exit 0
fi
# We need access to CONFIG_ symbols
case "${KCONFIG_CONFIG}" in
*/*)
. "${KCONFIG_CONFIG}"
;;
*)
# Force using a file from the current directory
. "./${KCONFIG_CONFIG}"
esac
# Update version
info GEN .version
if [ ! -r .version ]; then
rm -f .version;
echo 1 >.version;
else
mv .version .old_version;
expr 0$(cat .old_version) + 1 >.version;
fi;
# final build of init/
${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init GCC_PLUGINS_CFLAGS="${GCC_PLUGINS_CFLAGS}"
archive_builtin
#link vmlinux.o
info LD vmlinux.o
modpost_link vmlinux.o
# modpost vmlinux.o to check for section mismatches
${MAKE} -f "${srctree}/scripts/Makefile.modpost" vmlinux.o
kallsymso=""
kallsyms_vmlinux=""
if [ -n "${CONFIG_KALLSYMS}" ]; then
# kallsyms support
# Generate section listing all symbols and add it into vmlinux
# It's a three step process:
# 1) Link .tmp_vmlinux1 so it has all symbols and sections,
# but __kallsyms is empty.
# Running kallsyms on that gives us .tmp_kallsyms1.o with
# the right size
# 2) Link .tmp_vmlinux2 so it now has a __kallsyms section of
# the right size, but due to the added section, some
# addresses have shifted.
# From here, we generate a correct .tmp_kallsyms2.o
# 3) That link may have expanded the kernel image enough that
# more linker branch stubs / trampolines had to be added, which
# introduces new names, which further expands kallsyms. Do another
# pass if that is the case. In theory it's possible this results
# in even more stubs, but unlikely.
# KALLSYMS_EXTRA_PASS=1 may also used to debug or work around
# other bugs.
# 4) The correct ${kallsymso} is linked into the final vmlinux.
#
# a) Verify that the System.map from vmlinux matches the map from
# ${kallsymso}.
kallsymso=.tmp_kallsyms2.o
kallsyms_vmlinux=.tmp_vmlinux2
# step 1
vmlinux_link "" .tmp_vmlinux1
kallsyms .tmp_vmlinux1 .tmp_kallsyms1.o
# step 2
vmlinux_link .tmp_kallsyms1.o .tmp_vmlinux2
kallsyms .tmp_vmlinux2 .tmp_kallsyms2.o
# step 3
size1=$(stat -c "%s" .tmp_kallsyms1.o)
size2=$(stat -c "%s" .tmp_kallsyms2.o)
if [ $size1 -ne $size2 ] || [ -n "${KALLSYMS_EXTRA_PASS}" ]; then
kallsymso=.tmp_kallsyms3.o
kallsyms_vmlinux=.tmp_vmlinux3
vmlinux_link .tmp_kallsyms2.o .tmp_vmlinux3
kallsyms .tmp_vmlinux3 .tmp_kallsyms3.o
fi
fi
info LD vmlinux
vmlinux_link "${kallsymso}" vmlinux
if [ -n "${CONFIG_BUILDTIME_EXTABLE_SORT}" ]; then
info SORTEX vmlinux
sortextable vmlinux
fi
info SYSMAP System.map
mksysmap vmlinux System.map
# step a (see comment above)
if [ -n "${CONFIG_KALLSYMS}" ]; then
mksysmap ${kallsyms_vmlinux} .tmp_System.map
if ! cmp -s System.map .tmp_System.map; then
echo >&2 Inconsistent kallsyms data
echo >&2 Try "make KALLSYMS_EXTRA_PASS=1" as a workaround
exit 1
fi
fi
# We made a new kernel - delete old version file
rm -f .old_version