[COFF] Add libcall symbols to the link when LTO is being used
llvm-svn: 369694
This commit is contained in:
parent
b43923da5b
commit
a1c022c791
|
@ -1055,6 +1055,12 @@ void LinkerDriver::maybeExportMinGWSymbols(const opt::InputArgList &args) {
|
|||
});
|
||||
}
|
||||
|
||||
static const char *libcallRoutineNames[] = {
|
||||
#define HANDLE_LIBCALL(code, name) name,
|
||||
#include "llvm/IR/RuntimeLibcalls.def"
|
||||
#undef HANDLE_LIBCALL
|
||||
};
|
||||
|
||||
void LinkerDriver::link(ArrayRef<const char *> argsArr) {
|
||||
// Needed for LTO.
|
||||
InitializeAllTargetInfos();
|
||||
|
@ -1758,6 +1764,15 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr) {
|
|||
u->weakAlias = symtab->addUndefined(to);
|
||||
}
|
||||
|
||||
// If any inputs are bitcode files, the LTO code generator may create
|
||||
// references to library functions that are not 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.
|
||||
if (!BitcodeFile::instances.empty())
|
||||
for (const char *s : libcallRoutineNames)
|
||||
symtab->addLibcall(s);
|
||||
|
||||
// Windows specific -- if __load_config_used can be resolved, resolve it.
|
||||
if (symtab->findUnderscore("_load_config_used"))
|
||||
addUndefined(mangle("_load_config_used"));
|
||||
|
|
|
@ -584,6 +584,18 @@ Symbol *SymbolTable::addImportThunk(StringRef name, DefinedImportData *id,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void SymbolTable::addLibcall(StringRef name) {
|
||||
Symbol *sym = findUnderscore(name);
|
||||
if (!sym)
|
||||
return;
|
||||
|
||||
if (Lazy *l = dyn_cast<Lazy>(sym)) {
|
||||
MemoryBufferRef mb = l->getMemberBuffer();
|
||||
if (identify_magic(mb.getBuffer()) == llvm::file_magic::bitcode)
|
||||
addUndefined(sym->getName());
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Chunk *> SymbolTable::getChunks() {
|
||||
std::vector<Chunk *> res;
|
||||
for (ObjFile *file : ObjFile::instances) {
|
||||
|
|
|
@ -100,6 +100,7 @@ public:
|
|||
Symbol *addImportData(StringRef n, ImportFile *f);
|
||||
Symbol *addImportThunk(StringRef name, DefinedImportData *s,
|
||||
uint16_t machine);
|
||||
void addLibcall(StringRef name);
|
||||
|
||||
void reportDuplicate(Symbol *existing, InputFile *newFile);
|
||||
|
||||
|
|
|
@ -118,5 +118,14 @@ Defined *Undefined::getWeakAlias() {
|
|||
return d;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MemoryBufferRef Lazy::getMemberBuffer() {
|
||||
Archive::Child c =
|
||||
CHECK(sym.getMember(),
|
||||
"could not get the member for symbol " + toCOFFString(sym));
|
||||
return CHECK(c.getMemoryBufferRef(),
|
||||
"could not get the buffer for the member defining symbol " +
|
||||
toCOFFString(sym));
|
||||
}
|
||||
} // namespace coff
|
||||
} // namespace lld
|
||||
|
|
|
@ -265,6 +265,8 @@ public:
|
|||
|
||||
static bool classof(const Symbol *s) { return s->kind() == LazyKind; }
|
||||
|
||||
MemoryBufferRef getMemberBuffer();
|
||||
|
||||
ArchiveFile *file;
|
||||
|
||||
private:
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
|
||||
target triple = "i686-unknown-windows"
|
||||
|
||||
define void @memcpy() {
|
||||
ret void
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
.globl ___sync_val_compare_and_swap_8
|
||||
___sync_val_compare_and_swap_8:
|
|
@ -0,0 +1,22 @@
|
|||
; REQUIRES: x86
|
||||
; RUN: rm -f %t.a
|
||||
; RUN: llvm-as -o %t.obj %s
|
||||
; RUN: llvm-as -o %t2.obj %S/Inputs/libcall-archive.ll
|
||||
; RUN: llvm-mc -filetype=obj -triple=i686-unknown-windows -o %t3.obj %S/Inputs/libcall-archive.s
|
||||
; RUN: llvm-ar rcs %t.a %t2.obj %t3.obj
|
||||
; RUN: lld-link -out:%t.exe -subsystem:console -entry:start -safeseh:no -lldmap:- %t.obj %t.a | FileCheck %s
|
||||
|
||||
; CHECK-NOT: ___sync_val_compare_and_swap_8
|
||||
; CHECK: _start
|
||||
; CHECK: _memcpy
|
||||
|
||||
target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
|
||||
target triple = "i686-unknown-windows"
|
||||
|
||||
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)
|
Loading…
Reference in New Issue