cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

link-vmlinux.sh (9073B)


      1#!/bin/sh
      2# SPDX-License-Identifier: GPL-2.0
      3#
      4# link vmlinux
      5#
      6# vmlinux is linked from the objects selected by $(KBUILD_VMLINUX_OBJS) and
      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.
      9# $(KBUILD_VMLINUX_LIBS) are archives which are linked conditionally
     10# (not within --whole-archive), and do not require symbol indexes added.
     11#
     12# vmlinux
     13#   ^
     14#   |
     15#   +--< $(KBUILD_VMLINUX_OBJS)
     16#   |    +--< init/built-in.a drivers/built-in.a mm/built-in.a + more
     17#   |
     18#   +--< $(KBUILD_VMLINUX_LIBS)
     19#   |    +--< lib/lib.a + more
     20#   |
     21#   +-< ${kallsymso} (see description in KALLSYMS section)
     22#
     23# vmlinux version (uname -v) cannot be updated during normal
     24# descending-into-subdirs phase since we do not yet know if we need to
     25# update vmlinux.
     26# Therefore this step is delayed until just before final link of vmlinux.
     27#
     28# System.map is generated to document addresses of all kernel symbols
     29
     30# Error out on error
     31set -e
     32
     33LD="$1"
     34KBUILD_LDFLAGS="$2"
     35LDFLAGS_vmlinux="$3"
     36
     37is_enabled() {
     38	grep -q "^$1=y" include/config/auto.conf
     39}
     40
     41# Nice output in kbuild format
     42# Will be supressed by "make -s"
     43info()
     44{
     45	printf "  %-7s %s\n" "${1}" "${2}"
     46}
     47
     48# Link of vmlinux
     49# ${1} - output file
     50# ${2}, ${3}, ... - optional extra .o files
     51vmlinux_link()
     52{
     53	local output=${1}
     54	local objs
     55	local libs
     56	local ld
     57	local ldflags
     58	local ldlibs
     59
     60	info LD ${output}
     61
     62	# skip output file argument
     63	shift
     64
     65	if is_enabled CONFIG_LTO_CLANG || is_enabled CONFIG_X86_KERNEL_IBT; then
     66		# Use vmlinux.o instead of performing the slow LTO link again.
     67		objs=vmlinux.o
     68		libs=
     69	else
     70		objs="${KBUILD_VMLINUX_OBJS}"
     71		libs="${KBUILD_VMLINUX_LIBS}"
     72	fi
     73
     74	if is_enabled CONFIG_MODULES; then
     75		objs="${objs} .vmlinux.export.o"
     76	fi
     77
     78	if [ "${SRCARCH}" = "um" ]; then
     79		wl=-Wl,
     80		ld="${CC}"
     81		ldflags="${CFLAGS_vmlinux}"
     82		ldlibs="-lutil -lrt -lpthread"
     83	else
     84		wl=
     85		ld="${LD}"
     86		ldflags="${KBUILD_LDFLAGS} ${LDFLAGS_vmlinux}"
     87		ldlibs=
     88	fi
     89
     90	ldflags="${ldflags} ${wl}--script=${objtree}/${KBUILD_LDS}"
     91
     92	# The kallsyms linking does not need debug symbols included.
     93	if [ "$output" != "${output#.tmp_vmlinux.kallsyms}" ] ; then
     94		ldflags="${ldflags} ${wl}--strip-debug"
     95	fi
     96
     97	if is_enabled CONFIG_VMLINUX_MAP; then
     98		ldflags="${ldflags} ${wl}-Map=${output}.map"
     99	fi
    100
    101	${ld} ${ldflags} -o ${output}					\
    102		${wl}--whole-archive ${objs} ${wl}--no-whole-archive	\
    103		${wl}--start-group ${libs} ${wl}--end-group		\
    104		$@ ${ldlibs}
    105}
    106
    107# generate .BTF typeinfo from DWARF debuginfo
    108# ${1} - vmlinux image
    109# ${2} - file to dump raw BTF data into
    110gen_btf()
    111{
    112	local pahole_ver
    113
    114	if ! [ -x "$(command -v ${PAHOLE})" ]; then
    115		echo >&2 "BTF: ${1}: pahole (${PAHOLE}) is not available"
    116		return 1
    117	fi
    118
    119	pahole_ver=$(${PAHOLE} --version | sed -E 's/v([0-9]+)\.([0-9]+)/\1\2/')
    120	if [ "${pahole_ver}" -lt "116" ]; then
    121		echo >&2 "BTF: ${1}: pahole version $(${PAHOLE} --version) is too old, need at least v1.16"
    122		return 1
    123	fi
    124
    125	vmlinux_link ${1}
    126
    127	info "BTF" ${2}
    128	LLVM_OBJCOPY="${OBJCOPY}" ${PAHOLE} -J ${PAHOLE_FLAGS} ${1}
    129
    130	# Create ${2} which contains just .BTF section but no symbols. Add
    131	# SHF_ALLOC because .BTF will be part of the vmlinux image. --strip-all
    132	# deletes all symbols including __start_BTF and __stop_BTF, which will
    133	# be redefined in the linker script. Add 2>/dev/null to suppress GNU
    134	# objcopy warnings: "empty loadable segment detected at ..."
    135	${OBJCOPY} --only-section=.BTF --set-section-flags .BTF=alloc,readonly \
    136		--strip-all ${1} ${2} 2>/dev/null
    137	# Change e_type to ET_REL so that it can be used to link final vmlinux.
    138	# Unlike GNU ld, lld does not allow an ET_EXEC input.
    139	printf '\1' | dd of=${2} conv=notrunc bs=1 seek=16 status=none
    140}
    141
    142# Create ${2} .S file with all symbols from the ${1} object file
    143kallsyms()
    144{
    145	local kallsymopt;
    146
    147	if is_enabled CONFIG_KALLSYMS_ALL; then
    148		kallsymopt="${kallsymopt} --all-symbols"
    149	fi
    150
    151	if is_enabled CONFIG_KALLSYMS_ABSOLUTE_PERCPU; then
    152		kallsymopt="${kallsymopt} --absolute-percpu"
    153	fi
    154
    155	if is_enabled CONFIG_KALLSYMS_BASE_RELATIVE; then
    156		kallsymopt="${kallsymopt} --base-relative"
    157	fi
    158
    159	info KSYMS ${2}
    160	${NM} -n ${1} | scripts/kallsyms ${kallsymopt} > ${2}
    161}
    162
    163# Perform one step in kallsyms generation, including temporary linking of
    164# vmlinux.
    165kallsyms_step()
    166{
    167	kallsymso_prev=${kallsymso}
    168	kallsyms_vmlinux=.tmp_vmlinux.kallsyms${1}
    169	kallsymso=${kallsyms_vmlinux}.o
    170	kallsyms_S=${kallsyms_vmlinux}.S
    171
    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}
    179}
    180
    181# Create map file with all symbols from ${1}
    182# See mksymap for additional details
    183mksysmap()
    184{
    185	${CONFIG_SHELL} "${srctree}/scripts/mksysmap" ${1} ${2}
    186}
    187
    188sorttable()
    189{
    190	${objtree}/scripts/sorttable ${1}
    191}
    192
    193# Delete output files in case of error
    194cleanup()
    195{
    196	rm -f .btf.*
    197	rm -f System.map
    198	rm -f vmlinux
    199	rm -f vmlinux.map
    200	rm -f .vmlinux.objs
    201	rm -f .vmlinux.export.c
    202}
    203
    204# Use "make V=1" to debug this script
    205case "${KBUILD_VERBOSE}" in
    206*1*)
    207	set -x
    208	;;
    209esac
    210
    211if [ "$1" = "clean" ]; then
    212	cleanup
    213	exit 0
    214fi
    215
    216# Update version
    217info GEN .version
    218if [ -r .version ]; then
    219	VERSION=$(expr 0$(cat .version) + 1)
    220	echo $VERSION > .version
    221else
    222	rm -f .version
    223	echo 1 > .version
    224fi;
    225
    226# final build of init/
    227${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init need-builtin=1
    228
    229#link vmlinux.o
    230${MAKE} -f "${srctree}/scripts/Makefile.vmlinux_o"
    231
    232# Generate the list of in-tree objects in vmlinux
    233#
    234# This is used to retrieve symbol versions generated by genksyms.
    235for 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
    247done > .vmlinux.objs
    248
    249# modpost vmlinux.o to check for section mismatches
    250${MAKE} -f "${srctree}/scripts/Makefile.modpost" MODPOST_VMLINUX=1
    251
    252info MODINFO modules.builtin.modinfo
    253${OBJCOPY} -j .modinfo -O binary vmlinux.o modules.builtin.modinfo
    254info GEN modules.builtin
    255# The second line aids cases where multiple modules share the same object.
    256tr '\0' '\n' < modules.builtin.modinfo | sed -n 's/^[[:alnum:]:_]*\.file=//p' |
    257	tr ' ' '\n' | uniq | sed -e 's:^:kernel/:' -e 's/$/.ko/' > modules.builtin
    258
    259if is_enabled CONFIG_MODULES; then
    260	${MAKE} -f "${srctree}/scripts/Makefile.vmlinux" .vmlinux.export.o
    261fi
    262
    263btf_vmlinux_bin_o=""
    264if is_enabled CONFIG_DEBUG_INFO_BTF; then
    265	btf_vmlinux_bin_o=.btf.vmlinux.bin.o
    266	if ! gen_btf .tmp_vmlinux.btf $btf_vmlinux_bin_o ; then
    267		echo >&2 "Failed to generate BTF for vmlinux"
    268		echo >&2 "Try to disable CONFIG_DEBUG_INFO_BTF"
    269		exit 1
    270	fi
    271fi
    272
    273kallsymso=""
    274kallsymso_prev=""
    275kallsyms_vmlinux=""
    276if is_enabled CONFIG_KALLSYMS; then
    277
    278	# kallsyms support
    279	# Generate section listing all symbols and add it into vmlinux
    280	# It's a three step process:
    281	# 1)  Link .tmp_vmlinux.kallsyms1 so it has all symbols and sections,
    282	#     but __kallsyms is empty.
    283	#     Running kallsyms on that gives us .tmp_kallsyms1.o with
    284	#     the right size
    285	# 2)  Link .tmp_vmlinux.kallsyms2 so it now has a __kallsyms section of
    286	#     the right size, but due to the added section, some
    287	#     addresses have shifted.
    288	#     From here, we generate a correct .tmp_vmlinux.kallsyms2.o
    289	# 3)  That link may have expanded the kernel image enough that
    290	#     more linker branch stubs / trampolines had to be added, which
    291	#     introduces new names, which further expands kallsyms. Do another
    292	#     pass if that is the case. In theory it's possible this results
    293	#     in even more stubs, but unlikely.
    294	#     KALLSYMS_EXTRA_PASS=1 may also used to debug or work around
    295	#     other bugs.
    296	# 4)  The correct ${kallsymso} is linked into the final vmlinux.
    297	#
    298	# a)  Verify that the System.map from vmlinux matches the map from
    299	#     ${kallsymso}.
    300
    301	kallsyms_step 1
    302	kallsyms_step 2
    303
    304	# step 3
    305	size1=$(${CONFIG_SHELL} "${srctree}/scripts/file-size.sh" ${kallsymso_prev})
    306	size2=$(${CONFIG_SHELL} "${srctree}/scripts/file-size.sh" ${kallsymso})
    307
    308	if [ $size1 -ne $size2 ] || [ -n "${KALLSYMS_EXTRA_PASS}" ]; then
    309		kallsyms_step 3
    310	fi
    311fi
    312
    313vmlinux_link vmlinux "${kallsymso}" ${btf_vmlinux_bin_o}
    314
    315# fill in BTF IDs
    316if is_enabled CONFIG_DEBUG_INFO_BTF && is_enabled CONFIG_BPF; then
    317	info BTFIDS vmlinux
    318	${RESOLVE_BTFIDS} vmlinux
    319fi
    320
    321info SYSMAP System.map
    322mksysmap vmlinux System.map
    323
    324if is_enabled CONFIG_BUILDTIME_TABLE_SORT; then
    325	info SORTTAB vmlinux
    326	if ! sorttable vmlinux; then
    327		echo >&2 Failed to sort kernel tables
    328		exit 1
    329	fi
    330fi
    331
    332# step a (see comment above)
    333if is_enabled CONFIG_KALLSYMS; then
    334	mksysmap ${kallsyms_vmlinux} .tmp_System.map
    335
    336	if ! cmp -s System.map .tmp_System.map; then
    337		echo >&2 Inconsistent kallsyms data
    338		echo >&2 Try "make KALLSYMS_EXTRA_PASS=1" as a workaround
    339		exit 1
    340	fi
    341fi
    342
    343# For fixdep
    344echo "vmlinux: $0" > .vmlinux.d