162306a36Sopenharmony_ci#!/bin/sh 262306a36Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0 362306a36Sopenharmony_ci# 462306a36Sopenharmony_ci# link vmlinux 562306a36Sopenharmony_ci# 662306a36Sopenharmony_ci# vmlinux is linked from the objects in vmlinux.a and $(KBUILD_VMLINUX_LIBS). 762306a36Sopenharmony_ci# vmlinux.a contains objects that are linked unconditionally. 862306a36Sopenharmony_ci# $(KBUILD_VMLINUX_LIBS) are archives which are linked conditionally 962306a36Sopenharmony_ci# (not within --whole-archive), and do not require symbol indexes added. 1062306a36Sopenharmony_ci# 1162306a36Sopenharmony_ci# vmlinux 1262306a36Sopenharmony_ci# ^ 1362306a36Sopenharmony_ci# | 1462306a36Sopenharmony_ci# +--< vmlinux.a 1562306a36Sopenharmony_ci# | 1662306a36Sopenharmony_ci# +--< $(KBUILD_VMLINUX_LIBS) 1762306a36Sopenharmony_ci# | +--< lib/lib.a + more 1862306a36Sopenharmony_ci# | 1962306a36Sopenharmony_ci# +-< ${kallsymso} (see description in KALLSYMS section) 2062306a36Sopenharmony_ci# 2162306a36Sopenharmony_ci# vmlinux version (uname -v) cannot be updated during normal 2262306a36Sopenharmony_ci# descending-into-subdirs phase since we do not yet know if we need to 2362306a36Sopenharmony_ci# update vmlinux. 2462306a36Sopenharmony_ci# Therefore this step is delayed until just before final link of vmlinux. 2562306a36Sopenharmony_ci# 2662306a36Sopenharmony_ci# System.map is generated to document addresses of all kernel symbols 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci# Error out on error 2962306a36Sopenharmony_ciset -e 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ciLD="$1" 3262306a36Sopenharmony_ciKBUILD_LDFLAGS="$2" 3362306a36Sopenharmony_ciLDFLAGS_vmlinux="$3" 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ciis_enabled() { 3662306a36Sopenharmony_ci grep -q "^$1=y" include/config/auto.conf 3762306a36Sopenharmony_ci} 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci# Nice output in kbuild format 4062306a36Sopenharmony_ci# Will be supressed by "make -s" 4162306a36Sopenharmony_ciinfo() 4262306a36Sopenharmony_ci{ 4362306a36Sopenharmony_ci printf " %-7s %s\n" "${1}" "${2}" 4462306a36Sopenharmony_ci} 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci# Link of vmlinux 4762306a36Sopenharmony_ci# ${1} - output file 4862306a36Sopenharmony_ci# ${2}, ${3}, ... - optional extra .o files 4962306a36Sopenharmony_civmlinux_link() 5062306a36Sopenharmony_ci{ 5162306a36Sopenharmony_ci local output=${1} 5262306a36Sopenharmony_ci local objs 5362306a36Sopenharmony_ci local libs 5462306a36Sopenharmony_ci local ld 5562306a36Sopenharmony_ci local ldflags 5662306a36Sopenharmony_ci local ldlibs 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci info LD ${output} 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci # skip output file argument 6162306a36Sopenharmony_ci shift 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci if is_enabled CONFIG_LTO_CLANG || is_enabled CONFIG_X86_KERNEL_IBT; then 6462306a36Sopenharmony_ci # Use vmlinux.o instead of performing the slow LTO link again. 6562306a36Sopenharmony_ci objs=vmlinux.o 6662306a36Sopenharmony_ci libs= 6762306a36Sopenharmony_ci else 6862306a36Sopenharmony_ci objs=vmlinux.a 6962306a36Sopenharmony_ci libs="${KBUILD_VMLINUX_LIBS}" 7062306a36Sopenharmony_ci fi 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci if is_enabled CONFIG_MODULES; then 7362306a36Sopenharmony_ci objs="${objs} .vmlinux.export.o" 7462306a36Sopenharmony_ci fi 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci objs="${objs} init/version-timestamp.o" 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci if [ "${SRCARCH}" = "um" ]; then 7962306a36Sopenharmony_ci wl=-Wl, 8062306a36Sopenharmony_ci ld="${CC}" 8162306a36Sopenharmony_ci ldflags="${CFLAGS_vmlinux}" 8262306a36Sopenharmony_ci ldlibs="-lutil -lrt -lpthread" 8362306a36Sopenharmony_ci else 8462306a36Sopenharmony_ci wl= 8562306a36Sopenharmony_ci ld="${LD}" 8662306a36Sopenharmony_ci ldflags="${KBUILD_LDFLAGS} ${LDFLAGS_vmlinux}" 8762306a36Sopenharmony_ci ldlibs= 8862306a36Sopenharmony_ci fi 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci ldflags="${ldflags} ${wl}--script=${objtree}/${KBUILD_LDS}" 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci # The kallsyms linking does not need debug symbols included. 9362306a36Sopenharmony_ci if [ "$output" != "${output#.tmp_vmlinux.kallsyms}" ] ; then 9462306a36Sopenharmony_ci ldflags="${ldflags} ${wl}--strip-debug" 9562306a36Sopenharmony_ci fi 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci if is_enabled CONFIG_VMLINUX_MAP; then 9862306a36Sopenharmony_ci ldflags="${ldflags} ${wl}-Map=${output}.map" 9962306a36Sopenharmony_ci fi 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci ${ld} ${ldflags} -o ${output} \ 10262306a36Sopenharmony_ci ${wl}--whole-archive ${objs} ${wl}--no-whole-archive \ 10362306a36Sopenharmony_ci ${wl}--start-group ${libs} ${wl}--end-group \ 10462306a36Sopenharmony_ci $@ ${ldlibs} 10562306a36Sopenharmony_ci} 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci# generate .BTF typeinfo from DWARF debuginfo 10862306a36Sopenharmony_ci# ${1} - vmlinux image 10962306a36Sopenharmony_ci# ${2} - file to dump raw BTF data into 11062306a36Sopenharmony_cigen_btf() 11162306a36Sopenharmony_ci{ 11262306a36Sopenharmony_ci local pahole_ver 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci if ! [ -x "$(command -v ${PAHOLE})" ]; then 11562306a36Sopenharmony_ci echo >&2 "BTF: ${1}: pahole (${PAHOLE}) is not available" 11662306a36Sopenharmony_ci return 1 11762306a36Sopenharmony_ci fi 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci pahole_ver=$(${PAHOLE} --version | sed -E 's/v([0-9]+)\.([0-9]+)/\1\2/') 12062306a36Sopenharmony_ci if [ "${pahole_ver}" -lt "116" ]; then 12162306a36Sopenharmony_ci echo >&2 "BTF: ${1}: pahole version $(${PAHOLE} --version) is too old, need at least v1.16" 12262306a36Sopenharmony_ci return 1 12362306a36Sopenharmony_ci fi 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci vmlinux_link ${1} 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci info "BTF" ${2} 12862306a36Sopenharmony_ci LLVM_OBJCOPY="${OBJCOPY}" ${PAHOLE} -J ${PAHOLE_FLAGS} ${1} 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci # Create ${2} which contains just .BTF section but no symbols. Add 13162306a36Sopenharmony_ci # SHF_ALLOC because .BTF will be part of the vmlinux image. --strip-all 13262306a36Sopenharmony_ci # deletes all symbols including __start_BTF and __stop_BTF, which will 13362306a36Sopenharmony_ci # be redefined in the linker script. Add 2>/dev/null to suppress GNU 13462306a36Sopenharmony_ci # objcopy warnings: "empty loadable segment detected at ..." 13562306a36Sopenharmony_ci ${OBJCOPY} --only-section=.BTF --set-section-flags .BTF=alloc,readonly \ 13662306a36Sopenharmony_ci --strip-all ${1} ${2} 2>/dev/null 13762306a36Sopenharmony_ci # Change e_type to ET_REL so that it can be used to link final vmlinux. 13862306a36Sopenharmony_ci # GNU ld 2.35+ and lld do not allow an ET_EXEC input. 13962306a36Sopenharmony_ci if is_enabled CONFIG_CPU_BIG_ENDIAN; then 14062306a36Sopenharmony_ci et_rel='\0\1' 14162306a36Sopenharmony_ci else 14262306a36Sopenharmony_ci et_rel='\1\0' 14362306a36Sopenharmony_ci fi 14462306a36Sopenharmony_ci printf "${et_rel}" | dd of=${2} conv=notrunc bs=1 seek=16 status=none 14562306a36Sopenharmony_ci} 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci# Create ${2} .S file with all symbols from the ${1} object file 14862306a36Sopenharmony_cikallsyms() 14962306a36Sopenharmony_ci{ 15062306a36Sopenharmony_ci local kallsymopt; 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci if is_enabled CONFIG_KALLSYMS_ALL; then 15362306a36Sopenharmony_ci kallsymopt="${kallsymopt} --all-symbols" 15462306a36Sopenharmony_ci fi 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci if is_enabled CONFIG_KALLSYMS_ABSOLUTE_PERCPU; then 15762306a36Sopenharmony_ci kallsymopt="${kallsymopt} --absolute-percpu" 15862306a36Sopenharmony_ci fi 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci if is_enabled CONFIG_KALLSYMS_BASE_RELATIVE; then 16162306a36Sopenharmony_ci kallsymopt="${kallsymopt} --base-relative" 16262306a36Sopenharmony_ci fi 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ci if is_enabled CONFIG_LTO_CLANG; then 16562306a36Sopenharmony_ci kallsymopt="${kallsymopt} --lto-clang" 16662306a36Sopenharmony_ci fi 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci info KSYMS ${2} 16962306a36Sopenharmony_ci scripts/kallsyms ${kallsymopt} ${1} > ${2} 17062306a36Sopenharmony_ci} 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci# Perform one step in kallsyms generation, including temporary linking of 17362306a36Sopenharmony_ci# vmlinux. 17462306a36Sopenharmony_cikallsyms_step() 17562306a36Sopenharmony_ci{ 17662306a36Sopenharmony_ci kallsymso_prev=${kallsymso} 17762306a36Sopenharmony_ci kallsyms_vmlinux=.tmp_vmlinux.kallsyms${1} 17862306a36Sopenharmony_ci kallsymso=${kallsyms_vmlinux}.o 17962306a36Sopenharmony_ci kallsyms_S=${kallsyms_vmlinux}.S 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_ci vmlinux_link ${kallsyms_vmlinux} "${kallsymso_prev}" ${btf_vmlinux_bin_o} 18262306a36Sopenharmony_ci mksysmap ${kallsyms_vmlinux} ${kallsyms_vmlinux}.syms ${kallsymso_prev} 18362306a36Sopenharmony_ci kallsyms ${kallsyms_vmlinux}.syms ${kallsyms_S} 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_ci info AS ${kallsyms_S} 18662306a36Sopenharmony_ci ${CC} ${NOSTDINC_FLAGS} ${LINUXINCLUDE} ${KBUILD_CPPFLAGS} \ 18762306a36Sopenharmony_ci ${KBUILD_AFLAGS} ${KBUILD_AFLAGS_KERNEL} \ 18862306a36Sopenharmony_ci -c -o ${kallsymso} ${kallsyms_S} 18962306a36Sopenharmony_ci} 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci# Create map file with all symbols from ${1} 19262306a36Sopenharmony_ci# See mksymap for additional details 19362306a36Sopenharmony_cimksysmap() 19462306a36Sopenharmony_ci{ 19562306a36Sopenharmony_ci info NM ${2} 19662306a36Sopenharmony_ci ${CONFIG_SHELL} "${srctree}/scripts/mksysmap" ${1} ${2} ${3} 19762306a36Sopenharmony_ci} 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_cisorttable() 20062306a36Sopenharmony_ci{ 20162306a36Sopenharmony_ci ${objtree}/scripts/sorttable ${1} 20262306a36Sopenharmony_ci} 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci# Delete output files in case of error 20562306a36Sopenharmony_cicleanup() 20662306a36Sopenharmony_ci{ 20762306a36Sopenharmony_ci rm -f .btf.* 20862306a36Sopenharmony_ci rm -f System.map 20962306a36Sopenharmony_ci rm -f vmlinux 21062306a36Sopenharmony_ci rm -f vmlinux.map 21162306a36Sopenharmony_ci} 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_ci# Use "make V=1" to debug this script 21462306a36Sopenharmony_cicase "${KBUILD_VERBOSE}" in 21562306a36Sopenharmony_ci*1*) 21662306a36Sopenharmony_ci set -x 21762306a36Sopenharmony_ci ;; 21862306a36Sopenharmony_ciesac 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_ciif [ "$1" = "clean" ]; then 22162306a36Sopenharmony_ci cleanup 22262306a36Sopenharmony_ci exit 0 22362306a36Sopenharmony_cifi 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init init/version-timestamp.o 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_cibtf_vmlinux_bin_o="" 22862306a36Sopenharmony_ciif is_enabled CONFIG_DEBUG_INFO_BTF; then 22962306a36Sopenharmony_ci btf_vmlinux_bin_o=.btf.vmlinux.bin.o 23062306a36Sopenharmony_ci if ! gen_btf .tmp_vmlinux.btf $btf_vmlinux_bin_o ; then 23162306a36Sopenharmony_ci echo >&2 "Failed to generate BTF for vmlinux" 23262306a36Sopenharmony_ci echo >&2 "Try to disable CONFIG_DEBUG_INFO_BTF" 23362306a36Sopenharmony_ci exit 1 23462306a36Sopenharmony_ci fi 23562306a36Sopenharmony_cifi 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_cikallsymso="" 23862306a36Sopenharmony_cikallsymso_prev="" 23962306a36Sopenharmony_cikallsyms_vmlinux="" 24062306a36Sopenharmony_ciif is_enabled CONFIG_KALLSYMS; then 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ci # kallsyms support 24362306a36Sopenharmony_ci # Generate section listing all symbols and add it into vmlinux 24462306a36Sopenharmony_ci # It's a three step process: 24562306a36Sopenharmony_ci # 1) Link .tmp_vmlinux.kallsyms1 so it has all symbols and sections, 24662306a36Sopenharmony_ci # but __kallsyms is empty. 24762306a36Sopenharmony_ci # Running kallsyms on that gives us .tmp_kallsyms1.o with 24862306a36Sopenharmony_ci # the right size 24962306a36Sopenharmony_ci # 2) Link .tmp_vmlinux.kallsyms2 so it now has a __kallsyms section of 25062306a36Sopenharmony_ci # the right size, but due to the added section, some 25162306a36Sopenharmony_ci # addresses have shifted. 25262306a36Sopenharmony_ci # From here, we generate a correct .tmp_vmlinux.kallsyms2.o 25362306a36Sopenharmony_ci # 3) That link may have expanded the kernel image enough that 25462306a36Sopenharmony_ci # more linker branch stubs / trampolines had to be added, which 25562306a36Sopenharmony_ci # introduces new names, which further expands kallsyms. Do another 25662306a36Sopenharmony_ci # pass if that is the case. In theory it's possible this results 25762306a36Sopenharmony_ci # in even more stubs, but unlikely. 25862306a36Sopenharmony_ci # KALLSYMS_EXTRA_PASS=1 may also used to debug or work around 25962306a36Sopenharmony_ci # other bugs. 26062306a36Sopenharmony_ci # 4) The correct ${kallsymso} is linked into the final vmlinux. 26162306a36Sopenharmony_ci # 26262306a36Sopenharmony_ci # a) Verify that the System.map from vmlinux matches the map from 26362306a36Sopenharmony_ci # ${kallsymso}. 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_ci kallsyms_step 1 26662306a36Sopenharmony_ci kallsyms_step 2 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_ci # step 3 26962306a36Sopenharmony_ci size1=$(${CONFIG_SHELL} "${srctree}/scripts/file-size.sh" ${kallsymso_prev}) 27062306a36Sopenharmony_ci size2=$(${CONFIG_SHELL} "${srctree}/scripts/file-size.sh" ${kallsymso}) 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ci if [ $size1 -ne $size2 ] || [ -n "${KALLSYMS_EXTRA_PASS}" ]; then 27362306a36Sopenharmony_ci kallsyms_step 3 27462306a36Sopenharmony_ci fi 27562306a36Sopenharmony_cifi 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_civmlinux_link vmlinux "${kallsymso}" ${btf_vmlinux_bin_o} 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ci# fill in BTF IDs 28062306a36Sopenharmony_ciif is_enabled CONFIG_DEBUG_INFO_BTF && is_enabled CONFIG_BPF; then 28162306a36Sopenharmony_ci info BTFIDS vmlinux 28262306a36Sopenharmony_ci ${RESOLVE_BTFIDS} vmlinux 28362306a36Sopenharmony_cifi 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_cimksysmap vmlinux System.map ${kallsymso} 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_ciif is_enabled CONFIG_BUILDTIME_TABLE_SORT; then 28862306a36Sopenharmony_ci info SORTTAB vmlinux 28962306a36Sopenharmony_ci if ! sorttable vmlinux; then 29062306a36Sopenharmony_ci echo >&2 Failed to sort kernel tables 29162306a36Sopenharmony_ci exit 1 29262306a36Sopenharmony_ci fi 29362306a36Sopenharmony_cifi 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_ci# step a (see comment above) 29662306a36Sopenharmony_ciif is_enabled CONFIG_KALLSYMS; then 29762306a36Sopenharmony_ci if ! cmp -s System.map ${kallsyms_vmlinux}.syms; then 29862306a36Sopenharmony_ci echo >&2 Inconsistent kallsyms data 29962306a36Sopenharmony_ci echo >&2 'Try "make KALLSYMS_EXTRA_PASS=1" as a workaround' 30062306a36Sopenharmony_ci exit 1 30162306a36Sopenharmony_ci fi 30262306a36Sopenharmony_cifi 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_ci# For fixdep 30562306a36Sopenharmony_ciecho "vmlinux: $0" > .vmlinux.d 306