You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
240 lines
5.7 KiB
240 lines
5.7 KiB
#!/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 |
|
} |
|
|
|
# Link of vmlinux.o used for section mismatch analysis |
|
# ${1} output file |
|
modpost_link() |
|
{ |
|
${LD} ${LDFLAGS} -r -o ${1} ${KBUILD_VMLINUX_INIT} \ |
|
--start-group ${KBUILD_VMLINUX_MAIN} --end-group |
|
} |
|
|
|
# Link of vmlinux |
|
# ${1} - optional extra .o files |
|
# ${2} - output file |
|
vmlinux_link() |
|
{ |
|
local lds="${objtree}/${KBUILD_LDS}" |
|
|
|
if [ "${SRCARCH}" != "um" ]; then |
|
${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} -o ${2} \ |
|
-T ${lds} ${KBUILD_VMLINUX_INIT} \ |
|
--start-group ${KBUILD_VMLINUX_MAIN} --end-group ${1} |
|
else |
|
${CC} ${CFLAGS_vmlinux} -o ${2} \ |
|
-Wl,-T,${lds} ${KBUILD_VMLINUX_INIT} \ |
|
-Wl,--start-group \ |
|
${KBUILD_VMLINUX_MAIN} \ |
|
-Wl,--end-group \ |
|
-lutil ${1} |
|
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_ARM}" ] && [ -n "${CONFIG_PAGE_OFFSET}" ]; then |
|
kallsymopt="${kallsymopt} --page-offset=$CONFIG_PAGE_OFFSET" |
|
fi |
|
|
|
if [ -n "${CONFIG_X86_64}" ]; then |
|
kallsymopt="${kallsymopt} --absolute-percpu" |
|
fi |
|
|
|
local aflags="${KBUILD_AFLAGS} ${KBUILD_AFLAGS_KERNEL} \ |
|
${NOSTDINC_FLAGS} ${LINUXINCLUDE} ${KBUILD_CPPFLAGS}" |
|
|
|
${NM} -n ${1} | \ |
|
scripts/kallsyms ${kallsymopt} | \ |
|
${CC} ${aflags} -c -o ${2} -x assembler-with-cpp - |
|
} |
|
|
|
# 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 |
|
trap cleanup SIGHUP SIGINT SIGQUIT SIGTERM ERR |
|
cleanup() |
|
{ |
|
rm -f .old_version |
|
rm -f .tmp_System.map |
|
rm -f .tmp_kallsyms* |
|
rm -f .tmp_version |
|
rm -f .tmp_vmlinux* |
|
rm -f System.map |
|
rm -f vmlinux |
|
rm -f vmlinux.o |
|
} |
|
|
|
# |
|
# |
|
# 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 |
|
|
|
#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 |
|
|
|
# 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 |
|
|
|
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 |
|
# 2a) We may use an extra pass as this has been necessary to |
|
# woraround some alignment related bugs. |
|
# KALLSYMS_EXTRA_PASS=1 is used to trigger this. |
|
# 3) 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 2a |
|
if [ -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 |
|
cleanup |
|
exit 1 |
|
fi |
|
fi |
|
|
|
# We made a new kernel - delete old version file |
|
rm -f .old_version
|
|
|