• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/bin/sh
2#
3# link vmlinux
4#
5# vmlinux is linked from the objects selected by $(KBUILD_VMLINUX_INIT) and
6# $(KBUILD_VMLINUX_MAIN). Most are built-in.o files from top-level directories
7# in the kernel tree, others are specified in arch/$(ARCH)/Makefile.
8# Ordering when linking is important, and $(KBUILD_VMLINUX_INIT) must be first.
9#
10# vmlinux
11#   ^
12#   |
13#   +-< $(KBUILD_VMLINUX_INIT)
14#   |   +--< init/version.o + more
15#   |
16#   +--< $(KBUILD_VMLINUX_MAIN)
17#   |    +--< drivers/built-in.o mm/built-in.o + more
18#   |
19#   +-< ${kallsymso} (see description in KALLSYMS section)
20#
21# vmlinux version (uname -v) cannot be updated during normal
22# descending-into-subdirs phase since we do not yet know if we need to
23# update vmlinux.
24# Therefore this step is delayed until just before final link of vmlinux.
25#
26# System.map is generated to document addresses of all kernel symbols
27
28# Error out on error
29set -e
30
31# Nice output in kbuild format
32# Will be supressed by "make -s"
33info()
34{
35	if [ "${quiet}" != "silent_" ]; then
36		printf "  %-7s %s\n" ${1} ${2}
37	fi
38}
39
40# Thin archive build here makes a final archive with
41# symbol table and indexes from vmlinux objects, which can be
42# used as input to linker.
43#
44# Traditional incremental style of link does not require this step
45#
46# built-in.o output file
47#
48archive_builtin()
49{
50	if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then
51		info AR built-in.o
52		rm -f built-in.o;
53		${AR} rcsT${KBUILD_ARFLAGS} built-in.o			\
54					${KBUILD_VMLINUX_INIT}		\
55					${KBUILD_VMLINUX_MAIN}
56
57		if [ -n "${CONFIG_LTO_CLANG}" ]; then
58			mv -f built-in.o built-in.o.tmp
59			${LLVM_AR} rcsT${KBUILD_ARFLAGS} built-in.o $(${AR} t built-in.o.tmp)
60			rm -f built-in.o.tmp
61		fi
62	fi
63}
64
65# If CONFIG_LTO_CLANG is selected, collect generated symbol versions into
66# .tmp_symversions
67modversions()
68{
69	if [ -z "${CONFIG_LTO_CLANG}" ]; then
70		return
71	fi
72
73	if [ -z "${CONFIG_MODVERSIONS}" ]; then
74		return
75	fi
76
77	rm -f .tmp_symversions
78
79	for a in built-in.o ${KBUILD_VMLINUX_LIBS}; do
80		for o in $(${AR} t $a); do
81			if [ -f ${o}.symversions ]; then
82				cat ${o}.symversions >> .tmp_symversions
83			fi
84		done
85	done
86
87	echo "-T .tmp_symversions"
88}
89
90# Link of vmlinux.o used for section mismatch analysis
91# ${1} output file
92modpost_link()
93{
94	local objects
95
96	if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then
97		objects="--whole-archive built-in.o"
98	else
99		objects="${KBUILD_VMLINUX_INIT}				\
100			--start-group					\
101			${KBUILD_VMLINUX_MAIN}				\
102			--end-group"
103	fi
104
105	if [ -n "${CONFIG_LTO_CLANG}" ]; then
106		# This might take a while, so indicate that we're doing
107		# an LTO link
108		info LTO vmlinux.o
109	else
110		info LD vmlinux.o
111	fi
112
113	${LD} ${LDFLAGS} -r -o ${1} $(modversions) ${objects}
114}
115
116# If CONFIG_LTO_CLANG is selected, we postpone running recordmcount until
117# we have compiled LLVM IR to an object file.
118recordmcount()
119{
120	if [ -z "${CONFIG_LTO_CLANG}" ]; then
121		return
122	fi
123
124	if [ -n "${CONFIG_FTRACE_MCOUNT_RECORD}" ]; then
125		scripts/recordmcount ${RECORDMCOUNT_FLAGS} $*
126	fi
127}
128
129# Link of vmlinux
130# ${1} - optional extra .o files
131# ${2} - output file
132vmlinux_link()
133{
134	local lds="${objtree}/${KBUILD_LDS}"
135	local objects
136
137	if [ "${SRCARCH}" != "um" ]; then
138		local ld=${LD}
139		local ldflags="${LDFLAGS} ${LDFLAGS_vmlinux}"
140
141		if [ -n "${LDFINAL_vmlinux}" ]; then
142			ld=${LDFINAL_vmlinux}
143			ldflags="${LDFLAGS_FINAL_vmlinux} ${LDFLAGS_vmlinux}"
144		fi
145
146		if [[ -n "${CONFIG_THIN_ARCHIVES}" && -z "${CONFIG_LTO_CLANG}" ]]; then
147			objects="--whole-archive built-in.o ${1}"
148		else
149			objects="${KBUILD_VMLINUX_INIT}			\
150				--start-group				\
151				${KBUILD_VMLINUX_MAIN}			\
152				--end-group				\
153				${1}"
154		fi
155
156		${ld} ${ldflags} -o ${2} -T ${lds} ${objects}
157	else
158		if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then
159			objects="-Wl,--whole-archive built-in.o ${1}"
160		else
161			objects="${KBUILD_VMLINUX_INIT}			\
162				-Wl,--start-group			\
163				${KBUILD_VMLINUX_MAIN}			\
164				-Wl,--end-group				\
165				${1}"
166		fi
167
168		${CC} ${CFLAGS_vmlinux} -o ${2}				\
169			-Wl,-T,${lds}					\
170			${objects}					\
171			-lutil -lrt -lpthread
172		rm -f linux
173	fi
174}
175
176# Create ${2} .o file with all symbols from the ${1} object file
177kallsyms()
178{
179	info KSYM ${2}
180	local kallsymopt;
181
182	if [ -n "${CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX}" ]; then
183		kallsymopt="${kallsymopt} --symbol-prefix=_"
184	fi
185
186	if [ -n "${CONFIG_KALLSYMS_ALL}" ]; then
187		kallsymopt="${kallsymopt} --all-symbols"
188	fi
189
190	if [ -n "${CONFIG_KALLSYMS_ABSOLUTE_PERCPU}" ]; then
191		kallsymopt="${kallsymopt} --absolute-percpu"
192	fi
193
194	if [ -n "${CONFIG_KALLSYMS_BASE_RELATIVE}" ]; then
195		kallsymopt="${kallsymopt} --base-relative"
196	fi
197
198	local aflags="${KBUILD_AFLAGS} ${KBUILD_AFLAGS_KERNEL}               \
199		      ${NOSTDINC_FLAGS} ${LINUXINCLUDE} ${KBUILD_CPPFLAGS}"
200
201	local afile="`basename ${2} .o`.S"
202
203	${NM} -n ${1} | scripts/kallsyms ${kallsymopt} > ${afile}
204	${CC} ${aflags} -c -o ${2} ${afile}
205}
206
207# Create map file with all symbols from ${1}
208# See mksymap for additional details
209mksysmap()
210{
211	${CONFIG_SHELL} "${srctree}/scripts/mksysmap" ${1} ${2}
212}
213
214sortextable()
215{
216	${objtree}/scripts/sortextable ${1}
217}
218
219# Delete output files in case of error
220cleanup()
221{
222	rm -f .old_version
223	rm -f .tmp_System.map
224	rm -f .tmp_kallsyms*
225	rm -f .tmp_version
226	rm -f .tmp_symversions
227	rm -f .tmp_vmlinux*
228	rm -f built-in.o
229	rm -f System.map
230	rm -f vmlinux
231	rm -f vmlinux.o
232}
233
234on_exit()
235{
236	if [ $? -ne 0 ]; then
237		cleanup
238	fi
239}
240trap on_exit EXIT
241
242on_signals()
243{
244	exit 1
245}
246trap on_signals HUP INT QUIT TERM
247
248#
249#
250# Use "make V=1" to debug this script
251case "${KBUILD_VERBOSE}" in
252*1*)
253	set -x
254	;;
255esac
256
257if [ "$1" = "clean" ]; then
258	cleanup
259	exit 0
260fi
261
262# We need access to CONFIG_ symbols
263case "${KCONFIG_CONFIG}" in
264*/*)
265	. "${KCONFIG_CONFIG}"
266	;;
267*)
268	# Force using a file from the current directory
269	. "./${KCONFIG_CONFIG}"
270esac
271
272# Update version
273info GEN .version
274if [ ! -r .version ]; then
275	rm -f .version;
276	echo 1 >.version;
277else
278	mv .version .old_version;
279	expr 0$(cat .old_version) + 1 >.version;
280fi;
281
282archive_builtin
283
284#link vmlinux.o
285modpost_link vmlinux.o
286
287# modpost vmlinux.o to check for section mismatches
288${MAKE} -f "${srctree}/scripts/Makefile.modpost" vmlinux.o
289
290# final build of init/
291${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init GCC_PLUGINS_CFLAGS="${GCC_PLUGINS_CFLAGS}"
292
293if [ -n "${CONFIG_LTO_CLANG}" ]; then
294	# Re-use vmlinux.o, so we can avoid the slow LTO link step in
295	# vmlinux_link
296	KBUILD_VMLINUX_INIT=
297	KBUILD_VMLINUX_MAIN=vmlinux.o
298
299	# Call recordmcount if needed
300	recordmcount vmlinux.o
301fi
302
303kallsymso=""
304kallsyms_vmlinux=""
305if [ -n "${CONFIG_KALLSYMS}" ]; then
306
307	# kallsyms support
308	# Generate section listing all symbols and add it into vmlinux
309	# It's a three step process:
310	# 1)  Link .tmp_vmlinux1 so it has all symbols and sections,
311	#     but __kallsyms is empty.
312	#     Running kallsyms on that gives us .tmp_kallsyms1.o with
313	#     the right size
314	# 2)  Link .tmp_vmlinux2 so it now has a __kallsyms section of
315	#     the right size, but due to the added section, some
316	#     addresses have shifted.
317	#     From here, we generate a correct .tmp_kallsyms2.o
318	# 2a) We may use an extra pass as this has been necessary to
319	#     woraround some alignment related bugs.
320	#     KALLSYMS_EXTRA_PASS=1 is used to trigger this.
321	# 3)  The correct ${kallsymso} is linked into the final vmlinux.
322	#
323	# a)  Verify that the System.map from vmlinux matches the map from
324	#     ${kallsymso}.
325
326	kallsymso=.tmp_kallsyms2.o
327	kallsyms_vmlinux=.tmp_vmlinux2
328
329	# step 1
330	vmlinux_link "" .tmp_vmlinux1
331	kallsyms .tmp_vmlinux1 .tmp_kallsyms1.o
332
333	# step 2
334	vmlinux_link .tmp_kallsyms1.o .tmp_vmlinux2
335	kallsyms .tmp_vmlinux2 .tmp_kallsyms2.o
336
337	# step 2a
338	if [ -n "${KALLSYMS_EXTRA_PASS}" ]; then
339		kallsymso=.tmp_kallsyms3.o
340		kallsyms_vmlinux=.tmp_vmlinux3
341
342		vmlinux_link .tmp_kallsyms2.o .tmp_vmlinux3
343
344		kallsyms .tmp_vmlinux3 .tmp_kallsyms3.o
345	fi
346fi
347
348info LD vmlinux
349vmlinux_link "${kallsymso}" vmlinux
350
351if [ -n "${CONFIG_BUILDTIME_EXTABLE_SORT}" ]; then
352	info SORTEX vmlinux
353	sortextable vmlinux
354fi
355
356info SYSMAP System.map
357mksysmap vmlinux System.map
358
359# step a (see comment above)
360if [ -n "${CONFIG_KALLSYMS}" ]; then
361	mksysmap ${kallsyms_vmlinux} .tmp_System.map
362
363	if ! cmp -s System.map .tmp_System.map; then
364		echo >&2 Inconsistent kallsyms data
365		echo >&2 Try "make KALLSYMS_EXTRA_PASS=1" as a workaround
366		exit 1
367	fi
368fi
369
370# We made a new kernel - delete old version file
371rm -f .old_version
372