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 selected by $(KBUILD_VMLINUX_OBJS) and 7 # vmlinux.a contains objects that are linked u !! 7 # $(KBUILD_VMLINUX_LIBS). Most are built-in.a files from top-level directories >> 8 # in the kernel tree, others are specified in arch/$(ARCH)/Makefile. 8 # $(KBUILD_VMLINUX_LIBS) are archives which ar 9 # $(KBUILD_VMLINUX_LIBS) are archives which are linked conditionally 9 # (not within --whole-archive), and do not req 10 # (not within --whole-archive), and do not require symbol indexes added. 10 # 11 # 11 # vmlinux 12 # vmlinux 12 # ^ 13 # ^ 13 # | 14 # | 14 # +--< vmlinux.a !! 15 # +--< $(KBUILD_VMLINUX_OBJS) >> 16 # | +--< init/built-in.a drivers/built-in.a mm/built-in.a + more 15 # | 17 # | 16 # +--< $(KBUILD_VMLINUX_LIBS) 18 # +--< $(KBUILD_VMLINUX_LIBS) 17 # | +--< lib/lib.a + more 19 # | +--< lib/lib.a + more 18 # | 20 # | 19 # +-< ${kallsymso} (see description in KALLS 21 # +-< ${kallsymso} (see description in KALLSYMS section) 20 # 22 # 21 # vmlinux version (uname -v) cannot be updated 23 # vmlinux version (uname -v) cannot be updated during normal 22 # descending-into-subdirs phase since we do no 24 # descending-into-subdirs phase since we do not yet know if we need to 23 # update vmlinux. 25 # update vmlinux. 24 # Therefore this step is delayed until just be 26 # Therefore this step is delayed until just before final link of vmlinux. 25 # 27 # 26 # System.map is generated to document addresse 28 # System.map is generated to document addresses of all kernel symbols 27 29 28 # Error out on error 30 # Error out on error 29 set -e 31 set -e 30 32 31 LD="$1" 33 LD="$1" 32 KBUILD_LDFLAGS="$2" 34 KBUILD_LDFLAGS="$2" 33 LDFLAGS_vmlinux="$3" 35 LDFLAGS_vmlinux="$3" 34 36 35 is_enabled() { 37 is_enabled() { 36 grep -q "^$1=y" include/config/auto.co 38 grep -q "^$1=y" include/config/auto.conf 37 } 39 } 38 40 39 # Nice output in kbuild format 41 # Nice output in kbuild format 40 # Will be supressed by "make -s" 42 # Will be supressed by "make -s" 41 info() 43 info() 42 { 44 { 43 printf " %-7s %s\n" "${1}" "${2}" 45 printf " %-7s %s\n" "${1}" "${2}" 44 } 46 } 45 47 46 # Link of vmlinux 48 # Link of vmlinux 47 # ${1} - output file 49 # ${1} - output file >> 50 # ${2}, ${3}, ... - optional extra .o files 48 vmlinux_link() 51 vmlinux_link() 49 { 52 { 50 local output=${1} 53 local output=${1} 51 local objs 54 local objs 52 local libs 55 local libs 53 local ld 56 local ld 54 local ldflags 57 local ldflags 55 local ldlibs 58 local ldlibs 56 59 57 info LD ${output} 60 info LD ${output} 58 61 59 # skip output file argument 62 # skip output file argument 60 shift 63 shift 61 64 62 if is_enabled CONFIG_LTO_CLANG || is_e 65 if is_enabled CONFIG_LTO_CLANG || is_enabled CONFIG_X86_KERNEL_IBT; then 63 # Use vmlinux.o instead of per 66 # Use vmlinux.o instead of performing the slow LTO link again. 64 objs=vmlinux.o 67 objs=vmlinux.o 65 libs= 68 libs= 66 else 69 else 67 objs=vmlinux.a !! 70 objs="${KBUILD_VMLINUX_OBJS}" 68 libs="${KBUILD_VMLINUX_LIBS}" 71 libs="${KBUILD_VMLINUX_LIBS}" 69 fi 72 fi 70 73 71 if is_enabled CONFIG_MODULES; then 74 if is_enabled CONFIG_MODULES; then 72 objs="${objs} .vmlinux.export. 75 objs="${objs} .vmlinux.export.o" 73 fi 76 fi 74 77 75 objs="${objs} init/version-timestamp.o << 76 << 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" 161 !! 157 fi 162 info AS "${2}.o" << 163 ${CC} ${NOSTDINC_FLAGS} ${LINUXINCLUDE << 164 ${KBUILD_AFLAGS} ${KBUILD_AFLAGS << 165 158 166 kallsymso=${2}.o !! 159 info KSYMS ${2} >> 160 ${NM} -n ${1} | scripts/kallsyms ${kallsymopt} > ${2} 167 } 161 } 168 162 169 # Perform kallsyms for the given temporary vml !! 163 # Perform one step in kallsyms generation, including temporary linking of 170 sysmap_and_kallsyms() !! 164 # vmlinux. >> 165 kallsyms_step() 171 { 166 { 172 mksysmap "${1}" "${1}.syms" !! 167 kallsymso_prev=${kallsymso} 173 kallsyms "${1}.syms" "${1}.kallsyms" !! 168 kallsyms_vmlinux=.tmp_vmlinux.kallsyms${1} >> 169 kallsymso=${kallsyms_vmlinux}.o >> 170 kallsyms_S=${kallsyms_vmlinux}.S 174 171 175 kallsyms_sysmap=${1}.syms !! 172 vmlinux_link ${kallsyms_vmlinux} "${kallsymso_prev}" ${btf_vmlinux_bin_o} >> 173 kallsyms ${kallsyms_vmlinux} ${kallsyms_S} >> 174 >> 175 info AS ${kallsyms_S} >> 176 ${CC} ${NOSTDINC_FLAGS} ${LINUXINCLUDE} ${KBUILD_CPPFLAGS} \ >> 177 ${KBUILD_AFLAGS} ${KBUILD_AFLAGS_KERNEL} \ >> 178 -c -o ${kallsymso} ${kallsyms_S} 176 } 179 } 177 180 178 # Create map file with all symbols from ${1} 181 # Create map file with all symbols from ${1} 179 # See mksymap for additional details 182 # See mksymap for additional details 180 mksysmap() 183 mksysmap() 181 { 184 { 182 info NM ${2} !! 185 ${CONFIG_SHELL} "${srctree}/scripts/mksysmap" ${1} ${2} 183 ${NM} -n "${1}" | sed -f "${srctree}/s << 184 } 186 } 185 187 186 sorttable() 188 sorttable() 187 { 189 { 188 ${objtree}/scripts/sorttable ${1} 190 ${objtree}/scripts/sorttable ${1} 189 } 191 } 190 192 >> 193 # Delete output files in case of error 191 cleanup() 194 cleanup() 192 { 195 { 193 rm -f .btf.* 196 rm -f .btf.* 194 rm -f System.map 197 rm -f System.map 195 rm -f vmlinux 198 rm -f vmlinux 196 rm -f vmlinux.map 199 rm -f vmlinux.map >> 200 rm -f .vmlinux.objs >> 201 rm -f .vmlinux.export.c 197 } 202 } 198 203 199 # Use "make V=1" to debug this script 204 # Use "make V=1" to debug this script 200 case "${KBUILD_VERBOSE}" in 205 case "${KBUILD_VERBOSE}" in 201 *1*) 206 *1*) 202 set -x 207 set -x 203 ;; 208 ;; 204 esac 209 esac 205 210 206 if [ "$1" = "clean" ]; then 211 if [ "$1" = "clean" ]; then 207 cleanup 212 cleanup 208 exit 0 213 exit 0 209 fi 214 fi 210 215 211 ${MAKE} -f "${srctree}/scripts/Makefile.build" !! 216 # Update version >> 217 info GEN .version >> 218 if [ -r .version ]; then >> 219 VERSION=$(expr 0$(cat .version) + 1) >> 220 echo $VERSION > .version >> 221 else >> 222 rm -f .version >> 223 echo 1 > .version >> 224 fi; 212 225 213 btf_vmlinux_bin_o= !! 226 # final build of init/ 214 kallsymso= !! 227 ${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init need-builtin=1 215 strip_debug= << 216 228 217 if is_enabled CONFIG_KALLSYMS; then !! 229 #link vmlinux.o 218 truncate -s0 .tmp_vmlinux.kallsyms0.sy !! 230 ${MAKE} -f "${srctree}/scripts/Makefile.vmlinux_o" 219 kallsyms .tmp_vmlinux.kallsyms0.syms . << 220 fi << 221 << 222 if is_enabled CONFIG_KALLSYMS || is_enabled CO << 223 231 224 # The kallsyms linking does not need d !! 232 # Generate the list of in-tree objects in vmlinux 225 if ! is_enabled CONFIG_DEBUG_INFO_BTF; !! 233 # 226 strip_debug=1 !! 234 # This is used to retrieve symbol versions generated by genksyms. 227 fi !! 235 for f in ${KBUILD_VMLINUX_OBJS} ${KBUILD_VMLINUX_LIBS}; do >> 236 case ${f} in >> 237 *libgcc.a) >> 238 # Some architectures do '$(CC) --print-libgcc-file-name' to >> 239 # borrow libgcc.a from the toolchain. >> 240 # There is no EXPORT_SYMBOL in external objects. Ignore this. >> 241 ;; >> 242 *.a) >> 243 ${AR} t ${f} ;; >> 244 *) >> 245 echo ${f} ;; >> 246 esac >> 247 done > .vmlinux.objs >> 248 >> 249 # modpost vmlinux.o to check for section mismatches >> 250 ${MAKE} -f "${srctree}/scripts/Makefile.modpost" MODPOST_VMLINUX=1 >> 251 >> 252 info MODINFO modules.builtin.modinfo >> 253 ${OBJCOPY} -j .modinfo -O binary vmlinux.o modules.builtin.modinfo >> 254 info GEN modules.builtin >> 255 # The second line aids cases where multiple modules share the same object. >> 256 tr '\0' '\n' < modules.builtin.modinfo | sed -n 's/^[[:alnum:]:_]*\.file=//p' | >> 257 tr ' ' '\n' | uniq | sed -e 's:^:kernel/:' -e 's/$/.ko/' > modules.builtin 228 258 229 vmlinux_link .tmp_vmlinux1 !! 259 if is_enabled CONFIG_MODULES; then >> 260 ${MAKE} -f "${srctree}/scripts/Makefile.vmlinux" .vmlinux.export.o 230 fi 261 fi 231 262 >> 263 btf_vmlinux_bin_o="" 232 if is_enabled CONFIG_DEBUG_INFO_BTF; then 264 if is_enabled CONFIG_DEBUG_INFO_BTF; then 233 if ! gen_btf .tmp_vmlinux1; then !! 265 btf_vmlinux_bin_o=.btf.vmlinux.bin.o >> 266 if ! gen_btf .tmp_vmlinux.btf $btf_vmlinux_bin_o ; then 234 echo >&2 "Failed to generate B 267 echo >&2 "Failed to generate BTF for vmlinux" 235 echo >&2 "Try to disable CONFI 268 echo >&2 "Try to disable CONFIG_DEBUG_INFO_BTF" 236 exit 1 269 exit 1 237 fi 270 fi 238 fi 271 fi 239 272 >> 273 kallsymso="" >> 274 kallsymso_prev="" >> 275 kallsyms_vmlinux="" 240 if is_enabled CONFIG_KALLSYMS; then 276 if is_enabled CONFIG_KALLSYMS; then 241 277 242 # kallsyms support 278 # kallsyms support 243 # Generate section listing all symbols 279 # Generate section listing all symbols and add it into vmlinux 244 # It's a four step process: !! 280 # It's a three step process: 245 # 0) Generate a dummy __kallsyms with << 246 # 1) Link .tmp_vmlinux.kallsyms1 so i 281 # 1) Link .tmp_vmlinux.kallsyms1 so it has all symbols and sections, 247 # with a dummy __kallsyms. !! 282 # but __kallsyms is empty. 248 # Running kallsyms on that gives u 283 # Running kallsyms on that gives us .tmp_kallsyms1.o with 249 # the right size 284 # the right size 250 # 2) Link .tmp_vmlinux.kallsyms2 so i 285 # 2) Link .tmp_vmlinux.kallsyms2 so it now has a __kallsyms section of 251 # the right size, but due to the a 286 # the right size, but due to the added section, some 252 # addresses have shifted. 287 # addresses have shifted. 253 # From here, we generate a correct 288 # From here, we generate a correct .tmp_vmlinux.kallsyms2.o 254 # 3) That link may have expanded the 289 # 3) That link may have expanded the kernel image enough that 255 # more linker branch stubs / tramp 290 # more linker branch stubs / trampolines had to be added, which 256 # introduces new names, which furt 291 # introduces new names, which further expands kallsyms. Do another 257 # pass if that is the case. In the 292 # pass if that is the case. In theory it's possible this results 258 # in even more stubs, but unlikely 293 # in even more stubs, but unlikely. 259 # KALLSYMS_EXTRA_PASS=1 may also u 294 # KALLSYMS_EXTRA_PASS=1 may also used to debug or work around 260 # other bugs. 295 # other bugs. 261 # 4) The correct ${kallsymso} is link 296 # 4) The correct ${kallsymso} is linked into the final vmlinux. 262 # 297 # 263 # a) Verify that the System.map from 298 # a) Verify that the System.map from vmlinux matches the map from 264 # ${kallsymso}. 299 # ${kallsymso}. 265 300 266 # The kallsyms linking does not need d !! 301 kallsyms_step 1 267 strip_debug=1 !! 302 kallsyms_step 2 268 << 269 sysmap_and_kallsyms .tmp_vmlinux1 << 270 size1=$(${CONFIG_SHELL} "${srctree}/sc << 271 303 272 vmlinux_link .tmp_vmlinux2 !! 304 # step 3 273 sysmap_and_kallsyms .tmp_vmlinux2 !! 305 size1=$(${CONFIG_SHELL} "${srctree}/scripts/file-size.sh" ${kallsymso_prev}) 274 size2=$(${CONFIG_SHELL} "${srctree}/sc 306 size2=$(${CONFIG_SHELL} "${srctree}/scripts/file-size.sh" ${kallsymso}) 275 307 276 if [ $size1 -ne $size2 ] || [ -n "${KA 308 if [ $size1 -ne $size2 ] || [ -n "${KALLSYMS_EXTRA_PASS}" ]; then 277 vmlinux_link .tmp_vmlinux3 !! 309 kallsyms_step 3 278 sysmap_and_kallsyms .tmp_vmlin << 279 fi 310 fi 280 fi 311 fi 281 312 282 strip_debug= !! 313 vmlinux_link vmlinux "${kallsymso}" ${btf_vmlinux_bin_o} 283 << 284 vmlinux_link vmlinux << 285 314 286 # fill in BTF IDs 315 # fill in BTF IDs 287 if is_enabled CONFIG_DEBUG_INFO_BTF && is_enab 316 if is_enabled CONFIG_DEBUG_INFO_BTF && is_enabled CONFIG_BPF; then 288 info BTFIDS vmlinux 317 info BTFIDS vmlinux 289 ${RESOLVE_BTFIDS} vmlinux 318 ${RESOLVE_BTFIDS} vmlinux 290 fi 319 fi 291 320 >> 321 info SYSMAP System.map 292 mksysmap vmlinux System.map 322 mksysmap vmlinux System.map 293 323 294 if is_enabled CONFIG_BUILDTIME_TABLE_SORT; the 324 if is_enabled CONFIG_BUILDTIME_TABLE_SORT; then 295 info SORTTAB vmlinux 325 info SORTTAB vmlinux 296 if ! sorttable vmlinux; then 326 if ! sorttable vmlinux; then 297 echo >&2 Failed to sort kernel 327 echo >&2 Failed to sort kernel tables 298 exit 1 328 exit 1 299 fi 329 fi 300 fi 330 fi 301 331 302 # step a (see comment above) 332 # step a (see comment above) 303 if is_enabled CONFIG_KALLSYMS; then 333 if is_enabled CONFIG_KALLSYMS; then 304 if ! cmp -s System.map "${kallsyms_sys !! 334 mksysmap ${kallsyms_vmlinux} .tmp_System.map >> 335 >> 336 if ! cmp -s System.map .tmp_System.map; then 305 echo >&2 Inconsistent kallsyms 337 echo >&2 Inconsistent kallsyms data 306 echo >&2 'Try "make KALLSYMS_E !! 338 echo >&2 Try "make KALLSYMS_EXTRA_PASS=1" as a workaround 307 exit 1 339 exit 1 308 fi 340 fi 309 fi 341 fi 310 342 311 # For fixdep 343 # For fixdep 312 echo "vmlinux: $0" > .vmlinux.d 344 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.