diff options
Diffstat (limited to 'scripts/link-vmlinux.sh')
-rwxr-xr-x | scripts/link-vmlinux.sh | 85 |
1 files changed, 78 insertions, 7 deletions
diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index e6818b8e7141..ecba415423ec 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -61,7 +61,39 @@ archive_builtin() ${AR} rcsTP${KBUILD_ARFLAGS} built-in.o \ ${KBUILD_VMLINUX_INIT} \ ${KBUILD_VMLINUX_MAIN} + + if [ -n "${CONFIG_LTO_CLANG}" ]; then + mv -f built-in.o built-in.o.tmp + ${LLVM_AR} rcsT${KBUILD_ARFLAGS} built-in.o $(${AR} t built-in.o.tmp) + rm -f built-in.o.tmp + fi + fi +} + +# If CONFIG_LTO_CLANG is selected, generate a linker script to ensure correct +# ordering of initcalls, and with CONFIG_MODVERSIONS also enabled, collect the +# previously generated symbol versions into the same script. +lto_lds() +{ + if [ -z "${CONFIG_LTO_CLANG}" ]; then + return + fi + + ${srctree}/scripts/generate_initcall_order.pl \ + built-in.o ${KBUILD_VMLINUX_LIBS} \ + > .tmp_lto.lds + + if [ -n "${CONFIG_MODVERSIONS}" ]; then + for a in built-in.o ${KBUILD_VMLINUX_LIBS}; do + for o in $(${AR} t $a); do + if [ -f ${o}.symversions ]; then + cat ${o}.symversions >> .tmp_lto.lds + fi + done + done fi + + echo "-T .tmp_lto.lds" } # Link of vmlinux.o used for section mismatch analysis @@ -84,7 +116,29 @@ modpost_link() ${KBUILD_VMLINUX_LIBS} \ --end-group" fi - ${LD} ${LDFLAGS} -r -o ${1} ${objects} + + if [ -n "${CONFIG_LTO_CLANG}" ]; then + # This might take a while, so indicate that we're doing + # an LTO link + info LTO vmlinux.o + else + info LD vmlinux.o + fi + + ${LD} ${LDFLAGS} -r -o ${1} $(lto_lds) ${objects} +} + +# If CONFIG_LTO_CLANG is selected, we postpone running recordmcount until +# we have compiled LLVM IR to an object file. +recordmcount() +{ + if [ -z "${CONFIG_LTO_CLANG}" ]; then + return + fi + + if [ -n "${CONFIG_FTRACE_MCOUNT_RECORD}" ]; then + scripts/recordmcount ${RECORDMCOUNT_FLAGS} $* + fi } # Link of vmlinux @@ -96,8 +150,16 @@ vmlinux_link() local objects if [ "${SRCARCH}" != "um" ]; then - if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then - objects="--whole-archive \ + local ld=${LD} + local ldflags="${LDFLAGS} ${LDFLAGS_vmlinux}" + + if [ -n "${LDFINAL_vmlinux}" ]; then + ld=${LDFINAL_vmlinux} + ldflags="${LDFLAGS_FINAL_vmlinux} ${LDFLAGS_vmlinux}" + fi + + if [[ -n "${CONFIG_THIN_ARCHIVES}" && -z "${CONFIG_LTO_CLANG}" ]]; then + objects="--whole-archive \ built-in.o \ --no-whole-archive \ --start-group \ @@ -113,8 +175,7 @@ vmlinux_link() ${1}" fi - ${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} -o ${2} \ - -T ${lds} ${objects} + ${ld} ${ldflags} -o ${2} -T ${lds} ${objects} else if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then objects="-Wl,--whole-archive \ @@ -141,7 +202,6 @@ vmlinux_link() fi } - # Create ${2} .o file with all symbols from the ${1} object file kallsyms() { @@ -192,6 +252,7 @@ cleanup() rm -f .tmp_System.map rm -f .tmp_kallsyms* rm -f .tmp_version + rm -f .tmp_lto.lds rm -f .tmp_vmlinux* rm -f built-in.o rm -f System.map @@ -253,12 +314,22 @@ ${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init GCC_PLUGINS_CFLAGS="${GC archive_builtin #link vmlinux.o -info LD vmlinux.o modpost_link vmlinux.o # modpost vmlinux.o to check for section mismatches ${MAKE} -f "${srctree}/scripts/Makefile.modpost" vmlinux.o +if [ -n "${CONFIG_LTO_CLANG}" ]; then + # Re-use vmlinux.o, so we can avoid the slow LTO link step in + # vmlinux_link + KBUILD_VMLINUX_INIT= + KBUILD_VMLINUX_MAIN=vmlinux.o + KBUILD_VMLINUX_LIBS= + + # Call recordmcount if needed + recordmcount vmlinux.o +fi + kallsymso="" kallsyms_vmlinux="" if [ -n "${CONFIG_KALLSYMS}" ]; then |