1#!/bin/sh 2# 3# link vmlinux 4# 5# vmlinux is linked from the objects selected by $(KBUILD_VMLINUX_INIT) and 6# $(KBUILD_VMLINUX_MAIN). Most are built-in.o files from top-level directories 7# in the kernel tree, others are specified in arch/$(ARCH)/Makefile. 8# Ordering when linking is important, and $(KBUILD_VMLINUX_INIT) must be first. 9# 10# vmlinux 11# ^ 12# | 13# +-< $(KBUILD_VMLINUX_INIT) 14# | +--< init/version.o + more 15# | 16# +--< $(KBUILD_VMLINUX_MAIN) 17# | +--< drivers/built-in.o mm/built-in.o + more 18# | 19# +-< ${kallsymso} (see description in KALLSYMS section) 20# 21# vmlinux version (uname -v) cannot be updated during normal 22# descending-into-subdirs phase since we do not yet know if we need to 23# update vmlinux. 24# Therefore this step is delayed until just before final link of vmlinux. 25# 26# System.map is generated to document addresses of all kernel symbols 27 28# Error out on error 29set -e 30 31# Nice output in kbuild format 32# Will be supressed by "make -s" 33info() 34{ 35 if [ "${quiet}" != "silent_" ]; then 36 printf " %-7s %s\n" ${1} ${2} 37 fi 38} 39 40# Thin archive build here makes a final archive with 41# symbol table and indexes from vmlinux objects, which can be 42# used as input to linker. 43# 44# Traditional incremental style of link does not require this step 45# 46# built-in.o output file 47# 48archive_builtin() 49{ 50 if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then 51 info AR built-in.o 52 rm -f built-in.o; 53 ${AR} rcsT${KBUILD_ARFLAGS} built-in.o \ 54 ${KBUILD_VMLINUX_INIT} \ 55 ${KBUILD_VMLINUX_MAIN} 56 fi 57} 58 59# Link of vmlinux.o used for section mismatch analysis 60# ${1} output file 61modpost_link() 62{ 63 local objects 64 65 if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then 66 objects="--whole-archive built-in.o" 67 else 68 objects="${KBUILD_VMLINUX_INIT} \ 69 --start-group \ 70 ${KBUILD_VMLINUX_MAIN} \ 71 --end-group" 72 fi 73 ${LD} ${LDFLAGS} -r -o ${1} ${objects} 74} 75 76# Link of vmlinux 77# ${1} - optional extra .o files 78# ${2} - output file 79vmlinux_link() 80{ 81 local lds="${objtree}/${KBUILD_LDS}" 82 local objects 83 84 if [ "${SRCARCH}" != "um" ]; then 85 if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then 86 objects="--whole-archive built-in.o ${1}" 87 else 88 objects="${KBUILD_VMLINUX_INIT} \ 89 --start-group \ 90 ${KBUILD_VMLINUX_MAIN} \ 91 --end-group \ 92 ${1}" 93 fi 94 95 ${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} -o ${2} \ 96 -T ${lds} ${objects} 97 else 98 if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then 99 objects="-Wl,--whole-archive built-in.o ${1}" 100 else 101 objects="${KBUILD_VMLINUX_INIT} \ 102 -Wl,--start-group \ 103 ${KBUILD_VMLINUX_MAIN} \ 104 -Wl,--end-group \ 105 ${1}" 106 fi 107 108 ${CC} ${CFLAGS_vmlinux} -o ${2} \ 109 -Wl,-T,${lds} \ 110 ${objects} \ 111 -lutil -lrt -lpthread 112 rm -f linux 113 fi 114} 115 116 117# Create ${2} .o file with all symbols from the ${1} object file 118kallsyms() 119{ 120 info KSYM ${2} 121 local kallsymopt; 122 123 if [ -n "${CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX}" ]; then 124 kallsymopt="${kallsymopt} --symbol-prefix=_" 125 fi 126 127 if [ -n "${CONFIG_KALLSYMS_ALL}" ]; then 128 kallsymopt="${kallsymopt} --all-symbols" 129 fi 130 131 if [ -n "${CONFIG_KALLSYMS_ABSOLUTE_PERCPU}" ]; then 132 kallsymopt="${kallsymopt} --absolute-percpu" 133 fi 134 135 if [ -n "${CONFIG_KALLSYMS_BASE_RELATIVE}" ]; then 136 kallsymopt="${kallsymopt} --base-relative" 137 fi 138 139 local aflags="${KBUILD_AFLAGS} ${KBUILD_AFLAGS_KERNEL} \ 140 ${NOSTDINC_FLAGS} ${LINUXINCLUDE} ${KBUILD_CPPFLAGS}" 141 142 local afile="`basename ${2} .o`.S" 143 144 ${NM} -n ${1} | scripts/kallsyms ${kallsymopt} > ${afile} 145 ${CC} ${aflags} -c -o ${2} ${afile} 146} 147 148# Create map file with all symbols from ${1} 149# See mksymap for additional details 150mksysmap() 151{ 152 ${CONFIG_SHELL} "${srctree}/scripts/mksysmap" ${1} ${2} 153} 154 155sortextable() 156{ 157 ${objtree}/scripts/sortextable ${1} 158} 159 160# Delete output files in case of error 161cleanup() 162{ 163 rm -f .old_version 164 rm -f .tmp_System.map 165 rm -f .tmp_kallsyms* 166 rm -f .tmp_version 167 rm -f .tmp_vmlinux* 168 rm -f built-in.o 169 rm -f System.map 170 rm -f vmlinux 171 rm -f vmlinux.o 172} 173 174on_exit() 175{ 176 if [ $? -ne 0 ]; then 177 cleanup 178 fi 179} 180trap on_exit EXIT 181 182on_signals() 183{ 184 exit 1 185} 186trap on_signals HUP INT QUIT TERM 187 188# 189# 190# Use "make V=1" to debug this script 191case "${KBUILD_VERBOSE}" in 192*1*) 193 set -x 194 ;; 195esac 196 197if [ "$1" = "clean" ]; then 198 cleanup 199 exit 0 200fi 201 202# We need access to CONFIG_ symbols 203case "${KCONFIG_CONFIG}" in 204*/*) 205 . "${KCONFIG_CONFIG}" 206 ;; 207*) 208 # Force using a file from the current directory 209 . "./${KCONFIG_CONFIG}" 210esac 211 212archive_builtin 213 214#link vmlinux.o 215info LD vmlinux.o 216modpost_link vmlinux.o 217 218# modpost vmlinux.o to check for section mismatches 219${MAKE} -f "${srctree}/scripts/Makefile.modpost" vmlinux.o 220 221# Update version 222info GEN .version 223if [ ! -r .version ]; then 224 rm -f .version; 225 echo 1 >.version; 226else 227 mv .version .old_version; 228 expr 0$(cat .old_version) + 1 >.version; 229fi; 230 231# final build of init/ 232${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init GCC_PLUGINS_CFLAGS="${GCC_PLUGINS_CFLAGS}" 233 234kallsymso="" 235kallsyms_vmlinux="" 236if [ -n "${CONFIG_KALLSYMS}" ]; then 237 238 # kallsyms support 239 # Generate section listing all symbols and add it into vmlinux 240 # It's a three step process: 241 # 1) Link .tmp_vmlinux1 so it has all symbols and sections, 242 # but __kallsyms is empty. 243 # Running kallsyms on that gives us .tmp_kallsyms1.o with 244 # the right size 245 # 2) Link .tmp_vmlinux2 so it now has a __kallsyms section of 246 # the right size, but due to the added section, some 247 # addresses have shifted. 248 # From here, we generate a correct .tmp_kallsyms2.o 249 # 2a) We may use an extra pass as this has been necessary to 250 # woraround some alignment related bugs. 251 # KALLSYMS_EXTRA_PASS=1 is used to trigger this. 252 # 3) The correct ${kallsymso} is linked into the final vmlinux. 253 # 254 # a) Verify that the System.map from vmlinux matches the map from 255 # ${kallsymso}. 256 257 kallsymso=.tmp_kallsyms2.o 258 kallsyms_vmlinux=.tmp_vmlinux2 259 260 # step 1 261 vmlinux_link "" .tmp_vmlinux1 262 kallsyms .tmp_vmlinux1 .tmp_kallsyms1.o 263 264 # step 2 265 vmlinux_link .tmp_kallsyms1.o .tmp_vmlinux2 266 kallsyms .tmp_vmlinux2 .tmp_kallsyms2.o 267 268 # step 2a 269 if [ -n "${KALLSYMS_EXTRA_PASS}" ]; then 270 kallsymso=.tmp_kallsyms3.o 271 kallsyms_vmlinux=.tmp_vmlinux3 272 273 vmlinux_link .tmp_kallsyms2.o .tmp_vmlinux3 274 275 kallsyms .tmp_vmlinux3 .tmp_kallsyms3.o 276 fi 277fi 278 279info LD vmlinux 280vmlinux_link "${kallsymso}" vmlinux 281 282if [ -n "${CONFIG_BUILDTIME_EXTABLE_SORT}" ]; then 283 info SORTEX vmlinux 284 sortextable vmlinux 285fi 286 287info SYSMAP System.map 288mksysmap vmlinux System.map 289 290# step a (see comment above) 291if [ -n "${CONFIG_KALLSYMS}" ]; then 292 mksysmap ${kallsyms_vmlinux} .tmp_System.map 293 294 if ! cmp -s System.map .tmp_System.map; then 295 echo >&2 Inconsistent kallsyms data 296 echo >&2 Try "make KALLSYMS_EXTRA_PASS=1" as a workaround 297 exit 1 298 fi 299fi 300 301# We made a new kernel - delete old version file 302rm -f .old_version 303