Date: Thu, 23 Jan 2020 21:35:52 +0000 (UTC) From: Dimitry Andric <dim@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: 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... Message-ID: <202001232135.00NLZqFG058917@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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 ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202001232135.00NLZqFG058917>