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 212# Update version 213info GEN .version 214if [ ! -r .version ]; then 215 rm -f .version; 216 echo 1 >.version; 217else 218 mv .version .old_version; 219 expr 0$(cat .old_version) + 1 >.version; 220fi; 221 222# final build of init/ 223${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init GCC_PLUGINS_CFLAGS="${GCC_PLUGINS_CFLAGS}" 224 225archive_builtin 226 227#link vmlinux.o 228info LD vmlinux.o 229modpost_link vmlinux.o 230 231# modpost vmlinux.o to check for section mismatches 232${MAKE} -f "${srctree}/scripts/Makefile.modpost" vmlinux.o 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 # 3) That link may have expanded the kernel image enough that 250 # more linker branch stubs / trampolines had to be added, which 251 # introduces new names, which further expands kallsyms. Do another 252 # pass if that is the case. In theory it's possible this results 253 # in even more stubs, but unlikely. 254 # KALLSYMS_EXTRA_PASS=1 may also used to debug or work around 255 # other bugs. 256 # 4) The correct ${kallsymso} is linked into the final vmlinux. 257 # 258 # a) Verify that the System.map from vmlinux matches the map from 259 # ${kallsymso}. 260 261 kallsymso=.tmp_kallsyms2.o 262 kallsyms_vmlinux=.tmp_vmlinux2 263 264 # step 1 265 vmlinux_link "" .tmp_vmlinux1 266 kallsyms .tmp_vmlinux1 .tmp_kallsyms1.o 267 268 # step 2 269 vmlinux_link .tmp_kallsyms1.o .tmp_vmlinux2 270 kallsyms .tmp_vmlinux2 .tmp_kallsyms2.o 271 272 # step 3 273 size1=$(stat -c "%s" .tmp_kallsyms1.o) 274 size2=$(stat -c "%s" .tmp_kallsyms2.o) 275 276 if [ $size1 -ne $size2 ] || [ -n "${KALLSYMS_EXTRA_PASS}" ]; then 277 kallsymso=.tmp_kallsyms3.o 278 kallsyms_vmlinux=.tmp_vmlinux3 279 280 vmlinux_link .tmp_kallsyms2.o .tmp_vmlinux3 281 282 kallsyms .tmp_vmlinux3 .tmp_kallsyms3.o 283 fi 284fi 285 286info LD vmlinux 287vmlinux_link "${kallsymso}" vmlinux 288 289if [ -n "${CONFIG_BUILDTIME_EXTABLE_SORT}" ]; then 290 info SORTEX vmlinux 291 sortextable vmlinux 292fi 293 294info SYSMAP System.map 295mksysmap vmlinux System.map 296 297# step a (see comment above) 298if [ -n "${CONFIG_KALLSYMS}" ]; then 299 mksysmap ${kallsyms_vmlinux} .tmp_System.map 300 301 if ! cmp -s System.map .tmp_System.map; then 302 echo >&2 Inconsistent kallsyms data 303 echo >&2 Try "make KALLSYMS_EXTRA_PASS=1" as a workaround 304 exit 1 305 fi 306fi 307 308# We made a new kernel - delete old version file 309rm -f .old_version 310