From 103b4dc7002f33851174a433d63774780a953eba Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Tue, 31 Jul 2018 20:36:17 +0000 Subject: [PATCH] ELF: Add libcall symbols to the link when LTO is being used. If any of our inputs are bitcode files, the LTO code generator may create references to certain library functions that might not be explicit in the bitcode file's symbol table. If any of those library functions are defined in a bitcode file in an archive member, we need to arrange to use LTO to compile those archive members by adding them to the link beforehand. Differential Revision: https://reviews.llvm.org/D50017 git-svn-id: https://llvm.org/svn/llvm-project/lld/trunk@338434 91177308-0d34-0410-b5e6-96231b3b80d8 --- ELF/Driver.cpp | 22 +++++++++++++++++++--- test/ELF/lto/Inputs/libcall-archive.ll | 6 ++++++ test/ELF/lto/libcall-archive.ll | 20 ++++++++++++++++++++ 3 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 test/ELF/lto/Inputs/libcall-archive.ll create mode 100644 test/ELF/lto/libcall-archive.ll diff --git a/ELF/Driver.cpp b/ELF/Driver.cpp index 7794abce8..50555fb1c 100644 --- a/ELF/Driver.cpp +++ b/ELF/Driver.cpp @@ -1313,6 +1313,12 @@ static void findKeepUniqueSections(opt::InputArgList &Args) { } } +static const char *LibcallRoutineNames[] = { +#define HANDLE_LIBCALL(code, name) name, +#include "llvm/IR/RuntimeLibcalls.def" +#undef HANDLE_LIBCALL +}; + // Do actual linking. Note that when this function is called, // all linker scripts have already been parsed. template void LinkerDriver::link(opt::InputArgList &Args) { @@ -1379,11 +1385,21 @@ template void LinkerDriver::link(opt::InputArgList &Args) { for (StringRef S : Config->Undefined) handleUndefined(S); - // If an entry symbol is in a static archive, pull out that file now - // to complete the symbol table. After this, no new names except a - // few linker-synthesized ones will be added to the symbol table. + // If an entry symbol is in a static archive, pull out that file now. handleUndefined(Config->Entry); + // If any of our inputs are bitcode files, the LTO code generator may create + // references to certain library functions that might not be explicit in the + // bitcode file's symbol table. If any of those library functions are defined + // in a bitcode file in an archive member, we need to arrange to use LTO to + // compile those archive members by adding them to the link beforehand. + // + // With this the symbol table should be complete. After this, no new names + // except a few linker-synthesized ones will be added to the symbol table. + if (!BitcodeFiles.empty()) + for (const char *S : LibcallRoutineNames) + handleUndefined(S); + // Return if there were name resolution errors. if (errorCount()) return; diff --git a/test/ELF/lto/Inputs/libcall-archive.ll b/test/ELF/lto/Inputs/libcall-archive.ll new file mode 100644 index 000000000..4e6421c30 --- /dev/null +++ b/test/ELF/lto/Inputs/libcall-archive.ll @@ -0,0 +1,6 @@ +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define void @memcpy() { + ret void +} diff --git a/test/ELF/lto/libcall-archive.ll b/test/ELF/lto/libcall-archive.ll new file mode 100644 index 000000000..731e25938 --- /dev/null +++ b/test/ELF/lto/libcall-archive.ll @@ -0,0 +1,20 @@ +; RUN: rm -f %t.a +; RUN: llvm-as -o %t.o %s +; RUN: llvm-as -o %t2.o %S/Inputs/libcall-archive.ll +; RUN: llvm-ar rcs %t.a %t2.o +; RUN: ld.lld -o %t %t.o %t.a +; RUN: llvm-nm %t | FileCheck %s + +; CHECK: T _start +; CHECK: T memcpy + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define void @_start(i8* %a, i8* %b) { +entry: + call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* %b, i64 1024, i1 false) + ret void +} + +declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1)