Back to home page

OSCL-LXR

 
 

    


0001 #!/bin/sh
0002 # SPDX-License-Identifier: GPL-2.0
0003 #
0004 # link vmlinux
0005 #
0006 # vmlinux is linked from the objects selected by $(KBUILD_VMLINUX_OBJS) and
0007 # $(KBUILD_VMLINUX_LIBS). Most are built-in.a files from top-level directories
0008 # in the kernel tree, others are specified in arch/$(ARCH)/Makefile.
0009 # $(KBUILD_VMLINUX_LIBS) are archives which are linked conditionally
0010 # (not within --whole-archive), and do not require symbol indexes added.
0011 #
0012 # vmlinux
0013 #   ^
0014 #   |
0015 #   +--< $(KBUILD_VMLINUX_OBJS)
0016 #   |    +--< init/built-in.a drivers/built-in.a mm/built-in.a + more
0017 #   |
0018 #   +--< $(KBUILD_VMLINUX_LIBS)
0019 #   |    +--< lib/lib.a + more
0020 #   |
0021 #   +-< ${kallsymso} (see description in KALLSYMS section)
0022 #
0023 # vmlinux version (uname -v) cannot be updated during normal
0024 # descending-into-subdirs phase since we do not yet know if we need to
0025 # update vmlinux.
0026 # Therefore this step is delayed until just before final link of vmlinux.
0027 #
0028 # System.map is generated to document addresses of all kernel symbols
0029 
0030 # Error out on error
0031 set -e
0032 
0033 LD="$1"
0034 KBUILD_LDFLAGS="$2"
0035 LDFLAGS_vmlinux="$3"
0036 
0037 is_enabled() {
0038         grep -q "^$1=y" include/config/auto.conf
0039 }
0040 
0041 # Nice output in kbuild format
0042 # Will be supressed by "make -s"
0043 info()
0044 {
0045         printf "  %-7s %s\n" "${1}" "${2}"
0046 }
0047 
0048 # Link of vmlinux
0049 # ${1} - output file
0050 # ${2}, ${3}, ... - optional extra .o files
0051 vmlinux_link()
0052 {
0053         local output=${1}
0054         local objs
0055         local libs
0056         local ld
0057         local ldflags
0058         local ldlibs
0059 
0060         info LD ${output}
0061 
0062         # skip output file argument
0063         shift
0064 
0065         if is_enabled CONFIG_LTO_CLANG || is_enabled CONFIG_X86_KERNEL_IBT; then
0066                 # Use vmlinux.o instead of performing the slow LTO link again.
0067                 objs=vmlinux.o
0068                 libs=
0069         else
0070                 objs="${KBUILD_VMLINUX_OBJS}"
0071                 libs="${KBUILD_VMLINUX_LIBS}"
0072         fi
0073 
0074         if is_enabled CONFIG_MODULES; then
0075                 objs="${objs} .vmlinux.export.o"
0076         fi
0077 
0078         if [ "${SRCARCH}" = "um" ]; then
0079                 wl=-Wl,
0080                 ld="${CC}"
0081                 ldflags="${CFLAGS_vmlinux}"
0082                 ldlibs="-lutil -lrt -lpthread"
0083         else
0084                 wl=
0085                 ld="${LD}"
0086                 ldflags="${KBUILD_LDFLAGS} ${LDFLAGS_vmlinux}"
0087                 ldlibs=
0088         fi
0089 
0090         ldflags="${ldflags} ${wl}--script=${objtree}/${KBUILD_LDS}"
0091 
0092         # The kallsyms linking does not need debug symbols included.
0093         if [ "$output" != "${output#.tmp_vmlinux.kallsyms}" ] ; then
0094                 ldflags="${ldflags} ${wl}--strip-debug"
0095         fi
0096 
0097         if is_enabled CONFIG_VMLINUX_MAP; then
0098                 ldflags="${ldflags} ${wl}-Map=${output}.map"
0099         fi
0100 
0101         ${ld} ${ldflags} -o ${output}                                   \
0102                 ${wl}--whole-archive ${objs} ${wl}--no-whole-archive    \
0103                 ${wl}--start-group ${libs} ${wl}--end-group             \
0104                 $@ ${ldlibs}
0105 }
0106 
0107 # generate .BTF typeinfo from DWARF debuginfo
0108 # ${1} - vmlinux image
0109 # ${2} - file to dump raw BTF data into
0110 gen_btf()
0111 {
0112         local pahole_ver
0113 
0114         if ! [ -x "$(command -v ${PAHOLE})" ]; then
0115                 echo >&2 "BTF: ${1}: pahole (${PAHOLE}) is not available"
0116                 return 1
0117         fi
0118 
0119         pahole_ver=$(${PAHOLE} --version | sed -E 's/v([0-9]+)\.([0-9]+)/\1\2/')
0120         if [ "${pahole_ver}" -lt "116" ]; then
0121                 echo >&2 "BTF: ${1}: pahole version $(${PAHOLE} --version) is too old, need at least v1.16"
0122                 return 1
0123         fi
0124 
0125         vmlinux_link ${1}
0126 
0127         info "BTF" ${2}
0128         LLVM_OBJCOPY="${OBJCOPY}" ${PAHOLE} -J ${PAHOLE_FLAGS} ${1}
0129 
0130         # Create ${2} which contains just .BTF section but no symbols. Add
0131         # SHF_ALLOC because .BTF will be part of the vmlinux image. --strip-all
0132         # deletes all symbols including __start_BTF and __stop_BTF, which will
0133         # be redefined in the linker script. Add 2>/dev/null to suppress GNU
0134         # objcopy warnings: "empty loadable segment detected at ..."
0135         ${OBJCOPY} --only-section=.BTF --set-section-flags .BTF=alloc,readonly \
0136                 --strip-all ${1} ${2} 2>/dev/null
0137         # Change e_type to ET_REL so that it can be used to link final vmlinux.
0138         # Unlike GNU ld, lld does not allow an ET_EXEC input.
0139         printf '\1' | dd of=${2} conv=notrunc bs=1 seek=16 status=none
0140 }
0141 
0142 # Create ${2} .S file with all symbols from the ${1} object file
0143 kallsyms()
0144 {
0145         local kallsymopt;
0146 
0147         if is_enabled CONFIG_KALLSYMS_ALL; then
0148                 kallsymopt="${kallsymopt} --all-symbols"
0149         fi
0150 
0151         if is_enabled CONFIG_KALLSYMS_ABSOLUTE_PERCPU; then
0152                 kallsymopt="${kallsymopt} --absolute-percpu"
0153         fi
0154 
0155         if is_enabled CONFIG_KALLSYMS_BASE_RELATIVE; then
0156                 kallsymopt="${kallsymopt} --base-relative"
0157         fi
0158 
0159         info KSYMS ${2}
0160         ${NM} -n ${1} | scripts/kallsyms ${kallsymopt} > ${2}
0161 }
0162 
0163 # Perform one step in kallsyms generation, including temporary linking of
0164 # vmlinux.
0165 kallsyms_step()
0166 {
0167         kallsymso_prev=${kallsymso}
0168         kallsyms_vmlinux=.tmp_vmlinux.kallsyms${1}
0169         kallsymso=${kallsyms_vmlinux}.o
0170         kallsyms_S=${kallsyms_vmlinux}.S
0171 
0172         vmlinux_link ${kallsyms_vmlinux} "${kallsymso_prev}" ${btf_vmlinux_bin_o}
0173         kallsyms ${kallsyms_vmlinux} ${kallsyms_S}
0174 
0175         info AS ${kallsyms_S}
0176         ${CC} ${NOSTDINC_FLAGS} ${LINUXINCLUDE} ${KBUILD_CPPFLAGS} \
0177               ${KBUILD_AFLAGS} ${KBUILD_AFLAGS_KERNEL} \
0178               -c -o ${kallsymso} ${kallsyms_S}
0179 }
0180 
0181 # Create map file with all symbols from ${1}
0182 # See mksymap for additional details
0183 mksysmap()
0184 {
0185         ${CONFIG_SHELL} "${srctree}/scripts/mksysmap" ${1} ${2}
0186 }
0187 
0188 sorttable()
0189 {
0190         ${objtree}/scripts/sorttable ${1}
0191 }
0192 
0193 # Delete output files in case of error
0194 cleanup()
0195 {
0196         rm -f .btf.*
0197         rm -f System.map
0198         rm -f vmlinux
0199         rm -f vmlinux.map
0200         rm -f .vmlinux.objs
0201         rm -f .vmlinux.export.c
0202 }
0203 
0204 # Use "make V=1" to debug this script
0205 case "${KBUILD_VERBOSE}" in
0206 *1*)
0207         set -x
0208         ;;
0209 esac
0210 
0211 if [ "$1" = "clean" ]; then
0212         cleanup
0213         exit 0
0214 fi
0215 
0216 # Update version
0217 info GEN .version
0218 if [ -r .version ]; then
0219         VERSION=$(expr 0$(cat .version) + 1)
0220         echo $VERSION > .version
0221 else
0222         rm -f .version
0223         echo 1 > .version
0224 fi;
0225 
0226 # final build of init/
0227 ${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init need-builtin=1
0228 
0229 #link vmlinux.o
0230 ${MAKE} -f "${srctree}/scripts/Makefile.vmlinux_o"
0231 
0232 # Generate the list of in-tree objects in vmlinux
0233 #
0234 # This is used to retrieve symbol versions generated by genksyms.
0235 for f in ${KBUILD_VMLINUX_OBJS} ${KBUILD_VMLINUX_LIBS}; do
0236         case ${f} in
0237         *libgcc.a)
0238                 # Some architectures do '$(CC) --print-libgcc-file-name' to
0239                 # borrow libgcc.a from the toolchain.
0240                 # There is no EXPORT_SYMBOL in external objects. Ignore this.
0241                 ;;
0242         *.a)
0243                 ${AR} t ${f} ;;
0244         *)
0245                 echo ${f} ;;
0246         esac
0247 done > .vmlinux.objs
0248 
0249 # modpost vmlinux.o to check for section mismatches
0250 ${MAKE} -f "${srctree}/scripts/Makefile.modpost" MODPOST_VMLINUX=1
0251 
0252 info MODINFO modules.builtin.modinfo
0253 ${OBJCOPY} -j .modinfo -O binary vmlinux.o modules.builtin.modinfo
0254 info GEN modules.builtin
0255 # The second line aids cases where multiple modules share the same object.
0256 tr '\0' '\n' < modules.builtin.modinfo | sed -n 's/^[[:alnum:]:_]*\.file=//p' |
0257         tr ' ' '\n' | uniq | sed -e 's:^:kernel/:' -e 's/$/.ko/' > modules.builtin
0258 
0259 if is_enabled CONFIG_MODULES; then
0260         ${MAKE} -f "${srctree}/scripts/Makefile.vmlinux" .vmlinux.export.o
0261 fi
0262 
0263 btf_vmlinux_bin_o=""
0264 if is_enabled CONFIG_DEBUG_INFO_BTF; then
0265         btf_vmlinux_bin_o=.btf.vmlinux.bin.o
0266         if ! gen_btf .tmp_vmlinux.btf $btf_vmlinux_bin_o ; then
0267                 echo >&2 "Failed to generate BTF for vmlinux"
0268                 echo >&2 "Try to disable CONFIG_DEBUG_INFO_BTF"
0269                 exit 1
0270         fi
0271 fi
0272 
0273 kallsymso=""
0274 kallsymso_prev=""
0275 kallsyms_vmlinux=""
0276 if is_enabled CONFIG_KALLSYMS; then
0277 
0278         # kallsyms support
0279         # Generate section listing all symbols and add it into vmlinux
0280         # It's a three step process:
0281         # 1)  Link .tmp_vmlinux.kallsyms1 so it has all symbols and sections,
0282         #     but __kallsyms is empty.
0283         #     Running kallsyms on that gives us .tmp_kallsyms1.o with
0284         #     the right size
0285         # 2)  Link .tmp_vmlinux.kallsyms2 so it now has a __kallsyms section of
0286         #     the right size, but due to the added section, some
0287         #     addresses have shifted.
0288         #     From here, we generate a correct .tmp_vmlinux.kallsyms2.o
0289         # 3)  That link may have expanded the kernel image enough that
0290         #     more linker branch stubs / trampolines had to be added, which
0291         #     introduces new names, which further expands kallsyms. Do another
0292         #     pass if that is the case. In theory it's possible this results
0293         #     in even more stubs, but unlikely.
0294         #     KALLSYMS_EXTRA_PASS=1 may also used to debug or work around
0295         #     other bugs.
0296         # 4)  The correct ${kallsymso} is linked into the final vmlinux.
0297         #
0298         # a)  Verify that the System.map from vmlinux matches the map from
0299         #     ${kallsymso}.
0300 
0301         kallsyms_step 1
0302         kallsyms_step 2
0303 
0304         # step 3
0305         size1=$(${CONFIG_SHELL} "${srctree}/scripts/file-size.sh" ${kallsymso_prev})
0306         size2=$(${CONFIG_SHELL} "${srctree}/scripts/file-size.sh" ${kallsymso})
0307 
0308         if [ $size1 -ne $size2 ] || [ -n "${KALLSYMS_EXTRA_PASS}" ]; then
0309                 kallsyms_step 3
0310         fi
0311 fi
0312 
0313 vmlinux_link vmlinux "${kallsymso}" ${btf_vmlinux_bin_o}
0314 
0315 # fill in BTF IDs
0316 if is_enabled CONFIG_DEBUG_INFO_BTF && is_enabled CONFIG_BPF; then
0317         info BTFIDS vmlinux
0318         ${RESOLVE_BTFIDS} vmlinux
0319 fi
0320 
0321 info SYSMAP System.map
0322 mksysmap vmlinux System.map
0323 
0324 if is_enabled CONFIG_BUILDTIME_TABLE_SORT; then
0325         info SORTTAB vmlinux
0326         if ! sorttable vmlinux; then
0327                 echo >&2 Failed to sort kernel tables
0328                 exit 1
0329         fi
0330 fi
0331 
0332 # step a (see comment above)
0333 if is_enabled CONFIG_KALLSYMS; then
0334         mksysmap ${kallsyms_vmlinux} .tmp_System.map
0335 
0336         if ! cmp -s System.map .tmp_System.map; then
0337                 echo >&2 Inconsistent kallsyms data
0338                 echo >&2 Try "make KALLSYMS_EXTRA_PASS=1" as a workaround
0339                 exit 1
0340         fi
0341 fi
0342 
0343 # For fixdep
0344 echo "vmlinux: $0" > .vmlinux.d