kbuild: lto: fix module versioning
[linux-2.6-microblaze.git] / scripts / link-vmlinux.sh
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
31 set -e
32
33 LD="$1"
34 KBUILD_LDFLAGS="$2"
35 LDFLAGS_vmlinux="$3"
36
37 # Nice output in kbuild format
38 # Will be supressed by "make -s"
39 info()
40 {
41         if [ "${quiet}" != "silent_" ]; then
42                 printf "  %-7s %s\n" "${1}" "${2}"
43         fi
44 }
45
46 # If CONFIG_LTO_CLANG is selected, collect generated symbol versions into
47 # .tmp_symversions.lds
48 gen_symversions()
49 {
50         info GEN .tmp_symversions.lds
51         rm -f .tmp_symversions.lds
52
53         for o in ${KBUILD_VMLINUX_OBJS} ${KBUILD_VMLINUX_LIBS}; do
54                 if [ -f ${o}.symversions ]; then
55                         cat ${o}.symversions >> .tmp_symversions.lds
56                 fi
57         done
58 }
59
60 # Link of vmlinux.o used for section mismatch analysis
61 # ${1} output file
62 modpost_link()
63 {
64         local objects
65         local lds=""
66
67         objects="--whole-archive                                \
68                 ${KBUILD_VMLINUX_OBJS}                          \
69                 --no-whole-archive                              \
70                 --start-group                                   \
71                 ${KBUILD_VMLINUX_LIBS}                          \
72                 --end-group"
73
74         if [ -n "${CONFIG_LTO_CLANG}" ]; then
75                 if [ -n "${CONFIG_MODVERSIONS}" ]; then
76                         gen_symversions
77                         lds="${lds} -T .tmp_symversions.lds"
78                 fi
79
80                 # This might take a while, so indicate that we're doing
81                 # an LTO link
82                 info LTO ${1}
83         else
84                 info LD ${1}
85         fi
86
87         ${LD} ${KBUILD_LDFLAGS} -r -o ${1} ${lds} ${objects}
88 }
89
90 objtool_link()
91 {
92         local objtoolopt;
93
94         if [ -n "${CONFIG_VMLINUX_VALIDATION}" ]; then
95                 objtoolopt="check"
96                 if [ -z "${CONFIG_FRAME_POINTER}" ]; then
97                         objtoolopt="${objtoolopt} --no-fp"
98                 fi
99                 if [ -n "${CONFIG_GCOV_KERNEL}" ]; then
100                         objtoolopt="${objtoolopt} --no-unreachable"
101                 fi
102                 if [ -n "${CONFIG_RETPOLINE}" ]; then
103                         objtoolopt="${objtoolopt} --retpoline"
104                 fi
105                 if [ -n "${CONFIG_X86_SMAP}" ]; then
106                         objtoolopt="${objtoolopt} --uaccess"
107                 fi
108                 info OBJTOOL ${1}
109                 tools/objtool/objtool ${objtoolopt} ${1}
110         fi
111 }
112
113 # Link of vmlinux
114 # ${1} - output file
115 # ${2}, ${3}, ... - optional extra .o files
116 vmlinux_link()
117 {
118         local lds="${objtree}/${KBUILD_LDS}"
119         local output=${1}
120         local objects
121         local strip_debug
122
123         info LD ${output}
124
125         # skip output file argument
126         shift
127
128         # The kallsyms linking does not need debug symbols included.
129         if [ "$output" != "${output#.tmp_vmlinux.kallsyms}" ] ; then
130                 strip_debug=-Wl,--strip-debug
131         fi
132
133         if [ "${SRCARCH}" != "um" ]; then
134                 if [ -n "${CONFIG_LTO_CLANG}" ]; then
135                         # Use vmlinux.o instead of performing the slow LTO
136                         # link again.
137                         objects="--whole-archive                \
138                                 vmlinux.o                       \
139                                 --no-whole-archive              \
140                                 ${@}"
141                 else
142                         objects="--whole-archive                \
143                                 ${KBUILD_VMLINUX_OBJS}          \
144                                 --no-whole-archive              \
145                                 --start-group                   \
146                                 ${KBUILD_VMLINUX_LIBS}          \
147                                 --end-group                     \
148                                 ${@}"
149                 fi
150
151                 ${LD} ${KBUILD_LDFLAGS} ${LDFLAGS_vmlinux}      \
152                         ${strip_debug#-Wl,}                     \
153                         -o ${output}                            \
154                         -T ${lds} ${objects}
155         else
156                 objects="-Wl,--whole-archive                    \
157                         ${KBUILD_VMLINUX_OBJS}                  \
158                         -Wl,--no-whole-archive                  \
159                         -Wl,--start-group                       \
160                         ${KBUILD_VMLINUX_LIBS}                  \
161                         -Wl,--end-group                         \
162                         ${@}"
163
164                 ${CC} ${CFLAGS_vmlinux}                         \
165                         ${strip_debug}                          \
166                         -o ${output}                            \
167                         -Wl,-T,${lds}                           \
168                         ${objects}                              \
169                         -lutil -lrt -lpthread
170                 rm -f linux
171         fi
172 }
173
174 # generate .BTF typeinfo from DWARF debuginfo
175 # ${1} - vmlinux image
176 # ${2} - file to dump raw BTF data into
177 gen_btf()
178 {
179         local pahole_ver
180
181         if ! [ -x "$(command -v ${PAHOLE})" ]; then
182                 echo >&2 "BTF: ${1}: pahole (${PAHOLE}) is not available"
183                 return 1
184         fi
185
186         pahole_ver=$(${PAHOLE} --version | sed -E 's/v([0-9]+)\.([0-9]+)/\1\2/')
187         if [ "${pahole_ver}" -lt "116" ]; then
188                 echo >&2 "BTF: ${1}: pahole version $(${PAHOLE} --version) is too old, need at least v1.16"
189                 return 1
190         fi
191
192         vmlinux_link ${1}
193
194         info "BTF" ${2}
195         LLVM_OBJCOPY=${OBJCOPY} ${PAHOLE} -J ${1}
196
197         # Create ${2} which contains just .BTF section but no symbols. Add
198         # SHF_ALLOC because .BTF will be part of the vmlinux image. --strip-all
199         # deletes all symbols including __start_BTF and __stop_BTF, which will
200         # be redefined in the linker script. Add 2>/dev/null to suppress GNU
201         # objcopy warnings: "empty loadable segment detected at ..."
202         ${OBJCOPY} --only-section=.BTF --set-section-flags .BTF=alloc,readonly \
203                 --strip-all ${1} ${2} 2>/dev/null
204         # Change e_type to ET_REL so that it can be used to link final vmlinux.
205         # Unlike GNU ld, lld does not allow an ET_EXEC input.
206         printf '\1' | dd of=${2} conv=notrunc bs=1 seek=16 status=none
207 }
208
209 # Create ${2} .S file with all symbols from the ${1} object file
210 kallsyms()
211 {
212         local kallsymopt;
213
214         if [ -n "${CONFIG_KALLSYMS_ALL}" ]; then
215                 kallsymopt="${kallsymopt} --all-symbols"
216         fi
217
218         if [ -n "${CONFIG_KALLSYMS_ABSOLUTE_PERCPU}" ]; then
219                 kallsymopt="${kallsymopt} --absolute-percpu"
220         fi
221
222         if [ -n "${CONFIG_KALLSYMS_BASE_RELATIVE}" ]; then
223                 kallsymopt="${kallsymopt} --base-relative"
224         fi
225
226         info KSYMS ${2}
227         ${NM} -n ${1} | scripts/kallsyms ${kallsymopt} > ${2}
228 }
229
230 # Perform one step in kallsyms generation, including temporary linking of
231 # vmlinux.
232 kallsyms_step()
233 {
234         kallsymso_prev=${kallsymso}
235         kallsyms_vmlinux=.tmp_vmlinux.kallsyms${1}
236         kallsymso=${kallsyms_vmlinux}.o
237         kallsyms_S=${kallsyms_vmlinux}.S
238
239         vmlinux_link ${kallsyms_vmlinux} "${kallsymso_prev}" ${btf_vmlinux_bin_o}
240         kallsyms ${kallsyms_vmlinux} ${kallsyms_S}
241
242         info AS ${kallsyms_S}
243         ${CC} ${NOSTDINC_FLAGS} ${LINUXINCLUDE} ${KBUILD_CPPFLAGS} \
244               ${KBUILD_AFLAGS} ${KBUILD_AFLAGS_KERNEL} \
245               -c -o ${kallsymso} ${kallsyms_S}
246 }
247
248 # Create map file with all symbols from ${1}
249 # See mksymap for additional details
250 mksysmap()
251 {
252         ${CONFIG_SHELL} "${srctree}/scripts/mksysmap" ${1} ${2}
253 }
254
255 sorttable()
256 {
257         ${objtree}/scripts/sorttable ${1}
258 }
259
260 # Delete output files in case of error
261 cleanup()
262 {
263         rm -f .btf.*
264         rm -f .tmp_System.map
265         rm -f .tmp_symversions.lds
266         rm -f .tmp_vmlinux*
267         rm -f System.map
268         rm -f vmlinux
269         rm -f vmlinux.o
270 }
271
272 on_exit()
273 {
274         if [ $? -ne 0 ]; then
275                 cleanup
276         fi
277 }
278 trap on_exit EXIT
279
280 on_signals()
281 {
282         exit 1
283 }
284 trap on_signals HUP INT QUIT TERM
285
286 # Use "make V=1" to debug this script
287 case "${KBUILD_VERBOSE}" in
288 *1*)
289         set -x
290         ;;
291 esac
292
293 if [ "$1" = "clean" ]; then
294         cleanup
295         exit 0
296 fi
297
298 # We need access to CONFIG_ symbols
299 . include/config/auto.conf
300
301 # Update version
302 info GEN .version
303 if [ -r .version ]; then
304         VERSION=$(expr 0$(cat .version) + 1)
305         echo $VERSION > .version
306 else
307         rm -f .version
308         echo 1 > .version
309 fi;
310
311 # final build of init/
312 ${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init need-builtin=1
313
314 #link vmlinux.o
315 modpost_link vmlinux.o
316 objtool_link vmlinux.o
317
318 # modpost vmlinux.o to check for section mismatches
319 ${MAKE} -f "${srctree}/scripts/Makefile.modpost" MODPOST_VMLINUX=1
320
321 info MODINFO modules.builtin.modinfo
322 ${OBJCOPY} -j .modinfo -O binary vmlinux.o modules.builtin.modinfo
323 info GEN modules.builtin
324 # The second line aids cases where multiple modules share the same object.
325 tr '\0' '\n' < modules.builtin.modinfo | sed -n 's/^[[:alnum:]:_]*\.file=//p' |
326         tr ' ' '\n' | uniq | sed -e 's:^:kernel/:' -e 's/$/.ko/' > modules.builtin
327
328 btf_vmlinux_bin_o=""
329 if [ -n "${CONFIG_DEBUG_INFO_BTF}" ]; then
330         btf_vmlinux_bin_o=.btf.vmlinux.bin.o
331         if ! gen_btf .tmp_vmlinux.btf $btf_vmlinux_bin_o ; then
332                 echo >&2 "Failed to generate BTF for vmlinux"
333                 echo >&2 "Try to disable CONFIG_DEBUG_INFO_BTF"
334                 exit 1
335         fi
336 fi
337
338 kallsymso=""
339 kallsymso_prev=""
340 kallsyms_vmlinux=""
341 if [ -n "${CONFIG_KALLSYMS}" ]; then
342
343         # kallsyms support
344         # Generate section listing all symbols and add it into vmlinux
345         # It's a three step process:
346         # 1)  Link .tmp_vmlinux1 so it has all symbols and sections,
347         #     but __kallsyms is empty.
348         #     Running kallsyms on that gives us .tmp_kallsyms1.o with
349         #     the right size
350         # 2)  Link .tmp_vmlinux2 so it now has a __kallsyms section of
351         #     the right size, but due to the added section, some
352         #     addresses have shifted.
353         #     From here, we generate a correct .tmp_kallsyms2.o
354         # 3)  That link may have expanded the kernel image enough that
355         #     more linker branch stubs / trampolines had to be added, which
356         #     introduces new names, which further expands kallsyms. Do another
357         #     pass if that is the case. In theory it's possible this results
358         #     in even more stubs, but unlikely.
359         #     KALLSYMS_EXTRA_PASS=1 may also used to debug or work around
360         #     other bugs.
361         # 4)  The correct ${kallsymso} is linked into the final vmlinux.
362         #
363         # a)  Verify that the System.map from vmlinux matches the map from
364         #     ${kallsymso}.
365
366         kallsyms_step 1
367         kallsyms_step 2
368
369         # step 3
370         size1=$(${CONFIG_SHELL} "${srctree}/scripts/file-size.sh" ${kallsymso_prev})
371         size2=$(${CONFIG_SHELL} "${srctree}/scripts/file-size.sh" ${kallsymso})
372
373         if [ $size1 -ne $size2 ] || [ -n "${KALLSYMS_EXTRA_PASS}" ]; then
374                 kallsyms_step 3
375         fi
376 fi
377
378 vmlinux_link vmlinux "${kallsymso}" ${btf_vmlinux_bin_o}
379
380 # fill in BTF IDs
381 if [ -n "${CONFIG_DEBUG_INFO_BTF}" -a -n "${CONFIG_BPF}" ]; then
382         info BTFIDS vmlinux
383         ${RESOLVE_BTFIDS} vmlinux
384 fi
385
386 if [ -n "${CONFIG_BUILDTIME_TABLE_SORT}" ]; then
387         info SORTTAB vmlinux
388         if ! sorttable vmlinux; then
389                 echo >&2 Failed to sort kernel tables
390                 exit 1
391         fi
392 fi
393
394 info SYSMAP System.map
395 mksysmap vmlinux System.map
396
397 # step a (see comment above)
398 if [ -n "${CONFIG_KALLSYMS}" ]; then
399         mksysmap ${kallsyms_vmlinux} .tmp_System.map
400
401         if ! cmp -s System.map .tmp_System.map; then
402                 echo >&2 Inconsistent kallsyms data
403                 echo >&2 Try "make KALLSYMS_EXTRA_PASS=1" as a workaround
404                 exit 1
405         fi
406 fi