forked from OSchip/llvm-project
Revert "[lld-link] implement -start-lib and -end-lib"
This reverts commit r370487 as it is causing ASan/MSan failures on sanitizer-x86_64-linux-fast llvm-svn: 370550
This commit is contained in:
parent
d8c20b9443
commit
802aab5de8
|
@ -231,7 +231,7 @@ void TypeServerSource::enqueue(const ObjFile *dependentFile,
|
|||
if (!it.second)
|
||||
return; // another OBJ already scheduled this PDB for load
|
||||
|
||||
driver->enqueuePath(*p, false, false);
|
||||
driver->enqueuePath(*p, false);
|
||||
}
|
||||
|
||||
// Create an instance of TypeServerSource or an error string if the PDB couldn't
|
||||
|
|
|
@ -170,7 +170,7 @@ MemoryBufferRef LinkerDriver::takeBuffer(std::unique_ptr<MemoryBuffer> mb) {
|
|||
}
|
||||
|
||||
void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuffer> mb,
|
||||
bool wholeArchive, bool lazy) {
|
||||
bool wholeArchive) {
|
||||
StringRef filename = mb->getBufferIdentifier();
|
||||
|
||||
MemoryBufferRef mbref = takeBuffer(std::move(mb));
|
||||
|
@ -195,17 +195,11 @@ void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuffer> mb,
|
|||
symtab->addFile(make<ArchiveFile>(mbref));
|
||||
break;
|
||||
case file_magic::bitcode:
|
||||
if (lazy)
|
||||
symtab->addFile(make<LazyObjFile>(mbref));
|
||||
else
|
||||
symtab->addFile(make<BitcodeFile>(mbref, "", 0));
|
||||
symtab->addFile(make<BitcodeFile>(mbref, "", 0));
|
||||
break;
|
||||
case file_magic::coff_object:
|
||||
case file_magic::coff_import_library:
|
||||
if (lazy)
|
||||
symtab->addFile(make<LazyObjFile>(mbref));
|
||||
else
|
||||
symtab->addFile(make<ObjFile>(mbref));
|
||||
symtab->addFile(make<ObjFile>(mbref));
|
||||
break;
|
||||
case file_magic::pdb:
|
||||
loadTypeServerSource(mbref);
|
||||
|
@ -226,7 +220,7 @@ void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuffer> mb,
|
|||
}
|
||||
}
|
||||
|
||||
void LinkerDriver::enqueuePath(StringRef path, bool wholeArchive, bool lazy) {
|
||||
void LinkerDriver::enqueuePath(StringRef path, bool wholeArchive) {
|
||||
auto future =
|
||||
std::make_shared<std::future<MBErrPair>>(createFutureForFile(path));
|
||||
std::string pathStr = path;
|
||||
|
@ -246,7 +240,7 @@ void LinkerDriver::enqueuePath(StringRef path, bool wholeArchive, bool lazy) {
|
|||
else
|
||||
error(msg + "; did you mean '" + nearest + "'");
|
||||
} else
|
||||
driver->addBuffer(std::move(mbOrErr.first), wholeArchive, lazy);
|
||||
driver->addBuffer(std::move(mbOrErr.first), wholeArchive);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -365,7 +359,7 @@ void LinkerDriver::parseDirectives(InputFile *file) {
|
|||
break;
|
||||
case OPT_defaultlib:
|
||||
if (Optional<StringRef> path = findLib(arg->getValue()))
|
||||
enqueuePath(*path, false, false);
|
||||
enqueuePath(*path, false);
|
||||
break;
|
||||
case OPT_entry:
|
||||
config->entry = addUndefined(mangle(arg->getValue()));
|
||||
|
@ -1559,45 +1553,19 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr) {
|
|||
return false;
|
||||
};
|
||||
|
||||
// Create a list of input files. These can be given as OPT_INPUT options
|
||||
// and OPT_wholearchive_file options, and we also need to track OPT_start_lib
|
||||
// and OPT_end_lib.
|
||||
bool inLib = false;
|
||||
for (auto *arg : args) {
|
||||
switch (arg->getOption().getID()) {
|
||||
case OPT_end_lib:
|
||||
if (!inLib)
|
||||
error("stray " + arg->getSpelling());
|
||||
inLib = false;
|
||||
break;
|
||||
case OPT_start_lib:
|
||||
if (inLib)
|
||||
error("nested " + arg->getSpelling());
|
||||
inLib = true;
|
||||
break;
|
||||
case OPT_wholearchive_file:
|
||||
if (Optional<StringRef> path = findFile(arg->getValue()))
|
||||
enqueuePath(*path, true, inLib);
|
||||
break;
|
||||
case OPT_INPUT:
|
||||
if (Optional<StringRef> path = findFile(arg->getValue()))
|
||||
enqueuePath(*path, isWholeArchive(*path), inLib);
|
||||
break;
|
||||
default:
|
||||
// Ignore other options.
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Create a list of input files. Files can be given as arguments
|
||||
// for /defaultlib option.
|
||||
for (auto *arg : args.filtered(OPT_INPUT, OPT_wholearchive_file))
|
||||
if (Optional<StringRef> path = findFile(arg->getValue()))
|
||||
enqueuePath(*path, isWholeArchive(*path));
|
||||
|
||||
// Process files specified as /defaultlib. These should be enequeued after
|
||||
// other files, which is why they are in a separate loop.
|
||||
for (auto *arg : args.filtered(OPT_defaultlib))
|
||||
if (Optional<StringRef> path = findLib(arg->getValue()))
|
||||
enqueuePath(*path, false, false);
|
||||
enqueuePath(*path, false);
|
||||
|
||||
// Windows specific -- Create a resource file containing a manifest file.
|
||||
if (config->manifest == Configuration::Embed)
|
||||
addBuffer(createManifestRes(), false, false);
|
||||
addBuffer(createManifestRes(), false);
|
||||
|
||||
// Read all input files given via the command line.
|
||||
run();
|
||||
|
@ -1814,7 +1782,7 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr) {
|
|||
if (args.hasArg(OPT_include_optional)) {
|
||||
// Handle /includeoptional
|
||||
for (auto *arg : args.filtered(OPT_include_optional))
|
||||
if (dyn_cast_or_null<LazyArchive>(symtab->find(arg->getValue())))
|
||||
if (dyn_cast_or_null<Lazy>(symtab->find(arg->getValue())))
|
||||
addUndefined(arg->getValue());
|
||||
while (run());
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ public:
|
|||
|
||||
MemoryBufferRef takeBuffer(std::unique_ptr<MemoryBuffer> mb);
|
||||
|
||||
void enqueuePath(StringRef path, bool wholeArchive, bool lazy);
|
||||
void enqueuePath(StringRef path, bool wholeArchive);
|
||||
|
||||
private:
|
||||
std::unique_ptr<llvm::TarWriter> tar; // for /linkrepro
|
||||
|
@ -124,8 +124,7 @@ private:
|
|||
StringRef findDefaultEntry();
|
||||
WindowsSubsystem inferSubsystem();
|
||||
|
||||
void addBuffer(std::unique_ptr<MemoryBuffer> mb, bool wholeArchive,
|
||||
bool lazy);
|
||||
void addBuffer(std::unique_ptr<MemoryBuffer> mb, bool wholeArchive);
|
||||
void addArchiveBuffer(MemoryBufferRef mbref, StringRef symName,
|
||||
StringRef parentName, uint64_t offsetInArchive);
|
||||
|
||||
|
|
|
@ -73,10 +73,6 @@ static void checkAndSetWeakAlias(SymbolTable *symtab, InputFile *f,
|
|||
}
|
||||
}
|
||||
|
||||
static bool ignoredSymbolName(StringRef name) {
|
||||
return name == "@feat.00" || name == "@comp.id";
|
||||
}
|
||||
|
||||
ArchiveFile::ArchiveFile(MemoryBufferRef m) : InputFile(ArchiveKind, m) {}
|
||||
|
||||
void ArchiveFile::parse() {
|
||||
|
@ -85,7 +81,7 @@ void ArchiveFile::parse() {
|
|||
|
||||
// Read the symbol table to construct Lazy objects.
|
||||
for (const Archive::Symbol &sym : file->symbols())
|
||||
symtab->addLazyArchive(this, sym);
|
||||
symtab->addLazy(this, sym);
|
||||
}
|
||||
|
||||
// Returns a buffer pointing to a member file containing a given symbol.
|
||||
|
@ -120,49 +116,6 @@ std::vector<MemoryBufferRef> getArchiveMembers(Archive *file) {
|
|||
return v;
|
||||
}
|
||||
|
||||
void LazyObjFile::fetch() {
|
||||
if (mb.getBuffer().empty())
|
||||
return;
|
||||
|
||||
InputFile *file;
|
||||
if (isBitcode(mb))
|
||||
file = make<BitcodeFile>(mb, "", 0, std::move(symbols));
|
||||
else
|
||||
file = make<ObjFile>(mb, std::move(symbols));
|
||||
mb = {};
|
||||
symtab->addFile(file);
|
||||
}
|
||||
|
||||
void LazyObjFile::parse() {
|
||||
if (isBitcode(this->mb)) {
|
||||
// Bitcode file.
|
||||
std::unique_ptr<lto::InputFile> obj =
|
||||
CHECK(lto::InputFile::create(this->mb), this);
|
||||
for (const lto::InputFile::Symbol &sym : obj->symbols()) {
|
||||
if (!sym.isUndefined())
|
||||
symtab->addLazyObject(this, sym.getName());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Native object file.
|
||||
COFFObjectFile *coffObj =
|
||||
dyn_cast<COFFObjectFile>(CHECK(createBinary(mb), this).get());
|
||||
uint32_t numSymbols = coffObj->getNumberOfSymbols();
|
||||
for (uint32_t i = 0; i < numSymbols; ++i) {
|
||||
COFFSymbolRef coffSym = check(coffObj->getSymbol(i));
|
||||
if (coffSym.isUndefined() || !coffSym.isExternal() ||
|
||||
coffSym.isWeakExternal())
|
||||
continue;
|
||||
StringRef name;
|
||||
coffObj->getSymbolName(coffSym, name);
|
||||
if (coffSym.isAbsolute() && ignoredSymbolName(name))
|
||||
continue;
|
||||
symtab->addLazyObject(this, name);
|
||||
i += coffSym.getNumberOfAuxSymbols();
|
||||
}
|
||||
}
|
||||
|
||||
void ObjFile::parse() {
|
||||
// Parse a memory buffer as a COFF file.
|
||||
std::unique_ptr<Binary> bin = CHECK(createBinary(mb), this);
|
||||
|
@ -573,11 +526,13 @@ Optional<Symbol *> ObjFile::createDefined(
|
|||
if (sym.isAbsolute()) {
|
||||
StringRef name = getName();
|
||||
|
||||
if (name == "@feat.00")
|
||||
feat00Flags = sym.getValue();
|
||||
// Skip special symbols.
|
||||
if (ignoredSymbolName(name))
|
||||
if (name == "@comp.id")
|
||||
return nullptr;
|
||||
if (name == "@feat.00") {
|
||||
feat00Flags = sym.getValue();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (sym.isExternal())
|
||||
return symtab->addAbsolute(name, sym);
|
||||
|
@ -827,9 +782,8 @@ void ImportFile::parse() {
|
|||
}
|
||||
|
||||
BitcodeFile::BitcodeFile(MemoryBufferRef mb, StringRef archiveName,
|
||||
uint64_t offsetInArchive,
|
||||
std::vector<Symbol *> &&symbols)
|
||||
: InputFile(BitcodeKind, mb), symbols(std::move(symbols)) {
|
||||
uint64_t offsetInArchive)
|
||||
: InputFile(BitcodeKind, mb) {
|
||||
std::string path = mb.getBufferIdentifier().str();
|
||||
if (config->thinLTOIndexOnly)
|
||||
path = replaceThinLTOSuffix(mb.getBufferIdentifier());
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
#include "llvm/BinaryFormat/Magic.h"
|
||||
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
|
||||
#include "llvm/LTO/LTO.h"
|
||||
#include "llvm/Object/Archive.h"
|
||||
|
@ -56,13 +55,7 @@ class TpiSource;
|
|||
// The root class of input files.
|
||||
class InputFile {
|
||||
public:
|
||||
enum Kind {
|
||||
ArchiveKind,
|
||||
ObjectKind,
|
||||
LazyObjectKind,
|
||||
ImportKind,
|
||||
BitcodeKind
|
||||
};
|
||||
enum Kind { ArchiveKind, ObjectKind, ImportKind, BitcodeKind };
|
||||
Kind kind() const { return fileKind; }
|
||||
virtual ~InputFile() {}
|
||||
|
||||
|
@ -109,28 +102,10 @@ private:
|
|||
llvm::DenseSet<uint64_t> seen;
|
||||
};
|
||||
|
||||
// .obj or .o file between -start-lib and -end-lib.
|
||||
class LazyObjFile : public InputFile {
|
||||
public:
|
||||
explicit LazyObjFile(MemoryBufferRef m) : InputFile(LazyObjectKind, m) {}
|
||||
static bool classof(const InputFile *f) {
|
||||
return f->kind() == LazyObjectKind;
|
||||
}
|
||||
// Makes this object file part of the link.
|
||||
void fetch();
|
||||
// Adds the symbols in this file to the symbol table as LazyObject symbols.
|
||||
void parse() override;
|
||||
|
||||
private:
|
||||
std::vector<Symbol *> symbols;
|
||||
};
|
||||
|
||||
// .obj or .o file. This may be a member of an archive file.
|
||||
class ObjFile : public InputFile {
|
||||
public:
|
||||
explicit ObjFile(MemoryBufferRef m) : InputFile(ObjectKind, m) {}
|
||||
explicit ObjFile(MemoryBufferRef m, std::vector<Symbol *> &&symbols)
|
||||
: InputFile(ObjectKind, m), symbols(std::move(symbols)) {}
|
||||
static bool classof(const InputFile *f) { return f->kind() == ObjectKind; }
|
||||
void parse() override;
|
||||
MachineTypes getMachineType() override;
|
||||
|
@ -326,11 +301,7 @@ public:
|
|||
class BitcodeFile : public InputFile {
|
||||
public:
|
||||
BitcodeFile(MemoryBufferRef mb, StringRef archiveName,
|
||||
uint64_t offsetInArchive)
|
||||
: BitcodeFile(mb, archiveName, offsetInArchive, {}) {}
|
||||
explicit BitcodeFile(MemoryBufferRef m, StringRef archiveName,
|
||||
uint64_t offsetInArchive,
|
||||
std::vector<Symbol *> &&symbols);
|
||||
uint64_t offsetInArchive);
|
||||
static bool classof(const InputFile *f) { return f->kind() == BitcodeKind; }
|
||||
ArrayRef<Symbol *> getSymbols() { return symbols; }
|
||||
MachineTypes getMachineType() override;
|
||||
|
@ -343,10 +314,6 @@ private:
|
|||
std::vector<Symbol *> symbols;
|
||||
};
|
||||
|
||||
inline bool isBitcode(MemoryBufferRef mb) {
|
||||
return identify_magic(mb.getBuffer()) == llvm::file_magic::bitcode;
|
||||
}
|
||||
|
||||
std::string replaceThinLTOSuffix(StringRef path);
|
||||
} // namespace coff
|
||||
|
||||
|
|
|
@ -162,8 +162,6 @@ def help : F<"help">;
|
|||
def help_q : Flag<["/??", "-??", "/?", "-?"], "">, Alias<help>;
|
||||
|
||||
// LLD extensions
|
||||
def end_lib : F<"end-lib">,
|
||||
HelpText<"End a grouping of objects that should be treated as if they were together in an archive">;
|
||||
def exclude_all_symbols : F<"exclude-all-symbols">;
|
||||
def export_all_symbols : F<"export-all-symbols">;
|
||||
defm demangle : B<"demangle",
|
||||
|
@ -178,8 +176,6 @@ def pdb_source_path : P<"pdbsourcepath",
|
|||
"Base path used to make relative source file path absolute in PDB">;
|
||||
def rsp_quoting : Joined<["--"], "rsp-quoting=">,
|
||||
HelpText<"Quoting style for response files, 'windows' (default) or 'posix'">;
|
||||
def start_lib : F<"start-lib">,
|
||||
HelpText<"Start a grouping of objects that should be treated as if they were together in an archive">;
|
||||
def thinlto_emit_imports_files :
|
||||
F<"thinlto-emit-imports-files">,
|
||||
HelpText<"Emit .imports files with -thinlto-index-only">;
|
||||
|
|
|
@ -61,24 +61,6 @@ static void errorOrWarn(const Twine &s) {
|
|||
error(s);
|
||||
}
|
||||
|
||||
// Causes the file associated with a lazy symbol to be linked in.
|
||||
static void forceLazy(Symbol *s) {
|
||||
s->pendingArchiveLoad = true;
|
||||
switch (s->kind()) {
|
||||
case Symbol::Kind::LazyArchiveKind: {
|
||||
auto *l = cast<LazyArchive>(s);
|
||||
l->file->addMember(l->sym);
|
||||
break;
|
||||
}
|
||||
case Symbol::Kind::LazyObjectKind:
|
||||
cast<LazyObject>(s)->file->fetch();
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable(
|
||||
"symbol passed to forceLazy is not a LazyArchive or LazyObject");
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the symbol in SC whose value is <= Addr that is closest to Addr.
|
||||
// This is generally the global variable or function whose definition contains
|
||||
// Addr.
|
||||
|
@ -210,15 +192,16 @@ void SymbolTable::loadMinGWAutomaticImports() {
|
|||
|
||||
if (name.startswith("__imp_"))
|
||||
continue;
|
||||
// If we have an undefined symbol, but we have a lazy symbol we could
|
||||
// load, load it.
|
||||
Symbol *l = find(("__imp_" + name).str());
|
||||
if (!l || l->pendingArchiveLoad || !l->isLazy())
|
||||
// If we have an undefined symbol, but we have a Lazy representing a
|
||||
// symbol we could load from file, make sure to load that.
|
||||
Lazy *l = dyn_cast_or_null<Lazy>(find(("__imp_" + name).str()));
|
||||
if (!l || l->pendingArchiveLoad)
|
||||
continue;
|
||||
|
||||
log("Loading lazy " + l->getName() + " from " + l->getFile()->getName() +
|
||||
log("Loading lazy " + l->getName() + " from " + l->file->getName() +
|
||||
" for automatic import");
|
||||
forceLazy(l);
|
||||
l->pendingArchiveLoad = true;
|
||||
l->file->addMember(l->sym);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -452,22 +435,26 @@ Symbol *SymbolTable::addUndefined(StringRef name, InputFile *f,
|
|||
Symbol *s;
|
||||
bool wasInserted;
|
||||
std::tie(s, wasInserted) = insert(name, f);
|
||||
if (wasInserted || (s->isLazy() && isWeakAlias)) {
|
||||
if (wasInserted || (isa<Lazy>(s) && isWeakAlias)) {
|
||||
replaceSymbol<Undefined>(s, name);
|
||||
return s;
|
||||
}
|
||||
if (s->isLazy())
|
||||
forceLazy(s);
|
||||
if (auto *l = dyn_cast<Lazy>(s)) {
|
||||
if (!s->pendingArchiveLoad) {
|
||||
s->pendingArchiveLoad = true;
|
||||
l->file->addMember(l->sym);
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
void SymbolTable::addLazyArchive(ArchiveFile *f, const Archive::Symbol &sym) {
|
||||
void SymbolTable::addLazy(ArchiveFile *f, const Archive::Symbol &sym) {
|
||||
StringRef name = sym.getName();
|
||||
Symbol *s;
|
||||
bool wasInserted;
|
||||
std::tie(s, wasInserted) = insert(name);
|
||||
if (wasInserted) {
|
||||
replaceSymbol<LazyArchive>(s, f, sym);
|
||||
replaceSymbol<Lazy>(s, f, sym);
|
||||
return;
|
||||
}
|
||||
auto *u = dyn_cast<Undefined>(s);
|
||||
|
@ -477,21 +464,6 @@ void SymbolTable::addLazyArchive(ArchiveFile *f, const Archive::Symbol &sym) {
|
|||
f->addMember(sym);
|
||||
}
|
||||
|
||||
void SymbolTable::addLazyObject(LazyObjFile *f, StringRef n) {
|
||||
Symbol *s;
|
||||
bool wasInserted;
|
||||
std::tie(s, wasInserted) = insert(n, f);
|
||||
if (wasInserted) {
|
||||
replaceSymbol<LazyObject>(s, f, n);
|
||||
return;
|
||||
}
|
||||
auto *u = dyn_cast<Undefined>(s);
|
||||
if (!u || u->weakAlias || s->pendingArchiveLoad)
|
||||
return;
|
||||
s->pendingArchiveLoad = true;
|
||||
f->fetch();
|
||||
}
|
||||
|
||||
void SymbolTable::reportDuplicate(Symbol *existing, InputFile *newFile) {
|
||||
std::string msg = "duplicate symbol: " + toString(*existing) + " in " +
|
||||
toString(existing->getFile()) + " and in " +
|
||||
|
@ -508,7 +480,7 @@ Symbol *SymbolTable::addAbsolute(StringRef n, COFFSymbolRef sym) {
|
|||
bool wasInserted;
|
||||
std::tie(s, wasInserted) = insert(n, nullptr);
|
||||
s->isUsedInRegularObj = true;
|
||||
if (wasInserted || isa<Undefined>(s) || s->isLazy())
|
||||
if (wasInserted || isa<Undefined>(s) || isa<Lazy>(s))
|
||||
replaceSymbol<DefinedAbsolute>(s, n, sym);
|
||||
else if (!isa<DefinedCOFF>(s))
|
||||
reportDuplicate(s, nullptr);
|
||||
|
@ -520,7 +492,7 @@ Symbol *SymbolTable::addAbsolute(StringRef n, uint64_t va) {
|
|||
bool wasInserted;
|
||||
std::tie(s, wasInserted) = insert(n, nullptr);
|
||||
s->isUsedInRegularObj = true;
|
||||
if (wasInserted || isa<Undefined>(s) || s->isLazy())
|
||||
if (wasInserted || isa<Undefined>(s) || isa<Lazy>(s))
|
||||
replaceSymbol<DefinedAbsolute>(s, n, va);
|
||||
else if (!isa<DefinedCOFF>(s))
|
||||
reportDuplicate(s, nullptr);
|
||||
|
@ -532,7 +504,7 @@ Symbol *SymbolTable::addSynthetic(StringRef n, Chunk *c) {
|
|||
bool wasInserted;
|
||||
std::tie(s, wasInserted) = insert(n, nullptr);
|
||||
s->isUsedInRegularObj = true;
|
||||
if (wasInserted || isa<Undefined>(s) || s->isLazy())
|
||||
if (wasInserted || isa<Undefined>(s) || isa<Lazy>(s))
|
||||
replaceSymbol<DefinedSynthetic>(s, n, c);
|
||||
else if (!isa<DefinedCOFF>(s))
|
||||
reportDuplicate(s, nullptr);
|
||||
|
@ -588,7 +560,7 @@ Symbol *SymbolTable::addImportData(StringRef n, ImportFile *f) {
|
|||
bool wasInserted;
|
||||
std::tie(s, wasInserted) = insert(n, nullptr);
|
||||
s->isUsedInRegularObj = true;
|
||||
if (wasInserted || isa<Undefined>(s) || s->isLazy()) {
|
||||
if (wasInserted || isa<Undefined>(s) || isa<Lazy>(s)) {
|
||||
replaceSymbol<DefinedImportData>(s, n, f);
|
||||
return s;
|
||||
}
|
||||
|
@ -603,7 +575,7 @@ Symbol *SymbolTable::addImportThunk(StringRef name, DefinedImportData *id,
|
|||
bool wasInserted;
|
||||
std::tie(s, wasInserted) = insert(name, nullptr);
|
||||
s->isUsedInRegularObj = true;
|
||||
if (wasInserted || isa<Undefined>(s) || s->isLazy()) {
|
||||
if (wasInserted || isa<Undefined>(s) || isa<Lazy>(s)) {
|
||||
replaceSymbol<DefinedImportThunk>(s, name, id, machine);
|
||||
return s;
|
||||
}
|
||||
|
@ -617,12 +589,9 @@ void SymbolTable::addLibcall(StringRef name) {
|
|||
if (!sym)
|
||||
return;
|
||||
|
||||
if (auto *l = dyn_cast<LazyArchive>(sym)) {
|
||||
if (Lazy *l = dyn_cast<Lazy>(sym)) {
|
||||
MemoryBufferRef mb = l->getMemberBuffer();
|
||||
if (isBitcode(mb))
|
||||
addUndefined(sym->getName());
|
||||
} else if (LazyObject *o = dyn_cast<LazyObject>(sym)) {
|
||||
if (isBitcode(o->file->mb))
|
||||
if (identify_magic(mb.getBuffer()) == llvm::file_magic::bitcode)
|
||||
addUndefined(sym->getName());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ class Defined;
|
|||
class DefinedAbsolute;
|
||||
class DefinedRegular;
|
||||
class DefinedRelative;
|
||||
class LazyArchive;
|
||||
class Lazy;
|
||||
class SectionChunk;
|
||||
class Symbol;
|
||||
|
||||
|
@ -86,8 +86,7 @@ public:
|
|||
Symbol *addAbsolute(StringRef n, uint64_t va);
|
||||
|
||||
Symbol *addUndefined(StringRef name, InputFile *f, bool isWeakAlias);
|
||||
void addLazyArchive(ArchiveFile *f, const Archive::Symbol &sym);
|
||||
void addLazyObject(LazyObjFile *f, StringRef n);
|
||||
void addLazy(ArchiveFile *f, const Archive::Symbol &sym);
|
||||
Symbol *addAbsolute(StringRef n, COFFSymbolRef s);
|
||||
Symbol *addRegular(InputFile *f, StringRef n,
|
||||
const llvm::object::coff_symbol_generic *s = nullptr,
|
||||
|
|
|
@ -61,9 +61,7 @@ StringRef Symbol::getName() {
|
|||
InputFile *Symbol::getFile() {
|
||||
if (auto *sym = dyn_cast<DefinedCOFF>(this))
|
||||
return sym->file;
|
||||
if (auto *sym = dyn_cast<LazyArchive>(this))
|
||||
return sym->file;
|
||||
if (auto *sym = dyn_cast<LazyObject>(this))
|
||||
if (auto *sym = dyn_cast<Lazy>(this))
|
||||
return sym->file;
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -121,7 +119,7 @@ Defined *Undefined::getWeakAlias() {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
MemoryBufferRef LazyArchive::getMemberBuffer() {
|
||||
MemoryBufferRef Lazy::getMemberBuffer() {
|
||||
Archive::Child c =
|
||||
CHECK(sym.getMember(),
|
||||
"could not get the member for symbol " + toCOFFString(sym));
|
||||
|
|
|
@ -59,8 +59,7 @@ public:
|
|||
DefinedSyntheticKind,
|
||||
|
||||
UndefinedKind,
|
||||
LazyArchiveKind,
|
||||
LazyObjectKind,
|
||||
LazyKind,
|
||||
|
||||
LastDefinedCOFFKind = DefinedCommonKind,
|
||||
LastDefinedKind = DefinedSyntheticKind,
|
||||
|
@ -80,10 +79,6 @@ public:
|
|||
// after calling markLive.
|
||||
bool isLive() const;
|
||||
|
||||
bool isLazy() const {
|
||||
return symbolKind == LazyArchiveKind || symbolKind == LazyObjectKind;
|
||||
}
|
||||
|
||||
protected:
|
||||
friend SymbolTable;
|
||||
explicit Symbol(Kind k, StringRef n = "")
|
||||
|
@ -261,27 +256,24 @@ private:
|
|||
// This class represents a symbol defined in an archive file. It is
|
||||
// created from an archive file header, and it knows how to load an
|
||||
// object file from an archive to replace itself with a defined
|
||||
// symbol. If the resolver finds both Undefined and LazyArchive for
|
||||
// the same name, it will ask the LazyArchive to load a file.
|
||||
class LazyArchive : public Symbol {
|
||||
// symbol. If the resolver finds both Undefined and Lazy for
|
||||
// the same name, it will ask the Lazy to load a file.
|
||||
class Lazy : public Symbol {
|
||||
public:
|
||||
LazyArchive(ArchiveFile *f, const Archive::Symbol s)
|
||||
: Symbol(LazyArchiveKind, s.getName()), file(f), sym(s) {}
|
||||
Lazy(ArchiveFile *f, const Archive::Symbol s)
|
||||
: Symbol(LazyKind, s.getName()), file(f), sym(s) {}
|
||||
|
||||
static bool classof(const Symbol *s) { return s->kind() == LazyArchiveKind; }
|
||||
static bool classof(const Symbol *s) { return s->kind() == LazyKind; }
|
||||
|
||||
MemoryBufferRef getMemberBuffer();
|
||||
|
||||
ArchiveFile *file;
|
||||
const Archive::Symbol sym;
|
||||
};
|
||||
|
||||
class LazyObject : public Symbol {
|
||||
public:
|
||||
LazyObject(LazyObjFile *f, StringRef n)
|
||||
: Symbol(LazyObjectKind, n), file(f) {}
|
||||
static bool classof(const Symbol *s) { return s->kind() == LazyObjectKind; }
|
||||
LazyObjFile *file;
|
||||
private:
|
||||
friend SymbolTable;
|
||||
|
||||
private:
|
||||
const Archive::Symbol sym;
|
||||
};
|
||||
|
||||
// Undefined symbols.
|
||||
|
@ -389,8 +381,7 @@ inline uint64_t Defined::getRVA() {
|
|||
return cast<DefinedCommon>(this)->getRVA();
|
||||
case DefinedRegularKind:
|
||||
return cast<DefinedRegular>(this)->getRVA();
|
||||
case LazyArchiveKind:
|
||||
case LazyObjectKind:
|
||||
case LazyKind:
|
||||
case UndefinedKind:
|
||||
llvm_unreachable("Cannot get the address for an undefined symbol.");
|
||||
}
|
||||
|
@ -413,8 +404,7 @@ inline Chunk *Defined::getChunk() {
|
|||
return cast<DefinedLocalImport>(this)->getChunk();
|
||||
case DefinedCommonKind:
|
||||
return cast<DefinedCommon>(this)->getChunk();
|
||||
case LazyArchiveKind:
|
||||
case LazyObjectKind:
|
||||
case LazyKind:
|
||||
case UndefinedKind:
|
||||
llvm_unreachable("Cannot get the chunk of an undefined symbol.");
|
||||
}
|
||||
|
@ -429,12 +419,11 @@ union SymbolUnion {
|
|||
alignas(DefinedCommon) char b[sizeof(DefinedCommon)];
|
||||
alignas(DefinedAbsolute) char c[sizeof(DefinedAbsolute)];
|
||||
alignas(DefinedSynthetic) char d[sizeof(DefinedSynthetic)];
|
||||
alignas(LazyArchive) char e[sizeof(LazyArchive)];
|
||||
alignas(Lazy) char e[sizeof(Lazy)];
|
||||
alignas(Undefined) char f[sizeof(Undefined)];
|
||||
alignas(DefinedImportData) char g[sizeof(DefinedImportData)];
|
||||
alignas(DefinedImportThunk) char h[sizeof(DefinedImportThunk)];
|
||||
alignas(DefinedLocalImport) char i[sizeof(DefinedLocalImport)];
|
||||
alignas(LazyObject) char j[sizeof(LazyObject)];
|
||||
};
|
||||
|
||||
template <typename T, typename... ArgT>
|
||||
|
|
|
@ -1519,8 +1519,7 @@ static void maybeAddAddressTakenFunction(SymbolRVASet &addressTakenSyms,
|
|||
// Absolute is never code, synthetic generally isn't and usually isn't
|
||||
// determinable.
|
||||
break;
|
||||
case Symbol::LazyArchiveKind:
|
||||
case Symbol::LazyObjectKind:
|
||||
case Symbol::LazyKind:
|
||||
case Symbol::UndefinedKind:
|
||||
// Undefined symbols resolve to zero, so they don't have an RVA. Lazy
|
||||
// symbols shouldn't have relocations.
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-pc-windows-msvc"
|
||||
|
||||
declare i32 @bar()
|
||||
|
||||
define i32 @foo() {
|
||||
%1 = call i32 () @bar()
|
||||
%2 = add i32 %1, 1
|
||||
ret i32 %2
|
||||
}
|
||||
|
||||
!llvm.linker.options = !{!0}
|
||||
!0 = !{!"/INCLUDE:foo"}
|
|
@ -1,9 +0,0 @@
|
|||
target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-pc-windows-msvc"
|
||||
|
||||
define i32 @bar() {
|
||||
ret i32 1
|
||||
}
|
||||
|
||||
!llvm.linker.options = !{!0}
|
||||
!0 = !{!"/INCLUDE:bar"}
|
|
@ -1,19 +0,0 @@
|
|||
; REQUIRES: x86
|
||||
;
|
||||
; We need an input file to lld, so create one.
|
||||
; RUN: llc -filetype=obj %s -o %t.obj
|
||||
|
||||
; RUN: not lld-link %t.obj -end-lib 2>&1 \
|
||||
; RUN: | FileCheck --check-prefix=STRAY_END %s
|
||||
; STRAY_END: stray -end-lib
|
||||
|
||||
; RUN: not lld-link -start-lib -start-lib %t.obj 2>&1 \
|
||||
; RUN: | FileCheck --check-prefix=NESTED_START %s
|
||||
; NESTED_START: nested -start-lib
|
||||
|
||||
target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-pc-windows-msvc"
|
||||
|
||||
define void @main() {
|
||||
ret void
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
; REQUIRES: x86
|
||||
;
|
||||
; RUN: llc -filetype=obj %s -o %t.obj
|
||||
; RUN: llc -filetype=obj %p/Inputs/start-lib1.ll -o %t1.obj
|
||||
; RUN: llc -filetype=obj %p/Inputs/start-lib2.ll -o %t2.obj
|
||||
; RUN: opt -thinlto-bc %s -o %t.bc
|
||||
; RUN: opt -thinlto-bc %p/Inputs/start-lib1.ll -o %t1.bc
|
||||
; RUN: opt -thinlto-bc %p/Inputs/start-lib2.ll -o %t2.bc
|
||||
;
|
||||
; RUN: lld-link -out:%t1.exe -entry:main -opt:noref -lldmap:%t1.map \
|
||||
; RUN: %t.obj %t1.obj %t2.obj
|
||||
; RUN: FileCheck --check-prefix=TEST1 %s < %t1.map
|
||||
; RUN: lld-link -out:%t1.exe -entry:main -opt:noref -lldmap:%t1.thinlto.map \
|
||||
; RUN: %t.bc %t1.bc %t2.bc
|
||||
; RUN: FileCheck --check-prefix=TEST1 %s < %t1.thinlto.map
|
||||
; TEST1: foo
|
||||
; TEST1: bar
|
||||
;
|
||||
; RUN: lld-link -out:%t2.exe -entry:main -opt:noref -lldmap:%t2.map \
|
||||
; RUN: %t.obj -start-lib %t1.obj -end-lib %t2.obj
|
||||
; RUN: FileCheck --check-prefix=TEST2 %s < %t2.map
|
||||
; RUN: lld-link -out:%t2.exe -entry:main -opt:noref -lldmap:%t2.thinlto.map \
|
||||
; RUN: %t.bc -start-lib %t1.bc -end-lib %t2.bc
|
||||
; RUN: FileCheck --check-prefix=TEST2 %s < %t2.thinlto.map
|
||||
; TEST2-NOT: Name: foo
|
||||
; TEST2: bar
|
||||
; TEST2-NOT: Name: foo
|
||||
;
|
||||
; RUN: lld-link -out:%t3.exe -entry:main -opt:noref -lldmap:%t3.map \
|
||||
; RUN: %t.obj -start-lib %t1.obj %t2.obj
|
||||
; RUN: FileCheck --check-prefix=TEST3 %s < %t3.map
|
||||
; RUN: lld-link -out:%t3.exe -entry:main -opt:noref -lldmap:%t3.thinlto.map \
|
||||
; RUN: %t.bc -start-lib %t1.bc %t2.bc
|
||||
; RUN: FileCheck --check-prefix=TEST3 %s < %t3.thinlto.map
|
||||
; TEST3-NOT: foo
|
||||
; TEST3-NOT: bar
|
||||
|
||||
target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-pc-windows-msvc"
|
||||
|
||||
define void @main() {
|
||||
ret void
|
||||
}
|
Loading…
Reference in New Issue