From owner-svn-src-all@freebsd.org Wed Apr 26 19:24:47 2017 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 5AAF6D51D4F; Wed, 26 Apr 2017 19:24:47 +0000 (UTC) (envelope-from dim@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 16136B59; Wed, 26 Apr 2017 19:24:47 +0000 (UTC) (envelope-from dim@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v3QJOkcF030645; Wed, 26 Apr 2017 19:24:46 GMT (envelope-from dim@FreeBSD.org) Received: (from dim@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v3QJOgrT030609; Wed, 26 Apr 2017 19:24:42 GMT (envelope-from dim@FreeBSD.org) Message-Id: <201704261924.v3QJOgrT030609@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: dim set sender to dim@FreeBSD.org using -f From: Dimitry Andric Date: Wed, 26 Apr 2017 19:24:42 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org Subject: svn commit: r317453 - in vendor/lld/dist: COFF ELF test/COFF test/COFF/Inputs test/ELF test/ELF/Inputs test/ELF/linkerscript test/ELF/lto X-SVN-Group: vendor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 26 Apr 2017 19:24:47 -0000 Author: dim Date: Wed Apr 26 19:24:42 2017 New Revision: 317453 URL: https://svnweb.freebsd.org/changeset/base/317453 Log: Vendor import of lld trunk r301441: https://llvm.org/svn/llvm-project/lld/trunk@301441 Added: vendor/lld/dist/test/COFF/Inputs/constant-export.ll vendor/lld/dist/test/COFF/Inputs/msvclto-order-a.ll vendor/lld/dist/test/COFF/Inputs/msvclto-order-b.ll vendor/lld/dist/test/COFF/constant-export.test vendor/lld/dist/test/COFF/constant-export.yaml vendor/lld/dist/test/COFF/msvclto-order.ll vendor/lld/dist/test/ELF/Inputs/progname-ver.s (contents, props changed) vendor/lld/dist/test/ELF/defsym.s (contents, props changed) vendor/lld/dist/test/ELF/driver-access.test vendor/lld/dist/test/ELF/icf-i386.s (contents, props changed) Deleted: vendor/lld/dist/test/ELF/Inputs/progname-ver.so Modified: vendor/lld/dist/COFF/Chunks.cpp vendor/lld/dist/COFF/Config.h vendor/lld/dist/COFF/Driver.cpp vendor/lld/dist/COFF/Driver.h vendor/lld/dist/COFF/DriverUtils.cpp vendor/lld/dist/COFF/InputFiles.h vendor/lld/dist/COFF/Librarian.cpp vendor/lld/dist/COFF/ModuleDef.cpp vendor/lld/dist/COFF/SymbolTable.h vendor/lld/dist/ELF/Driver.cpp vendor/lld/dist/ELF/Filesystem.cpp vendor/lld/dist/ELF/Filesystem.h vendor/lld/dist/ELF/InputFiles.cpp vendor/lld/dist/ELF/InputFiles.h vendor/lld/dist/ELF/Options.td vendor/lld/dist/ELF/OutputSections.cpp vendor/lld/dist/ELF/SymbolTable.cpp vendor/lld/dist/ELF/SymbolTable.h vendor/lld/dist/ELF/Symbols.cpp vendor/lld/dist/ELF/SyntheticSections.cpp vendor/lld/dist/ELF/Target.cpp vendor/lld/dist/ELF/Writer.cpp vendor/lld/dist/test/COFF/linkenv.test vendor/lld/dist/test/ELF/incompatible-section-flags.s vendor/lld/dist/test/ELF/linkerscript/sections.s vendor/lld/dist/test/ELF/lto/asmundef.ll vendor/lld/dist/test/ELF/progname.s vendor/lld/dist/test/ELF/tls-dynamic-i686.s Modified: vendor/lld/dist/COFF/Chunks.cpp ============================================================================== --- vendor/lld/dist/COFF/Chunks.cpp Wed Apr 26 19:24:39 2017 (r317452) +++ vendor/lld/dist/COFF/Chunks.cpp Wed Apr 26 19:24:42 2017 (r317453) @@ -319,8 +319,48 @@ void SEHTableChunk::writeTo(uint8_t *Buf std::sort(Begin, Begin + Cnt); } -// Windows-specific. -// This class represents a block in .reloc section. +// Windows-specific. This class represents a block in .reloc section. +// The format is described here. +// +// On Windows, each DLL is linked against a fixed base address and +// usually loaded to that address. However, if there's already another +// DLL that overlaps, the loader has to relocate it. To do that, DLLs +// contain .reloc sections which contain offsets that need to be fixed +// up at runtime. If the loader find that a DLL cannot be loaded to its +// desired base address, it loads it to somewhere else, and add - to each offset that is +// specified by .reloc section. +// +// In ELF terms, .reloc sections contain arrays of relocation offsets. +// All these offsets in the section are implicitly R_*_RELATIVE, and +// addends are read from section contents (so it is REL as opposed to +// RELA). +// +// This already reduce the size of relocations to 1/3 compared to ELF +// .dynrel, but Windows does more to reduce it (probably because it was +// invented for PCs in the late '80s or early '90s.) Offsets in .reloc +// are grouped by page where page size is 16 bits, and offsets sharing +// the same page address are stored consecutively to represent them with +// less space. This is a very similar to the page table which is grouped +// by (multiple stages of) pages. +// +// For example, let's say we have 0x00030, 0x00500, 0x01000, 0x01100, +// 0x20004, and 0x20008 in a .reloc section. In the section, they are +// represented like this: +// +// 0x00000 -- page address (4 bytes) +// 16 -- size of this block (4 bytes) +// 0x0030 -- entries (2 bytes each) +// 0x0500 +// 0x1000 +// 0x1100 +// 0x20000 -- page address (4 bytes) +// 12 -- size of this block (4 bytes) +// 0x0004 -- entries (2 bytes each) +// 0x0008 +// +// Usually we have a lot of relocatinos for each page, so the number of +// bytes for one .reloc entry is close to 2 bytes. BaserelChunk::BaserelChunk(uint32_t Page, Baserel *Begin, Baserel *End) { // Block header consists of 4 byte page RVA and 4 byte block size. // Each entry is 2 byte. Last entry may be padding. Modified: vendor/lld/dist/COFF/Config.h ============================================================================== --- vendor/lld/dist/COFF/Config.h Wed Apr 26 19:24:39 2017 (r317452) +++ vendor/lld/dist/COFF/Config.h Wed Apr 26 19:24:42 2017 (r317453) @@ -43,6 +43,7 @@ struct Export { bool Noname = false; bool Data = false; bool Private = false; + bool Constant = false; // If an export is a form of /export:foo=dllname.bar, that means // that foo should be exported as an alias to bar in the DLL. Modified: vendor/lld/dist/COFF/Driver.cpp ============================================================================== --- vendor/lld/dist/COFF/Driver.cpp Wed Apr 26 19:24:39 2017 (r317452) +++ vendor/lld/dist/COFF/Driver.cpp Wed Apr 26 19:24:42 2017 (r317453) @@ -512,6 +512,23 @@ void LinkerDriver::invokeMSVC(opt::Input std::string Rsp = "/nologo\n"; std::vector Temps; + // Write out archive members that we used in symbol resolution and pass these + // to MSVC before any archives, so that MSVC uses the same objects to satisfy + // references. + for (const auto *O : Symtab.ObjectFiles) { + if (O->ParentName.empty()) + continue; + SmallString<128> S; + int Fd; + if (auto EC = sys::fs::createTemporaryFile( + "lld-" + sys::path::filename(O->ParentName), ".obj", Fd, S)) + fatal(EC, "cannot create a temporary file"); + raw_fd_ostream OS(Fd, /*shouldClose*/ true); + OS << O->MB.getBuffer(); + Temps.push_back(S.str()); + Rsp += quote(S) + "\n"; + } + for (auto *Arg : Args) { switch (Arg->getOption().getID()) { case OPT_linkrepro: Modified: vendor/lld/dist/COFF/Driver.h ============================================================================== --- vendor/lld/dist/COFF/Driver.h Wed Apr 26 19:24:39 2017 (r317452) +++ vendor/lld/dist/COFF/Driver.h Wed Apr 26 19:24:42 2017 (r317453) @@ -48,7 +48,7 @@ public: llvm::opt::InputArgList parse(llvm::ArrayRef Args); // Concatenate LINK environment varirable and given arguments and parse them. - llvm::opt::InputArgList parseLINK(llvm::ArrayRef Args); + llvm::opt::InputArgList parseLINK(std::vector Args); // Tokenizes a given string and then parses as command line options. llvm::opt::InputArgList parse(StringRef S) { return parse(tokenize(S)); } Modified: vendor/lld/dist/COFF/DriverUtils.cpp ============================================================================== --- vendor/lld/dist/COFF/DriverUtils.cpp Wed Apr 26 19:24:39 2017 (r317452) +++ vendor/lld/dist/COFF/DriverUtils.cpp Wed Apr 26 19:24:42 2017 (r317453) @@ -479,6 +479,10 @@ Export parseExport(StringRef Arg) { E.Data = true; continue; } + if (Tok.equals_lower("constant")) { + E.Constant = true; + continue; + } if (Tok.equals_lower("private")) { E.Private = true; continue; @@ -695,17 +699,20 @@ opt::InputArgList ArgParser::parse(Array return Args; } -// link.exe has an interesting feature. If LINK environment exists, -// its contents are handled as a command line string. So you can pass -// extra arguments using the environment variable. -opt::InputArgList ArgParser::parseLINK(ArrayRef Args) { +// 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 Args) { // Concatenate LINK env and command line arguments, and then parse them. - Optional Env = Process::GetEnv("LINK"); - if (!Env) - return parse(Args); - std::vector V = tokenize(*Env); - V.insert(V.end(), Args.begin(), Args.end()); - return parse(V); + if (Optional S = Process::GetEnv("LINK")) { + std::vector V = tokenize(*S); + Args.insert(Args.begin(), V.begin(), V.end()); + } + if (Optional S = Process::GetEnv("_LINK_")) { + std::vector V = tokenize(*S); + Args.insert(Args.begin(), V.begin(), V.end()); + } + return parse(Args); } std::vector ArgParser::tokenize(StringRef S) { Modified: vendor/lld/dist/COFF/InputFiles.h ============================================================================== --- vendor/lld/dist/COFF/InputFiles.h Wed Apr 26 19:24:39 2017 (r317452) +++ vendor/lld/dist/COFF/InputFiles.h Wed Apr 26 19:24:42 2017 (r317453) @@ -58,6 +58,8 @@ public: // Returns the CPU type this file was compiled to. virtual MachineTypes getMachineType() { return IMAGE_FILE_MACHINE_UNKNOWN; } + MemoryBufferRef MB; + // An archive file name if this file is created from an archive. StringRef ParentName; @@ -67,7 +69,6 @@ public: protected: InputFile(Kind K, MemoryBufferRef M) : MB(M), FileKind(K) {} - MemoryBufferRef MB; std::string Directives; private: Modified: vendor/lld/dist/COFF/Librarian.cpp ============================================================================== --- vendor/lld/dist/COFF/Librarian.cpp Wed Apr 26 19:24:39 2017 (r317452) +++ vendor/lld/dist/COFF/Librarian.cpp Wed Apr 26 19:24:42 2017 (r317453) @@ -162,7 +162,7 @@ public: // Create a short import file which is described in PE/COFF spec 7. Import // Library Format. NewArchiveMember createShortImport(StringRef Sym, uint16_t Ordinal, - ImportNameType NameType, bool isData); + ImportType Type, ImportNameType NameType); }; } @@ -440,8 +440,8 @@ NewArchiveMember ObjectFactory::createNu NewArchiveMember ObjectFactory::createShortImport(StringRef Sym, uint16_t Ordinal, - ImportNameType NameType, - bool isData) { + ImportType ImportType, + ImportNameType NameType) { size_t ImpSize = DLLName.size() + Sym.size() + 2; // +2 for NULs size_t Size = sizeof(coff_import_header) + ImpSize; char *Buf = Alloc.Allocate(Size); @@ -456,8 +456,7 @@ NewArchiveMember ObjectFactory::createSh Imp->SizeOfData = ImpSize; if (Ordinal > 0) Imp->OrdinalHint = Ordinal; - Imp->TypeInfo = (isData ? IMPORT_DATA : IMPORT_CODE); - Imp->TypeInfo |= NameType << 2; + Imp->TypeInfo = (NameType << 2) | ImportType; // Write symbol name and DLL name. memcpy(P, Sym.data(), Sym.size()); @@ -490,11 +489,18 @@ void lld::coff::writeImportLibrary() { if (E.Private) continue; - ImportNameType Type = getNameType(E.SymbolName, E.Name); + ImportType ImportType = IMPORT_CODE; + if (E.Data) + ImportType = IMPORT_DATA; + if (E.Constant) + ImportType = IMPORT_CONST; + + ImportNameType NameType = getNameType(E.SymbolName, E.Name); std::string Name = E.ExtName.empty() ? std::string(E.SymbolName) : replace(E.SymbolName, E.Name, E.ExtName); - Members.push_back(OF.createShortImport(Name, E.Ordinal, Type, E.Data)); + Members.push_back(OF.createShortImport(Name, E.Ordinal, ImportType, + NameType)); } std::pair Result = Modified: vendor/lld/dist/COFF/ModuleDef.cpp ============================================================================== --- vendor/lld/dist/COFF/ModuleDef.cpp Wed Apr 26 19:24:39 2017 (r317452) +++ vendor/lld/dist/COFF/ModuleDef.cpp Wed Apr 26 19:24:42 2017 (r317453) @@ -38,6 +38,7 @@ enum Kind { Comma, Equal, KwBase, + KwConstant, KwData, KwExports, KwHeapsize, @@ -92,6 +93,7 @@ public: StringRef Word = Buf.substr(0, End); Kind K = llvm::StringSwitch(Word) .Case("BASE", KwBase) + .Case("CONSTANT", KwConstant) .Case("DATA", KwData) .Case("EXPORTS", KwExports) .Case("HEAPSIZE", KwHeapsize) @@ -227,6 +229,11 @@ private: E.Data = true; continue; } + if (Tok.K == KwConstant) { + warn("CONSTANT keyword is obsolete; use DATA"); + E.Constant = true; + continue; + } if (Tok.K == KwPrivate) { E.Private = true; continue; Modified: vendor/lld/dist/COFF/SymbolTable.h ============================================================================== --- vendor/lld/dist/COFF/SymbolTable.h Wed Apr 26 19:24:39 2017 (r317452) +++ vendor/lld/dist/COFF/SymbolTable.h Wed Apr 26 19:24:42 2017 (r317453) @@ -108,14 +108,9 @@ public: std::vector LocalImportChunks; private: - void readArchive(); - void readObjects(); - std::pair insert(StringRef Name); StringRef findByPrefix(StringRef Prefix); - void addCombinedLTOObject(ObjectFile *Obj); - llvm::DenseMap Symtab; std::vector BitcodeFiles; Modified: vendor/lld/dist/ELF/Driver.cpp ============================================================================== --- vendor/lld/dist/ELF/Driver.cpp Wed Apr 26 19:24:39 2017 (r317452) +++ vendor/lld/dist/ELF/Driver.cpp Wed Apr 26 19:24:42 2017 (r317453) @@ -184,8 +184,6 @@ void LinkerDriver::addFile(StringRef Pat error("attempted static link of dynamic object " + Path); return; } - Files.push_back(createSharedFile(MBRef)); - // DSOs usually have DT_SONAME tags in their ELF headers, and the // sonames are used to identify DSOs. But if they are missing, // they are identified by filenames. We don't know whether the new @@ -196,8 +194,8 @@ void LinkerDriver::addFile(StringRef Pat // If a file was specified by -lfoo, the directory part is not // significant, as a user did not specify it. This behavior is // compatible with GNU. - Files.back()->DefaultSoName = - WithLOption ? sys::path::filename(Path) : Path; + Files.push_back(createSharedFile( + MBRef, WithLOption ? sys::path::filename(Path) : Path)); return; default: if (InLib) @@ -708,10 +706,6 @@ void LinkerDriver::readConfigs(opt::Inpu if (!Config->Shared && !Config->AuxiliaryList.empty()) error("-f may not be used without -shared"); - for (auto *Arg : Args.filtered(OPT_dynamic_list)) - if (Optional Buffer = readFile(Arg->getValue())) - readDynamicList(*Buffer); - if (auto *Arg = Args.getLastArg(OPT_symbol_ordering_file)) if (Optional Buffer = readFile(Arg->getValue())) Config->SymbolOrderingFile = getLines(*Buffer); @@ -726,21 +720,31 @@ void LinkerDriver::readConfigs(opt::Inpu {S, /*IsExternCpp*/ false, /*HasWildcard*/ false}); } - for (auto *Arg : Args.filtered(OPT_export_dynamic_symbol)) - Config->VersionScriptGlobals.push_back( - {Arg->getValue(), /*IsExternCpp*/ false, /*HasWildcard*/ false}); - - // Dynamic lists are a simplified linker script that doesn't need the - // "global:" and implicitly ends with a "local:*". Set the variables needed to - // simulate that. - if (Args.hasArg(OPT_dynamic_list) || Args.hasArg(OPT_export_dynamic_symbol)) { - Config->ExportDynamic = true; - if (!Config->Shared) - Config->DefaultSymbolVersion = VER_NDX_LOCAL; - } + bool HasExportDynamic = + getArg(Args, OPT_export_dynamic, OPT_no_export_dynamic, false); - if (getArg(Args, OPT_export_dynamic, OPT_no_export_dynamic, false)) - Config->DefaultSymbolVersion = VER_NDX_GLOBAL; + // Parses -dynamic-list and -export-dynamic-symbol. They make some + // symbols private. Note that -export-dynamic takes precedence over them + // as it says all symbols should be exported. + if (!HasExportDynamic) { + for (auto *Arg : Args.filtered(OPT_dynamic_list)) + if (Optional Buffer = readFile(Arg->getValue())) + readDynamicList(*Buffer); + + for (auto *Arg : Args.filtered(OPT_export_dynamic_symbol)) + Config->VersionScriptGlobals.push_back( + {Arg->getValue(), /*IsExternCpp*/ false, /*HasWildcard*/ false}); + + // Dynamic lists are a simplified linker script that doesn't need the + // "global:" and implicitly ends with a "local:*". Set the variables + // needed to simulate that. + if (Args.hasArg(OPT_dynamic_list) || + Args.hasArg(OPT_export_dynamic_symbol)) { + Config->ExportDynamic = true; + if (!Config->Shared) + Config->DefaultSymbolVersion = VER_NDX_LOCAL; + } + } if (auto *Arg = Args.getLastArg(OPT_version_script)) if (Optional Buffer = readFile(Arg->getValue())) @@ -876,6 +880,21 @@ static uint64_t getImageBase(opt::InputA return V; } +// Parses --defsym=alias option. +static std::vector> +getDefsym(opt::InputArgList &Args) { + std::vector> Ret; + for (auto *Arg : Args.filtered(OPT_defsym)) { + StringRef From; + StringRef To; + std::tie(From, To) = StringRef(Arg->getValue()).split('='); + if (!isValidCIdentifier(To)) + error("--defsym: symbol name expected, but got " + To); + Ret.push_back({From, To}); + } + return Ret; +} + // Do actual linking. Note that when this function is called, // all linker scripts have already been parsed. template void LinkerDriver::link(opt::InputArgList &Args) { @@ -893,9 +912,11 @@ template void LinkerDriver: // Fail early if the output file or map file is not writable. If a user has a // long link, e.g. due to a large LTO link, they do not wish to run it and // find that it failed because there was a mistake in their command-line. - if (!isFileWritable(Config->OutputFile, "output file")) - return; - if (!isFileWritable(Config->MapFile, "map file")) + if (auto E = tryCreateFile(Config->OutputFile)) + error("cannot open output file " + Config->OutputFile + ": " + E.message()); + if (auto E = tryCreateFile(Config->MapFile)) + error("cannot open map file " + Config->MapFile + ": " + E.message()); + if (ErrorCount) return; // Use default entry point name if no name was given via the command @@ -941,6 +962,10 @@ template void LinkerDriver: for (auto *Arg : Args.filtered(OPT_wrap)) Symtab.wrap(Arg->getValue()); + // Handle --defsym=sym=alias option. + for (std::pair &Def : getDefsym(Args)) + Symtab.alias(Def.first, Def.second); + // Now that we have a complete list of input files. // Beyond this point, no new files are added. // Aggregate all input sections into one place. Modified: vendor/lld/dist/ELF/Filesystem.cpp ============================================================================== --- vendor/lld/dist/ELF/Filesystem.cpp Wed Apr 26 19:24:39 2017 (r317452) +++ vendor/lld/dist/ELF/Filesystem.cpp Wed Apr 26 19:24:42 2017 (r317453) @@ -13,7 +13,6 @@ #include "Filesystem.h" #include "Config.h" -#include "Error.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/FileOutputBuffer.h" #include @@ -58,22 +57,20 @@ void elf::unlinkAsync(StringRef Path) { std::thread([=] { ::remove(TempPath.str().str().c_str()); }).detach(); } -// Returns true if a given file seems to be writable. +// Simulate file creation to see if Path is writable. // // Determining whether a file is writable or not is amazingly hard, // and after all the only reliable way of doing that is to actually // create a file. But we don't want to do that in this function // because LLD shouldn't update any file if it will end in a failure. -// We also don't want to reimplement heuristics. So we'll let -// FileOutputBuffer do the work. +// We also don't want to reimplement heuristics to determine if a +// file is writable. So we'll let FileOutputBuffer do the work. // // FileOutputBuffer doesn't touch a desitnation file until commit() // is called. We use that class without calling commit() to predict // if the given file is writable. -bool elf::isFileWritable(StringRef Path, StringRef Desc) { - if (auto EC = FileOutputBuffer::create(Path, 1).getError()) { - error("cannot open " + Desc + " " + Path + ": " + EC.message()); - return false; - } - return true; +std::error_code elf::tryCreateFile(StringRef Path) { + if (Path.empty()) + return std::error_code(); + return FileOutputBuffer::create(Path, 1).getError(); } Modified: vendor/lld/dist/ELF/Filesystem.h ============================================================================== --- vendor/lld/dist/ELF/Filesystem.h Wed Apr 26 19:24:39 2017 (r317452) +++ vendor/lld/dist/ELF/Filesystem.h Wed Apr 26 19:24:42 2017 (r317453) @@ -15,7 +15,7 @@ namespace lld { namespace elf { void unlinkAsync(StringRef Path); -bool isFileWritable(StringRef Path, StringRef FileDescription); +std::error_code tryCreateFile(StringRef Path); } } Modified: vendor/lld/dist/ELF/InputFiles.cpp ============================================================================== --- vendor/lld/dist/ELF/InputFiles.cpp Wed Apr 26 19:24:39 2017 (r317452) +++ vendor/lld/dist/ELF/InputFiles.cpp Wed Apr 26 19:24:42 2017 (r317453) @@ -608,8 +608,9 @@ ArchiveFile::getMember(const Archive::Sy } template -SharedFile::SharedFile(MemoryBufferRef M) - : ELFFileBase(Base::SharedKind, M), AsNeeded(Config->AsNeeded) {} +SharedFile::SharedFile(MemoryBufferRef M, StringRef DefaultSoName) + : ELFFileBase(Base::SharedKind, M), SoName(DefaultSoName), + AsNeeded(Config->AsNeeded) {} template const typename ELFT::Shdr * @@ -619,12 +620,6 @@ SharedFile::getSection(const Elf_S toString(this)); } -template StringRef SharedFile::getSoName() const { - if (SoName.empty()) - return this->DefaultSoName; - return SoName; -} - // Partially parse the shared object file so that we can call // getSoName on this object. template void SharedFile::parseSoName() { @@ -867,8 +862,23 @@ void BitcodeFile::parse(DenseSet(KeptComdats, ObjSym, this)); } +// Small bit of template meta programming to handle the SharedFile constructor +// being the only one with a DefaultSoName parameter. +template