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