diff options
Diffstat (limited to 'lld/COFF/Driver.cpp')
-rw-r--r-- | lld/COFF/Driver.cpp | 1798 |
1 files changed, 899 insertions, 899 deletions
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index 24937abcbe4..be9072b3642 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -54,54 +54,54 @@ using llvm::sys::Process; namespace lld { namespace coff { -static Timer InputFileTimer("Input File Reading", Timer::root()); +static Timer inputFileTimer("Input File Reading", Timer::root()); -Configuration *Config; -LinkerDriver *Driver; +Configuration *config; +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 = +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>(); + errorHandler().exitEarly = canExitEarly; + config = make<Configuration>(); - Symtab = make<SymbolTable>(); + symtab = make<SymbolTable>(); - Driver = make<LinkerDriver>(); - Driver->link(Args); + driver = make<LinkerDriver>(); + driver->link(args); // Call exit() if we can to avoid calling destructors. - if (CanExitEarly) + if (canExitEarly) exitLld(errorCount() ? 1 : 0); freeArena(); - ObjFile::Instances.clear(); - ImportFile::Instances.clear(); - BitcodeFile::Instances.clear(); - memset(MergeChunk::Instances, 0, sizeof(MergeChunk::Instances)); + ObjFile::instances.clear(); + ImportFile::instances.clear(); + BitcodeFile::instances.clear(); + memset(MergeChunk::instances, 0, sizeof(MergeChunk::instances)); return !errorCount(); } // Drop directory components and replace extension with ".exe" or ".dll". -static std::string getOutputPath(StringRef Path) { - auto P = Path.find_last_of("\\/"); - StringRef S = (P == StringRef::npos) ? Path : Path.substr(P + 1); - const char* E = Config->DLL ? ".dll" : ".exe"; - return (S.substr(0, S.rfind('.')) + E).str(); +static std::string getOutputPath(StringRef path) { + auto p = path.find_last_of("\\/"); + StringRef s = (p == StringRef::npos) ? path : path.substr(p + 1); + const char* e = config->dll ? ".dll" : ".exe"; + return (s.substr(0, s.rfind('.')) + e).str(); } // Returns true if S matches /crtend.?\.o$/. -static bool isCrtend(StringRef S) { - if (!S.endswith(".o")) +static bool isCrtend(StringRef s) { + if (!s.endswith(".o")) return false; - S = S.drop_back(2); - if (S.endswith("crtend")) + s = s.drop_back(2); + if (s.endswith("crtend")) return true; - return !S.empty() && S.drop_back().endswith("crtend"); + return !s.empty() && s.drop_back().endswith("crtend"); } // ErrorOr is not default constructible, so it cannot be used as the type @@ -113,257 +113,257 @@ using MBErrPair = std::pair<std::unique_ptr<MemoryBuffer>, std::error_code>; // Create a std::future that opens and maps a file using the best strategy for // the host platform. -static std::future<MBErrPair> createFutureForFile(std::string Path) { +static std::future<MBErrPair> createFutureForFile(std::string path) { #if _WIN32 // On Windows, file I/O is relatively slow so it is best to do this // asynchronously. auto Strategy = std::launch::async; #else - auto Strategy = std::launch::deferred; + auto strategy = std::launch::deferred; #endif - return std::async(Strategy, [=]() { - auto MBOrErr = MemoryBuffer::getFile(Path, + return std::async(strategy, [=]() { + auto mbOrErr = MemoryBuffer::getFile(path, /*FileSize*/ -1, /*RequiresNullTerminator*/ false); - if (!MBOrErr) - return MBErrPair{nullptr, MBOrErr.getError()}; - return MBErrPair{std::move(*MBOrErr), std::error_code()}; + if (!mbOrErr) + return MBErrPair{nullptr, mbOrErr.getError()}; + return MBErrPair{std::move(*mbOrErr), std::error_code()}; }); } // Symbol names are mangled by prepending "_" on x86. -static StringRef mangle(StringRef Sym) { - assert(Config->Machine != IMAGE_FILE_MACHINE_UNKNOWN); - if (Config->Machine == I386) - return Saver.save("_" + Sym); - return Sym; +static StringRef mangle(StringRef sym) { + assert(config->machine != IMAGE_FILE_MACHINE_UNKNOWN); + if (config->machine == I386) + return saver.save("_" + sym); + return sym; } -static bool findUnderscoreMangle(StringRef Sym) { - Symbol *S = Symtab->findMangle(mangle(Sym)); - return S && !isa<Undefined>(S); +static bool findUnderscoreMangle(StringRef sym) { + Symbol *s = symtab->findMangle(mangle(sym)); + return s && !isa<Undefined>(s); } -MemoryBufferRef LinkerDriver::takeBuffer(std::unique_ptr<MemoryBuffer> MB) { - MemoryBufferRef MBRef = *MB; - make<std::unique_ptr<MemoryBuffer>>(std::move(MB)); // take ownership +MemoryBufferRef LinkerDriver::takeBuffer(std::unique_ptr<MemoryBuffer> mb) { + MemoryBufferRef mbref = *mb; + make<std::unique_ptr<MemoryBuffer>>(std::move(mb)); // take ownership - if (Driver->Tar) - Driver->Tar->append(relativeToRoot(MBRef.getBufferIdentifier()), - MBRef.getBuffer()); - return MBRef; + if (driver->tar) + driver->tar->append(relativeToRoot(mbref.getBufferIdentifier()), + mbref.getBuffer()); + return mbref; } -void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuffer> MB, - bool WholeArchive) { - StringRef Filename = MB->getBufferIdentifier(); +void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuffer> mb, + bool wholeArchive) { + StringRef filename = mb->getBufferIdentifier(); - MemoryBufferRef MBRef = takeBuffer(std::move(MB)); - FilePaths.push_back(Filename); + MemoryBufferRef mbref = takeBuffer(std::move(mb)); + filePaths.push_back(filename); // File type is detected by contents, not by file extension. - switch (identify_magic(MBRef.getBuffer())) { + switch (identify_magic(mbref.getBuffer())) { case file_magic::windows_resource: - Resources.push_back(MBRef); + resources.push_back(mbref); break; case file_magic::archive: - if (WholeArchive) { - std::unique_ptr<Archive> File = - CHECK(Archive::create(MBRef), Filename + ": failed to parse archive"); + if (wholeArchive) { + std::unique_ptr<Archive> file = + CHECK(Archive::create(mbref), filename + ": failed to parse archive"); - for (MemoryBufferRef M : getArchiveMembers(File.get())) - addArchiveBuffer(M, "<whole-archive>", Filename, 0); + for (MemoryBufferRef m : getArchiveMembers(file.get())) + addArchiveBuffer(m, "<whole-archive>", filename, 0); return; } - Symtab->addFile(make<ArchiveFile>(MBRef)); + symtab->addFile(make<ArchiveFile>(mbref)); break; case file_magic::bitcode: - Symtab->addFile(make<BitcodeFile>(MBRef, "", 0)); + symtab->addFile(make<BitcodeFile>(mbref, "", 0)); break; case file_magic::coff_object: case file_magic::coff_import_library: - Symtab->addFile(make<ObjFile>(MBRef)); + symtab->addFile(make<ObjFile>(mbref)); break; case file_magic::pdb: - loadTypeServerSource(MBRef); + loadTypeServerSource(mbref); break; case file_magic::coff_cl_gl_object: - error(Filename + ": is not a native COFF file. Recompile without /GL"); + error(filename + ": is not a native COFF file. Recompile without /GL"); break; case file_magic::pecoff_executable: - if (Filename.endswith_lower(".dll")) { - error(Filename + ": bad file type. Did you specify a DLL instead of an " + if (filename.endswith_lower(".dll")) { + error(filename + ": bad file type. Did you specify a DLL instead of an " "import library?"); break; } LLVM_FALLTHROUGH; default: - error(MBRef.getBufferIdentifier() + ": unknown file type"); + error(mbref.getBufferIdentifier() + ": unknown file type"); break; } } -void LinkerDriver::enqueuePath(StringRef Path, bool WholeArchive) { - auto Future = - std::make_shared<std::future<MBErrPair>>(createFutureForFile(Path)); - std::string PathStr = Path; +void LinkerDriver::enqueuePath(StringRef path, bool wholeArchive) { + auto future = + std::make_shared<std::future<MBErrPair>>(createFutureForFile(path)); + std::string pathStr = path; enqueueTask([=]() { - auto MBOrErr = Future->get(); - if (MBOrErr.second) { - std::string Msg = - "could not open '" + PathStr + "': " + MBOrErr.second.message(); + auto mbOrErr = future->get(); + if (mbOrErr.second) { + std::string msg = + "could not open '" + pathStr + "': " + mbOrErr.second.message(); // Check if the filename is a typo for an option flag. OptTable thinks // that all args that are not known options and that start with / are // filenames, but e.g. `/nodefaultlibs` is more likely a typo for // the option `/nodefaultlib` than a reference to a file in the root // directory. - std::string Nearest; - if (COFFOptTable().findNearest(PathStr, Nearest) > 1) - error(Msg); + std::string nearest; + if (COFFOptTable().findNearest(pathStr, nearest) > 1) + error(msg); else - error(Msg + "; did you mean '" + Nearest + "'"); + error(msg + "; did you mean '" + nearest + "'"); } else - Driver->addBuffer(std::move(MBOrErr.first), WholeArchive); + driver->addBuffer(std::move(mbOrErr.first), wholeArchive); }); } -void LinkerDriver::addArchiveBuffer(MemoryBufferRef MB, StringRef SymName, - StringRef ParentName, - uint64_t OffsetInArchive) { - file_magic Magic = identify_magic(MB.getBuffer()); - if (Magic == file_magic::coff_import_library) { - InputFile *Imp = make<ImportFile>(MB); - Imp->ParentName = ParentName; - Symtab->addFile(Imp); +void LinkerDriver::addArchiveBuffer(MemoryBufferRef mb, StringRef symName, + StringRef parentName, + uint64_t offsetInArchive) { + file_magic magic = identify_magic(mb.getBuffer()); + if (magic == file_magic::coff_import_library) { + InputFile *imp = make<ImportFile>(mb); + imp->parentName = parentName; + symtab->addFile(imp); return; } - InputFile *Obj; - if (Magic == file_magic::coff_object) { - Obj = make<ObjFile>(MB); - } else if (Magic == file_magic::bitcode) { - Obj = make<BitcodeFile>(MB, ParentName, OffsetInArchive); + InputFile *obj; + if (magic == file_magic::coff_object) { + obj = make<ObjFile>(mb); + } else if (magic == file_magic::bitcode) { + obj = make<BitcodeFile>(mb, parentName, offsetInArchive); } else { - error("unknown file type: " + MB.getBufferIdentifier()); + error("unknown file type: " + mb.getBufferIdentifier()); return; } - Obj->ParentName = ParentName; - Symtab->addFile(Obj); - log("Loaded " + toString(Obj) + " for " + SymName); + obj->parentName = parentName; + symtab->addFile(obj); + log("Loaded " + toString(obj) + " for " + symName); } -void LinkerDriver::enqueueArchiveMember(const Archive::Child &C, - StringRef SymName, - StringRef ParentName) { +void LinkerDriver::enqueueArchiveMember(const Archive::Child &c, + StringRef symName, + StringRef parentName) { - auto ReportBufferError = [=](Error &&E, - StringRef ChildName) { + auto reportBufferError = [=](Error &&e, + StringRef childName) { fatal("could not get the buffer for the member defining symbol " + - SymName + ": " + ParentName + "(" + ChildName + "): " + - toString(std::move(E))); + symName + ": " + parentName + "(" + childName + "): " + + toString(std::move(e))); }; - if (!C.getParent()->isThin()) { - uint64_t OffsetInArchive = C.getChildOffset(); - Expected<MemoryBufferRef> MBOrErr = C.getMemoryBufferRef(); - if (!MBOrErr) - ReportBufferError(MBOrErr.takeError(), check(C.getFullName())); - MemoryBufferRef MB = MBOrErr.get(); + if (!c.getParent()->isThin()) { + uint64_t offsetInArchive = c.getChildOffset(); + Expected<MemoryBufferRef> mbOrErr = c.getMemoryBufferRef(); + if (!mbOrErr) + reportBufferError(mbOrErr.takeError(), check(c.getFullName())); + MemoryBufferRef mb = mbOrErr.get(); enqueueTask([=]() { - Driver->addArchiveBuffer(MB, SymName, ParentName, OffsetInArchive); + driver->addArchiveBuffer(mb, symName, parentName, offsetInArchive); }); return; } - std::string ChildName = CHECK( - C.getFullName(), + std::string childName = CHECK( + c.getFullName(), "could not get the filename for the member defining symbol " + - SymName); - auto Future = std::make_shared<std::future<MBErrPair>>( - createFutureForFile(ChildName)); + symName); + auto future = std::make_shared<std::future<MBErrPair>>( + createFutureForFile(childName)); enqueueTask([=]() { - auto MBOrErr = Future->get(); - if (MBOrErr.second) - ReportBufferError(errorCodeToError(MBOrErr.second), ChildName); - Driver->addArchiveBuffer(takeBuffer(std::move(MBOrErr.first)), SymName, - ParentName, /* OffsetInArchive */ 0); + auto mbOrErr = future->get(); + if (mbOrErr.second) + reportBufferError(errorCodeToError(mbOrErr.second), childName); + driver->addArchiveBuffer(takeBuffer(std::move(mbOrErr.first)), symName, + parentName, /* OffsetInArchive */ 0); }); } -static bool isDecorated(StringRef Sym) { - return Sym.startswith("@") || Sym.contains("@@") || Sym.startswith("?") || - (!Config->MinGW && Sym.contains('@')); +static bool isDecorated(StringRef sym) { + return sym.startswith("@") || sym.contains("@@") || sym.startswith("?") || + (!config->mingw && sym.contains('@')); } // Parses .drectve section contents and returns a list of files // specified by /defaultlib. -void LinkerDriver::parseDirectives(InputFile *File) { - StringRef S = File->getDirectives(); - if (S.empty()) +void LinkerDriver::parseDirectives(InputFile *file) { + StringRef s = file->getDirectives(); + if (s.empty()) return; - log("Directives: " + toString(File) + ": " + S); + log("Directives: " + toString(file) + ": " + s); - ArgParser Parser; + ArgParser parser; // .drectve is always tokenized using Windows shell rules. // /EXPORT: option can appear too many times, processing in fastpath. - opt::InputArgList Args; - std::vector<StringRef> Exports; - std::tie(Args, Exports) = Parser.parseDirectives(S); + opt::InputArgList args; + std::vector<StringRef> exports; + std::tie(args, exports) = parser.parseDirectives(s); - for (StringRef E : Exports) { + for (StringRef e : exports) { // If a common header file contains dllexported function // declarations, many object files may end up with having the // same /EXPORT options. In order to save cost of parsing them, // we dedup them first. - if (!DirectivesExports.insert(E).second) + if (!directivesExports.insert(e).second) continue; - Export Exp = parseExport(E); - if (Config->Machine == I386 && Config->MinGW) { - if (!isDecorated(Exp.Name)) - Exp.Name = Saver.save("_" + Exp.Name); - if (!Exp.ExtName.empty() && !isDecorated(Exp.ExtName)) - Exp.ExtName = Saver.save("_" + Exp.ExtName); + Export exp = parseExport(e); + if (config->machine == I386 && config->mingw) { + if (!isDecorated(exp.name)) + exp.name = saver.save("_" + exp.name); + if (!exp.extName.empty() && !isDecorated(exp.extName)) + exp.extName = saver.save("_" + exp.extName); } - Exp.Directives = true; - Config->Exports.push_back(Exp); + exp.directives = true; + config->exports.push_back(exp); } - for (auto *Arg : Args) { - switch (Arg->getOption().getID()) { + for (auto *arg : args) { + switch (arg->getOption().getID()) { case OPT_aligncomm: - parseAligncomm(Arg->getValue()); + parseAligncomm(arg->getValue()); break; case OPT_alternatename: - parseAlternateName(Arg->getValue()); + parseAlternateName(arg->getValue()); break; case OPT_defaultlib: - if (Optional<StringRef> Path = findLib(Arg->getValue())) - enqueuePath(*Path, false); + if (Optional<StringRef> path = findLib(arg->getValue())) + enqueuePath(*path, false); break; case OPT_entry: - Config->Entry = addUndefined(mangle(Arg->getValue())); + config->entry = addUndefined(mangle(arg->getValue())); break; case OPT_failifmismatch: - checkFailIfMismatch(Arg->getValue(), File); + checkFailIfMismatch(arg->getValue(), file); break; case OPT_incl: - addUndefined(Arg->getValue()); + addUndefined(arg->getValue()); break; case OPT_merge: - parseMerge(Arg->getValue()); + parseMerge(arg->getValue()); break; case OPT_nodefaultlib: - Config->NoDefaultLibs.insert(doFindLib(Arg->getValue()).lower()); + config->noDefaultLibs.insert(doFindLib(arg->getValue()).lower()); break; case OPT_section: - parseSection(Arg->getValue()); + parseSection(arg->getValue()); break; case OPT_subsystem: - parseSubsystem(Arg->getValue(), &Config->Subsystem, - &Config->MajorOSVersion, &Config->MinorOSVersion); + parseSubsystem(arg->getValue(), &config->subsystem, + &config->majorOSVersion, &config->minorOSVersion); break; // Only add flags here that link.exe accepts in // `#pragma comment(linker, "/flag")`-generated sections. @@ -372,138 +372,138 @@ void LinkerDriver::parseDirectives(InputFile *File) { case OPT_throwingnew: break; default: - error(Arg->getSpelling() + " is not allowed in .drectve"); + error(arg->getSpelling() + " is not allowed in .drectve"); } } } // Find file from search paths. You can omit ".obj", this function takes // care of that. Note that the returned path is not guaranteed to exist. -StringRef LinkerDriver::doFindFile(StringRef Filename) { - bool HasPathSep = (Filename.find_first_of("/\\") != StringRef::npos); - if (HasPathSep) - return Filename; - bool HasExt = Filename.contains('.'); - for (StringRef Dir : SearchPaths) { - SmallString<128> Path = Dir; - sys::path::append(Path, Filename); - if (sys::fs::exists(Path.str())) - return Saver.save(Path.str()); - if (!HasExt) { - Path.append(".obj"); - if (sys::fs::exists(Path.str())) - return Saver.save(Path.str()); +StringRef LinkerDriver::doFindFile(StringRef filename) { + bool hasPathSep = (filename.find_first_of("/\\") != StringRef::npos); + if (hasPathSep) + return filename; + bool hasExt = filename.contains('.'); + for (StringRef dir : searchPaths) { + SmallString<128> path = dir; + sys::path::append(path, filename); + if (sys::fs::exists(path.str())) + return saver.save(path.str()); + if (!hasExt) { + path.append(".obj"); + if (sys::fs::exists(path.str())) + return saver.save(path.str()); } } - return Filename; + return filename; } -static Optional<sys::fs::UniqueID> getUniqueID(StringRef Path) { - sys::fs::UniqueID Ret; - if (sys::fs::getUniqueID(Path, Ret)) +static Optional<sys::fs::UniqueID> getUniqueID(StringRef path) { + sys::fs::UniqueID ret; + if (sys::fs::getUniqueID(path, ret)) return None; - return Ret; + return ret; } // Resolves a file path. This never returns the same path // (in that case, it returns None). -Optional<StringRef> LinkerDriver::findFile(StringRef Filename) { - StringRef Path = doFindFile(Filename); +Optional<StringRef> LinkerDriver::findFile(StringRef filename) { + StringRef path = doFindFile(filename); - if (Optional<sys::fs::UniqueID> ID = getUniqueID(Path)) { - bool Seen = !VisitedFiles.insert(*ID).second; - if (Seen) + if (Optional<sys::fs::UniqueID> id = getUniqueID(path)) { + bool seen = !visitedFiles.insert(*id).second; + if (seen) return None; } - if (Path.endswith_lower(".lib")) - VisitedLibs.insert(sys::path::filename(Path)); - return Path; + if (path.endswith_lower(".lib")) + visitedLibs.insert(sys::path::filename(path)); + return path; } // MinGW specific. If an embedded directive specified to link to // foo.lib, but it isn't found, try libfoo.a instead. -StringRef LinkerDriver::doFindLibMinGW(StringRef Filename) { - if (Filename.contains('/') || Filename.contains('\\')) - return Filename; - - SmallString<128> S = Filename; - sys::path::replace_extension(S, ".a"); - StringRef LibName = Saver.save("lib" + S.str()); - return doFindFile(LibName); +StringRef LinkerDriver::doFindLibMinGW(StringRef filename) { + if (filename.contains('/') || filename.contains('\\')) + return filename; + + SmallString<128> s = filename; + sys::path::replace_extension(s, ".a"); + StringRef libName = saver.save("lib" + s.str()); + return doFindFile(libName); } // Find library file from search path. -StringRef LinkerDriver::doFindLib(StringRef Filename) { +StringRef LinkerDriver::doFindLib(StringRef filename) { // Add ".lib" to Filename if that has no file extension. - bool HasExt = Filename.contains('.'); - if (!HasExt) - Filename = Saver.save(Filename + ".lib"); - StringRef Ret = doFindFile(Filename); + bool hasExt = filename.contains('.'); + if (!hasExt) + filename = saver.save(filename + ".lib"); + StringRef ret = doFindFile(filename); // For MinGW, if the find above didn't turn up anything, try // looking for a MinGW formatted library name. - if (Config->MinGW && Ret == Filename) - return doFindLibMinGW(Filename); - return Ret; + if (config->mingw && ret == filename) + return doFindLibMinGW(filename); + return ret; } // Resolves a library path. /nodefaultlib options are taken into // consideration. This never returns the same path (in that case, // it returns None). -Optional<StringRef> LinkerDriver::findLib(StringRef Filename) { - if (Config->NoDefaultLibAll) +Optional<StringRef> LinkerDriver::findLib(StringRef filename) { + if (config->noDefaultLibAll) return None; - if (!VisitedLibs.insert(Filename.lower()).second) + if (!visitedLibs.insert(filename.lower()).second) return None; - StringRef Path = doFindLib(Filename); - if (Config->NoDefaultLibs.count(Path.lower())) + StringRef path = doFindLib(filename); + if (config->noDefaultLibs.count(path.lower())) return None; - if (Optional<sys::fs::UniqueID> ID = getUniqueID(Path)) - if (!VisitedFiles.insert(*ID).second) + if (Optional<sys::fs::UniqueID> id = getUniqueID(path)) + if (!visitedFiles.insert(*id).second) return None; - return Path; + return path; } // Parses LIB environment which contains a list of search paths. void LinkerDriver::addLibSearchPaths() { - Optional<std::string> EnvOpt = Process::GetEnv("LIB"); - if (!EnvOpt.hasValue()) + Optional<std::string> envOpt = Process::GetEnv("LIB"); + if (!envOpt.hasValue()) return; - StringRef Env = Saver.save(*EnvOpt); - while (!Env.empty()) { - StringRef Path; - std::tie(Path, Env) = Env.split(';'); - SearchPaths.push_back(Path); + StringRef env = saver.save(*envOpt); + while (!env.empty()) { + StringRef path; + std::tie(path, env) = env.split(';'); + searchPaths.push_back(path); } } -Symbol *LinkerDriver::addUndefined(StringRef Name) { - Symbol *B = Symtab->addUndefined(Name); - if (!B->IsGCRoot) { - B->IsGCRoot = true; - Config->GCRoot.push_back(B); +Symbol *LinkerDriver::addUndefined(StringRef name) { + Symbol *b = symtab->addUndefined(name); + if (!b->isGCRoot) { + b->isGCRoot = true; + config->gCRoot.push_back(b); } - return B; + return b; } -StringRef LinkerDriver::mangleMaybe(Symbol *S) { +StringRef LinkerDriver::mangleMaybe(Symbol *s) { // If the plain symbol name has already been resolved, do nothing. - Undefined *Unmangled = dyn_cast<Undefined>(S); - if (!Unmangled) + Undefined *unmangled = dyn_cast<Undefined>(s); + if (!unmangled) return ""; // Otherwise, see if a similar, mangled symbol exists in the symbol table. - Symbol *Mangled = Symtab->findMangle(Unmangled->getName()); - if (!Mangled) + Symbol *mangled = symtab->findMangle(unmangled->getName()); + if (!mangled) return ""; // If we find a similar mangled symbol, make this an alias to it and return // its name. - log(Unmangled->getName() + " aliased to " + Mangled->getName()); - Unmangled->WeakAlias = Symtab->addUndefined(Mangled->getName()); - return Mangled->getName(); + log(unmangled->getName() + " aliased to " + mangled->getName()); + unmangled->weakAlias = symtab->addUndefined(mangled->getName()); + return mangled->getName(); } // Windows specific -- find default entry point name. @@ -512,15 +512,15 @@ StringRef LinkerDriver::mangleMaybe(Symbol *S) { // each of which corresponds to a user-defined "main" function. This function // infers an entry point from a user-defined "main" function. StringRef LinkerDriver::findDefaultEntry() { - assert(Config->Subsystem != IMAGE_SUBSYSTEM_UNKNOWN && + assert(config->subsystem != IMAGE_SUBSYSTEM_UNKNOWN && "must handle /subsystem before calling this"); - if (Config->MinGW) - return mangle(Config->Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI + if (config->mingw) + return mangle(config->subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI ? "WinMainCRTStartup" : "mainCRTStartup"); - if (Config->Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI) { + if (config->subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI) { if (findUnderscoreMangle("wWinMain")) { if (!findUnderscoreMangle("WinMain")) return mangle("wWinMainCRTStartup"); @@ -537,44 +537,44 @@ StringRef LinkerDriver::findDefaultEntry() { } WindowsSubsystem LinkerDriver::inferSubsystem() { - if (Config->DLL) + if (config->dll) return IMAGE_SUBSYSTEM_WINDOWS_GUI; - if (Config->MinGW) + if (config->mingw) return IMAGE_SUBSYSTEM_WINDOWS_CUI; // Note that link.exe infers the subsystem from the presence of these // functions even if /entry: or /nodefaultlib are passed which causes them // to not be called. - bool HaveMain = findUnderscoreMangle("main"); - bool HaveWMain = findUnderscoreMangle("wmain"); - bool HaveWinMain = findUnderscoreMangle("WinMain"); - bool HaveWWinMain = findUnderscoreMangle("wWinMain"); - if (HaveMain || HaveWMain) { - if (HaveWinMain || HaveWWinMain) { - warn(std::string("found ") + (HaveMain ? "main" : "wmain") + " and " + - (HaveWinMain ? "WinMain" : "wWinMain") + + bool haveMain = findUnderscoreMangle("main"); + bool haveWMain = findUnderscoreMangle("wmain"); + bool haveWinMain = findUnderscoreMangle("WinMain"); + bool haveWWinMain = findUnderscoreMangle("wWinMain"); + if (haveMain || haveWMain) { + if (haveWinMain || haveWWinMain) { + warn(std::string("found ") + (haveMain ? "main" : "wmain") + " and " + + (haveWinMain ? "WinMain" : "wWinMain") + "; defaulting to /subsystem:console"); } return IMAGE_SUBSYSTEM_WINDOWS_CUI; } - if (HaveWinMain || HaveWWinMain) + if (haveWinMain || haveWWinMain) return IMAGE_SUBSYSTEM_WINDOWS_GUI; return IMAGE_SUBSYSTEM_UNKNOWN; } static uint64_t getDefaultImageBase() { - if (Config->is64()) - return Config->DLL ? 0x180000000 : 0x140000000; - return Config->DLL ? 0x10000000 : 0x400000; + if (config->is64()) + return config->dll ? 0x180000000 : 0x140000000; + return config->dll ? 0x10000000 : 0x400000; } -static std::string createResponseFile(const opt::InputArgList &Args, - ArrayRef<StringRef> FilePaths, - ArrayRef<StringRef> SearchPaths) { - SmallString<0> Data; - raw_svector_ostream OS(Data); +static std::string createResponseFile(const opt::InputArgList &args, + ArrayRef<StringRef> filePaths, + ArrayRef<StringRef> searchPaths) { + SmallString<0> data; + raw_svector_ostream os(data); - for (auto *Arg : Args) { - switch (Arg->getOption().getID()) { + for (auto *arg : args) { + switch (arg->getOption().getID()) { case OPT_linkrepro: case OPT_INPUT: case OPT_defaultlib: @@ -589,34 +589,34 @@ static std::string createResponseFile(const opt::InputArgList &Args, case OPT_implib: case OPT_pdb: case OPT_out: - OS << Arg->getSpelling() << sys::path::filename(Arg->getValue()) << "\n"; + os << arg->getSpelling() << sys::path::filename(arg->getValue()) << "\n"; break; default: - OS << toString(*Arg) << "\n"; + os << toString(*arg) << "\n"; } } - for (StringRef Path : SearchPaths) { - std::string RelPath = relativeToRoot(Path); - OS << "/libpath:" << quote(RelPath) << "\n"; + for (StringRef path : searchPaths) { + std::string relPath = relativeToRoot(path); + os << "/libpath:" << quote(relPath) << "\n"; } - for (StringRef Path : FilePaths) - OS << quote(relativeToRoot(Path)) << "\n"; + for (StringRef path : filePaths) + os << quote(relativeToRoot(path)) << "\n"; - return Data.str(); + return data.str(); } enum class DebugKind { Unknown, None, Full, FastLink, GHash, Dwarf, Symtab }; -static DebugKind parseDebugKind(const opt::InputArgList &Args) { - auto *A = Args.getLastArg(OPT_debug, OPT_debug_opt); - if (!A) +static DebugKind parseDebugKind(const opt::InputArgList &args) { + auto *a = args.getLastArg(OPT_debug, OPT_debug_opt); + if (!a) return DebugKind::None; - if (A->getNumValues() == 0) + if (a->getNumValues() == 0) return DebugKind::Full; - DebugKind Debug = StringSwitch<DebugKind>(A->getValue()) + DebugKind debug = StringSwitch<DebugKind>(a->getValue()) .CaseLower("none", DebugKind::None) .CaseLower("full", DebugKind::Full) .CaseLower("fastlink", DebugKind::FastLink) @@ -626,68 +626,68 @@ static DebugKind parseDebugKind(const opt::InputArgList &Args) { .CaseLower("symtab", DebugKind::Symtab) .Default(DebugKind::Unknown); - if (Debug == DebugKind::FastLink) { + if (debug == DebugKind::FastLink) { warn("/debug:fastlink unsupported; using /debug:full"); return DebugKind::Full; } - if (Debug == DebugKind::Unknown) { - error("/debug: unknown option: " + Twine(A->getValue())); + if (debug == DebugKind::Unknown) { + error("/debug: unknown option: " + Twine(a->getValue())); return DebugKind::None; } - return Debug; + return debug; } -static unsigned parseDebugTypes(const opt::InputArgList &Args) { - unsigned DebugTypes = static_cast<unsigned>(DebugType::None); +static unsigned parseDebugTypes(const opt::InputArgList &args) { + unsigned debugTypes = static_cast<unsigned>(DebugType::None); - if (auto *A = Args.getLastArg(OPT_debugtype)) { - SmallVector<StringRef, 3> Types; - StringRef(A->getValue()) - .split(Types, ',', /*MaxSplit=*/-1, /*KeepEmpty=*/false); + if (auto *a = args.getLastArg(OPT_debugtype)) { + SmallVector<StringRef, 3> types; + StringRef(a->getValue()) + .split(types, ',', /*MaxSplit=*/-1, /*KeepEmpty=*/false); - for (StringRef Type : Types) { - unsigned V = StringSwitch<unsigned>(Type.lower()) + for (StringRef type : types) { + unsigned v = StringSwitch<unsigned>(type.lower()) .Case("cv", static_cast<unsigned>(DebugType::CV)) .Case("pdata", static_cast<unsigned>(DebugType::PData)) .Case("fixup", static_cast<unsigned>(DebugType::Fixup)) .Default(0); - if (V == 0) { - warn("/debugtype: unknown option '" + Type + "'"); + if (v == 0) { + warn("/debugtype: unknown option '" + type + "'"); continue; } - DebugTypes |= V; + debugTypes |= v; } - return DebugTypes; + return debugTypes; } // Default debug types - DebugTypes = static_cast<unsigned>(DebugType::CV); - if (Args.hasArg(OPT_driver)) - DebugTypes |= static_cast<unsigned>(DebugType::PData); - if (Args.hasArg(OPT_profile)) - DebugTypes |= static_cast<unsigned>(DebugType::Fixup); + debugTypes = static_cast<unsigned>(DebugType::CV); + if (args.hasArg(OPT_driver)) + debugTypes |= static_cast<unsigned>(DebugType::PData); + if (args.hasArg(OPT_profile)) + debugTypes |= static_cast<unsigned>(DebugType::Fixup); - return DebugTypes; + return debugTypes; } -static std::string getMapFile(const opt::InputArgList &Args) { - auto *Arg = Args.getLastArg(OPT_lldmap, OPT_lldmap_file); - if (!Arg) +static std::string getMapFile(const opt::InputArgList &args) { + auto *arg = args.getLastArg(OPT_lldmap, OPT_lldmap_file); + if (!arg) return ""; - if (Arg->getOption().getID() == OPT_lldmap_file) - return Arg->getValue(); + if (arg->getOption().getID() == OPT_lldmap_file) + return arg->getValue(); - assert(Arg->getOption().getID() == OPT_lldmap); - StringRef OutFile = Config->OutputFile; - return (OutFile.substr(0, OutFile.rfind('.')) + ".map").str(); + assert(arg->getOption().getID() == OPT_lldmap); + StringRef outFile = config->outputFile; + return (outFile.substr(0, outFile.rfind('.')) + ".map").str(); } static std::string getImplibPath() { - if (!Config->Implib.empty()) - return Config->Implib; - SmallString<128> Out = StringRef(Config->OutputFile); - sys::path::replace_extension(Out, ".lib"); - return Out.str(); + if (!config->implib.empty()) + return config->implib; + SmallString<128> out = StringRef(config->outputFile); + sys::path::replace_extension(out, ".lib"); + return out.str(); } // @@ -698,226 +698,226 @@ static std::string getImplibPath() { // LINK | {value} | {value}.{.dll/.exe} | {output name} // LIB | {value} | {value}.dll | {output name}.dll // -static std::string getImportName(bool AsLib) { - SmallString<128> Out; +static std::string getImportName(bool asLib) { + SmallString<128> out; - if (Config->ImportName.empty()) { - Out.assign(sys::path::filename(Config->OutputFile)); - if (AsLib) - sys::path::replace_extension(Out, ".dll"); + if (config->importName.empty()) { + out.assign(sys::path::filename(config->outputFile)); + if (asLib) + sys::path::replace_extension(out, ".dll"); } else { - Out.assign(Config->ImportName); - if (!sys::path::has_extension(Out)) - sys::path::replace_extension(Out, - (Config->DLL || AsLib) ? ".dll" : ".exe"); + out.assign(config->importName); + if (!sys::path::has_extension(out)) + sys::path::replace_extension(out, + (config->dll || asLib) ? ".dll" : ".exe"); } - return Out.str(); + return out.str(); } -static void createImportLibrary(bool AsLib) { - std::vector<COFFShortExport> Exports; - for (Export &E1 : Config->Exports) { - COFFShortExport E2; - E2.Name = E1.Name; - E2.SymbolName = E1.SymbolName; - E2.ExtName = E1.ExtName; - E2.Ordinal = E1.Ordinal; - E2.Noname = E1.Noname; - E2.Data = E1.Data; - E2.Private = E1.Private; - E2.Constant = E1.Constant; - Exports.push_back(E2); - } - - auto HandleError = [](Error &&E) { - handleAllErrors(std::move(E), - [](ErrorInfoBase &EIB) { error(EIB.message()); }); +static void createImportLibrary(bool asLib) { + std::vector<COFFShortExport> exports; + for (Export &e1 : config->exports) { + COFFShortExport e2; + e2.Name = e1.name; + e2.SymbolName = e1.symbolName; + e2.ExtName = e1.extName; + e2.Ordinal = e1.ordinal; + e2.Noname = e1.noname; + e2.Data = e1.data; + e2.Private = e1.isPrivate; + e2.Constant = e1.constant; + exports.push_back(e2); + } + + auto handleError = [](Error &&e) { + handleAllErrors(std::move(e), + [](ErrorInfoBase &eib) { error(eib.message()); }); }; - std::string LibName = getImportName(AsLib); - std::string Path = getImplibPath(); + std::string libName = getImportName(asLib); + std::string path = getImplibPath(); - if (!Config->Incremental) { - HandleError(writeImportLibrary(LibName, Path, Exports, Config->Machine, - Config->MinGW)); + if (!config->incremental) { + handleError(writeImportLibrary(libName, path, exports, config->machine, + config->mingw)); return; } // If the import library already exists, replace it only if the contents // have changed. - ErrorOr<std::unique_ptr<MemoryBuffer>> OldBuf = MemoryBuffer::getFile( - Path, /*FileSize*/ -1, /*RequiresNullTerminator*/ false); - if (!OldBuf) { - HandleError(writeImportLibrary(LibName, Path, Exports, Config->Machine, - Config->MinGW)); + ErrorOr<std::unique_ptr<MemoryBuffer>> oldBuf = MemoryBuffer::getFile( + path, /*FileSize*/ -1, /*RequiresNullTerminator*/ false); + if (!oldBuf) { + handleError(writeImportLibrary(libName, path, exports, config->machine, + config->mingw)); return; } - SmallString<128> TmpName; - if (std::error_code EC = - sys::fs::createUniqueFile(Path + ".tmp-%%%%%%%%.lib", TmpName)) - fatal("cannot create temporary file for import library " + Path + ": " + - EC.message()); + SmallString<128> tmpName; + if (std::error_code ec = + sys::fs::createUniqueFile(path + ".tmp-%%%%%%%%.lib", tmpName)) + fatal("cannot create temporary file for import library " + path + ": " + + ec.message()); - if (Error E = writeImportLibrary(LibName, TmpName, Exports, Config->Machine, - Config->MinGW)) { - HandleError(std::move(E)); + if (Error e = writeImportLibrary(libName, tmpName, exports, config->machine, + config->mingw)) { + handleError(std::move(e)); return; } - std::unique_ptr<MemoryBuffer> NewBuf = check(MemoryBuffer::getFile( - TmpName, /*FileSize*/ -1, /*RequiresNullTerminator*/ false)); - if ((*OldBuf)->getBuffer() != NewBuf->getBuffer()) { - OldBuf->reset(); - HandleError(errorCodeToError(sys::fs::rename(TmpName, Path))); + std::unique_ptr<MemoryBuffer> newBuf = check(MemoryBuffer::getFile( + tmpName, /*FileSize*/ -1, /*RequiresNullTerminator*/ false)); + if ((*oldBuf)->getBuffer() != newBuf->getBuffer()) { + oldBuf->reset(); + handleError(errorCodeToError(sys::fs::rename(tmpName, path))); } else { - sys::fs::remove(TmpName); + sys::fs::remove(tmpName); } } -static void parseModuleDefs(StringRef Path) { - std::unique_ptr<MemoryBuffer> MB = CHECK( - MemoryBuffer::getFile(Path, -1, false, true), "could not open " + Path); - COFFModuleDefinition M = check(parseCOFFModuleDefinition( - MB->getMemBufferRef(), Config->Machine, Config->MinGW)); - - if (Config->OutputFile.empty()) - Config->OutputFile = Saver.save(M.OutputFile); - Config->ImportName = Saver.save(M.ImportName); - if (M.ImageBase) - Config->ImageBase = M.ImageBase; - if (M.StackReserve) - Config->StackReserve = M.StackReserve; - if (M.StackCommit) - Config->StackCommit = M.StackCommit; - if (M.HeapReserve) - Config->HeapReserve = M.HeapReserve; - if (M.HeapCommit) - Config->HeapCommit = M.HeapCommit; - if (M.MajorImageVersion) - Config->MajorImageVersion = M.MajorImageVersion; - if (M.MinorImageVersion) - Config->MinorImageVersion = M.MinorImageVersion; - if (M.MajorOSVersion) - Config->MajorOSVersion = M.MajorOSVersion; - if (M.MinorOSVersion) - Config->MinorOSVersion = M.MinorOSVersion; - - for (COFFShortExport E1 : M.Exports) { - Export E2; +static void parseModuleDefs(StringRef path) { + std::unique_ptr<MemoryBuffer> mb = CHECK( + MemoryBuffer::getFile(path, -1, false, true), "could not open " + path); + COFFModuleDefinition m = check(parseCOFFModuleDefinition( + mb->getMemBufferRef(), config->machine, config->mingw)); + + if (config->outputFile.empty()) + config->outputFile = saver.save(m.OutputFile); + config->importName = saver.save(m.ImportName); + if (m.ImageBase) + config->imageBase = m.ImageBase; + if (m.StackReserve) + config->stackReserve = m.StackReserve; + if (m.StackCommit) + config->stackCommit = m.StackCommit; + if (m.HeapReserve) + config->heapReserve = m.HeapReserve; + if (m.HeapCommit) + config->heapCommit = m.HeapCommit; + if (m.MajorImageVersion) + config->majorImageVersion = m.MajorImageVersion; + if (m.MinorImageVersion) + config->minorImageVersion = m.MinorImageVersion; + if (m.MajorOSVersion) + config->majorOSVersion = m.MajorOSVersion; + if (m.MinorOSVersion) + config->minorOSVersion = m.MinorOSVersion; + + for (COFFShortExport e1 : m.Exports) { + Export e2; // In simple cases, only Name is set. Renamed exports are parsed // and set as "ExtName = Name". If Name has the form "OtherDll.Func", // it shouldn't be a normal exported function but a forward to another // DLL instead. This is supported by both MS and GNU linkers. - if (E1.ExtName != E1.Name && StringRef(E1.Name).contains('.')) { - E2.Name = Saver.save(E1.ExtName); - E2.ForwardTo = Saver.save(E1.Name); - Config->Exports.push_back(E2); + if (e1.ExtName != e1.Name && StringRef(e1.Name).contains('.')) { + e2.name = saver.save(e1.ExtName); + e2.forwardTo = saver.save(e1.Name); + config->exports.push_back(e2); continue; } - E2.Name = Saver.save(E1.Name); - E2.ExtName = Saver.save(E1.ExtName); - E2.Ordinal = E1.Ordinal; - E2.Noname = E1.Noname; - E2.Data = E1.Data; - E2.Private = E1.Private; - E2.Constant = E1.Constant; - Config->Exports.push_back(E2); + e2.name = saver.save(e1.Name); + e2.extName = saver.save(e1.ExtName); + e2.ordinal = e1.Ordinal; + e2.noname = e1.Noname; + e2.data = e1.Data; + e2.isPrivate = e1.Private; + e2.constant = e1.Constant; + config->exports.push_back(e2); } } -void LinkerDriver::enqueueTask(std::function<void()> Task) { - TaskQueue.push_back(std::move(Task)); +void LinkerDriver::enqueueTask(std::function<void()> task) { + taskQueue.push_back(std::move(task)); } bool LinkerDriver::run() { - ScopedTimer T(InputFileTimer); + ScopedTimer t(inputFileTimer); - bool DidWork = !TaskQueue.empty(); - while (!TaskQueue.empty()) { - TaskQueue.front()(); - TaskQueue.pop_front(); + bool didWork = !taskQueue.empty(); + while (!taskQueue.empty()) { + taskQueue.front()(); + taskQueue.pop_front(); } - return DidWork; + return didWork; } // Parse an /order file. If an option is given, the linker places // COMDAT sections in the same order as their names appear in the // given file. -static void parseOrderFile(StringRef Arg) { +static void parseOrderFile(StringRef arg) { // For some reason, the MSVC linker requires a filename to be // preceded by "@". - if (!Arg.startswith("@")) { + if (!arg.startswith("@")) { error("malformed /order option: '@' missing"); return; } // Get a list of all comdat sections for error checking. - DenseSet<StringRef> Set; - for (Chunk *C : Symtab->getChunks()) - if (auto *Sec = dyn_cast<SectionChunk>(C)) - if (Sec->Sym) - Set.insert(Sec->Sym->getName()); + DenseSet<StringRef> set; + for (Chunk *c : symtab->getChunks()) + if (auto *sec = dyn_cast<SectionChunk>(c)) + if (sec->sym) + set.insert(sec->sym->getName()); // Open a file. - StringRef Path = Arg.substr(1); - std::unique_ptr<MemoryBuffer> MB = CHECK( - MemoryBuffer::getFile(Path, -1, false, true), "could not open " + Path); + StringRef path = arg.substr(1); + std::unique_ptr<MemoryBuffer> mb = CHECK( + MemoryBuffer::getFile(path, -1, false, true), "could not open " + path); // Parse a file. An order file contains one symbol per line. // All symbols that were not present in a given order file are // considered to have the lowest priority 0 and are placed at // end of an output section. - for (std::string S : args::getLines(MB->getMemBufferRef())) { - if (Config->Machine == I386 && !isDecorated(S)) - S = "_" + S; + for (std::string s : args::getLines(mb->getMemBufferRef())) { + if (config->machine == I386 && !isDecorated(s)) + s = "_" + s; - if (Set.count(S) == 0) { - if (Config->WarnMissingOrderSymbol) - warn("/order:" + Arg + ": missing symbol: " + S + " [LNK4037]"); + if (set.count(s) == 0) { + if (config->warnMissingOrderSymbol) + warn("/order:" + arg + ": missing symbol: " + s + " [LNK4037]"); } else - Config->Order[S] = INT_MIN + Config->Order.size(); + config->order[s] = INT_MIN + config->order.size(); } } -static void markAddrsig(Symbol *S) { - if (auto *D = dyn_cast_or_null<Defined>(S)) - if (SectionChunk *C = dyn_cast_or_null<SectionChunk>(D->getChunk())) - C->KeepUnique = true; +static void markAddrsig(Symbol *s) { + if (auto *d = dyn_cast_or_null<Defined>(s)) + if (SectionChunk *c = dyn_cast_or_null<SectionChunk>(d->getChunk())) + c->keepUnique = true; } static void findKeepUniqueSections() { // Exported symbols could be address-significant in other executables or DSOs, // so we conservatively mark them as address-significant. - for (Export &R : Config->Exports) - markAddrsig(R.Sym); + for (Export &r : config->exports) + markAddrsig(r.sym); // Visit the address-significance table in each object file and mark each // referenced symbol as address-significant. - for (ObjFile *Obj : ObjFile::Instances) { - ArrayRef<Symbol *> Syms = Obj->getSymbols(); - if (Obj->AddrsigSec) { - ArrayRef<uint8_t> Contents; + for (ObjFile *obj : ObjFile::instances) { + ArrayRef<Symbol *> syms = obj->getSymbols(); + if (obj->addrsigSec) { + ArrayRef<uint8_t> contents; cantFail( - Obj->getCOFFObj()->getSectionContents(Obj->AddrsigSec, Contents)); - const uint8_t *Cur = Contents.begin(); - while (Cur != Contents.end()) { - unsigned Size; - const char *Err; - uint64_t SymIndex = decodeULEB128(Cur, &Size, Contents.end(), &Err); - if (Err) - fatal(toString(Obj) + ": could not decode addrsig section: " + Err); - if (SymIndex >= Syms.size()) - fatal(toString(Obj) + ": invalid symbol index in addrsig section"); - markAddrsig(Syms[SymIndex]); - Cur += Size; + obj->getCOFFObj()->getSectionContents(obj->addrsigSec, contents)); + const uint8_t *cur = contents.begin(); + while (cur != contents.end()) { + unsigned size; + const char *err; + uint64_t symIndex = decodeULEB128(cur, &size, contents.end(), &err); + if (err) + fatal(toString(obj) + ": could not decode addrsig section: " + err); + if (symIndex >= syms.size()) + fatal(toString(obj) + ": invalid symbol index in addrsig section"); + markAddrsig(syms[symIndex]); + cur += size; } } else { // If an object file does not have an address-significance table, // conservatively mark all of its symbols as address-significant. - for (Symbol *S : Syms) - markAddrsig(S); + for (Symbol *s : syms) + markAddrsig(s); } } } @@ -928,14 +928,14 @@ static void findKeepUniqueSections() { // binary). // lld only supports %_PDB% and %_EXT% and warns on references to all other env // vars. -static void parsePDBAltPath(StringRef AltPath) { - SmallString<128> Buf; - StringRef PDBBasename = - sys::path::filename(Config->PDBPath, sys::path::Style::windows); - StringRef BinaryExtension = - sys::path::extension(Config->OutputFile, sys::path::Style::windows); - if (!BinaryExtension.empty()) - BinaryExtension = BinaryExtension.substr(1); // %_EXT% does not include '.'. +static void parsePDBAltPath(StringRef altPath) { + SmallString<128> buf; + StringRef pdbBasename = + sys::path::filename(config->pdbPath, sys::path::Style::windows); + StringRef binaryExtension = + sys::path::extension(config->outputFile, sys::path::Style::windows); + if (!binaryExtension.empty()) + binaryExtension = binaryExtension.substr(1); // %_EXT% does not include '.'. // Invariant: // +--------- Cursor ('a...' might be the empty string). @@ -943,34 +943,34 @@ static void parsePDBAltPath(StringRef AltPath) { // | | +- SecondMark // v v v // a...%...%... - size_t Cursor = 0; - while (Cursor < AltPath.size()) { - size_t FirstMark, SecondMark; - if ((FirstMark = AltPath.find('%', Cursor)) == StringRef::npos || - (SecondMark = AltPath.find('%', FirstMark + 1)) == StringRef::npos) { + size_t cursor = 0; + while (cursor < altPath.size()) { + size_t firstMark, secondMark; + if ((firstMark = altPath.find('%', cursor)) == StringRef::npos || + (secondMark = altPath.find('%', firstMark + 1)) == StringRef::npos) { // Didn't find another full fragment, treat rest of string as literal. - Buf.append(AltPath.substr(Cursor)); + buf.append(altPath.substr(cursor)); break; } // Found a full fragment. Append text in front of first %, and interpret // text between first and second % as variable name. - Buf.append(AltPath.substr(Cursor, FirstMark - Cursor)); - StringRef Var = AltPath.substr(FirstMark, SecondMark - FirstMark + 1); - if (Var.equals_lower("%_pdb%")) - Buf.append(PDBBasename); - else if (Var.equals_lower("%_ext%")) - Buf.append(BinaryExtension); + buf.append(altPath.substr(cursor, firstMark - cursor)); + StringRef var = altPath.substr(firstMark, secondMark - firstMark + 1); + if (var.equals_lower("%_pdb%")) + buf.append(pdbBasename); + else if (var.equals_lower("%_ext%")) + buf.append(binaryExtension); else { warn("only %_PDB% and %_EXT% supported in /pdbaltpath:, keeping " + - Var + " as literal"); - Buf.append(Var); + var + " as literal"); + buf.append(var); } - Cursor = SecondMark + 1; + cursor = secondMark + 1; } - Config->PDBAltPath = Buf; + config->pdbAltPath = buf; } /// Check that at most one resource obj file was used. @@ -983,19 +983,19 @@ static void diagnoseMultipleResourceObjFiles() { // 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; - for (ObjFile *F : ObjFile::Instances) { - if (!F->IsResourceObjFile) + ObjFile *resourceObjFile = nullptr; + for (ObjFile *f : ObjFile::instances) { + if (!f->isResourceObjFile) continue; - if (!ResourceObjFile) { - ResourceObjFile = F; + if (!resourceObjFile) { + resourceObjFile = f; continue; } - error(toString(F) + + error(toString(f) + ": more than one resource obj file not allowed, already got " + - toString(ResourceObjFile)); + toString(resourceObjFile)); } } @@ -1005,39 +1005,39 @@ static void diagnoseMultipleResourceObjFiles() { // explicitly specified. The automatic behavior can be disabled using the // -exclude-all-symbols option, so that lld-link behaves like link.exe rather // than MinGW in the case that nothing is explicitly exported. -void LinkerDriver::maybeExportMinGWSymbols(const opt::InputArgList &Args) { - if (!Config->DLL) +void LinkerDriver::maybeExportMinGWSymbols(const opt::InputArgList &args) { + if (!config->dll) return; - if (!Args.hasArg(OPT_export_all_symbols)) { - if (!Config->Exports.empty()) + if (!args.hasArg(OPT_export_all_symbols)) { + if (!config->exports.empty()) return; - if (Args.hasArg(OPT_exclude_all_symbols)) + if (args.hasArg(OPT_exclude_all_symbols)) return; } - AutoExporter Exporter; + AutoExporter exporter; - for (auto *Arg : Args.filtered(OPT_wholearchive_file)) - if (Optional<StringRef> Path = doFindFile(Arg->getValue())) - Exporter.addWholeArchive(*Path); + for (auto *arg : args.filtered(OPT_wholearchive_file)) + if (Optional<StringRef> path = doFindFile(arg->getValue())) + exporter.addWholeArchive(*path); - Symtab->forEachSymbol([&](Symbol *S) { - auto *Def = dyn_cast<Defined>(S); - if (!Exporter.shouldExport(Def)) + symtab->forEachSymbol([&](Symbol *s) { + auto *def = dyn_cast<Defined>(s); + if (!exporter.shouldExport(def)) return; - Export E; - E.Name = Def->getName(); - E.Sym = Def; - if (Chunk *C = Def->getChunk()) - if (!(C->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE)) - E.Data = true; - Config->Exports.push_back(E); + Export e; + e.name = def->getName(); + e.sym = def; + if (Chunk *c = def->getChunk()) + if (!(c->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE)) + e.data = true; + config->exports.push_back(e); }); } -void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { +void LinkerDriver::link(ArrayRef<const char *> argsArr) { // Needed for LTO. InitializeAllTargetInfos(); InitializeAllTargets(); @@ -1047,306 +1047,306 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { // If the first command line argument is "/lib", link.exe acts like lib.exe. // We call our own implementation of lib.exe that understands bitcode files. - if (ArgsArr.size() > 1 && StringRef(ArgsArr[1]).equals_lower("/lib")) { - if (llvm::libDriverMain(ArgsArr.slice(1)) != 0) + if (argsArr.size() > 1 && StringRef(argsArr[1]).equals_lower("/lib")) { + if (llvm::libDriverMain(argsArr.slice(1)) != 0) fatal("lib failed"); return; } // Parse command line options. - ArgParser Parser; - opt::InputArgList Args = Parser.parseLINK(ArgsArr); + ArgParser parser; + opt::InputArgList args = parser.parseLINK(argsArr); // Parse and evaluate -mllvm options. - std::vector<const char *> V; - V.push_back("lld-link (LLVM option parsing)"); - for (auto *Arg : Args.filtered(OPT_mllvm)) - V.push_back(Arg->getValue()); - cl::ParseCommandLineOptions(V.size(), V.data()); + std::vector<const char *> v; + v.push_back("lld-link (LLVM option parsing)"); + for (auto *arg : args.filtered(OPT_mllvm)) + v.push_back(arg->getValue()); + cl::ParseCommandLineOptions(v.size(), v.data()); // Handle /errorlimit early, because error() depends on it. - if (auto *Arg = Args.getLastArg(OPT_errorlimit)) { - int N = 20; - StringRef S = Arg->getValue(); - if (S.getAsInteger(10, N)) - error(Arg->getSpelling() + " number expected, but got " + S); - errorHandler().ErrorLimit = N; + if (auto *arg = args.getLastArg(OPT_errorlimit)) { + int n = 20; + StringRef s = arg->getValue(); + if (s.getAsInteger(10, n)) + error(arg->getSpelling() + " number expected, but got " + s); + errorHandler().errorLimit = n; } // Handle /help - if (Args.hasArg(OPT_help)) { - printHelp(ArgsArr[0]); + if (args.hasArg(OPT_help)) { + printHelp(argsArr[0]); return; } - lld::ThreadsEnabled = Args.hasFlag(OPT_threads, OPT_threads_no, true); + lld::threadsEnabled = args.hasFlag(OPT_threads, OPT_threads_no, true); - if (Args.hasArg(OPT_show_timing)) - Config->ShowTiming = true; + if (args.hasArg(OPT_show_timing)) + config->showTiming = true; - Config->ShowSummary = Args.hasArg(OPT_summary); + config->showSummary = args.hasArg(OPT_summary); - ScopedTimer T(Timer::root()); + ScopedTimer t(Timer::root()); // Handle --version, which is an lld extension. This option is a bit odd // because it doesn't start with "/", but we deliberately chose "--" to // avoid conflict with /version and for compatibility with clang-cl. - if (Args.hasArg(OPT_dash_dash_version)) { + if (args.hasArg(OPT_dash_dash_version)) { outs() << getLLDVersion() << "\n"; return; } // Handle /lldmingw early, since it can potentially affect how other // options are handled. - Config->MinGW = Args.hasArg(OPT_lldmingw); + 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"); + if (auto *arg = args.getLastArg(OPT_linkrepro)) { + SmallString<64> path = StringRef(arg->getValue()); + sys::path::append(path, "repro.tar"); - Expected<std::unique_ptr<TarWriter>> ErrOrWriter = - TarWriter::create(Path, "repro"); + Expected<std::unique_ptr<TarWriter>> errOrWriter = + TarWriter::create(path, "repro"); - if (ErrOrWriter) { - Tar = std::move(*ErrOrWriter); + if (errOrWriter) { + tar = std::move(*errOrWriter); } else { - error("/linkrepro: failed to open " + Path + ": " + - toString(ErrOrWriter.takeError())); + error("/linkrepro: failed to open " + path + ": " + + toString(errOrWriter.takeError())); } } - if (!Args.hasArg(OPT_INPUT)) { - if (Args.hasArg(OPT_deffile)) - Config->NoEntry = true; + if (!args.hasArg(OPT_INPUT)) { + if (args.hasArg(OPT_deffile)) + config->noEntry = true; else fatal("no input files"); } // Construct search path list. - SearchPaths.push_back(""); - for (auto *Arg : Args.filtered(OPT_libpath)) - SearchPaths.push_back(Arg->getValue()); + searchPaths.push_back(""); + for (auto *arg : args.filtered(OPT_libpath)) + searchPaths.push_back(arg->getValue()); addLibSearchPaths(); // Handle /ignore - for (auto *Arg : Args.filtered(OPT_ignore)) { - SmallVector<StringRef, 8> Vec; - StringRef(Arg->getValue()).split(Vec, ','); - for (StringRef S : Vec) { - if (S == "4037") - Config->WarnMissingOrderSymbol = false; - else if (S == "4099") - Config->WarnDebugInfoUnusable = false; - else if (S == "4217") - Config->WarnLocallyDefinedImported = false; + for (auto *arg : args.filtered(OPT_ignore)) { + SmallVector<StringRef, 8> vec; + StringRef(arg->getValue()).split(vec, ','); + for (StringRef s : vec) { + if (s == "4037") + config->warnMissingOrderSymbol = false; + else if (s == "4099") + config->warnDebugInfoUnusable = false; + else if (s == "4217") + config->warnLocallyDefinedImported = false; // Other warning numbers are ignored. } } // Handle /out - if (auto *Arg = Args.getLastArg(OPT_out)) - Config->OutputFile = Arg->getValue(); + if (auto *arg = args.getLastArg(OPT_out)) + config->outputFile = arg->getValue(); // Handle /verbose - if (Args.hasArg(OPT_verbose)) - Config->Verbose = true; - errorHandler().Verbose = Config->Verbose; + if (args.hasArg(OPT_verbose)) + config->verbose = true; + errorHandler().verbose = config->verbose; // Handle /force or /force:unresolved - if (Args.hasArg(OPT_force, OPT_force_unresolved)) - Config->ForceUnresolved = true; + if (args.hasArg(OPT_force, OPT_force_unresolved)) + config->forceUnresolved = true; // Handle /force or /force:multiple - if (Args.hasArg(OPT_force, OPT_force_multiple)) - Config->ForceMultiple = true; + if (args.hasArg(OPT_force, OPT_force_multiple)) + config->forceMultiple = true; // Handle /force or /force:multipleres - if (Args.hasArg(OPT_force, OPT_force_multipleres)) - Config->ForceMultipleRes = true; + if (args.hasArg(OPT_force, OPT_force_multipleres)) + config->forceMultipleRes = true; // Handle /debug - DebugKind Debug = parseDebugKind(Args); - if (Debug == DebugKind::Full || Debug == DebugKind::Dwarf || - Debug == DebugKind::GHash) { - Config->Debug = true; - Config->Incremental = true; + DebugKind debug = parseDebugKind(args); + if (debug == DebugKind::Full || debug == DebugKind::Dwarf || + debug == DebugKind::GHash) { + config->debug = true; + config->incremental = true; } // Handle /demangle - Config->Demangle = Args.hasFlag(OPT_demangle, OPT_demangle_no); + config->demangle = args.hasFlag(OPT_demangle, OPT_demangle_no); // Handle /debugtype - Config->DebugTypes = parseDebugTypes(Args); + config->debugTypes = parseDebugTypes(args); // Handle /pdb - bool ShouldCreatePDB = - (Debug == DebugKind::Full || Debug == DebugKind::GHash); - if (ShouldCreatePDB) { - if (auto *Arg = Args.getLastArg(OPT_pdb)) - Config->PDBPath = Arg->getValue(); - if (auto *Arg = Args.getLastArg(OPT_pdbaltpath)) - Config->PDBAltPath = Arg->getValue(); - if (Args.hasArg(OPT_natvis)) - Config->NatvisFiles = Args.getAllArgValues(OPT_natvis); + bool shouldCreatePDB = + (debug == DebugKind::Full || debug == DebugKind::GHash); + if (shouldCreatePDB) { + if (auto *arg = args.getLastArg(OPT_pdb)) + config->pdbPath = arg->getValue(); + if (auto *arg = args.getLastArg(OPT_pdbaltpath)) + config->pdbAltPath = arg->getValue(); + if (args.hasArg(OPT_natvis)) + config->natvisFiles = args.getAllArgValues(OPT_natvis); - if (auto *Arg = Args.getLastArg(OPT_pdb_source_path)) - Config->PDBSourcePath = Arg->getValue(); + if (auto *arg = args.getLastArg(OPT_pdb_source_path)) + config->pdbSourcePath = arg->getValue(); } // Handle /noentry - if (Args.hasArg(OPT_noentry)) { - if (Args.hasArg(OPT_dll)) - Config->NoEntry = true; + if (args.hasArg(OPT_noentry)) { + if (args.hasArg(OPT_dll)) + config->noEntry = true; else error("/noentry must be specified with /dll"); } // Handle /dll - if (Args.hasArg(OPT_dll)) { - Config->DLL = true; - Config->ManifestID = 2; + if (args.hasArg(OPT_dll)) { + config->dll = true; + config->manifestID = 2; } // Handle /dynamicbase and /fixed. We can't use hasFlag for /dynamicbase // because we need to explicitly check whether that option or its inverse was // present in the argument list in order to handle /fixed. - auto *DynamicBaseArg = Args.getLastArg(OPT_dynamicbase, OPT_dynamicbase_no); - if (DynamicBaseArg && - DynamicBaseArg->getOption().getID() == OPT_dynamicbase_no) - Config->DynamicBase = false; + auto *dynamicBaseArg = args.getLastArg(OPT_dynamicbase, OPT_dynamicbase_no); + if (dynamicBaseArg && + dynamicBaseArg->getOption().getID() == OPT_dynamicbase_no) + config->dynamicBase = false; // MSDN claims "/FIXED:NO is the default setting for a DLL, and /FIXED is the // default setting for any other project type.", but link.exe defaults to // /FIXED:NO for exe outputs as well. Match behavior, not docs. - bool Fixed = Args.hasFlag(OPT_fixed, OPT_fixed_no, false); - if (Fixed) { - if (DynamicBaseArg && - DynamicBaseArg->getOption().getID() == OPT_dynamicbase) { + bool fixed = args.hasFlag(OPT_fixed, OPT_fixed_no, false); + if (fixed) { + if (dynamicBaseArg && + dynamicBaseArg->getOption().getID() == OPT_dynamicbase) { error("/fixed must not be specified with /dynamicbase"); } else { - Config->Relocatable = false; - Config->DynamicBase = false; + config->relocatable = false; + config->dynamicBase = false; } } // Handle /appcontainer - Config->AppContainer = - Args.hasFlag(OPT_appcontainer, OPT_appcontainer_no, false); + config->appContainer = + args.hasFlag(OPT_appcontainer, OPT_appcontainer_no, false); // Handle /machine - if (auto *Arg = Args.getLastArg(OPT_machine)) { - Config->Machine = getMachineType(Arg->getValue()); - if (Config->Machine == IMAGE_FILE_MACHINE_UNKNOWN) - fatal(Twine("unknown /machine argument: ") + Arg->getValue()); + if (auto *arg = args.getLastArg(OPT_machine)) { + config->machine = getMachineType(arg->getValue()); + if (config->machine == IMAGE_FILE_MACHINE_UNKNOWN) + fatal(Twine("unknown /machine argument: ") + arg->getValue()); } // Handle /nodefaultlib:<filename> - for (auto *Arg : Args.filtered(OPT_nodefaultlib)) - Config->NoDefaultLibs.insert(doFindLib(Arg->getValue()).lower()); + for (auto *arg : args.filtered(OPT_nodefaultlib)) + config->noDefaultLibs.insert(doFindLib(arg->getValue()).lower()); // Handle /nodefaultlib - if (Args.hasArg(OPT_nodefaultlib_all)) - Config->NoDefaultLibAll = true; + if (args.hasArg(OPT_nodefaultlib_all)) + config->noDefaultLibAll = true; // Handle /base - if (auto *Arg = Args.getLastArg(OPT_base)) - parseNumbers(Arg->getValue(), &Config->ImageBase); + if (auto *arg = args.getLastArg(OPT_base)) + parseNumbers(arg->getValue(), &config->imageBase); // Handle /filealign - if (auto *Arg = Args.getLastArg(OPT_filealign)) { - parseNumbers(Arg->getValue(), &Config->FileAlign); - if (!isPowerOf2_64(Config->FileAlign)) - error("/filealign: not a power of two: " + Twine(Config->FileAlign)); + if (auto *arg = args.getLastArg(OPT_filealign)) { + parseNumbers(arg->getValue(), &config->fileAlign); + if (!isPowerOf2_64(config->fileAlign)) + error("/filealign: not a power of two: " + Twine(config->fileAlign)); } // Handle /stack - if (auto *Arg = Args.getLastArg(OPT_stack)) - parseNumbers(Arg->getValue(), &Config->StackReserve, &Config->StackCommit); + if (auto *arg = args.getLastArg(OPT_stack)) + parseNumbers(arg->getValue(), &config->stackReserve, &config->stackCommit); // Handle /guard:cf - if (auto *Arg = Args.getLastArg(OPT_guard)) - parseGuard(Arg->getValue()); + if (auto *arg = args.getLastArg(OPT_guard)) + parseGuard(arg->getValue()); // Handle /heap - if (auto *Arg = Args.getLastArg(OPT_heap)) - parseNumbers(Arg->getValue(), &Config->HeapReserve, &Config->HeapCommit); + if (auto *arg = args.getLastArg(OPT_heap)) + parseNumbers(arg->getValue(), &config->heapReserve, &config->heapCommit); // Handle /version - if (auto *Arg = Args.getLastArg(OPT_version)) - parseVersion(Arg->getValue(), &Config->MajorImageVersion, - &Config->MinorImageVersion); + if (auto *arg = args.getLastArg(OPT_version)) + parseVersion(arg->getValue(), &config->majorImageVersion, + &config->minorImageVersion); // Handle /subsystem - if (auto *Arg = Args.getLastArg(OPT_subsystem)) - parseSubsystem(Arg->getValue(), &Config->Subsystem, &Config->MajorOSVersion, - &Config->MinorOSVersion); + if (auto *arg = args.getLastArg(OPT_subsystem)) + parseSubsystem(arg->getValue(), &config->subsystem, &config->majorOSVersion, + &config->minorOSVersion); // Handle /timestamp - if (llvm::opt::Arg *Arg = Args.getLastArg(OPT_timestamp, OPT_repro)) { - if (Arg->getOption().getID() == OPT_repro) { - Config->Timestamp = 0; - Config->Repro = true; + if (llvm::opt::Arg *arg = args.getLastArg(OPT_timestamp, OPT_repro)) { + if (arg->getOption().getID() == OPT_repro) { + config->timestamp = 0; + config->repro = true; } else { - Config->Repro = false; - StringRef Value(Arg->getValue()); - if (Value.getAsInteger(0, Config->Timestamp)) - fatal(Twine("invalid timestamp: ") + Value + + config->repro = false; + StringRef value(arg->getValue()); + if (value.getAsInteger(0, config->timestamp)) + fatal(Twine("invalid timestamp: ") + value + ". Expected 32-bit integer"); } } else { - Config->Repro = false; - Config->Timestamp = time(nullptr); + config->repro = false; + config->timestamp = time(nullptr); } // Handle /alternatename - for (auto *Arg : Args.filtered(OPT_alternatename)) - parseAlternateName(Arg->getValue()); + for (auto *arg : args.filtered(OPT_alternatename)) + parseAlternateName(arg->getValue()); // Handle /include - for (auto *Arg : Args.filtered(OPT_incl)) - addUndefined(Arg->getValue()); + for (auto *arg : args.filtered(OPT_incl)) + addUndefined(arg->getValue()); // Handle /implib - if (auto *Arg = Args.getLastArg(OPT_implib)) - Config->Implib = Arg->getValue(); + if (auto *arg = args.getLastArg(OPT_implib)) + config->implib = arg->getValue(); // Handle /opt. - bool DoGC = Debug == DebugKind::None || Args.hasArg(OPT_profile); - unsigned ICFLevel = - Args.hasArg(OPT_profile) ? 0 : 1; // 0: off, 1: limited, 2: on - unsigned TailMerge = 1; - for (auto *Arg : Args.filtered(OPT_opt)) { - std::string Str = StringRef(Arg->getValue()).lower(); - SmallVector<StringRef, 1> Vec; - StringRef(Str).split(Vec, ','); - for (StringRef S : Vec) { - if (S == "ref") { - DoGC = true; - } else if (S == "noref") { - DoGC = false; - } else if (S == "icf" || S.startswith("icf=")) { - ICFLevel = 2; - } else if (S == "noicf") { - ICFLevel = 0; - } else if (S == "lldtailmerge") { - TailMerge = 2; - } else if (S == "nolldtailmerge") { - TailMerge = 0; - } else if (S.startswith("lldlto=")) { - StringRef OptLevel = S.substr(7); - if (OptLevel.getAsInteger(10, Config->LTOO) || Config->LTOO > 3) - error("/opt:lldlto: invalid optimization level: " + OptLevel); - } else if (S.startswith("lldltojobs=")) { - StringRef Jobs = S.substr(11); - if (Jobs.getAsInteger(10, Config->ThinLTOJobs) || - Config->ThinLTOJobs == 0) - error("/opt:lldltojobs: invalid job count: " + Jobs); - } else if (S.startswith("lldltopartitions=")) { - StringRef N = S.substr(17); - if (N.getAsInteger(10, Config->LTOPartitions) || - Config->LTOPartitions == 0) - error("/opt:lldltopartitions: invalid partition count: " + N); - } else if (S != "lbr" && S != "nolbr") - error("/opt: unknown option: " + S); + bool doGC = debug == DebugKind::None || args.hasArg(OPT_profile); + unsigned icfLevel = + args.hasArg(OPT_profile) ? 0 : 1; // 0: off, 1: limited, 2: on + unsigned tailMerge = 1; + for (auto *arg : args.filtered(OPT_opt)) { + std::string str = StringRef(arg->getValue()).lower(); + SmallVector<StringRef, 1> vec; + StringRef(str).split(vec, ','); + for (StringRef s : vec) { + if (s == "ref") { + doGC = true; + } else if (s == "noref") { + doGC = false; + } else if (s == "icf" || s.startswith("icf=")) { + icfLevel = 2; + } else if (s == "noicf") { + icfLevel = 0; + } else if (s == "lldtailmerge") { + tailMerge = 2; + } else if (s == "nolldtailmerge") { + tailMerge = 0; + } else if (s.startswith("lldlto=")) { + StringRef optLevel = s.substr(7); + if (optLevel.getAsInteger(10, config->ltoo) || config->ltoo > 3) + error("/opt:lldlto: invalid optimization level: " + optLevel); + } else if (s.startswith("lldltojobs=")) { + StringRef jobs = s.substr(11); + if (jobs.getAsInteger(10, config->thinLTOJobs) || + config->thinLTOJobs == 0) + error("/opt:lldltojobs: invalid job count: " + jobs); + } else if (s.startswith("lldltopartitions=")) { + StringRef n = s.substr(17); + if (n.getAsInteger(10, config->ltoPartitions) || + config->ltoPartitions == 0) + error("/opt:lldltopartitions: invalid partition count: " + n); + } else if (s != "lbr" && s != "nolbr") + error("/opt: unknown option: " + s); } } @@ -1355,37 +1355,37 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { // FIXME: LLD only implements "limited" ICF, i.e. it only merges identical // code. If the user passes /OPT:ICF explicitly, LLD should merge identical // comdat readonly data. - if (ICFLevel == 1 && !DoGC) - ICFLevel = 0; - Config->DoGC = DoGC; - Config->DoICF = ICFLevel > 0; - Config->TailMerge = (TailMerge == 1 && Config->DoICF) || TailMerge == 2; + if (icfLevel == 1 && !doGC) + icfLevel = 0; + config->doGC = doGC; + config->doICF = icfLevel > 0; + config->tailMerge = (tailMerge == 1 && config->doICF) || tailMerge == 2; // Handle /lldsavetemps - if (Args.hasArg(OPT_lldsavetemps)) - Config->SaveTemps = true; + if (args.hasArg(OPT_lldsavetemps)) + config->saveTemps = true; // Handle /kill-at - if (Args.hasArg(OPT_kill_at)) - Config->KillAt = true; + if (args.hasArg(OPT_kill_at)) + config->killAt = true; // Handle /lldltocache - if (auto *Arg = Args.getLastArg(OPT_lldltocache)) - Config->LTOCache = Arg->getValue(); + if (auto *arg = args.getLastArg(OPT_lldltocache)) + config->ltoCache = arg->getValue(); // Handle /lldsavecachepolicy - if (auto *Arg = Args.getLastArg(OPT_lldltocachepolicy)) - Config->LTOCachePolicy = CHECK( - parseCachePruningPolicy(Arg->getValue()), - Twine("/lldltocachepolicy: invalid cache policy: ") + Arg->getValue()); + if (auto *arg = args.getLastArg(OPT_lldltocachepolicy)) + config->ltoCachePolicy = CHECK( + parseCachePruningPolicy(arg->getValue()), + Twine("/lldltocachepolicy: invalid cache policy: ") + arg->getValue()); // Handle /failifmismatch - for (auto *Arg : Args.filtered(OPT_failifmismatch)) - checkFailIfMismatch(Arg->getValue(), nullptr); + for (auto *arg : args.filtered(OPT_failifmismatch)) + checkFailIfMismatch(arg->getValue(), nullptr); // Handle /merge - for (auto *Arg : Args.filtered(OPT_merge)) - parseMerge(Arg->getValue()); + for (auto *arg : args.filtered(OPT_merge)) + parseMerge(arg->getValue()); // Add default section merging rules after user rules. User rules take // precedence, but we will emit a warning if there is a conflict. @@ -1395,128 +1395,128 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { parseMerge(".xdata=.rdata"); parseMerge(".bss=.data"); - if (Config->MinGW) { + if (config->mingw) { parseMerge(".ctors=.rdata"); parseMerge(".dtors=.rdata"); parseMerge(".CRT=.rdata"); } // Handle /section - for (auto *Arg : Args.filtered(OPT_section)) - parseSection(Arg->getValue()); + for (auto *arg : args.filtered(OPT_section)) + parseSection(arg->getValue()); // Handle /aligncomm - for (auto *Arg : Args.filtered(OPT_aligncomm)) - parseAligncomm(Arg->getValue()); + for (auto *arg : args.filtered(OPT_aligncomm)) + parseAligncomm(arg->getValue()); // Handle /manifestdependency. This enables /manifest unless /manifest:no is // also passed. - if (auto *Arg = Args.getLastArg(OPT_manifestdependency)) { - Config->ManifestDependency = Arg->getValue(); - Config->Manifest = Configuration::SideBySide; + if (auto *arg = args.getLastArg(OPT_manifestdependency)) { + config->manifestDependency = arg->getValue(); + config->manifest = Configuration::SideBySide; } // Handle /manifest and /manifest: - if (auto *Arg = Args.getLastArg(OPT_manifest, OPT_manifest_colon)) { - if (Arg->getOption().getID() == OPT_manifest) - Config->Manifest = Configuration::SideBySide; + if (auto *arg = args.getLastArg(OPT_manifest, OPT_manifest_colon)) { + if (arg->getOption().getID() == OPT_manifest) + config->manifest = Configuration::SideBySide; else - parseManifest(Arg->getValue()); + parseManifest(arg->getValue()); } // Handle /manifestuac - if (auto *Arg = Args.getLastArg(OPT_manifestuac)) - parseManifestUAC(Arg->getValue()); + if (auto *arg = args.getLastArg(OPT_manifestuac)) + parseManifestUAC(arg->getValue()); // Handle /manifestfile - if (auto *Arg = Args.getLastArg(OPT_manifestfile)) - Config->ManifestFile = Arg->getValue(); + if (auto *arg = args.getLastArg(OPT_manifestfile)) + config->manifestFile = arg->getValue(); // Handle /manifestinput - for (auto *Arg : Args.filtered(OPT_manifestinput)) - Config->ManifestInput.push_back(Arg->getValue()); + for (auto *arg : args.filtered(OPT_manifestinput)) + config->manifestInput.push_back(arg->getValue()); - if (!Config->ManifestInput.empty() && - Config->Manifest != Configuration::Embed) { + if (!config->manifestInput.empty() && + config->manifest != Configuration::Embed) { fatal("/manifestinput: requires /manifest:embed"); } // Handle miscellaneous boolean flags. - Config->AllowBind = Args.hasFlag(OPT_allowbind, OPT_allowbind_no, true); - Config->AllowIsolation = - Args.hasFlag(OPT_allowisolation, OPT_allowisolation_no, true); - Config->Incremental = - Args.hasFlag(OPT_incremental, OPT_incremental_no, - !Config->DoGC && !Config->DoICF && !Args.hasArg(OPT_order) && - !Args.hasArg(OPT_profile)); - Config->IntegrityCheck = - Args.hasFlag(OPT_integritycheck, OPT_integritycheck_no, false); - Config->NxCompat = Args.hasFlag(OPT_nxcompat, OPT_nxcompat_no, true); - for (auto *Arg : Args.filtered(OPT_swaprun)) - parseSwaprun(Arg->getValue()); - Config->TerminalServerAware = - !Config->DLL && Args.hasFlag(OPT_tsaware, OPT_tsaware_no, true); - Config->DebugDwarf = Debug == DebugKind::Dwarf; - Config->DebugGHashes = Debug == DebugKind::GHash; - Config->DebugSymtab = Debug == DebugKind::Symtab; - - Config->MapFile = getMapFile(Args); - - if (Config->Incremental && Args.hasArg(OPT_profile)) { + config->allowBind = args.hasFlag(OPT_allowbind, OPT_allowbind_no, true); + config->allowIsolation = + args.hasFlag(OPT_allowisolation, OPT_allowisolation_no, true); + config->incremental = + args.hasFlag(OPT_incremental, OPT_incremental_no, + !config->doGC && !config->doICF && !args.hasArg(OPT_order) && + !args.hasArg(OPT_profile)); + config->integrityCheck = + args.hasFlag(OPT_integritycheck, OPT_integritycheck_no, false); + config->nxCompat = args.hasFlag(OPT_nxcompat, OPT_nxcompat_no, true); + for (auto *arg : args.filtered(OPT_swaprun)) + parseSwaprun(arg->getValue()); + config->terminalServerAware = + !config->dll && args.hasFlag(OPT_tsaware, OPT_tsaware_no, true); + config->debugDwarf = debug == DebugKind::Dwarf; + config->debugGHashes = debug == DebugKind::GHash; + config->debugSymtab = debug == DebugKind::Symtab; + + config->mapFile = getMapFile(args); + + if (config->incremental && args.hasArg(OPT_profile)) { warn("ignoring '/incremental' due to '/profile' specification"); - Config->Incremental = false; + config->incremental = false; } - if (Config->Incremental && Args.hasArg(OPT_order)) { + if (config->incremental && args.hasArg(OPT_order)) { warn("ignoring '/incremental' due to '/order' specification"); - Config->Incremental = false; + config->incremental = false; } - if (Config->Incremental && Config->DoGC) { + if (config->incremental && config->doGC) { warn("ignoring '/incremental' because REF is enabled; use '/opt:noref' to " "disable"); - Config->Incremental = false; + config->incremental = false; } - if (Config->Incremental && Config->DoICF) { + if (config->incremental && config->doICF) { warn("ignoring '/incremental' because ICF is enabled; use '/opt:noicf' to " "disable"); - Config->Incremental = false; + config->incremental = false; } if (errorCount()) return; - std::set<sys::fs::UniqueID> WholeArchives; - for (auto *Arg : Args.filtered(OPT_wholearchive_file)) - if (Optional<StringRef> Path = doFindFile(Arg->getValue())) - if (Optional<sys::fs::UniqueID> ID = getUniqueID(*Path)) - WholeArchives.insert(*ID); + std::set<sys::fs::UniqueID> wholeArchives; + for (auto *arg : args.filtered(OPT_wholearchive_file)) + if (Optional<StringRef> path = doFindFile(arg->getValue())) + if (Optional<sys::fs::UniqueID> id = getUniqueID(*path)) + wholeArchives.insert(*id); // A predicate returning true if a given path is an argument for // /wholearchive:, or /wholearchive is enabled globally. // This function is a bit tricky because "foo.obj /wholearchive:././foo.obj" // needs to be handled as "/wholearchive:foo.obj foo.obj". - auto IsWholeArchive = [&](StringRef Path) -> bool { - if (Args.hasArg(OPT_wholearchive_flag)) + auto isWholeArchive = [&](StringRef path) -> bool { + if (args.hasArg(OPT_wholearchive_flag)) return true; - if (Optional<sys::fs::UniqueID> ID = getUniqueID(Path)) - return WholeArchives.count(*ID); + if (Optional<sys::fs::UniqueID> id = getUniqueID(path)) + return wholeArchives.count(*id); 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)); + for (auto *arg : args.filtered(OPT_INPUT, OPT_wholearchive_file)) + if (Optional<StringRef> path = findFile(arg->getValue())) + enqueuePath(*path, isWholeArchive(*path)); - for (auto *Arg : Args.filtered(OPT_defaultlib)) - if (Optional<StringRef> Path = findLib(Arg->getValue())) - enqueuePath(*Path, false); + for (auto *arg : args.filtered(OPT_defaultlib)) + if (Optional<StringRef> path = findLib(arg->getValue())) + enqueuePath(*path, false); // Windows specific -- Create a resource file containing a manifest file. - if (Config->Manifest == Configuration::Embed) + if (config->manifest == Configuration::Embed) addBuffer(createManifestRes(), false); // Read all input files given via the command line. @@ -1527,61 +1527,61 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { // We should have inferred a machine type by now from the input files, but if // not we assume x64. - if (Config->Machine == IMAGE_FILE_MACHINE_UNKNOWN) { + if (config->machine == IMAGE_FILE_MACHINE_UNKNOWN) { warn("/machine is not specified. x64 is assumed"); - Config->Machine = AMD64; + config->machine = AMD64; } - Config->Wordsize = Config->is64() ? 8 : 4; + config->wordsize = config->is64() ? 8 : 4; // Handle /functionpadmin - for (auto *Arg : Args.filtered(OPT_functionpadmin, OPT_functionpadmin_opt)) - parseFunctionPadMin(Arg, Config->Machine); + 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 (!resources.empty()) + symtab->addFile(make<ObjFile>(convertResToCOFF(resources))); - if (Tar) - Tar->append("response.txt", - createResponseFile(Args, FilePaths, - ArrayRef<StringRef>(SearchPaths).slice(1))); + if (tar) + tar->append("response.txt", + createResponseFile(args, filePaths, + ArrayRef<StringRef>(searchPaths).slice(1))); // Handle /largeaddressaware - Config->LargeAddressAware = Args.hasFlag( - OPT_largeaddressaware, OPT_largeaddressaware_no, Config->is64()); + config->largeAddressAware = args.hasFlag( + OPT_largeaddressaware, OPT_largeaddressaware_no, config->is64()); // Handle /highentropyva - Config->HighEntropyVA = - Config->is64() && - Args.hasFlag(OPT_highentropyva, OPT_highentropyva_no, true); + config->highEntropyVA = + config->is64() && + args.hasFlag(OPT_highentropyva, OPT_highentropyva_no, true); - if (!Config->DynamicBase && - (Config->Machine == ARMNT || Config->Machine == ARM64)) + if (!config->dynamicBase && + (config->machine == ARMNT || config->machine == ARM64)) error("/dynamicbase:no is not compatible with " + - machineToStr(Config->Machine)); + machineToStr(config->machine)); // Handle /export - for (auto *Arg : Args.filtered(OPT_export)) { - Export E = parseExport(Arg->getValue()); - if (Config->Machine == I386) { - if (!isDecorated(E.Name)) - E.Name = Saver.save("_" + E.Name); - if (!E.ExtName.empty() && !isDecorated(E.ExtName)) - E.ExtName = Saver.save("_" + E.ExtName); + for (auto *arg : args.filtered(OPT_export)) { + Export e = parseExport(arg->getValue()); + if (config->machine == I386) { + if (!isDecorated(e.name)) + e.name = saver.save("_" + e.name); + if (!e.extName.empty() && !isDecorated(e.extName)) + e.extName = saver.save("_" + e.extName); } - Config->Exports.push_back(E); + config->exports.push_back(e); } // Handle /def - if (auto *Arg = Args.getLastArg(OPT_deffile)) { + if (auto *arg = args.getLastArg(OPT_deffile)) { // parseModuleDefs mutates Config object. - parseModuleDefs(Arg->getValue()); + parseModuleDefs(arg->getValue()); } // Handle generation of import library from a def file. - if (!Args.hasArg(OPT_INPUT)) { + if (!args.hasArg(OPT_INPUT)) { fixupExports(); createImportLibrary(/*AsLib=*/true); return; @@ -1590,101 +1590,101 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { // Windows specific -- if no /subsystem is given, we need to infer // that from entry point name. Must happen before /entry handling, // and after the early return when just writing an import library. - if (Config->Subsystem == IMAGE_SUBSYSTEM_UNKNOWN) { - Config->Subsystem = inferSubsystem(); - if (Config->Subsystem == IMAGE_SUBSYSTEM_UNKNOWN) + if (config->subsystem == IMAGE_SUBSYSTEM_UNKNOWN) { + config->subsystem = inferSubsystem(); + if (config->subsystem == IMAGE_SUBSYSTEM_UNKNOWN) fatal("subsystem must be defined"); } // Handle /entry and /dll - if (auto *Arg = Args.getLastArg(OPT_entry)) { - Config->Entry = addUndefined(mangle(Arg->getValue())); - } else if (!Config->Entry && !Config->NoEntry) { - if (Args.hasArg(OPT_dll)) { - StringRef S = (Config->Machine == I386) ? "__DllMainCRTStartup@12" + if (auto *arg = args.getLastArg(OPT_entry)) { + config->entry = addUndefined(mangle(arg->getValue())); + } else if (!config->entry && !config->noEntry) { + if (args.hasArg(OPT_dll)) { + StringRef s = (config->machine == I386) ? "__DllMainCRTStartup@12" : "_DllMainCRTStartup"; - Config->Entry = addUndefined(S); + config->entry = addUndefined(s); } else { // Windows specific -- If entry point name is not given, we need to // infer that from user-defined entry name. - StringRef S = findDefaultEntry(); - if (S.empty()) + StringRef s = findDefaultEntry(); + if (s.empty()) fatal("entry point must be defined"); - Config->Entry = addUndefined(S); - log("Entry name inferred: " + S); + config->entry = addUndefined(s); + log("Entry name inferred: " + s); } } // Handle /delayload - for (auto *Arg : Args.filtered(OPT_delayload)) { - Config->DelayLoads.insert(StringRef(Arg->getValue()).lower()); - if (Config->Machine == I386) { - Config->DelayLoadHelper = addUndefined("___delayLoadHelper2@8"); + for (auto *arg : args.filtered(OPT_delayload)) { + config->delayLoads.insert(StringRef(arg->getValue()).lower()); + if (config->machine == I386) { + config->delayLoadHelper = addUndefined("___delayLoadHelper2@8"); } else { - Config->DelayLoadHelper = addUndefined("__delayLoadHelper2"); + config->delayLoadHelper = addUndefined("__delayLoadHelper2"); } } // Set default image name if neither /out or /def set it. - if (Config->OutputFile.empty()) { - Config->OutputFile = - getOutputPath((*Args.filtered(OPT_INPUT).begin())->getValue()); + if (config->outputFile.empty()) { + config->outputFile = + getOutputPath((*args.filtered(OPT_INPUT).begin())->getValue()); } // Fail early if an output file is not writable. - if (auto E = tryCreateFile(Config->OutputFile)) { - error("cannot open output file " + Config->OutputFile + ": " + E.message()); + if (auto e = tryCreateFile(config->outputFile)) { + error("cannot open output file " + config->outputFile + ": " + e.message()); return; } - if (ShouldCreatePDB) { + if (shouldCreatePDB) { // Put the PDB next to the image if no /pdb flag was passed. - if (Config->PDBPath.empty()) { - Config->PDBPath = Config->OutputFile; - sys::path::replace_extension(Config->PDBPath, ".pdb"); + if (config->pdbPath.empty()) { + config->pdbPath = config->outputFile; + sys::path::replace_extension(config->pdbPath, ".pdb"); } // The embedded PDB path should be the absolute path to the PDB if no // /pdbaltpath flag was passed. - if (Config->PDBAltPath.empty()) { - Config->PDBAltPath = Config->PDBPath; + if (config->pdbAltPath.empty()) { + config->pdbAltPath = config->pdbPath; // It's important to make the path absolute and remove dots. This path // will eventually be written into the PE header, and certain Microsoft // tools won't work correctly if these assumptions are not held. - sys::fs::make_absolute(Config->PDBAltPath); - sys::path::remove_dots(Config->PDBAltPath); + sys::fs::make_absolute(config->pdbAltPath); + sys::path::remove_dots(config->pdbAltPath); } else { // Don't do this earlier, so that Config->OutputFile is ready. - parsePDBAltPath(Config->PDBAltPath); + parsePDBAltPath(config->pdbAltPath); } } // Set default image base if /base is not given. - if (Config->ImageBase == uint64_t(-1)) - Config->ImageBase = getDefaultImageBase(); - - Symtab->addSynthetic(mangle("__ImageBase"), nullptr); - if (Config->Machine == I386) { - Symtab->addAbsolute("___safe_se_handler_table", 0); - Symtab->addAbsolute("___safe_se_handler_count", 0); - } - - Symtab->addAbsolute(mangle("__guard_fids_count"), 0); - Symtab->addAbsolute(mangle("__guard_fids_table"), 0); - Symtab->addAbsolute(mangle("__guard_flags"), 0); - Symtab->addAbsolute(mangle("__guard_iat_count"), 0); - Symtab->addAbsolute(mangle("__guard_iat_table"), 0); - Symtab->addAbsolute(mangle("__guard_longjmp_count"), 0); - Symtab->addAbsolute(mangle("__guard_longjmp_table"), 0); + if (config->imageBase == uint64_t(-1)) + config->imageBase = getDefaultImageBase(); + + symtab->addSynthetic(mangle("__ImageBase"), nullptr); + if (config->machine == I386) { + symtab->addAbsolute("___safe_se_handler_table", 0); + symtab->addAbsolute("___safe_se_handler_count", 0); + } + + symtab->addAbsolute(mangle("__guard_fids_count"), 0); + symtab->addAbsolute(mangle("__guard_fids_table"), 0); + symtab->addAbsolute(mangle("__guard_flags"), 0); + symtab->addAbsolute(mangle("__guard_iat_count"), 0); + symtab->addAbsolute(mangle("__guard_iat_table"), 0); + symtab->addAbsolute(mangle("__guard_longjmp_count"), 0); + symtab->addAbsolute(mangle("__guard_longjmp_table"), 0); // Needed for MSVC 2017 15.5 CRT. - Symtab->addAbsolute(mangle("__enclave_config"), 0); + symtab->addAbsolute(mangle("__enclave_config"), 0); - if (Config->MinGW) { - Symtab->addAbsolute(mangle("__RUNTIME_PSEUDO_RELOC_LIST__"), 0); - Symtab->addAbsolute(mangle("__RUNTIME_PSEUDO_RELOC_LIST_END__"), 0); - Symtab->addAbsolute(mangle("__CTOR_LIST__"), 0); - Symtab->addAbsolute(mangle("__DTOR_LIST__"), 0); + if (config->mingw) { + symtab->addAbsolute(mangle("__RUNTIME_PSEUDO_RELOC_LIST__"), 0); + symtab->addAbsolute(mangle("__RUNTIME_PSEUDO_RELOC_LIST_END__"), 0); + symtab->addAbsolute(mangle("__CTOR_LIST__"), 0); + symtab->addAbsolute(mangle("__DTOR_LIST__"), 0); } // This code may add new undefined symbols to the link, which may enqueue more @@ -1693,33 +1693,33 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { do { // Windows specific -- if entry point is not found, // search for its mangled names. - if (Config->Entry) - mangleMaybe(Config->Entry); + if (config->entry) + mangleMaybe(config->entry); // Windows specific -- Make sure we resolve all dllexported symbols. - for (Export &E : Config->Exports) { - if (!E.ForwardTo.empty()) + for (Export &e : config->exports) { + if (!e.forwardTo.empty()) continue; - E.Sym = addUndefined(E.Name); - if (!E.Directives) - E.SymbolName = mangleMaybe(E.Sym); + e.sym = addUndefined(e.name); + if (!e.directives) + e.symbolName = mangleMaybe(e.sym); } // Add weak aliases. Weak aliases is a mechanism to give remaining // undefined symbols final chance to be resolved successfully. - for (auto Pair : Config->AlternateNames) { - StringRef From = Pair.first; - StringRef To = Pair.second; - Symbol *Sym = Symtab->find(From); - if (!Sym) + for (auto pair : config->alternateNames) { + StringRef from = pair.first; + StringRef to = pair.second; + Symbol *sym = symtab->find(from); + if (!sym) continue; - if (auto *U = dyn_cast<Undefined>(Sym)) - if (!U->WeakAlias) - U->WeakAlias = Symtab->addUndefined(To); + if (auto *u = dyn_cast<Undefined>(sym)) + if (!u->weakAlias) + u->weakAlias = symtab->addUndefined(to); } // Windows specific -- if __load_config_used can be resolved, resolve it. - if (Symtab->findUnderscore("_load_config_used")) + if (symtab->findUnderscore("_load_config_used")) addUndefined(mangle("_load_config_used")); } while (run()); @@ -1728,18 +1728,18 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { // Do LTO by compiling bitcode input files to a set of native COFF files then // link those files. - Symtab->addCombinedLTOObjects(); + symtab->addCombinedLTOObjects(); run(); - if (Args.hasArg(OPT_include_optional)) { + 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()))) - addUndefined(Arg->getValue()); + for (auto *arg : args.filtered(OPT_include_optional)) + if (dyn_cast_or_null<Lazy>(symtab->find(arg->getValue()))) + addUndefined(arg->getValue()); while (run()); } - if (Config->MinGW) { + if (config->mingw) { // Load any further object files that might be needed for doing automatic // imports. // @@ -1753,28 +1753,28 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { // normal object file as well (although that won't be used for the // actual autoimport later on). If this pass adds new undefined references, // we won't iterate further to resolve them. - Symtab->loadMinGWAutomaticImports(); + symtab->loadMinGWAutomaticImports(); run(); } // Make sure we have resolved all symbols. - Symtab->reportRemainingUndefines(); + symtab->reportRemainingUndefines(); if (errorCount()) return; // Handle /safeseh. - if (Args.hasFlag(OPT_safeseh, OPT_safeseh_no, false)) { - for (ObjFile *File : ObjFile::Instances) - if (!File->hasSafeSEH()) - error("/safeseh: " + File->getName() + " is not compatible with SEH"); + if (args.hasFlag(OPT_safeseh, OPT_safeseh_no, false)) { + for (ObjFile *file : ObjFile::instances) + if (!file->hasSafeSEH()) + error("/safeseh: " + file->getName() + " is not compatible with SEH"); if (errorCount()) return; } - if (Config->MinGW) { + if (config->mingw) { // In MinGW, all symbols are automatically exported if no symbols // are chosen to be exported. - maybeExportMinGWSymbols(Args); + maybeExportMinGWSymbols(args); // Make sure the crtend.o object is the last object file. This object // file can contain terminating section chunks that need to be placed @@ -1782,12 +1782,12 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { // order provided on the command line, while lld will pull in needed // files from static libraries only after the last object file on the // command line. - for (auto I = ObjFile::Instances.begin(), E = ObjFile::Instances.end(); - I != E; I++) { - ObjFile *File = *I; - if (isCrtend(File->getName())) { - ObjFile::Instances.erase(I); - ObjFile::Instances.push_back(File); + for (auto i = ObjFile::instances.begin(), e = ObjFile::instances.end(); + i != e; i++) { + ObjFile *file = *i; + if (isCrtend(file->getName())) { + ObjFile::instances.erase(i); + ObjFile::instances.push_back(file); break; } } @@ -1795,58 +1795,58 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { // Windows specific -- when we are creating a .dll file, we also // need to create a .lib file. - if (!Config->Exports.empty() || Config->DLL) { + if (!config->exports.empty() || config->dll) { fixupExports(); createImportLibrary(/*AsLib=*/false); assignExportOrdinals(); } // Handle /output-def (MinGW specific). - if (auto *Arg = Args.getLastArg(OPT_output_def)) - writeDefFile(Arg->getValue()); + if (auto *arg = args.getLastArg(OPT_output_def)) + writeDefFile(arg->getValue()); // Set extra alignment for .comm symbols - for (auto Pair : Config->AlignComm) { - StringRef Name = Pair.first; - uint32_t Alignment = Pair.second; + for (auto pair : config->alignComm) { + StringRef name = pair.first; + uint32_t alignment = pair.second; - Symbol *Sym = Symtab->find(Name); - if (!Sym) { - warn("/aligncomm symbol " + Name + " not found"); + Symbol *sym = symtab->find(name); + if (!sym) { + warn("/aligncomm symbol " + name + " not found"); continue; } // If the symbol isn't common, it must have been replaced with a regular // symbol, which will carry its own alignment. - auto *DC = dyn_cast<DefinedCommon>(Sym); - if (!DC) + auto *dc = dyn_cast<DefinedCommon>(sym); + if (!dc) continue; - CommonChunk *C = DC->getChunk(); - C->setAlignment(std::max(C->getAlignment(), Alignment)); + CommonChunk *c = dc->getChunk(); + c->setAlignment(std::max(c->getAlignment(), alignment)); } // Windows specific -- Create a side-by-side manifest file. - if (Config->Manifest == Configuration::SideBySide) + if (config->manifest == Configuration::SideBySide) createSideBySideManifest(); // Handle /order. We want to do this at this moment because we // need a complete list of comdat sections to warn on nonexistent // functions. - if (auto *Arg = Args.getLastArg(OPT_order)) - parseOrderFile(Arg->getValue()); + if (auto *arg = args.getLastArg(OPT_order)) + parseOrderFile(arg->getValue()); // Identify unreferenced COMDAT sections. - if (Config->DoGC) - markLive(Symtab->getChunks()); + if (config->doGC) + markLive(symtab->getChunks()); // Needs to happen after the last call to addFile(). diagnoseMultipleResourceObjFiles(); // Identify identical COMDAT sections to merge them. - if (Config->DoICF) { + if (config->doICF) { findKeepUniqueSections(); - doICF(Symtab->getChunks()); + doICF(symtab->getChunks()); } // Write the result. @@ -1854,7 +1854,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { // Stop early so we can print the results. Timer::root().stop(); - if (Config->ShowTiming) + if (config->showTiming) Timer::root().print(); } |