svn commit: r357057 - in projects/clang1000-import/contrib/llvm-project/lld: COFF Common ELF ELF/Arch docs include/lld/Common include/lld/Core include/lld/ReaderWriter lib/Driver lib/ReaderWriter l...
Dimitry Andric
dim at FreeBSD.org
Thu Jan 23 21:35:54 UTC 2020
Author: dim
Date: Thu Jan 23 21:35:51 2020
New Revision: 357057
URL: https://svnweb.freebsd.org/changeset/base/357057
Log:
Merge ^/vendor/lld/dist up to its last change, and resolve conflicts.
Added:
projects/clang1000-import/contrib/llvm-project/lld/Common/DWARF.cpp
- copied unchanged from r357036, vendor/lld/dist/Common/DWARF.cpp
projects/clang1000-import/contrib/llvm-project/lld/ELF/ARMErrataFix.cpp
- copied unchanged from r357036, vendor/lld/dist/ELF/ARMErrataFix.cpp
projects/clang1000-import/contrib/llvm-project/lld/ELF/ARMErrataFix.h
- copied unchanged from r357036, vendor/lld/dist/ELF/ARMErrataFix.h
projects/clang1000-import/contrib/llvm-project/lld/include/lld/Common/DWARF.h
- copied unchanged from r357036, vendor/lld/dist/include/lld/Common/DWARF.h
Modified:
projects/clang1000-import/contrib/llvm-project/lld/COFF/CMakeLists.txt
projects/clang1000-import/contrib/llvm-project/lld/COFF/Config.h
projects/clang1000-import/contrib/llvm-project/lld/COFF/DLL.cpp
projects/clang1000-import/contrib/llvm-project/lld/COFF/DebugTypes.cpp
projects/clang1000-import/contrib/llvm-project/lld/COFF/Driver.cpp
projects/clang1000-import/contrib/llvm-project/lld/COFF/Driver.h
projects/clang1000-import/contrib/llvm-project/lld/COFF/DriverUtils.cpp
projects/clang1000-import/contrib/llvm-project/lld/COFF/ICF.cpp
projects/clang1000-import/contrib/llvm-project/lld/COFF/InputFiles.cpp
projects/clang1000-import/contrib/llvm-project/lld/COFF/InputFiles.h
projects/clang1000-import/contrib/llvm-project/lld/COFF/LTO.cpp
projects/clang1000-import/contrib/llvm-project/lld/COFF/MapFile.cpp
projects/clang1000-import/contrib/llvm-project/lld/COFF/MinGW.cpp
projects/clang1000-import/contrib/llvm-project/lld/COFF/Options.td
projects/clang1000-import/contrib/llvm-project/lld/COFF/PDB.cpp
projects/clang1000-import/contrib/llvm-project/lld/COFF/PDB.h
projects/clang1000-import/contrib/llvm-project/lld/COFF/SymbolTable.cpp
projects/clang1000-import/contrib/llvm-project/lld/COFF/SymbolTable.h
projects/clang1000-import/contrib/llvm-project/lld/COFF/Symbols.cpp
projects/clang1000-import/contrib/llvm-project/lld/COFF/Symbols.h
projects/clang1000-import/contrib/llvm-project/lld/COFF/Writer.cpp
projects/clang1000-import/contrib/llvm-project/lld/Common/CMakeLists.txt
projects/clang1000-import/contrib/llvm-project/lld/Common/ErrorHandler.cpp
projects/clang1000-import/contrib/llvm-project/lld/Common/Strings.cpp
projects/clang1000-import/contrib/llvm-project/lld/Common/TargetOptionsCommandFlags.cpp
projects/clang1000-import/contrib/llvm-project/lld/ELF/AArch64ErrataFix.cpp
projects/clang1000-import/contrib/llvm-project/lld/ELF/Arch/AArch64.cpp
projects/clang1000-import/contrib/llvm-project/lld/ELF/Arch/AMDGPU.cpp
projects/clang1000-import/contrib/llvm-project/lld/ELF/Arch/ARM.cpp
projects/clang1000-import/contrib/llvm-project/lld/ELF/Arch/AVR.cpp
projects/clang1000-import/contrib/llvm-project/lld/ELF/Arch/Hexagon.cpp
projects/clang1000-import/contrib/llvm-project/lld/ELF/Arch/MSP430.cpp
projects/clang1000-import/contrib/llvm-project/lld/ELF/Arch/Mips.cpp
projects/clang1000-import/contrib/llvm-project/lld/ELF/Arch/MipsArchTree.cpp
projects/clang1000-import/contrib/llvm-project/lld/ELF/Arch/PPC.cpp
projects/clang1000-import/contrib/llvm-project/lld/ELF/Arch/PPC64.cpp
projects/clang1000-import/contrib/llvm-project/lld/ELF/Arch/RISCV.cpp
projects/clang1000-import/contrib/llvm-project/lld/ELF/Arch/SPARCV9.cpp
projects/clang1000-import/contrib/llvm-project/lld/ELF/Arch/X86.cpp
projects/clang1000-import/contrib/llvm-project/lld/ELF/Arch/X86_64.cpp
projects/clang1000-import/contrib/llvm-project/lld/ELF/CMakeLists.txt
projects/clang1000-import/contrib/llvm-project/lld/ELF/CallGraphSort.cpp
projects/clang1000-import/contrib/llvm-project/lld/ELF/Config.h
projects/clang1000-import/contrib/llvm-project/lld/ELF/DWARF.cpp
projects/clang1000-import/contrib/llvm-project/lld/ELF/DWARF.h
projects/clang1000-import/contrib/llvm-project/lld/ELF/Driver.cpp
projects/clang1000-import/contrib/llvm-project/lld/ELF/DriverUtils.cpp
projects/clang1000-import/contrib/llvm-project/lld/ELF/EhFrame.cpp
projects/clang1000-import/contrib/llvm-project/lld/ELF/ICF.cpp
projects/clang1000-import/contrib/llvm-project/lld/ELF/InputFiles.cpp
projects/clang1000-import/contrib/llvm-project/lld/ELF/InputFiles.h
projects/clang1000-import/contrib/llvm-project/lld/ELF/InputSection.cpp
projects/clang1000-import/contrib/llvm-project/lld/ELF/InputSection.h
projects/clang1000-import/contrib/llvm-project/lld/ELF/LTO.cpp
projects/clang1000-import/contrib/llvm-project/lld/ELF/LinkerScript.cpp
projects/clang1000-import/contrib/llvm-project/lld/ELF/LinkerScript.h
projects/clang1000-import/contrib/llvm-project/lld/ELF/MapFile.cpp
projects/clang1000-import/contrib/llvm-project/lld/ELF/MarkLive.cpp
projects/clang1000-import/contrib/llvm-project/lld/ELF/Options.td
projects/clang1000-import/contrib/llvm-project/lld/ELF/OutputSections.cpp
projects/clang1000-import/contrib/llvm-project/lld/ELF/OutputSections.h
projects/clang1000-import/contrib/llvm-project/lld/ELF/Relocations.cpp
projects/clang1000-import/contrib/llvm-project/lld/ELF/Relocations.h
projects/clang1000-import/contrib/llvm-project/lld/ELF/ScriptLexer.cpp
projects/clang1000-import/contrib/llvm-project/lld/ELF/ScriptParser.cpp
projects/clang1000-import/contrib/llvm-project/lld/ELF/SymbolTable.cpp
projects/clang1000-import/contrib/llvm-project/lld/ELF/SymbolTable.h
projects/clang1000-import/contrib/llvm-project/lld/ELF/Symbols.cpp
projects/clang1000-import/contrib/llvm-project/lld/ELF/Symbols.h
projects/clang1000-import/contrib/llvm-project/lld/ELF/SyntheticSections.cpp
projects/clang1000-import/contrib/llvm-project/lld/ELF/SyntheticSections.h
projects/clang1000-import/contrib/llvm-project/lld/ELF/Target.cpp
projects/clang1000-import/contrib/llvm-project/lld/ELF/Writer.cpp
projects/clang1000-import/contrib/llvm-project/lld/ELF/Writer.h
projects/clang1000-import/contrib/llvm-project/lld/docs/ReleaseNotes.rst
projects/clang1000-import/contrib/llvm-project/lld/docs/WebAssembly.rst
projects/clang1000-import/contrib/llvm-project/lld/docs/conf.py
projects/clang1000-import/contrib/llvm-project/lld/docs/ld.lld.1
projects/clang1000-import/contrib/llvm-project/lld/include/lld/Common/ErrorHandler.h
projects/clang1000-import/contrib/llvm-project/lld/include/lld/Common/LLVM.h
projects/clang1000-import/contrib/llvm-project/lld/include/lld/Common/Strings.h
projects/clang1000-import/contrib/llvm-project/lld/include/lld/Common/TargetOptionsCommandFlags.h
projects/clang1000-import/contrib/llvm-project/lld/include/lld/Core/File.h
projects/clang1000-import/contrib/llvm-project/lld/include/lld/ReaderWriter/MachOLinkingContext.h
projects/clang1000-import/contrib/llvm-project/lld/lib/Driver/DarwinLdDriver.cpp
projects/clang1000-import/contrib/llvm-project/lld/lib/ReaderWriter/FileArchive.cpp
projects/clang1000-import/contrib/llvm-project/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp
projects/clang1000-import/contrib/llvm-project/lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp
projects/clang1000-import/contrib/llvm-project/lld/lib/ReaderWriter/MachO/DebugInfo.h
projects/clang1000-import/contrib/llvm-project/lld/lib/ReaderWriter/MachO/GOTPass.cpp
projects/clang1000-import/contrib/llvm-project/lld/lib/ReaderWriter/MachO/LayoutPass.cpp
projects/clang1000-import/contrib/llvm-project/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
projects/clang1000-import/contrib/llvm-project/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
projects/clang1000-import/contrib/llvm-project/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
projects/clang1000-import/contrib/llvm-project/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
projects/clang1000-import/contrib/llvm-project/lld/lib/ReaderWriter/MachO/ObjCPass.cpp
projects/clang1000-import/contrib/llvm-project/lld/lib/ReaderWriter/MachO/ShimPass.cpp
projects/clang1000-import/contrib/llvm-project/lld/lib/ReaderWriter/MachO/TLVPass.cpp
projects/clang1000-import/contrib/llvm-project/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
projects/clang1000-import/contrib/llvm-project/lld/tools/lld/lld.cpp
Directory Properties:
projects/clang1000-import/contrib/llvm-project/lld/ (props changed)
Modified: projects/clang1000-import/contrib/llvm-project/lld/COFF/CMakeLists.txt
==============================================================================
--- projects/clang1000-import/contrib/llvm-project/lld/COFF/CMakeLists.txt Thu Jan 23 17:38:17 2020 (r357056)
+++ projects/clang1000-import/contrib/llvm-project/lld/COFF/CMakeLists.txt Thu Jan 23 21:35:51 2020 (r357057)
@@ -28,8 +28,10 @@ add_lld_library(lldCOFF
BinaryFormat
Core
DebugInfoCodeView
+ DebugInfoDWARF
DebugInfoMSF
DebugInfoPDB
+ Demangle
LibDriver
LTO
MC
Modified: projects/clang1000-import/contrib/llvm-project/lld/COFF/Config.h
==============================================================================
--- projects/clang1000-import/contrib/llvm-project/lld/COFF/Config.h Thu Jan 23 17:38:17 2020 (r357056)
+++ projects/clang1000-import/contrib/llvm-project/lld/COFF/Config.h Thu Jan 23 21:35:51 2020 (r357057)
@@ -122,6 +122,7 @@ struct Configuration {
bool dll = false;
StringRef implib;
std::vector<Export> exports;
+ bool hadExplicitExports;
std::set<std::string> delayLoads;
std::map<std::string, int> dllOrder;
Symbol *delayLoadHelper = nullptr;
@@ -188,6 +189,9 @@ struct Configuration {
// Used for /thinlto-object-suffix-replace:
std::pair<llvm::StringRef, llvm::StringRef> thinLTOObjectSuffixReplace;
+
+ // Used for /lto-obj-path:
+ llvm::StringRef ltoObjPath;
uint64_t align = 4096;
uint64_t imageBase = -1;
Modified: projects/clang1000-import/contrib/llvm-project/lld/COFF/DLL.cpp
==============================================================================
--- projects/clang1000-import/contrib/llvm-project/lld/COFF/DLL.cpp Thu Jan 23 17:38:17 2020 (r357056)
+++ projects/clang1000-import/contrib/llvm-project/lld/COFF/DLL.cpp Thu Jan 23 21:35:51 2020 (r357057)
@@ -135,7 +135,7 @@ class NullChunk : public NonSectionChunk { (private)
static std::vector<std::vector<DefinedImportData *>>
binImports(const std::vector<DefinedImportData *> &imports) {
// Group DLL-imported symbols by DLL name because that's how
- // symbols are layed out in the import descriptor table.
+ // symbols are laid out in the import descriptor table.
auto less = [](const std::string &a, const std::string &b) {
return config->dllOrder[a] < config->dllOrder[b];
};
@@ -188,7 +188,7 @@ class DelayDirectoryChunk : public NonSectionChunk { (
// Initial contents for delay-loaded functions.
// This code calls __delayLoadHelper2 function to resolve a symbol
-// and then overwrites its jump table slot with the result
+// which then overwrites its jump table slot with the result
// for subsequent function calls.
static const uint8_t thunkX64[] = {
0x48, 0x8D, 0x05, 0, 0, 0, 0, // lea rax, [__imp_<FUNCNAME>]
Modified: projects/clang1000-import/contrib/llvm-project/lld/COFF/DebugTypes.cpp
==============================================================================
--- projects/clang1000-import/contrib/llvm-project/lld/COFF/DebugTypes.cpp Thu Jan 23 17:38:17 2020 (r357056)
+++ projects/clang1000-import/contrib/llvm-project/lld/COFF/DebugTypes.cpp Thu Jan 23 21:35:51 2020 (r357057)
@@ -17,11 +17,12 @@
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
#include "llvm/Support/Path.h"
-using namespace lld;
-using namespace lld::coff;
using namespace llvm;
using namespace llvm::codeview;
+namespace lld {
+namespace coff {
+
namespace {
// The TypeServerSource class represents a PDB type server, a file referenced by
// OBJ files compiled with MSVC /Zi. A single PDB can be shared by several OBJ
@@ -96,27 +97,25 @@ TpiSource::TpiSource(TpiKind k, const ObjFile *f) : ki
GC.push_back(std::unique_ptr<TpiSource>(this));
}
-TpiSource *lld::coff::makeTpiSource(const ObjFile *f) {
+TpiSource *makeTpiSource(const ObjFile *f) {
return new TpiSource(TpiSource::Regular, f);
}
-TpiSource *lld::coff::makeUseTypeServerSource(const ObjFile *f,
+TpiSource *makeUseTypeServerSource(const ObjFile *f,
const TypeServer2Record *ts) {
TypeServerSource::enqueue(f, *ts);
return new UseTypeServerSource(f, ts);
}
-TpiSource *lld::coff::makePrecompSource(const ObjFile *f) {
+TpiSource *makePrecompSource(const ObjFile *f) {
return new PrecompSource(f);
}
-TpiSource *lld::coff::makeUsePrecompSource(const ObjFile *f,
+TpiSource *makeUsePrecompSource(const ObjFile *f,
const PrecompRecord *precomp) {
return new UsePrecompSource(f, precomp);
}
-namespace lld {
-namespace coff {
template <>
const PrecompRecord &retrieveDependencyInfo(const TpiSource *source) {
assert(source->kind == TpiSource::UsingPCH);
@@ -128,8 +127,6 @@ const TypeServer2Record &retrieveDependencyInfo(const
assert(source->kind == TpiSource::UsingPDB);
return ((const UseTypeServerSource *)source)->typeServerDependency;
}
-} // namespace coff
-} // namespace lld
std::map<std::string, std::pair<std::string, TypeServerSource *>>
TypeServerSource::instances;
@@ -210,8 +207,7 @@ TypeServerSource::findFromFile(const ObjFile *dependen
// FIXME: Temporary interface until PDBLinker::maybeMergeTypeServerPDB() is
// moved here.
-Expected<llvm::pdb::NativeSession *>
-lld::coff::findTypeServerSource(const ObjFile *f) {
+Expected<llvm::pdb::NativeSession *> findTypeServerSource(const ObjFile *f) {
Expected<TypeServerSource *> ts = TypeServerSource::findFromFile(f);
if (!ts)
return ts.takeError();
@@ -231,7 +227,7 @@ void TypeServerSource::enqueue(const ObjFile *dependen
if (!it.second)
return; // another OBJ already scheduled this PDB for load
- driver->enqueuePath(*p, false);
+ driver->enqueuePath(*p, false, false);
}
// Create an instance of TypeServerSource or an error string if the PDB couldn't
@@ -239,7 +235,7 @@ void TypeServerSource::enqueue(const ObjFile *dependen
// will be merged in. NOTE - a PDB load failure is not a link error: some
// debug info will simply be missing from the final PDB - that is the default
// accepted behavior.
-void lld::coff::loadTypeServerSource(llvm::MemoryBufferRef m) {
+void loadTypeServerSource(llvm::MemoryBufferRef m) {
std::string path = normalizePdbPath(m.getBufferIdentifier());
Expected<TypeServerSource *> ts = TypeServerSource::getInstance(m);
@@ -266,3 +262,6 @@ Expected<TypeServerSource *> TypeServerSource::getInst
return info.takeError();
return new TypeServerSource(m, session.release());
}
+
+} // namespace coff
+} // namespace lld
Modified: projects/clang1000-import/contrib/llvm-project/lld/COFF/Driver.cpp
==============================================================================
--- projects/clang1000-import/contrib/llvm-project/lld/COFF/Driver.cpp Thu Jan 23 17:38:17 2020 (r357056)
+++ projects/clang1000-import/contrib/llvm-project/lld/COFF/Driver.cpp Thu Jan 23 21:35:51 2020 (r357057)
@@ -27,6 +27,7 @@
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/BinaryFormat/Magic.h"
+#include "llvm/LTO/LTO.h"
#include "llvm/Object/ArchiveWriter.h"
#include "llvm/Object/COFFImportFile.h"
#include "llvm/Object/COFFModuleDefinition.h"
@@ -63,16 +64,16 @@ LinkerDriver *driver;
bool link(ArrayRef<const char *> args, bool canExitEarly, raw_ostream &diag) {
errorHandler().logName = args::getFilenameWithoutExe(args[0]);
errorHandler().errorOS = &diag;
- errorHandler().colorDiagnostics = diag.has_colors();
errorHandler().errorLimitExceededMsg =
"too many errors emitted, stopping now"
" (use /errorlimit:0 to see all errors)";
errorHandler().exitEarly = canExitEarly;
- config = make<Configuration>();
+ enableColors(diag.has_colors());
+ config = make<Configuration>();
symtab = make<SymbolTable>();
-
driver = make<LinkerDriver>();
+
driver->link(args);
// Call exit() if we can to avoid calling destructors.
@@ -170,7 +171,7 @@ MemoryBufferRef LinkerDriver::takeBuffer(std::unique_p
}
void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuffer> mb,
- bool wholeArchive) {
+ bool wholeArchive, bool lazy) {
StringRef filename = mb->getBufferIdentifier();
MemoryBufferRef mbref = takeBuffer(std::move(mb));
@@ -188,18 +189,25 @@ void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuf
Archive *archive = file.get();
make<std::unique_ptr<Archive>>(std::move(file)); // take ownership
+ int memberIndex = 0;
for (MemoryBufferRef m : getArchiveMembers(archive))
- addArchiveBuffer(m, "<whole-archive>", filename, 0);
+ addArchiveBuffer(m, "<whole-archive>", filename, memberIndex++);
return;
}
symtab->addFile(make<ArchiveFile>(mbref));
break;
case file_magic::bitcode:
- symtab->addFile(make<BitcodeFile>(mbref, "", 0));
+ if (lazy)
+ symtab->addFile(make<LazyObjFile>(mbref));
+ else
+ symtab->addFile(make<BitcodeFile>(mbref, "", 0));
break;
case file_magic::coff_object:
case file_magic::coff_import_library:
- symtab->addFile(make<ObjFile>(mbref));
+ if (lazy)
+ symtab->addFile(make<LazyObjFile>(mbref));
+ else
+ symtab->addFile(make<ObjFile>(mbref));
break;
case file_magic::pdb:
loadTypeServerSource(mbref);
@@ -220,7 +228,7 @@ void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuf
}
}
-void LinkerDriver::enqueuePath(StringRef path, bool wholeArchive) {
+void LinkerDriver::enqueuePath(StringRef path, bool wholeArchive, bool lazy) {
auto future =
std::make_shared<std::future<MBErrPair>>(createFutureForFile(path));
std::string pathStr = path;
@@ -240,7 +248,7 @@ void LinkerDriver::enqueuePath(StringRef path, bool wh
else
error(msg + "; did you mean '" + nearest + "'");
} else
- driver->addBuffer(std::move(mbOrErr.first), wholeArchive);
+ driver->addBuffer(std::move(mbOrErr.first), wholeArchive, lazy);
});
}
@@ -303,9 +311,10 @@ void LinkerDriver::enqueueArchiveMember(const Archive:
auto mbOrErr = future->get();
if (mbOrErr.second)
reportBufferError(errorCodeToError(mbOrErr.second), childName);
+ // Pass empty string as archive name so that the original filename is
+ // used as the buffer identifier.
driver->addArchiveBuffer(takeBuffer(std::move(mbOrErr.first)),
- toCOFFString(sym), parentName,
- /*OffsetInArchive=*/0);
+ toCOFFString(sym), "", /*OffsetInArchive=*/0);
});
}
@@ -359,7 +368,7 @@ void LinkerDriver::parseDirectives(InputFile *file) {
break;
case OPT_defaultlib:
if (Optional<StringRef> path = findLib(arg->getValue()))
- enqueuePath(*path, false);
+ enqueuePath(*path, false, false);
break;
case OPT_entry:
config->entry = addUndefined(mangle(arg->getValue()));
@@ -594,6 +603,7 @@ static std::string createResponseFile(const opt::Input
for (auto *arg : args) {
switch (arg->getOption().getID()) {
case OPT_linkrepro:
+ case OPT_reproduce:
case OPT_INPUT:
case OPT_defaultlib:
case OPT_libpath:
@@ -708,9 +718,8 @@ static std::string getImplibPath() {
return out.str();
}
+// The import name is calculated as follows:
//
-// The import name is caculated as the following:
-//
// | LIBRARY w/ ext | LIBRARY w/o ext | no LIBRARY
// -----+----------------+---------------------+------------------
// LINK | {value} | {value}.{.dll/.exe} | {output name}
@@ -991,30 +1000,37 @@ static void parsePDBAltPath(StringRef altPath) {
config->pdbAltPath = buf;
}
-/// Check that at most one resource obj file was used.
+/// Convert resource files and potentially merge input resource object
+/// trees into one resource tree.
/// Call after ObjFile::Instances is complete.
-static void diagnoseMultipleResourceObjFiles() {
- // The .rsrc$01 section in a resource obj file contains a tree description
- // of resources. Merging multiple resource obj files would require merging
- // the trees instead of using usual linker section merging semantics.
- // Since link.exe disallows linking more than one resource obj file with
- // LNK4078, mirror that. The normal use of resource files is to give the
- // linker many .res files, which are then converted to a single resource obj
- // file internally, so this is not a big restriction in practice.
- ObjFile *resourceObjFile = nullptr;
+void LinkerDriver::convertResources() {
+ std::vector<ObjFile *> resourceObjFiles;
+
for (ObjFile *f : ObjFile::instances) {
- if (!f->isResourceObjFile)
- continue;
+ if (f->isResourceObjFile())
+ resourceObjFiles.push_back(f);
+ }
- if (!resourceObjFile) {
- resourceObjFile = f;
- continue;
- }
-
- error(toString(f) +
+ if (!config->mingw &&
+ (resourceObjFiles.size() > 1 ||
+ (resourceObjFiles.size() == 1 && !resources.empty()))) {
+ error((!resources.empty() ? "internal .obj file created from .res files"
+ : toString(resourceObjFiles[1])) +
": more than one resource obj file not allowed, already got " +
- toString(resourceObjFile));
+ toString(resourceObjFiles.front()));
+ return;
}
+
+ if (resources.empty() && resourceObjFiles.size() <= 1) {
+ // No resources to convert, and max one resource object file in
+ // the input. Keep that preconverted resource section as is.
+ for (ObjFile *f : resourceObjFiles)
+ f->includeResourceChunks();
+ return;
+ }
+ ObjFile *f = make<ObjFile>(convertResToCOFF(resources, resourceObjFiles));
+ symtab->addFile(f);
+ f->includeResourceChunks();
}
// In MinGW, if no symbols are chosen to be exported, then all symbols are
@@ -1055,12 +1071,26 @@ void LinkerDriver::maybeExportMinGWSymbols(const opt::
});
}
-static const char *libcallRoutineNames[] = {
-#define HANDLE_LIBCALL(code, name) name,
-#include "llvm/IR/RuntimeLibcalls.def"
-#undef HANDLE_LIBCALL
-};
+// lld has a feature to create a tar file containing all input files as well as
+// all command line options, so that other people can run lld again with exactly
+// the same inputs. This feature is accessible via /linkrepro and /reproduce.
+//
+// /linkrepro and /reproduce are very similar, but /linkrepro takes a directory
+// name while /reproduce takes a full path. We have /linkrepro for compatibility
+// with Microsoft link.exe.
+Optional<std::string> getReproduceFile(const opt::InputArgList &args) {
+ if (auto *arg = args.getLastArg(OPT_reproduce))
+ return std::string(arg->getValue());
+ if (auto *arg = args.getLastArg(OPT_linkrepro)) {
+ SmallString<64> path = StringRef(arg->getValue());
+ sys::path::append(path, "repro.tar");
+ return path.str().str();
+ }
+
+ return None;
+}
+
void LinkerDriver::link(ArrayRef<const char *> argsArr) {
// Needed for LTO.
InitializeAllTargetInfos();
@@ -1079,7 +1109,7 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr
// Parse command line options.
ArgParser parser;
- opt::InputArgList args = parser.parseLINK(argsArr);
+ opt::InputArgList args = parser.parse(argsArr);
// Parse and evaluate -mllvm options.
std::vector<const char *> v;
@@ -1123,22 +1153,20 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr
// options are handled.
config->mingw = args.hasArg(OPT_lldmingw);
- if (auto *arg = args.getLastArg(OPT_linkrepro)) {
- SmallString<64> path = StringRef(arg->getValue());
- sys::path::append(path, "repro.tar");
-
+ // Handle /linkrepro and /reproduce.
+ if (Optional<std::string> path = getReproduceFile(args)) {
Expected<std::unique_ptr<TarWriter>> errOrWriter =
- TarWriter::create(path, "repro");
+ TarWriter::create(*path, sys::path::stem(*path));
if (errOrWriter) {
tar = std::move(*errOrWriter);
} else {
- error("/linkrepro: failed to open " + path + ": " +
+ error("/linkrepro: failed to open " + *path + ": " +
toString(errOrWriter.takeError()));
}
}
- if (!args.hasArg(OPT_INPUT, OPT_wholearchive_file)) {
+ if (!args.hasArg(OPT_INPUT)) {
if (args.hasArg(OPT_deffile))
config->noEntry = true;
else
@@ -1149,7 +1177,8 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr
searchPaths.push_back("");
for (auto *arg : args.filtered(OPT_libpath))
searchPaths.push_back(arg->getValue());
- addLibSearchPaths();
+ if (!args.hasArg(OPT_lldignoreenv))
+ addLibSearchPaths();
// Handle /ignore
for (auto *arg : args.filtered(OPT_ignore)) {
@@ -1481,6 +1510,7 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr
getOldNewOptions(args, OPT_thinlto_prefix_replace);
config->thinLTOObjectSuffixReplace =
getOldNewOptions(args, OPT_thinlto_object_suffix_replace);
+ config->ltoObjPath = args.getLastArgValue(OPT_lto_obj_path);
// Handle miscellaneous boolean flags.
config->allowBind = args.hasFlag(OPT_allowbind, OPT_allowbind_no, true);
config->allowIsolation =
@@ -1545,19 +1575,45 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr
return false;
};
- // 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));
+ // 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;
+ }
+ }
+ // 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);
+ enqueuePath(*path, false, false);
// Windows specific -- Create a resource file containing a manifest file.
if (config->manifest == Configuration::Embed)
- addBuffer(createManifestRes(), false);
+ addBuffer(createManifestRes(), false, false);
// Read all input files given via the command line.
run();
@@ -1582,12 +1638,6 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr
for (auto *arg : args.filtered(OPT_functionpadmin, OPT_functionpadmin_opt))
parseFunctionPadMin(arg, config->machine);
- // Input files can be Windows resource files (.res files). We use
- // WindowsResource to convert resource files to a regular COFF file,
- // then link the resulting file normally.
- if (!resources.empty())
- symtab->addFile(make<ObjFile>(convertResToCOFF(resources)));
-
if (tar)
tar->append("response.txt",
createResponseFile(args, filePaths,
@@ -1626,7 +1676,7 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr
}
// Handle generation of import library from a def file.
- if (!args.hasArg(OPT_INPUT, OPT_wholearchive_file)) {
+ if (!args.hasArg(OPT_INPUT)) {
fixupExports();
createImportLibrary(/*asLib=*/true);
return;
@@ -1672,8 +1722,8 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr
// Set default image name if neither /out or /def set it.
if (config->outputFile.empty()) {
- config->outputFile = getOutputPath(
- (*args.filtered(OPT_INPUT, OPT_wholearchive_file).begin())->getValue());
+ config->outputFile =
+ getOutputPath((*args.filtered(OPT_INPUT).begin())->getValue());
}
// Fail early if an output file is not writable.
@@ -1769,7 +1819,7 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr
// 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)
+ for (auto *s : lto::LTO::getRuntimeLibcallSymbols())
symtab->addLibcall(s);
// Windows specific -- if __load_config_used can be resolved, resolve it.
@@ -1777,28 +1827,10 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr
addUndefined(mangle("_load_config_used"));
} while (run());
- if (errorCount())
- return;
-
- // Do LTO by compiling bitcode input files to a set of native COFF files then
- // link those files (unless -thinlto-index-only was given, in which case we
- // resolve symbols and write indices, but don't generate native code or link).
- symtab->addCombinedLTOObjects();
-
- // If -thinlto-index-only is given, we should create only "index
- // files" and not object files. Index file creation is already done
- // in addCombinedLTOObject, so we are done if that's the case.
- if (config->thinLTOIndexOnly)
- return;
-
- // If we generated native object files from bitcode files, this resolves
- // references to the symbols we use from them.
- run();
-
if (args.hasArg(OPT_include_optional)) {
// Handle /includeoptional
for (auto *arg : args.filtered(OPT_include_optional))
- if (dyn_cast_or_null<Lazy>(symtab->find(arg->getValue())))
+ if (dyn_cast_or_null<LazyArchive>(symtab->find(arg->getValue())))
addUndefined(arg->getValue());
while (run());
}
@@ -1821,11 +1853,36 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr
run();
}
- // Make sure we have resolved all symbols.
- symtab->reportRemainingUndefines();
+ // At this point, we should not have any symbols that cannot be resolved.
+ // If we are going to do codegen for link-time optimization, check for
+ // unresolvable symbols first, so we don't spend time generating code that
+ // will fail to link anyway.
+ if (!BitcodeFile::instances.empty() && !config->forceUnresolved)
+ symtab->reportUnresolvable();
if (errorCount())
return;
+ // Do LTO by compiling bitcode input files to a set of native COFF files then
+ // link those files (unless -thinlto-index-only was given, in which case we
+ // resolve symbols and write indices, but don't generate native code or link).
+ symtab->addCombinedLTOObjects();
+
+ // If -thinlto-index-only is given, we should create only "index
+ // files" and not object files. Index file creation is already done
+ // in addCombinedLTOObject, so we are done if that's the case.
+ if (config->thinLTOIndexOnly)
+ return;
+
+ // If we generated native object files from bitcode files, this resolves
+ // references to the symbols we use from them.
+ run();
+
+ // Resolve remaining undefined symbols and warn about imported locals.
+ symtab->resolveRemainingUndefines();
+ if (errorCount())
+ return;
+
+ config->hadExplicitExports = !config->exports.empty();
if (config->mingw) {
// In MinGW, all symbols are automatically exported if no symbols
// are chosen to be exported.
@@ -1849,10 +1906,12 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr
}
// Windows specific -- when we are creating a .dll file, we also
- // need to create a .lib file.
+ // need to create a .lib file. In MinGW mode, we only do that when the
+ // -implib option is given explicitly, for compatibility with GNU ld.
if (!config->exports.empty() || config->dll) {
fixupExports();
- createImportLibrary(/*asLib=*/false);
+ if (!config->mingw || !config->implib.empty())
+ createImportLibrary(/*asLib=*/false);
assignExportOrdinals();
}
@@ -1896,7 +1955,7 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr
markLive(symtab->getChunks());
// Needs to happen after the last call to addFile().
- diagnoseMultipleResourceObjFiles();
+ convertResources();
// Identify identical COMDAT sections to merge them.
if (config->doICF) {
Modified: projects/clang1000-import/contrib/llvm-project/lld/COFF/Driver.h
==============================================================================
--- projects/clang1000-import/contrib/llvm-project/lld/COFF/Driver.h Thu Jan 23 17:38:17 2020 (r357056)
+++ projects/clang1000-import/contrib/llvm-project/lld/COFF/Driver.h Thu Jan 23 21:35:51 2020 (r357057)
@@ -43,8 +43,8 @@ class COFFOptTable : public llvm::opt::OptTable { (pub
class ArgParser {
public:
- // Concatenate LINK environment variable and given arguments and parse them.
- llvm::opt::InputArgList parseLINK(std::vector<const char *> args);
+ // Parses command line options.
+ llvm::opt::InputArgList parse(llvm::ArrayRef<const char *> args);
// Tokenizes a given string and then parses as command line options.
llvm::opt::InputArgList parse(StringRef s) { return parse(tokenize(s)); }
@@ -56,8 +56,8 @@ class ArgParser { (public)
parseDirectives(StringRef s);
private:
- // Parses command line options.
- llvm::opt::InputArgList parse(llvm::ArrayRef<const char *> args);
+ // Concatenate LINK environment variable.
+ void addLINK(SmallVector<const char *, 256> &argv);
std::vector<const char *> tokenize(StringRef s);
@@ -77,7 +77,7 @@ class LinkerDriver { (public)
MemoryBufferRef takeBuffer(std::unique_ptr<MemoryBuffer> mb);
- void enqueuePath(StringRef path, bool wholeArchive);
+ void enqueuePath(StringRef path, bool wholeArchive, bool lazy);
private:
std::unique_ptr<llvm::TarWriter> tar; // for /linkrepro
@@ -98,6 +98,10 @@ class LinkerDriver { (public)
// Library search path. The first element is always "" (current directory).
std::vector<StringRef> searchPaths;
+ // Convert resource files and potentially merge input resource object
+ // trees into one resource tree.
+ void convertResources();
+
void maybeExportMinGWSymbols(const llvm::opt::InputArgList &args);
// We don't want to add the same file more than once.
@@ -120,7 +124,8 @@ class LinkerDriver { (public)
StringRef findDefaultEntry();
WindowsSubsystem inferSubsystem();
- void addBuffer(std::unique_ptr<MemoryBuffer> mb, bool wholeArchive);
+ void addBuffer(std::unique_ptr<MemoryBuffer> mb, bool wholeArchive,
+ bool lazy);
void addArchiveBuffer(MemoryBufferRef mbref, StringRef symName,
StringRef parentName, uint64_t offsetInArchive);
@@ -184,7 +189,8 @@ void assignExportOrdinals();
void checkFailIfMismatch(StringRef arg, InputFile *source);
// Convert Windows resource files (.res files) to a .obj file.
-MemoryBufferRef convertResToCOFF(ArrayRef<MemoryBufferRef> mbs);
+MemoryBufferRef convertResToCOFF(ArrayRef<MemoryBufferRef> mbs,
+ ArrayRef<ObjFile *> objs);
void runMSVCLinker(std::string rsp, ArrayRef<StringRef> objects);
Modified: projects/clang1000-import/contrib/llvm-project/lld/COFF/DriverUtils.cpp
==============================================================================
--- projects/clang1000-import/contrib/llvm-project/lld/COFF/DriverUtils.cpp Thu Jan 23 17:38:17 2020 (r357056)
+++ projects/clang1000-import/contrib/llvm-project/lld/COFF/DriverUtils.cpp Thu Jan 23 21:35:51 2020 (r357057)
@@ -322,7 +322,7 @@ class TemporaryFile { (public)
if (!contents.empty()) {
std::error_code ec;
- raw_fd_ostream os(path, ec, sys::fs::F_None);
+ raw_fd_ostream os(path, ec, sys::fs::OF_None);
if (ec)
fatal("failed to open " + path + ": " + ec.message());
os << contents;
@@ -410,7 +410,7 @@ static std::string createManifestXmlWithExternalMt(Str
// Create the default manifest file as a temporary file.
TemporaryFile Default("defaultxml", "manifest");
std::error_code ec;
- raw_fd_ostream os(Default.path, ec, sys::fs::F_Text);
+ raw_fd_ostream os(Default.path, ec, sys::fs::OF_Text);
if (ec)
fatal("failed to open " + Default.path + ": " + ec.message());
os << defaultXml;
@@ -511,7 +511,7 @@ void createSideBySideManifest() {
if (path == "")
path = config->outputFile + ".manifest";
std::error_code ec;
- raw_fd_ostream out(path, ec, sys::fs::F_Text);
+ raw_fd_ostream out(path, ec, sys::fs::OF_Text);
if (ec)
fatal("failed to create manifest: " + ec.message());
out << createManifestXml();
@@ -700,26 +700,42 @@ void checkFailIfMismatch(StringRef arg, InputFile *sou
// Convert Windows resource files (.res files) to a .obj file.
// Does what cvtres.exe does, but in-process and cross-platform.
-MemoryBufferRef convertResToCOFF(ArrayRef<MemoryBufferRef> mbs) {
- object::WindowsResourceParser parser;
+MemoryBufferRef convertResToCOFF(ArrayRef<MemoryBufferRef> mbs,
+ ArrayRef<ObjFile *> objs) {
+ object::WindowsResourceParser parser(/* MinGW */ config->mingw);
+ std::vector<std::string> duplicates;
for (MemoryBufferRef mb : mbs) {
std::unique_ptr<object::Binary> bin = check(object::createBinary(mb));
object::WindowsResource *rf = dyn_cast<object::WindowsResource>(bin.get());
if (!rf)
fatal("cannot compile non-resource file as resource");
- std::vector<std::string> duplicates;
if (auto ec = parser.parse(rf, duplicates))
fatal(toString(std::move(ec)));
+ }
- for (const auto &dupeDiag : duplicates)
- if (config->forceMultipleRes)
- warn(dupeDiag);
- else
- error(dupeDiag);
+ // Note: This processes all .res files before all objs. Ideally they'd be
+ // handled in the same order they were linked (to keep the right one, if
+ // there are duplicates that are tolerated due to forceMultipleRes).
+ for (ObjFile *f : objs) {
+ object::ResourceSectionRef rsf;
+ if (auto ec = rsf.load(f->getCOFFObj()))
+ fatal(toString(f) + ": " + toString(std::move(ec)));
+
+ if (auto ec = parser.parse(rsf, f->getName(), duplicates))
+ fatal(toString(std::move(ec)));
}
+ if (config->mingw)
+ parser.cleanUpManifests(duplicates);
+
+ for (const auto &dupeDiag : duplicates)
+ if (config->forceMultipleRes)
+ warn(dupeDiag);
+ else
+ error(dupeDiag);
+
Expected<std::unique_ptr<MemoryBuffer>> e =
llvm::object::writeWindowsResourceCOFF(config->machine, parser,
config->timestamp);
@@ -757,15 +773,15 @@ static void handleColorDiagnostics(opt::InputArgList &
if (!arg)
return;
if (arg->getOption().getID() == OPT_color_diagnostics) {
- errorHandler().colorDiagnostics = true;
+ enableColors(true);
} else if (arg->getOption().getID() == OPT_no_color_diagnostics) {
- errorHandler().colorDiagnostics = false;
+ enableColors(false);
} else {
StringRef s = arg->getValue();
if (s == "always")
- errorHandler().colorDiagnostics = true;
+ enableColors(true);
else if (s == "never")
- errorHandler().colorDiagnostics = false;
+ enableColors(false);
else if (s != "auto")
error("unknown option: --color-diagnostics=" + s);
}
@@ -792,13 +808,17 @@ opt::InputArgList ArgParser::parse(ArrayRef<const char
// We need to get the quoting style for response files before parsing all
// options so we parse here before and ignore all the options but
- // --rsp-quoting.
+ // --rsp-quoting and /lldignoreenv.
+ // (This means --rsp-quoting can't be added through %LINK%.)
opt::InputArgList args = table.ParseArgs(argv, missingIndex, missingCount);
- // Expand response files (arguments in the form of @<filename>)
- // and then parse the argument again.
+
+ // Expand response files (arguments in the form of @<filename>) and insert
+ // flags from %LINK% and %_LINK_%, and then parse the argument again.
SmallVector<const char *, 256> expandedArgv(argv.data(),
argv.data() + argv.size());
+ if (!args.hasArg(OPT_lldignoreenv))
+ addLINK(expandedArgv);
cl::ExpandResponseFiles(saver, getQuotingStyle(args), expandedArgv);
args = table.ParseArgs(makeArrayRef(expandedArgv).drop_front(), missingIndex,
missingCount);
@@ -868,7 +888,7 @@ ArgParser::parseDirectives(StringRef s) {
// link.exe has an interesting feature. If LINK or _LINK_ environment
// variables exist, their contents are handled as command line strings.
// So you can pass extra arguments using them.
-opt::InputArgList ArgParser::parseLINK(std::vector<const char *> argv) {
+void ArgParser::addLINK(SmallVector<const char *, 256> &argv) {
// Concatenate LINK env and command line arguments, and then parse them.
if (Optional<std::string> s = Process::GetEnv("LINK")) {
std::vector<const char *> v = tokenize(*s);
@@ -878,7 +898,6 @@ opt::InputArgList ArgParser::parseLINK(std::vector<con
std::vector<const char *> v = tokenize(*s);
argv.insert(std::next(argv.begin()), v.begin(), v.end());
}
- return parse(argv);
}
std::vector<const char *> ArgParser::tokenize(StringRef s) {
Modified: projects/clang1000-import/contrib/llvm-project/lld/COFF/ICF.cpp
==============================================================================
--- projects/clang1000-import/contrib/llvm-project/lld/COFF/ICF.cpp Thu Jan 23 17:38:17 2020 (r357056)
+++ projects/clang1000-import/contrib/llvm-project/lld/COFF/ICF.cpp Thu Jan 23 21:35:51 2020 (r357057)
@@ -13,7 +13,7 @@
//
// On Windows, ICF is enabled by default.
//
-// See ELF/ICF.cpp for the details about the algortihm.
+// See ELF/ICF.cpp for the details about the algorithm.
//
//===----------------------------------------------------------------------===//
@@ -77,7 +77,7 @@ class ICF { (private)
// section is insignificant to the user program and the behaviour matches that
// of the Visual C++ linker.
bool ICF::isEligible(SectionChunk *c) {
- // Non-comdat chunks, dead chunks, and writable chunks are not elegible.
+ // Non-comdat chunks, dead chunks, and writable chunks are not eligible.
bool writable = c->getOutputCharacteristics() & llvm::COFF::IMAGE_SCN_MEM_WRITE;
if (!c->isCOMDAT() || !c->live || writable)
return false;
@@ -274,7 +274,7 @@ void ICF::run(ArrayRef<Chunk *> vec) {
for (Symbol *b : sc->symbols())
if (auto *sym = dyn_cast_or_null<DefinedRegular>(b))
hash += sym->getChunk()->eqClass[cnt % 2];
- // Set MSB to 1 to avoid collisions with non-hash classs.
+ // Set MSB to 1 to avoid collisions with non-hash classes.
sc->eqClass[(cnt + 1) % 2] = hash | (1U << 31);
});
}
@@ -297,7 +297,7 @@ void ICF::run(ArrayRef<Chunk *> vec) {
log("ICF needed " + Twine(cnt) + " iterations");
- // Merge sections in the same classs.
+ // Merge sections in the same classes.
forEachClass([&](size_t begin, size_t end) {
if (end - begin == 1)
return;
Modified: projects/clang1000-import/contrib/llvm-project/lld/COFF/InputFiles.cpp
==============================================================================
--- projects/clang1000-import/contrib/llvm-project/lld/COFF/InputFiles.cpp Thu Jan 23 17:38:17 2020 (r357056)
+++ projects/clang1000-import/contrib/llvm-project/lld/COFF/InputFiles.cpp Thu Jan 23 21:35:51 2020 (r357057)
@@ -47,6 +47,24 @@ using llvm::Triple;
using llvm::support::ulittle32_t;
namespace lld {
+
+// Returns the last element of a path, which is supposed to be a filename.
+static StringRef getBasename(StringRef path) {
+ return sys::path::filename(path, sys::path::Style::windows);
+}
+
+// Returns a string in the format of "foo.obj" or "foo.obj(bar.lib)".
+std::string toString(const coff::InputFile *file) {
+ if (!file)
+ return "<internal>";
+ if (file->parentName.empty() || file->kind() == coff::InputFile::ImportKind)
+ return file->getName();
+
+ return (getBasename(file->parentName) + "(" + getBasename(file->getName()) +
+ ")")
+ .str();
+}
+
namespace coff {
std::vector<ObjFile *> ObjFile::instances;
@@ -73,6 +91,10 @@ static void checkAndSetWeakAlias(SymbolTable *symtab,
}
}
+static bool ignoredSymbolName(StringRef name) {
+ return name == "@feat.00" || name == "@comp.id";
+}
+
ArchiveFile::ArchiveFile(MemoryBufferRef m) : InputFile(ArchiveKind, m) {}
void ArchiveFile::parse() {
@@ -81,7 +103,7 @@ void ArchiveFile::parse() {
// Read the symbol table to construct Lazy objects.
for (const Archive::Symbol &sym : file->symbols())
- symtab->addLazy(this, sym);
+ symtab->addLazyArchive(this, sym);
}
// Returns a buffer pointing to a member file containing a given symbol.
@@ -116,6 +138,49 @@ std::vector<MemoryBufferRef> getArchiveMembers(Archive
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.
+ std::unique_ptr<Binary> coffObjPtr = CHECK(createBinary(mb), this);
+ COFFObjectFile *coffObj = cast<COFFObjectFile>(coffObjPtr.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);
@@ -206,10 +271,6 @@ SectionChunk *ObjFile::readSection(uint32_t sectionNum
if (def)
c->checksum = def->CheckSum;
- // link.exe uses the presence of .rsrc$01 for LNK4078, so match that.
- if (name == ".rsrc$01")
- isResourceObjFile = true;
-
// CodeView sections are stored to a different vector because they are not
// linked in the regular manner.
if (c->isCodeView())
@@ -226,12 +287,18 @@ SectionChunk *ObjFile::readSection(uint32_t sectionNum
// relocations, in .rdata, leader symbol name matches the MSVC name mangling
// for string literals) are subject to string tail merging.
MergeChunk::addSection(c);
+ else if (name == ".rsrc" || name.startswith(".rsrc$"))
+ resourceChunks.push_back(c);
else
chunks.push_back(c);
return c;
}
+void ObjFile::includeResourceChunks() {
+ chunks.insert(chunks.end(), resourceChunks.begin(), resourceChunks.end());
+}
+
void ObjFile::readAssociativeDefinition(
COFFSymbolRef sym, const coff_aux_section_definition *def) {
readAssociativeDefinition(sym, def, def->getNumber(sym.isBigObj()));
@@ -315,7 +382,8 @@ Symbol *ObjFile::createRegular(COFFSymbolRef sym) {
StringRef name;
coffObj->getSymbolName(sym, name);
if (sc)
- return symtab->addRegular(this, name, sym.getGeneric(), sc);
+ return symtab->addRegular(this, name, sym.getGeneric(), sc,
+ sym.getValue());
// For MinGW symbols named .weak.* that point to a discarded section,
// don't create an Undefined symbol. If nothing ever refers to the symbol,
// everything should be fine. If something actually refers to the symbol
@@ -469,7 +537,7 @@ void ObjFile::handleComdatSelection(COFFSymbolRef sym,
// if the two comdat sections have e.g. different alignment.
// Match that.
if (leaderChunk->getContents() != newChunk.getContents())
- symtab->reportDuplicate(leader, this);
+ symtab->reportDuplicate(leader, this, &newChunk, sym.getValue());
break;
}
@@ -524,13 +592,11 @@ Optional<Symbol *> ObjFile::createDefined(
if (sym.isAbsolute()) {
StringRef name = getName();
+ if (name == "@feat.00")
+ feat00Flags = sym.getValue();
// Skip special symbols.
- if (name == "@comp.id")
+ if (ignoredSymbolName(name))
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-projects
mailing list