xref: /OK3568_Linux_fs/kernel/scripts/link-vmlinux.sh (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun#!/bin/sh
2*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0
3*4882a593Smuzhiyun#
4*4882a593Smuzhiyun# link vmlinux
5*4882a593Smuzhiyun#
6*4882a593Smuzhiyun# vmlinux is linked from the objects selected by $(KBUILD_VMLINUX_OBJS) and
7*4882a593Smuzhiyun# $(KBUILD_VMLINUX_LIBS). Most are built-in.a files from top-level directories
8*4882a593Smuzhiyun# in the kernel tree, others are specified in arch/$(ARCH)/Makefile.
9*4882a593Smuzhiyun# $(KBUILD_VMLINUX_LIBS) are archives which are linked conditionally
10*4882a593Smuzhiyun# (not within --whole-archive), and do not require symbol indexes added.
11*4882a593Smuzhiyun#
12*4882a593Smuzhiyun# vmlinux
13*4882a593Smuzhiyun#   ^
14*4882a593Smuzhiyun#   |
15*4882a593Smuzhiyun#   +--< $(KBUILD_VMLINUX_OBJS)
16*4882a593Smuzhiyun#   |    +--< init/built-in.a drivers/built-in.a mm/built-in.a + more
17*4882a593Smuzhiyun#   |
18*4882a593Smuzhiyun#   +--< $(KBUILD_VMLINUX_LIBS)
19*4882a593Smuzhiyun#   |    +--< lib/lib.a + more
20*4882a593Smuzhiyun#   |
21*4882a593Smuzhiyun#   +-< ${kallsymso} (see description in KALLSYMS section)
22*4882a593Smuzhiyun#
23*4882a593Smuzhiyun# vmlinux version (uname -v) cannot be updated during normal
24*4882a593Smuzhiyun# descending-into-subdirs phase since we do not yet know if we need to
25*4882a593Smuzhiyun# update vmlinux.
26*4882a593Smuzhiyun# Therefore this step is delayed until just before final link of vmlinux.
27*4882a593Smuzhiyun#
28*4882a593Smuzhiyun# System.map is generated to document addresses of all kernel symbols
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun# Error out on error
31*4882a593Smuzhiyunset -e
32*4882a593Smuzhiyun
33*4882a593SmuzhiyunLD="$1"
34*4882a593SmuzhiyunKBUILD_LDFLAGS="$2"
35*4882a593SmuzhiyunLDFLAGS_vmlinux="$3"
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun# Nice output in kbuild format
38*4882a593Smuzhiyun# Will be supressed by "make -s"
39*4882a593Smuzhiyuninfo()
40*4882a593Smuzhiyun{
41*4882a593Smuzhiyun	if [ "${quiet}" != "silent_" ]; then
42*4882a593Smuzhiyun		printf "  %-7s %s\n" "${1}" "${2}"
43*4882a593Smuzhiyun	fi
44*4882a593Smuzhiyun}
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun# Generate a linker script to ensure correct ordering of initcalls.
47*4882a593Smuzhiyungen_initcalls()
48*4882a593Smuzhiyun{
49*4882a593Smuzhiyun	info GEN .tmp_initcalls.lds
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun	${PYTHON} ${srctree}/scripts/jobserver-exec		\
52*4882a593Smuzhiyun	${PERL} ${srctree}/scripts/generate_initcall_order.pl	\
53*4882a593Smuzhiyun		${KBUILD_VMLINUX_OBJS} ${KBUILD_VMLINUX_LIBS}	\
54*4882a593Smuzhiyun		> .tmp_initcalls.lds
55*4882a593Smuzhiyun}
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun# If CONFIG_LTO_CLANG is selected, collect generated symbol versions into
58*4882a593Smuzhiyun# .tmp_symversions.lds
59*4882a593Smuzhiyungen_symversions()
60*4882a593Smuzhiyun{
61*4882a593Smuzhiyun	info GEN .tmp_symversions.lds
62*4882a593Smuzhiyun	rm -f .tmp_symversions.lds
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun	for o in ${KBUILD_VMLINUX_OBJS} ${KBUILD_VMLINUX_LIBS}; do
65*4882a593Smuzhiyun		if [ -f ${o}.symversions ]; then
66*4882a593Smuzhiyun			cat ${o}.symversions >> .tmp_symversions.lds
67*4882a593Smuzhiyun		fi
68*4882a593Smuzhiyun	done
69*4882a593Smuzhiyun}
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun# Link of vmlinux.o used for section mismatch analysis
72*4882a593Smuzhiyun# ${1} output file
73*4882a593Smuzhiyunmodpost_link()
74*4882a593Smuzhiyun{
75*4882a593Smuzhiyun	local objects
76*4882a593Smuzhiyun	local lds=""
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun	objects="--whole-archive				\
79*4882a593Smuzhiyun		${KBUILD_VMLINUX_OBJS}				\
80*4882a593Smuzhiyun		--no-whole-archive				\
81*4882a593Smuzhiyun		--start-group					\
82*4882a593Smuzhiyun		${KBUILD_VMLINUX_LIBS}				\
83*4882a593Smuzhiyun		--end-group"
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun	if [ -n "${CONFIG_LTO_CLANG}" ]; then
86*4882a593Smuzhiyun		gen_initcalls
87*4882a593Smuzhiyun		lds="-T .tmp_initcalls.lds"
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun		if [ -n "${CONFIG_MODVERSIONS}" ]; then
90*4882a593Smuzhiyun			gen_symversions
91*4882a593Smuzhiyun			lds="${lds} -T .tmp_symversions.lds"
92*4882a593Smuzhiyun		fi
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun		# This might take a while, so indicate that we're doing
95*4882a593Smuzhiyun		# an LTO link
96*4882a593Smuzhiyun		info LTO ${1}
97*4882a593Smuzhiyun	else
98*4882a593Smuzhiyun		info LD ${1}
99*4882a593Smuzhiyun	fi
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun	${LD} ${KBUILD_LDFLAGS} -r -o ${1} ${lds} ${objects}
102*4882a593Smuzhiyun}
103*4882a593Smuzhiyun
104*4882a593Smuzhiyunobjtool_link()
105*4882a593Smuzhiyun{
106*4882a593Smuzhiyun	local objtoolcmd;
107*4882a593Smuzhiyun	local objtoolopt;
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun	if [ "${CONFIG_LTO_CLANG} ${CONFIG_STACK_VALIDATION}" = "y y" ]; then
110*4882a593Smuzhiyun		# Don't perform vmlinux validation unless explicitly requested,
111*4882a593Smuzhiyun		# but run objtool on vmlinux.o now that we have an object file.
112*4882a593Smuzhiyun		if [ -n "${CONFIG_UNWINDER_ORC}" ]; then
113*4882a593Smuzhiyun			objtoolcmd="orc generate"
114*4882a593Smuzhiyun		fi
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun		objtoolopt="${objtoolopt} --duplicate"
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun		if [ -n "${CONFIG_FTRACE_MCOUNT_USE_OBJTOOL}" ]; then
119*4882a593Smuzhiyun			objtoolopt="${objtoolopt} --mcount"
120*4882a593Smuzhiyun		fi
121*4882a593Smuzhiyun	fi
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun	if [ -n "${CONFIG_VMLINUX_VALIDATION}" ]; then
124*4882a593Smuzhiyun		objtoolopt="${objtoolopt} --noinstr"
125*4882a593Smuzhiyun	fi
126*4882a593Smuzhiyun
127*4882a593Smuzhiyun	if [ -n "${objtoolopt}" ]; then
128*4882a593Smuzhiyun		if [ -z "${objtoolcmd}" ]; then
129*4882a593Smuzhiyun			objtoolcmd="check"
130*4882a593Smuzhiyun		fi
131*4882a593Smuzhiyun		objtoolopt="${objtoolopt} --vmlinux"
132*4882a593Smuzhiyun		if [ -n "${CONFIG_CPU_UNRET_ENTRY}" ]; then
133*4882a593Smuzhiyun			objtoolopt="${objtoolopt} --unret"
134*4882a593Smuzhiyun		fi
135*4882a593Smuzhiyun		if [ -z "${CONFIG_FRAME_POINTER}" ]; then
136*4882a593Smuzhiyun			objtoolopt="${objtoolopt} --no-fp"
137*4882a593Smuzhiyun		fi
138*4882a593Smuzhiyun		if [ -n "${CONFIG_GCOV_KERNEL}" ] || [ -n "${CONFIG_LTO_CLANG}" ]; then
139*4882a593Smuzhiyun			objtoolopt="${objtoolopt} --no-unreachable"
140*4882a593Smuzhiyun		fi
141*4882a593Smuzhiyun		if [ -n "${CONFIG_RETPOLINE}" ]; then
142*4882a593Smuzhiyun			objtoolopt="${objtoolopt} --retpoline"
143*4882a593Smuzhiyun		fi
144*4882a593Smuzhiyun		if [ -n "${CONFIG_X86_SMAP}" ]; then
145*4882a593Smuzhiyun			objtoolopt="${objtoolopt} --uaccess"
146*4882a593Smuzhiyun		fi
147*4882a593Smuzhiyun		if [ -n "${CONFIG_SLS}" ]; then
148*4882a593Smuzhiyun			objtoolopt="${objtoolopt} --sls"
149*4882a593Smuzhiyun		fi
150*4882a593Smuzhiyun		info OBJTOOL ${1}
151*4882a593Smuzhiyun		tools/objtool/objtool ${objtoolcmd} ${objtoolopt} ${1}
152*4882a593Smuzhiyun	fi
153*4882a593Smuzhiyun}
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun# Link of vmlinux
156*4882a593Smuzhiyun# ${1} - output file
157*4882a593Smuzhiyun# ${2}, ${3}, ... - optional extra .o files
158*4882a593Smuzhiyunvmlinux_link()
159*4882a593Smuzhiyun{
160*4882a593Smuzhiyun	local lds="${objtree}/${KBUILD_LDS}"
161*4882a593Smuzhiyun	local output=${1}
162*4882a593Smuzhiyun	local objects
163*4882a593Smuzhiyun	local strip_debug
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun	info LD ${output}
166*4882a593Smuzhiyun
167*4882a593Smuzhiyun	# skip output file argument
168*4882a593Smuzhiyun	shift
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun	# The kallsyms linking does not need debug symbols included.
171*4882a593Smuzhiyun	if [ "$output" != "${output#.tmp_vmlinux.kallsyms}" ] ; then
172*4882a593Smuzhiyun		strip_debug=-Wl,--strip-debug
173*4882a593Smuzhiyun	fi
174*4882a593Smuzhiyun
175*4882a593Smuzhiyun	if [ "${SRCARCH}" != "um" ]; then
176*4882a593Smuzhiyun		if [ -n "${CONFIG_LTO_CLANG}" ]; then
177*4882a593Smuzhiyun			# Use vmlinux.o instead of performing the slow LTO
178*4882a593Smuzhiyun			# link again.
179*4882a593Smuzhiyun			objects="--whole-archive		\
180*4882a593Smuzhiyun				vmlinux.o 			\
181*4882a593Smuzhiyun				--no-whole-archive		\
182*4882a593Smuzhiyun				${@}"
183*4882a593Smuzhiyun		else
184*4882a593Smuzhiyun			objects="--whole-archive		\
185*4882a593Smuzhiyun				${KBUILD_VMLINUX_OBJS}		\
186*4882a593Smuzhiyun				--no-whole-archive		\
187*4882a593Smuzhiyun				--start-group			\
188*4882a593Smuzhiyun				${KBUILD_VMLINUX_LIBS}		\
189*4882a593Smuzhiyun				--end-group			\
190*4882a593Smuzhiyun				${@}"
191*4882a593Smuzhiyun		fi
192*4882a593Smuzhiyun
193*4882a593Smuzhiyun		${LD} ${KBUILD_LDFLAGS} ${LDFLAGS_vmlinux}	\
194*4882a593Smuzhiyun			${strip_debug#-Wl,}			\
195*4882a593Smuzhiyun			-o ${output}				\
196*4882a593Smuzhiyun			-T ${lds} ${objects}
197*4882a593Smuzhiyun	else
198*4882a593Smuzhiyun		objects="-Wl,--whole-archive			\
199*4882a593Smuzhiyun			${KBUILD_VMLINUX_OBJS}			\
200*4882a593Smuzhiyun			-Wl,--no-whole-archive			\
201*4882a593Smuzhiyun			-Wl,--start-group			\
202*4882a593Smuzhiyun			${KBUILD_VMLINUX_LIBS}			\
203*4882a593Smuzhiyun			-Wl,--end-group				\
204*4882a593Smuzhiyun			${@}"
205*4882a593Smuzhiyun
206*4882a593Smuzhiyun		${CC} ${CFLAGS_vmlinux}				\
207*4882a593Smuzhiyun			${strip_debug}				\
208*4882a593Smuzhiyun			-o ${output}				\
209*4882a593Smuzhiyun			-Wl,-T,${lds}				\
210*4882a593Smuzhiyun			${objects}				\
211*4882a593Smuzhiyun			-lutil -lrt -lpthread
212*4882a593Smuzhiyun		rm -f linux
213*4882a593Smuzhiyun	fi
214*4882a593Smuzhiyun}
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun# generate .BTF typeinfo from DWARF debuginfo
217*4882a593Smuzhiyun# ${1} - vmlinux image
218*4882a593Smuzhiyun# ${2} - file to dump raw BTF data into
219*4882a593Smuzhiyungen_btf()
220*4882a593Smuzhiyun{
221*4882a593Smuzhiyun	local pahole_ver
222*4882a593Smuzhiyun
223*4882a593Smuzhiyun	if ! [ -x "$(command -v ${PAHOLE})" ]; then
224*4882a593Smuzhiyun		echo >&2 "BTF: ${1}: pahole (${PAHOLE}) is not available"
225*4882a593Smuzhiyun		return 1
226*4882a593Smuzhiyun	fi
227*4882a593Smuzhiyun
228*4882a593Smuzhiyun	pahole_ver=$(${PAHOLE} --version | sed -E 's/v([0-9]+)\.([0-9]+)/\1\2/')
229*4882a593Smuzhiyun	if [ "${pahole_ver}" -lt "116" ]; then
230*4882a593Smuzhiyun		echo >&2 "BTF: ${1}: pahole version $(${PAHOLE} --version) is too old, need at least v1.16"
231*4882a593Smuzhiyun		return 1
232*4882a593Smuzhiyun	fi
233*4882a593Smuzhiyun
234*4882a593Smuzhiyun	vmlinux_link ${1}
235*4882a593Smuzhiyun
236*4882a593Smuzhiyun	info "BTF" ${2}
237*4882a593Smuzhiyun	LLVM_OBJCOPY="${OBJCOPY}" ${PAHOLE} -J ${PAHOLE_FLAGS} ${1}
238*4882a593Smuzhiyun
239*4882a593Smuzhiyun	# Create ${2} which contains just .BTF section but no symbols. Add
240*4882a593Smuzhiyun	# SHF_ALLOC because .BTF will be part of the vmlinux image. --strip-all
241*4882a593Smuzhiyun	# deletes all symbols including __start_BTF and __stop_BTF, which will
242*4882a593Smuzhiyun	# be redefined in the linker script. Add 2>/dev/null to suppress GNU
243*4882a593Smuzhiyun	# objcopy warnings: "empty loadable segment detected at ..."
244*4882a593Smuzhiyun	${OBJCOPY} --only-section=.BTF --set-section-flags .BTF=alloc,readonly \
245*4882a593Smuzhiyun		--strip-all ${1} ${2} 2>/dev/null
246*4882a593Smuzhiyun	# Change e_type to ET_REL so that it can be used to link final vmlinux.
247*4882a593Smuzhiyun	# Unlike GNU ld, lld does not allow an ET_EXEC input.
248*4882a593Smuzhiyun	printf '\1' | dd of=${2} conv=notrunc bs=1 seek=16 status=none
249*4882a593Smuzhiyun}
250*4882a593Smuzhiyun
251*4882a593Smuzhiyun# Create ${2} .S file with all symbols from the ${1} object file
252*4882a593Smuzhiyunkallsyms()
253*4882a593Smuzhiyun{
254*4882a593Smuzhiyun	local kallsymopt;
255*4882a593Smuzhiyun
256*4882a593Smuzhiyun	if [ -n "${CONFIG_KALLSYMS_ALL}" ]; then
257*4882a593Smuzhiyun		kallsymopt="${kallsymopt} --all-symbols"
258*4882a593Smuzhiyun	fi
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun	if [ -n "${CONFIG_KALLSYMS_ABSOLUTE_PERCPU}" ]; then
261*4882a593Smuzhiyun		kallsymopt="${kallsymopt} --absolute-percpu"
262*4882a593Smuzhiyun	fi
263*4882a593Smuzhiyun
264*4882a593Smuzhiyun	if [ -n "${CONFIG_KALLSYMS_BASE_RELATIVE}" ]; then
265*4882a593Smuzhiyun		kallsymopt="${kallsymopt} --base-relative"
266*4882a593Smuzhiyun	fi
267*4882a593Smuzhiyun
268*4882a593Smuzhiyun	info KSYMS ${2}
269*4882a593Smuzhiyun
270*4882a593Smuzhiyun	if [ -n "${CONFIG_CFI_CLANG}" ]; then
271*4882a593Smuzhiyun		${PERL} ${srctree}/scripts/generate_cfi_kallsyms.pl ${1} | \
272*4882a593Smuzhiyun			sort -n > .tmp_kallsyms
273*4882a593Smuzhiyun	else
274*4882a593Smuzhiyun		${NM} -n ${1} > .tmp_kallsyms
275*4882a593Smuzhiyun	fi
276*4882a593Smuzhiyun
277*4882a593Smuzhiyun	scripts/kallsyms ${kallsymopt} < .tmp_kallsyms > ${2}
278*4882a593Smuzhiyun}
279*4882a593Smuzhiyun
280*4882a593Smuzhiyun# Perform one step in kallsyms generation, including temporary linking of
281*4882a593Smuzhiyun# vmlinux.
282*4882a593Smuzhiyunkallsyms_step()
283*4882a593Smuzhiyun{
284*4882a593Smuzhiyun	kallsymso_prev=${kallsymso}
285*4882a593Smuzhiyun	kallsyms_vmlinux=.tmp_vmlinux.kallsyms${1}
286*4882a593Smuzhiyun	kallsymso=${kallsyms_vmlinux}.o
287*4882a593Smuzhiyun	kallsyms_S=${kallsyms_vmlinux}.S
288*4882a593Smuzhiyun
289*4882a593Smuzhiyun	vmlinux_link ${kallsyms_vmlinux} "${kallsymso_prev}" ${btf_vmlinux_bin_o}
290*4882a593Smuzhiyun	kallsyms ${kallsyms_vmlinux} ${kallsyms_S}
291*4882a593Smuzhiyun
292*4882a593Smuzhiyun	info AS ${kallsyms_S}
293*4882a593Smuzhiyun	${CC} ${NOSTDINC_FLAGS} ${LINUXINCLUDE} ${KBUILD_CPPFLAGS} \
294*4882a593Smuzhiyun	      ${KBUILD_AFLAGS} ${KBUILD_AFLAGS_KERNEL} \
295*4882a593Smuzhiyun	      -c -o ${kallsymso} ${kallsyms_S}
296*4882a593Smuzhiyun}
297*4882a593Smuzhiyun
298*4882a593Smuzhiyun# Create map file with all symbols from ${1}
299*4882a593Smuzhiyun# See mksymap for additional details
300*4882a593Smuzhiyunmksysmap()
301*4882a593Smuzhiyun{
302*4882a593Smuzhiyun	${CONFIG_SHELL} "${srctree}/scripts/mksysmap" ${1} ${2}
303*4882a593Smuzhiyun}
304*4882a593Smuzhiyun
305*4882a593Smuzhiyunsorttable()
306*4882a593Smuzhiyun{
307*4882a593Smuzhiyun	${objtree}/scripts/sorttable ${1}
308*4882a593Smuzhiyun}
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun# Delete output files in case of error
311*4882a593Smuzhiyuncleanup()
312*4882a593Smuzhiyun{
313*4882a593Smuzhiyun	rm -f .btf.*
314*4882a593Smuzhiyun	rm -f .tmp_System.map
315*4882a593Smuzhiyun	rm -f .tmp_kallsyms
316*4882a593Smuzhiyun	rm -f .tmp_initcalls.lds
317*4882a593Smuzhiyun	rm -f .tmp_symversions.lds
318*4882a593Smuzhiyun	rm -f .tmp_vmlinux*
319*4882a593Smuzhiyun	rm -f System.map
320*4882a593Smuzhiyun	rm -f vmlinux
321*4882a593Smuzhiyun	rm -f vmlinux.o
322*4882a593Smuzhiyun}
323*4882a593Smuzhiyun
324*4882a593Smuzhiyunon_exit()
325*4882a593Smuzhiyun{
326*4882a593Smuzhiyun	if [ $? -ne 0 ]; then
327*4882a593Smuzhiyun		cleanup
328*4882a593Smuzhiyun	fi
329*4882a593Smuzhiyun}
330*4882a593Smuzhiyuntrap on_exit EXIT
331*4882a593Smuzhiyun
332*4882a593Smuzhiyunon_signals()
333*4882a593Smuzhiyun{
334*4882a593Smuzhiyun	exit 1
335*4882a593Smuzhiyun}
336*4882a593Smuzhiyuntrap on_signals HUP INT QUIT TERM
337*4882a593Smuzhiyun
338*4882a593Smuzhiyun# Use "make V=1" to debug this script
339*4882a593Smuzhiyuncase "${KBUILD_VERBOSE}" in
340*4882a593Smuzhiyun*1*)
341*4882a593Smuzhiyun	set -x
342*4882a593Smuzhiyun	;;
343*4882a593Smuzhiyunesac
344*4882a593Smuzhiyun
345*4882a593Smuzhiyunif [ "$1" = "clean" ]; then
346*4882a593Smuzhiyun	cleanup
347*4882a593Smuzhiyun	exit 0
348*4882a593Smuzhiyunfi
349*4882a593Smuzhiyun
350*4882a593Smuzhiyun# We need access to CONFIG_ symbols
351*4882a593Smuzhiyun. include/config/auto.conf
352*4882a593Smuzhiyun
353*4882a593Smuzhiyun# Update version
354*4882a593Smuzhiyuninfo GEN .version
355*4882a593Smuzhiyunif [ -r .version ]; then
356*4882a593Smuzhiyun	VERSION=$(expr 0$(cat .version) + 1)
357*4882a593Smuzhiyun	echo $VERSION > .version
358*4882a593Smuzhiyunelse
359*4882a593Smuzhiyun	rm -f .version
360*4882a593Smuzhiyun	echo 1 > .version
361*4882a593Smuzhiyunfi;
362*4882a593Smuzhiyun
363*4882a593Smuzhiyun# final build of init/
364*4882a593Smuzhiyun${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init need-builtin=1
365*4882a593Smuzhiyun
366*4882a593Smuzhiyun#link vmlinux.o
367*4882a593Smuzhiyunmodpost_link vmlinux.o
368*4882a593Smuzhiyunobjtool_link vmlinux.o
369*4882a593Smuzhiyun
370*4882a593Smuzhiyun# modpost vmlinux.o to check for section mismatches
371*4882a593Smuzhiyun${MAKE} -f "${srctree}/scripts/Makefile.modpost" MODPOST_VMLINUX=1
372*4882a593Smuzhiyun
373*4882a593Smuzhiyuninfo MODINFO modules.builtin.modinfo
374*4882a593Smuzhiyun${OBJCOPY} -j .modinfo -O binary vmlinux.o modules.builtin.modinfo
375*4882a593Smuzhiyuninfo GEN modules.builtin
376*4882a593Smuzhiyun# The second line aids cases where multiple modules share the same object.
377*4882a593Smuzhiyuntr '\0' '\n' < modules.builtin.modinfo | sed -n 's/^[[:alnum:]:_]*\.file=//p' |
378*4882a593Smuzhiyun	tr ' ' '\n' | uniq | sed -e 's:^:kernel/:' -e 's/$/.ko/' > modules.builtin
379*4882a593Smuzhiyun
380*4882a593Smuzhiyunbtf_vmlinux_bin_o=""
381*4882a593Smuzhiyunif [ -n "${CONFIG_DEBUG_INFO_BTF}" ]; then
382*4882a593Smuzhiyun	btf_vmlinux_bin_o=.btf.vmlinux.bin.o
383*4882a593Smuzhiyun	if ! gen_btf .tmp_vmlinux.btf $btf_vmlinux_bin_o ; then
384*4882a593Smuzhiyun		echo >&2 "Failed to generate BTF for vmlinux"
385*4882a593Smuzhiyun		echo >&2 "Try to disable CONFIG_DEBUG_INFO_BTF"
386*4882a593Smuzhiyun		exit 1
387*4882a593Smuzhiyun	fi
388*4882a593Smuzhiyunfi
389*4882a593Smuzhiyun
390*4882a593Smuzhiyunkallsymso=""
391*4882a593Smuzhiyunkallsymso_prev=""
392*4882a593Smuzhiyunkallsyms_vmlinux=""
393*4882a593Smuzhiyunif [ -n "${CONFIG_KALLSYMS}" ]; then
394*4882a593Smuzhiyun
395*4882a593Smuzhiyun	# kallsyms support
396*4882a593Smuzhiyun	# Generate section listing all symbols and add it into vmlinux
397*4882a593Smuzhiyun	# It's a three step process:
398*4882a593Smuzhiyun	# 1)  Link .tmp_vmlinux1 so it has all symbols and sections,
399*4882a593Smuzhiyun	#     but __kallsyms is empty.
400*4882a593Smuzhiyun	#     Running kallsyms on that gives us .tmp_kallsyms1.o with
401*4882a593Smuzhiyun	#     the right size
402*4882a593Smuzhiyun	# 2)  Link .tmp_vmlinux2 so it now has a __kallsyms section of
403*4882a593Smuzhiyun	#     the right size, but due to the added section, some
404*4882a593Smuzhiyun	#     addresses have shifted.
405*4882a593Smuzhiyun	#     From here, we generate a correct .tmp_kallsyms2.o
406*4882a593Smuzhiyun	# 3)  That link may have expanded the kernel image enough that
407*4882a593Smuzhiyun	#     more linker branch stubs / trampolines had to be added, which
408*4882a593Smuzhiyun	#     introduces new names, which further expands kallsyms. Do another
409*4882a593Smuzhiyun	#     pass if that is the case. In theory it's possible this results
410*4882a593Smuzhiyun	#     in even more stubs, but unlikely.
411*4882a593Smuzhiyun	#     KALLSYMS_EXTRA_PASS=1 may also used to debug or work around
412*4882a593Smuzhiyun	#     other bugs.
413*4882a593Smuzhiyun	# 4)  The correct ${kallsymso} is linked into the final vmlinux.
414*4882a593Smuzhiyun	#
415*4882a593Smuzhiyun	# a)  Verify that the System.map from vmlinux matches the map from
416*4882a593Smuzhiyun	#     ${kallsymso}.
417*4882a593Smuzhiyun
418*4882a593Smuzhiyun	kallsyms_step 1
419*4882a593Smuzhiyun	kallsyms_step 2
420*4882a593Smuzhiyun
421*4882a593Smuzhiyun	# step 3
422*4882a593Smuzhiyun	size1=$(${CONFIG_SHELL} "${srctree}/scripts/file-size.sh" ${kallsymso_prev})
423*4882a593Smuzhiyun	size2=$(${CONFIG_SHELL} "${srctree}/scripts/file-size.sh" ${kallsymso})
424*4882a593Smuzhiyun
425*4882a593Smuzhiyun	if [ $size1 -ne $size2 ] || [ -n "${KALLSYMS_EXTRA_PASS}" ]; then
426*4882a593Smuzhiyun		kallsyms_step 3
427*4882a593Smuzhiyun	fi
428*4882a593Smuzhiyunfi
429*4882a593Smuzhiyun
430*4882a593Smuzhiyunvmlinux_link vmlinux "${kallsymso}" ${btf_vmlinux_bin_o}
431*4882a593Smuzhiyun
432*4882a593Smuzhiyun# fill in BTF IDs
433*4882a593Smuzhiyunif [ -n "${CONFIG_DEBUG_INFO_BTF}" -a -n "${CONFIG_BPF}" ]; then
434*4882a593Smuzhiyun	info BTFIDS vmlinux
435*4882a593Smuzhiyun	${RESOLVE_BTFIDS} vmlinux
436*4882a593Smuzhiyunfi
437*4882a593Smuzhiyun
438*4882a593Smuzhiyunif [ -n "${CONFIG_BUILDTIME_TABLE_SORT}" ]; then
439*4882a593Smuzhiyun	info SORTTAB vmlinux
440*4882a593Smuzhiyun	if ! sorttable vmlinux; then
441*4882a593Smuzhiyun		echo >&2 Failed to sort kernel tables
442*4882a593Smuzhiyun		exit 1
443*4882a593Smuzhiyun	fi
444*4882a593Smuzhiyunfi
445*4882a593Smuzhiyun
446*4882a593Smuzhiyuninfo SYSMAP System.map
447*4882a593Smuzhiyunmksysmap vmlinux System.map
448*4882a593Smuzhiyun
449*4882a593Smuzhiyun# step a (see comment above)
450*4882a593Smuzhiyunif [ -n "${CONFIG_KALLSYMS}" ]; then
451*4882a593Smuzhiyun	mksysmap ${kallsyms_vmlinux} .tmp_System.map
452*4882a593Smuzhiyun
453*4882a593Smuzhiyun	if ! cmp -s System.map .tmp_System.map; then
454*4882a593Smuzhiyun		echo >&2 Inconsistent kallsyms data
455*4882a593Smuzhiyun		echo >&2 Try "make KALLSYMS_EXTRA_PASS=1" as a workaround
456*4882a593Smuzhiyun		exit 1
457*4882a593Smuzhiyun	fi
458*4882a593Smuzhiyunfi
459