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