OSDN Git Service

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