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