1 #!/bin/sh 1 #!/bin/sh 2 # SPDX-License-Identifier: GPL-2.0 2 # SPDX-License-Identifier: GPL-2.0 3 # 3 # 4 # link vmlinux 4 # link vmlinux 5 # 5 # 6 # vmlinux is linked from the objects in vmlinu 6 # vmlinux is linked from the objects in vmlinux.a and $(KBUILD_VMLINUX_LIBS). 7 # vmlinux.a contains objects that are linked u 7 # vmlinux.a contains objects that are linked unconditionally. 8 # $(KBUILD_VMLINUX_LIBS) are archives which ar 8 # $(KBUILD_VMLINUX_LIBS) are archives which are linked conditionally 9 # (not within --whole-archive), and do not req 9 # (not within --whole-archive), and do not require symbol indexes added. 10 # 10 # 11 # vmlinux 11 # vmlinux 12 # ^ 12 # ^ 13 # | 13 # | 14 # +--< vmlinux.a 14 # +--< vmlinux.a 15 # | 15 # | 16 # +--< $(KBUILD_VMLINUX_LIBS) 16 # +--< $(KBUILD_VMLINUX_LIBS) 17 # | +--< lib/lib.a + more 17 # | +--< lib/lib.a + more 18 # | 18 # | 19 # +-< ${kallsymso} (see description in KALLS 19 # +-< ${kallsymso} (see description in KALLSYMS section) 20 # 20 # 21 # vmlinux version (uname -v) cannot be updated 21 # vmlinux version (uname -v) cannot be updated during normal 22 # descending-into-subdirs phase since we do no 22 # descending-into-subdirs phase since we do not yet know if we need to 23 # update vmlinux. 23 # update vmlinux. 24 # Therefore this step is delayed until just be 24 # Therefore this step is delayed until just before final link of vmlinux. 25 # 25 # 26 # System.map is generated to document addresse 26 # System.map is generated to document addresses of all kernel symbols 27 27 28 # Error out on error 28 # Error out on error 29 set -e 29 set -e 30 30 31 LD="$1" 31 LD="$1" 32 KBUILD_LDFLAGS="$2" 32 KBUILD_LDFLAGS="$2" 33 LDFLAGS_vmlinux="$3" 33 LDFLAGS_vmlinux="$3" 34 34 35 is_enabled() { 35 is_enabled() { 36 grep -q "^$1=y" include/config/auto.co 36 grep -q "^$1=y" include/config/auto.conf 37 } 37 } 38 38 39 # Nice output in kbuild format 39 # Nice output in kbuild format 40 # Will be supressed by "make -s" 40 # Will be supressed by "make -s" 41 info() 41 info() 42 { 42 { 43 printf " %-7s %s\n" "${1}" "${2}" 43 printf " %-7s %s\n" "${1}" "${2}" 44 } 44 } 45 45 46 # Link of vmlinux 46 # Link of vmlinux 47 # ${1} - output file 47 # ${1} - output file 48 vmlinux_link() 48 vmlinux_link() 49 { 49 { 50 local output=${1} 50 local output=${1} 51 local objs 51 local objs 52 local libs 52 local libs 53 local ld 53 local ld 54 local ldflags 54 local ldflags 55 local ldlibs 55 local ldlibs 56 56 57 info LD ${output} 57 info LD ${output} 58 58 59 # skip output file argument 59 # skip output file argument 60 shift 60 shift 61 61 62 if is_enabled CONFIG_LTO_CLANG || is_e 62 if is_enabled CONFIG_LTO_CLANG || is_enabled CONFIG_X86_KERNEL_IBT; then 63 # Use vmlinux.o instead of per 63 # Use vmlinux.o instead of performing the slow LTO link again. 64 objs=vmlinux.o 64 objs=vmlinux.o 65 libs= 65 libs= 66 else 66 else 67 objs=vmlinux.a 67 objs=vmlinux.a 68 libs="${KBUILD_VMLINUX_LIBS}" 68 libs="${KBUILD_VMLINUX_LIBS}" 69 fi 69 fi 70 70 71 if is_enabled CONFIG_MODULES; then 71 if is_enabled CONFIG_MODULES; then 72 objs="${objs} .vmlinux.export. 72 objs="${objs} .vmlinux.export.o" 73 fi 73 fi 74 74 75 objs="${objs} init/version-timestamp.o 75 objs="${objs} init/version-timestamp.o" 76 76 77 if [ "${SRCARCH}" = "um" ]; then 77 if [ "${SRCARCH}" = "um" ]; then 78 wl=-Wl, 78 wl=-Wl, 79 ld="${CC}" 79 ld="${CC}" 80 ldflags="${CFLAGS_vmlinux}" 80 ldflags="${CFLAGS_vmlinux}" 81 ldlibs="-lutil -lrt -lpthread" 81 ldlibs="-lutil -lrt -lpthread" 82 else 82 else 83 wl= 83 wl= 84 ld="${LD}" 84 ld="${LD}" 85 ldflags="${KBUILD_LDFLAGS} ${L 85 ldflags="${KBUILD_LDFLAGS} ${LDFLAGS_vmlinux}" 86 ldlibs= 86 ldlibs= 87 fi 87 fi 88 88 89 ldflags="${ldflags} ${wl}--script=${ob 89 ldflags="${ldflags} ${wl}--script=${objtree}/${KBUILD_LDS}" 90 90 91 # The kallsyms linking does not need d 91 # The kallsyms linking does not need debug symbols included. 92 if [ -n "${strip_debug}" ] ; then 92 if [ -n "${strip_debug}" ] ; then 93 ldflags="${ldflags} ${wl}--str 93 ldflags="${ldflags} ${wl}--strip-debug" 94 fi 94 fi 95 95 96 if is_enabled CONFIG_VMLINUX_MAP; then 96 if is_enabled CONFIG_VMLINUX_MAP; then 97 ldflags="${ldflags} ${wl}-Map= 97 ldflags="${ldflags} ${wl}-Map=${output}.map" 98 fi 98 fi 99 99 100 ${ld} ${ldflags} -o ${output} 100 ${ld} ${ldflags} -o ${output} \ 101 ${wl}--whole-archive ${objs} $ 101 ${wl}--whole-archive ${objs} ${wl}--no-whole-archive \ 102 ${wl}--start-group ${libs} ${w 102 ${wl}--start-group ${libs} ${wl}--end-group \ 103 ${kallsymso} ${btf_vmlinux_bin 103 ${kallsymso} ${btf_vmlinux_bin_o} ${ldlibs} 104 } 104 } 105 105 106 # generate .BTF typeinfo from DWARF debuginfo 106 # generate .BTF typeinfo from DWARF debuginfo 107 # ${1} - vmlinux image 107 # ${1} - vmlinux image 108 gen_btf() 108 gen_btf() 109 { 109 { 110 local pahole_ver 110 local pahole_ver 111 local btf_data=${1}.btf.o 111 local btf_data=${1}.btf.o 112 112 113 if ! [ -x "$(command -v ${PAHOLE})" ]; 113 if ! [ -x "$(command -v ${PAHOLE})" ]; then 114 echo >&2 "BTF: ${1}: pahole ($ 114 echo >&2 "BTF: ${1}: pahole (${PAHOLE}) is not available" 115 return 1 115 return 1 116 fi 116 fi 117 117 118 pahole_ver=$(${PAHOLE} --version | sed 118 pahole_ver=$(${PAHOLE} --version | sed -E 's/v([0-9]+)\.([0-9]+)/\1\2/') 119 if [ "${pahole_ver}" -lt "116" ]; then 119 if [ "${pahole_ver}" -lt "116" ]; then 120 echo >&2 "BTF: ${1}: pahole ve 120 echo >&2 "BTF: ${1}: pahole version $(${PAHOLE} --version) is too old, need at least v1.16" 121 return 1 121 return 1 122 fi 122 fi 123 123 124 info BTF "${btf_data}" 124 info BTF "${btf_data}" 125 LLVM_OBJCOPY="${OBJCOPY}" ${PAHOLE} -J 125 LLVM_OBJCOPY="${OBJCOPY}" ${PAHOLE} -J ${PAHOLE_FLAGS} ${1} 126 126 127 # Create ${btf_data} which contains ju 127 # Create ${btf_data} which contains just .BTF section but no symbols. Add 128 # SHF_ALLOC because .BTF will be part 128 # SHF_ALLOC because .BTF will be part of the vmlinux image. --strip-all 129 # deletes all symbols including __star 129 # deletes all symbols including __start_BTF and __stop_BTF, which will 130 # be redefined in the linker script. A 130 # be redefined in the linker script. Add 2>/dev/null to suppress GNU 131 # objcopy warnings: "empty loadable se 131 # objcopy warnings: "empty loadable segment detected at ..." 132 ${OBJCOPY} --only-section=.BTF --set-s 132 ${OBJCOPY} --only-section=.BTF --set-section-flags .BTF=alloc,readonly \ 133 --strip-all ${1} "${btf_data}" 133 --strip-all ${1} "${btf_data}" 2>/dev/null 134 # Change e_type to ET_REL so that it c 134 # Change e_type to ET_REL so that it can be used to link final vmlinux. 135 # GNU ld 2.35+ and lld do not allow an 135 # GNU ld 2.35+ and lld do not allow an ET_EXEC input. 136 if is_enabled CONFIG_CPU_BIG_ENDIAN; t 136 if is_enabled CONFIG_CPU_BIG_ENDIAN; then 137 et_rel='\0\1' 137 et_rel='\0\1' 138 else 138 else 139 et_rel='\1\0' 139 et_rel='\1\0' 140 fi 140 fi 141 printf "${et_rel}" | dd of="${btf_data 141 printf "${et_rel}" | dd of="${btf_data}" conv=notrunc bs=1 seek=16 status=none 142 142 143 btf_vmlinux_bin_o=${btf_data} 143 btf_vmlinux_bin_o=${btf_data} 144 } 144 } 145 145 146 # Create ${2}.o file with all symbols from the 146 # Create ${2}.o file with all symbols from the ${1} object file 147 kallsyms() 147 kallsyms() 148 { 148 { 149 local kallsymopt; 149 local kallsymopt; 150 150 151 if is_enabled CONFIG_KALLSYMS_ALL; the 151 if is_enabled CONFIG_KALLSYMS_ALL; then 152 kallsymopt="${kallsymopt} --al 152 kallsymopt="${kallsymopt} --all-symbols" 153 fi 153 fi 154 154 155 if is_enabled CONFIG_KALLSYMS_ABSOLUTE 155 if is_enabled CONFIG_KALLSYMS_ABSOLUTE_PERCPU; then 156 kallsymopt="${kallsymopt} --ab 156 kallsymopt="${kallsymopt} --absolute-percpu" 157 fi 157 fi 158 158 159 info KSYMS "${2}.S" 159 info KSYMS "${2}.S" 160 scripts/kallsyms ${kallsymopt} "${1}" 160 scripts/kallsyms ${kallsymopt} "${1}" > "${2}.S" 161 161 162 info AS "${2}.o" 162 info AS "${2}.o" 163 ${CC} ${NOSTDINC_FLAGS} ${LINUXINCLUDE 163 ${CC} ${NOSTDINC_FLAGS} ${LINUXINCLUDE} ${KBUILD_CPPFLAGS} \ 164 ${KBUILD_AFLAGS} ${KBUILD_AFLAGS 164 ${KBUILD_AFLAGS} ${KBUILD_AFLAGS_KERNEL} -c -o "${2}.o" "${2}.S" 165 165 166 kallsymso=${2}.o 166 kallsymso=${2}.o 167 } 167 } 168 168 169 # Perform kallsyms for the given temporary vml 169 # Perform kallsyms for the given temporary vmlinux. 170 sysmap_and_kallsyms() 170 sysmap_and_kallsyms() 171 { 171 { 172 mksysmap "${1}" "${1}.syms" 172 mksysmap "${1}" "${1}.syms" 173 kallsyms "${1}.syms" "${1}.kallsyms" 173 kallsyms "${1}.syms" "${1}.kallsyms" 174 174 175 kallsyms_sysmap=${1}.syms 175 kallsyms_sysmap=${1}.syms 176 } 176 } 177 177 178 # Create map file with all symbols from ${1} 178 # Create map file with all symbols from ${1} 179 # See mksymap for additional details 179 # See mksymap for additional details 180 mksysmap() 180 mksysmap() 181 { 181 { 182 info NM ${2} 182 info NM ${2} 183 ${NM} -n "${1}" | sed -f "${srctree}/s 183 ${NM} -n "${1}" | sed -f "${srctree}/scripts/mksysmap" > "${2}" 184 } 184 } 185 185 186 sorttable() 186 sorttable() 187 { 187 { 188 ${objtree}/scripts/sorttable ${1} 188 ${objtree}/scripts/sorttable ${1} 189 } 189 } 190 190 191 cleanup() 191 cleanup() 192 { 192 { 193 rm -f .btf.* 193 rm -f .btf.* 194 rm -f System.map 194 rm -f System.map 195 rm -f vmlinux 195 rm -f vmlinux 196 rm -f vmlinux.map 196 rm -f vmlinux.map 197 } 197 } 198 198 199 # Use "make V=1" to debug this script 199 # Use "make V=1" to debug this script 200 case "${KBUILD_VERBOSE}" in 200 case "${KBUILD_VERBOSE}" in 201 *1*) 201 *1*) 202 set -x 202 set -x 203 ;; 203 ;; 204 esac 204 esac 205 205 206 if [ "$1" = "clean" ]; then 206 if [ "$1" = "clean" ]; then 207 cleanup 207 cleanup 208 exit 0 208 exit 0 209 fi 209 fi 210 210 211 ${MAKE} -f "${srctree}/scripts/Makefile.build" 211 ${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init init/version-timestamp.o 212 212 213 btf_vmlinux_bin_o= 213 btf_vmlinux_bin_o= 214 kallsymso= 214 kallsymso= 215 strip_debug= 215 strip_debug= 216 216 217 if is_enabled CONFIG_KALLSYMS; then 217 if is_enabled CONFIG_KALLSYMS; then 218 truncate -s0 .tmp_vmlinux.kallsyms0.sy 218 truncate -s0 .tmp_vmlinux.kallsyms0.syms 219 kallsyms .tmp_vmlinux.kallsyms0.syms . 219 kallsyms .tmp_vmlinux.kallsyms0.syms .tmp_vmlinux0.kallsyms 220 fi 220 fi 221 221 222 if is_enabled CONFIG_KALLSYMS || is_enabled CO 222 if is_enabled CONFIG_KALLSYMS || is_enabled CONFIG_DEBUG_INFO_BTF; then 223 223 224 # The kallsyms linking does not need d 224 # The kallsyms linking does not need debug symbols, but the BTF does. 225 if ! is_enabled CONFIG_DEBUG_INFO_BTF; 225 if ! is_enabled CONFIG_DEBUG_INFO_BTF; then 226 strip_debug=1 226 strip_debug=1 227 fi 227 fi 228 228 229 vmlinux_link .tmp_vmlinux1 229 vmlinux_link .tmp_vmlinux1 230 fi 230 fi 231 231 232 if is_enabled CONFIG_DEBUG_INFO_BTF; then 232 if is_enabled CONFIG_DEBUG_INFO_BTF; then 233 if ! gen_btf .tmp_vmlinux1; then 233 if ! gen_btf .tmp_vmlinux1; then 234 echo >&2 "Failed to generate B 234 echo >&2 "Failed to generate BTF for vmlinux" 235 echo >&2 "Try to disable CONFI 235 echo >&2 "Try to disable CONFIG_DEBUG_INFO_BTF" 236 exit 1 236 exit 1 237 fi 237 fi 238 fi 238 fi 239 239 240 if is_enabled CONFIG_KALLSYMS; then 240 if is_enabled CONFIG_KALLSYMS; then 241 241 242 # kallsyms support 242 # kallsyms support 243 # Generate section listing all symbols 243 # Generate section listing all symbols and add it into vmlinux 244 # It's a four step process: 244 # It's a four step process: 245 # 0) Generate a dummy __kallsyms with 245 # 0) Generate a dummy __kallsyms with empty symbol list. 246 # 1) Link .tmp_vmlinux.kallsyms1 so i 246 # 1) Link .tmp_vmlinux.kallsyms1 so it has all symbols and sections, 247 # with a dummy __kallsyms. 247 # with a dummy __kallsyms. 248 # Running kallsyms on that gives u 248 # Running kallsyms on that gives us .tmp_kallsyms1.o with 249 # the right size 249 # the right size 250 # 2) Link .tmp_vmlinux.kallsyms2 so i 250 # 2) Link .tmp_vmlinux.kallsyms2 so it now has a __kallsyms section of 251 # the right size, but due to the a 251 # the right size, but due to the added section, some 252 # addresses have shifted. 252 # addresses have shifted. 253 # From here, we generate a correct 253 # From here, we generate a correct .tmp_vmlinux.kallsyms2.o 254 # 3) That link may have expanded the 254 # 3) That link may have expanded the kernel image enough that 255 # more linker branch stubs / tramp 255 # more linker branch stubs / trampolines had to be added, which 256 # introduces new names, which furt 256 # introduces new names, which further expands kallsyms. Do another 257 # pass if that is the case. In the 257 # pass if that is the case. In theory it's possible this results 258 # in even more stubs, but unlikely 258 # in even more stubs, but unlikely. 259 # KALLSYMS_EXTRA_PASS=1 may also u 259 # KALLSYMS_EXTRA_PASS=1 may also used to debug or work around 260 # other bugs. 260 # other bugs. 261 # 4) The correct ${kallsymso} is link 261 # 4) The correct ${kallsymso} is linked into the final vmlinux. 262 # 262 # 263 # a) Verify that the System.map from 263 # a) Verify that the System.map from vmlinux matches the map from 264 # ${kallsymso}. 264 # ${kallsymso}. 265 265 266 # The kallsyms linking does not need d 266 # The kallsyms linking does not need debug symbols included. 267 strip_debug=1 267 strip_debug=1 268 268 269 sysmap_and_kallsyms .tmp_vmlinux1 269 sysmap_and_kallsyms .tmp_vmlinux1 270 size1=$(${CONFIG_SHELL} "${srctree}/sc 270 size1=$(${CONFIG_SHELL} "${srctree}/scripts/file-size.sh" ${kallsymso}) 271 271 272 vmlinux_link .tmp_vmlinux2 272 vmlinux_link .tmp_vmlinux2 273 sysmap_and_kallsyms .tmp_vmlinux2 273 sysmap_and_kallsyms .tmp_vmlinux2 274 size2=$(${CONFIG_SHELL} "${srctree}/sc 274 size2=$(${CONFIG_SHELL} "${srctree}/scripts/file-size.sh" ${kallsymso}) 275 275 276 if [ $size1 -ne $size2 ] || [ -n "${KA 276 if [ $size1 -ne $size2 ] || [ -n "${KALLSYMS_EXTRA_PASS}" ]; then 277 vmlinux_link .tmp_vmlinux3 277 vmlinux_link .tmp_vmlinux3 278 sysmap_and_kallsyms .tmp_vmlin 278 sysmap_and_kallsyms .tmp_vmlinux3 279 fi 279 fi 280 fi 280 fi 281 281 282 strip_debug= 282 strip_debug= 283 283 284 vmlinux_link vmlinux 284 vmlinux_link vmlinux 285 285 286 # fill in BTF IDs 286 # fill in BTF IDs 287 if is_enabled CONFIG_DEBUG_INFO_BTF && is_enab 287 if is_enabled CONFIG_DEBUG_INFO_BTF && is_enabled CONFIG_BPF; then 288 info BTFIDS vmlinux 288 info BTFIDS vmlinux 289 ${RESOLVE_BTFIDS} vmlinux 289 ${RESOLVE_BTFIDS} vmlinux 290 fi 290 fi 291 291 292 mksysmap vmlinux System.map 292 mksysmap vmlinux System.map 293 293 294 if is_enabled CONFIG_BUILDTIME_TABLE_SORT; the 294 if is_enabled CONFIG_BUILDTIME_TABLE_SORT; then 295 info SORTTAB vmlinux 295 info SORTTAB vmlinux 296 if ! sorttable vmlinux; then 296 if ! sorttable vmlinux; then 297 echo >&2 Failed to sort kernel 297 echo >&2 Failed to sort kernel tables 298 exit 1 298 exit 1 299 fi 299 fi 300 fi 300 fi 301 301 302 # step a (see comment above) 302 # step a (see comment above) 303 if is_enabled CONFIG_KALLSYMS; then 303 if is_enabled CONFIG_KALLSYMS; then 304 if ! cmp -s System.map "${kallsyms_sys 304 if ! cmp -s System.map "${kallsyms_sysmap}"; then 305 echo >&2 Inconsistent kallsyms 305 echo >&2 Inconsistent kallsyms data 306 echo >&2 'Try "make KALLSYMS_E 306 echo >&2 'Try "make KALLSYMS_EXTRA_PASS=1" as a workaround' 307 exit 1 307 exit 1 308 fi 308 fi 309 fi 309 fi 310 310 311 # For fixdep 311 # For fixdep 312 echo "vmlinux: $0" > .vmlinux.d 312 echo "vmlinux: $0" > .vmlinux.d
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.