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 # GNU ld 2.35+ and lld do not allow an ET_EXEC input. 136 if is_enabled CONFIG_CPU_BIG_ENDIAN; t 139 if is_enabled CONFIG_CPU_BIG_ENDIAN; then 137 et_rel='\0\1' 140 et_rel='\0\1' 138 else 141 else 139 et_rel='\1\0' 142 et_rel='\1\0' 140 fi 143 fi 141 printf "${et_rel}" | dd of="${btf_data !! 144 printf "${et_rel}" | dd of=${2} conv=notrunc bs=1 seek=16 status=none 142 << 143 btf_vmlinux_bin_o=${btf_data} << 144 } 145 } 145 146 146 # Create ${2}.o file with all symbols from the !! 147 # Create ${2} .S file with all symbols from the ${1} object file 147 kallsyms() 148 kallsyms() 148 { 149 { 149 local kallsymopt; 150 local kallsymopt; 150 151 151 if is_enabled CONFIG_KALLSYMS_ALL; the 152 if is_enabled CONFIG_KALLSYMS_ALL; then 152 kallsymopt="${kallsymopt} --al 153 kallsymopt="${kallsymopt} --all-symbols" 153 fi 154 fi 154 155 155 if is_enabled CONFIG_KALLSYMS_ABSOLUTE 156 if is_enabled CONFIG_KALLSYMS_ABSOLUTE_PERCPU; then 156 kallsymopt="${kallsymopt} --ab 157 kallsymopt="${kallsymopt} --absolute-percpu" 157 fi 158 fi 158 159 159 info KSYMS "${2}.S" !! 160 if is_enabled CONFIG_KALLSYMS_BASE_RELATIVE; then 160 scripts/kallsyms ${kallsymopt} "${1}" !! 161 kallsymopt="${kallsymopt} --base-relative" >> 162 fi 161 163 162 info AS "${2}.o" !! 164 if is_enabled CONFIG_LTO_CLANG; then 163 ${CC} ${NOSTDINC_FLAGS} ${LINUXINCLUDE !! 165 kallsymopt="${kallsymopt} --lto-clang" 164 ${KBUILD_AFLAGS} ${KBUILD_AFLAGS !! 166 fi 165 167 166 kallsymso=${2}.o !! 168 info KSYMS ${2} >> 169 scripts/kallsyms ${kallsymopt} ${1} > ${2} 167 } 170 } 168 171 169 # Perform kallsyms for the given temporary vml !! 172 # Perform one step in kallsyms generation, including temporary linking of 170 sysmap_and_kallsyms() !! 173 # vmlinux. >> 174 kallsyms_step() 171 { 175 { 172 mksysmap "${1}" "${1}.syms" !! 176 kallsymso_prev=${kallsymso} 173 kallsyms "${1}.syms" "${1}.kallsyms" !! 177 kallsyms_vmlinux=.tmp_vmlinux.kallsyms${1} >> 178 kallsymso=${kallsyms_vmlinux}.o >> 179 kallsyms_S=${kallsyms_vmlinux}.S 174 180 175 kallsyms_sysmap=${1}.syms !! 181 vmlinux_link ${kallsyms_vmlinux} "${kallsymso_prev}" ${btf_vmlinux_bin_o} >> 182 mksysmap ${kallsyms_vmlinux} ${kallsyms_vmlinux}.syms ${kallsymso_prev} >> 183 kallsyms ${kallsyms_vmlinux}.syms ${kallsyms_S} >> 184 >> 185 info AS ${kallsymso} >> 186 ${CC} ${NOSTDINC_FLAGS} ${LINUXINCLUDE} ${KBUILD_CPPFLAGS} \ >> 187 ${KBUILD_AFLAGS} ${KBUILD_AFLAGS_KERNEL} \ >> 188 -c -o ${kallsymso} ${kallsyms_S} 176 } 189 } 177 190 178 # Create map file with all symbols from ${1} 191 # Create map file with all symbols from ${1} 179 # See mksymap for additional details 192 # See mksymap for additional details 180 mksysmap() 193 mksysmap() 181 { 194 { 182 info NM ${2} 195 info NM ${2} 183 ${NM} -n "${1}" | sed -f "${srctree}/s !! 196 ${CONFIG_SHELL} "${srctree}/scripts/mksysmap" ${1} ${2} ${3} 184 } 197 } 185 198 186 sorttable() 199 sorttable() 187 { 200 { 188 ${objtree}/scripts/sorttable ${1} 201 ${objtree}/scripts/sorttable ${1} 189 } 202 } 190 203 >> 204 # Delete output files in case of error 191 cleanup() 205 cleanup() 192 { 206 { 193 rm -f .btf.* 207 rm -f .btf.* 194 rm -f System.map 208 rm -f System.map 195 rm -f vmlinux 209 rm -f vmlinux 196 rm -f vmlinux.map 210 rm -f vmlinux.map 197 } 211 } 198 212 199 # Use "make V=1" to debug this script 213 # Use "make V=1" to debug this script 200 case "${KBUILD_VERBOSE}" in 214 case "${KBUILD_VERBOSE}" in 201 *1*) 215 *1*) 202 set -x 216 set -x 203 ;; 217 ;; 204 esac 218 esac 205 219 206 if [ "$1" = "clean" ]; then 220 if [ "$1" = "clean" ]; then 207 cleanup 221 cleanup 208 exit 0 222 exit 0 209 fi 223 fi 210 224 211 ${MAKE} -f "${srctree}/scripts/Makefile.build" 225 ${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init init/version-timestamp.o 212 226 213 btf_vmlinux_bin_o= !! 227 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 228 if is_enabled CONFIG_DEBUG_INFO_BTF; then 233 if ! gen_btf .tmp_vmlinux1; then !! 229 btf_vmlinux_bin_o=.btf.vmlinux.bin.o >> 230 if ! gen_btf .tmp_vmlinux.btf $btf_vmlinux_bin_o ; then 234 echo >&2 "Failed to generate B 231 echo >&2 "Failed to generate BTF for vmlinux" 235 echo >&2 "Try to disable CONFI 232 echo >&2 "Try to disable CONFIG_DEBUG_INFO_BTF" 236 exit 1 233 exit 1 237 fi 234 fi 238 fi 235 fi 239 236 >> 237 kallsymso="" >> 238 kallsymso_prev="" >> 239 kallsyms_vmlinux="" 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 three step process: 245 # 0) Generate a dummy __kallsyms with << 246 # 1) Link .tmp_vmlinux.kallsyms1 so i 245 # 1) Link .tmp_vmlinux.kallsyms1 so it has all symbols and sections, 247 # with a dummy __kallsyms. !! 246 # but __kallsyms is empty. 248 # Running kallsyms on that gives u 247 # Running kallsyms on that gives us .tmp_kallsyms1.o with 249 # the right size 248 # the right size 250 # 2) Link .tmp_vmlinux.kallsyms2 so i 249 # 2) Link .tmp_vmlinux.kallsyms2 so it now has a __kallsyms section of 251 # the right size, but due to the a 250 # the right size, but due to the added section, some 252 # addresses have shifted. 251 # addresses have shifted. 253 # From here, we generate a correct 252 # From here, we generate a correct .tmp_vmlinux.kallsyms2.o 254 # 3) That link may have expanded the 253 # 3) That link may have expanded the kernel image enough that 255 # more linker branch stubs / tramp 254 # more linker branch stubs / trampolines had to be added, which 256 # introduces new names, which furt 255 # introduces new names, which further expands kallsyms. Do another 257 # pass if that is the case. In the 256 # pass if that is the case. In theory it's possible this results 258 # in even more stubs, but unlikely 257 # in even more stubs, but unlikely. 259 # KALLSYMS_EXTRA_PASS=1 may also u 258 # KALLSYMS_EXTRA_PASS=1 may also used to debug or work around 260 # other bugs. 259 # other bugs. 261 # 4) The correct ${kallsymso} is link 260 # 4) The correct ${kallsymso} is linked into the final vmlinux. 262 # 261 # 263 # a) Verify that the System.map from 262 # a) Verify that the System.map from vmlinux matches the map from 264 # ${kallsymso}. 263 # ${kallsymso}. 265 264 266 # The kallsyms linking does not need d !! 265 kallsyms_step 1 267 strip_debug=1 !! 266 kallsyms_step 2 268 << 269 sysmap_and_kallsyms .tmp_vmlinux1 << 270 size1=$(${CONFIG_SHELL} "${srctree}/sc << 271 267 272 vmlinux_link .tmp_vmlinux2 !! 268 # step 3 273 sysmap_and_kallsyms .tmp_vmlinux2 !! 269 size1=$(${CONFIG_SHELL} "${srctree}/scripts/file-size.sh" ${kallsymso_prev}) 274 size2=$(${CONFIG_SHELL} "${srctree}/sc 270 size2=$(${CONFIG_SHELL} "${srctree}/scripts/file-size.sh" ${kallsymso}) 275 271 276 if [ $size1 -ne $size2 ] || [ -n "${KA 272 if [ $size1 -ne $size2 ] || [ -n "${KALLSYMS_EXTRA_PASS}" ]; then 277 vmlinux_link .tmp_vmlinux3 !! 273 kallsyms_step 3 278 sysmap_and_kallsyms .tmp_vmlin << 279 fi 274 fi 280 fi 275 fi 281 276 282 strip_debug= !! 277 vmlinux_link vmlinux "${kallsymso}" ${btf_vmlinux_bin_o} 283 << 284 vmlinux_link vmlinux << 285 278 286 # fill in BTF IDs 279 # fill in BTF IDs 287 if is_enabled CONFIG_DEBUG_INFO_BTF && is_enab 280 if is_enabled CONFIG_DEBUG_INFO_BTF && is_enabled CONFIG_BPF; then 288 info BTFIDS vmlinux 281 info BTFIDS vmlinux 289 ${RESOLVE_BTFIDS} vmlinux 282 ${RESOLVE_BTFIDS} vmlinux 290 fi 283 fi 291 284 292 mksysmap vmlinux System.map !! 285 mksysmap vmlinux System.map ${kallsymso} 293 286 294 if is_enabled CONFIG_BUILDTIME_TABLE_SORT; the 287 if is_enabled CONFIG_BUILDTIME_TABLE_SORT; then 295 info SORTTAB vmlinux 288 info SORTTAB vmlinux 296 if ! sorttable vmlinux; then 289 if ! sorttable vmlinux; then 297 echo >&2 Failed to sort kernel 290 echo >&2 Failed to sort kernel tables 298 exit 1 291 exit 1 299 fi 292 fi 300 fi 293 fi 301 294 302 # step a (see comment above) 295 # step a (see comment above) 303 if is_enabled CONFIG_KALLSYMS; then 296 if is_enabled CONFIG_KALLSYMS; then 304 if ! cmp -s System.map "${kallsyms_sys !! 297 if ! cmp -s System.map ${kallsyms_vmlinux}.syms; then 305 echo >&2 Inconsistent kallsyms 298 echo >&2 Inconsistent kallsyms data 306 echo >&2 'Try "make KALLSYMS_E 299 echo >&2 'Try "make KALLSYMS_EXTRA_PASS=1" as a workaround' 307 exit 1 300 exit 1 308 fi 301 fi 309 fi 302 fi 310 303 311 # For fixdep 304 # For fixdep 312 echo "vmlinux: $0" > .vmlinux.d 305 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.