link-vmlinux.sh 9.5 KB

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