Author: dim Date: Mon May 22 19:44:12 2017 New Revision: 318671 URL: https://svnweb.freebsd.org/changeset/base/318671
Log: Vendor import of lld trunk r303571: https://llvm.org/svn/llvm-project/lld/trunk@303571 Added: vendor/lld/dist/test/COFF/pdb-options.test vendor/lld/dist/test/ELF/arm-sbrel32.s (contents, props changed) Deleted: vendor/lld/dist/COFF/Librarian.cpp vendor/lld/dist/COFF/ModuleDef.cpp Modified: vendor/lld/dist/COFF/CMakeLists.txt vendor/lld/dist/COFF/Config.h vendor/lld/dist/COFF/DLL.cpp vendor/lld/dist/COFF/DLL.h vendor/lld/dist/COFF/Driver.cpp vendor/lld/dist/COFF/Driver.h vendor/lld/dist/COFF/DriverUtils.cpp vendor/lld/dist/COFF/InputFiles.cpp vendor/lld/dist/COFF/InputFiles.h vendor/lld/dist/COFF/Options.td vendor/lld/dist/COFF/PDB.cpp vendor/lld/dist/COFF/SymbolTable.h vendor/lld/dist/COFF/Writer.cpp vendor/lld/dist/ELF/InputSection.cpp vendor/lld/dist/ELF/InputSection.h vendor/lld/dist/ELF/LinkerScript.cpp vendor/lld/dist/ELF/MapFile.cpp vendor/lld/dist/ELF/MapFile.h vendor/lld/dist/ELF/Relocations.cpp vendor/lld/dist/ELF/Relocations.h vendor/lld/dist/ELF/SyntheticSections.cpp vendor/lld/dist/ELF/SyntheticSections.h vendor/lld/dist/ELF/Target.cpp vendor/lld/dist/ELF/Writer.cpp vendor/lld/dist/test/COFF/armnt-imports.test vendor/lld/dist/test/COFF/hello32.test vendor/lld/dist/test/COFF/imports.test vendor/lld/dist/test/COFF/invalid-debug-type.test vendor/lld/dist/test/COFF/options.test vendor/lld/dist/test/COFF/pdb-none.test vendor/lld/dist/test/COFF/pdb.test Modified: vendor/lld/dist/COFF/CMakeLists.txt ============================================================================== --- vendor/lld/dist/COFF/CMakeLists.txt Mon May 22 19:44:10 2017 (r318670) +++ vendor/lld/dist/COFF/CMakeLists.txt Mon May 22 19:44:12 2017 (r318671) @@ -14,11 +14,9 @@ add_lld_library(lldCOFF Error.cpp ICF.cpp InputFiles.cpp - Librarian.cpp LTO.cpp MapFile.cpp MarkLive.cpp - ModuleDef.cpp PDB.cpp Strings.cpp SymbolTable.cpp Modified: vendor/lld/dist/COFF/Config.h ============================================================================== --- vendor/lld/dist/COFF/Config.h Mon May 22 19:44:10 2017 (r318670) +++ vendor/lld/dist/COFF/Config.h Mon May 22 19:44:12 2017 (r318671) @@ -155,7 +155,6 @@ struct Configuration { uint32_t MajorOSVersion = 6; uint32_t MinorOSVersion = 0; bool DynamicBase = true; - bool AllowBind = true; bool NxCompat = true; bool AllowIsolation = true; bool TerminalServerAware = true; @@ -164,7 +163,6 @@ struct Configuration { bool AppContainer = false; // This is for debugging. - bool DebugPdb = false; bool DumpPdb = false; }; Modified: vendor/lld/dist/COFF/DLL.cpp ============================================================================== --- vendor/lld/dist/COFF/DLL.cpp Mon May 22 19:44:10 2017 (r318670) +++ vendor/lld/dist/COFF/DLL.cpp Mon May 22 19:44:12 2017 (r318671) @@ -100,13 +100,17 @@ public: void writeTo(uint8_t *Buf) const override { auto *E = (coff_import_directory_table_entry *)(Buf + OutputSectionOff); - E->ImportLookupTableRVA = LookupTab->getRVA(); E->NameRVA = DLLName->getRVA(); + + // The import descriptor table contains two pointers to + // the tables describing dllimported symbols. But the + // Windows loader actually uses only one. So we create + // only one table and set both fields to its address. + E->ImportLookupTableRVA = AddressTab->getRVA(); E->ImportAddressTableRVA = AddressTab->getRVA(); } Chunk *DLLName; - Chunk *LookupTab; Chunk *AddressTab; }; @@ -136,9 +140,9 @@ binImports(const std::vector<DefinedImpo M[Sym->getDLLName().lower()].push_back(Sym); std::vector<std::vector<DefinedImportData *>> V; - for (auto &P : M) { + for (auto &KV : M) { // Sort symbols by name for each group. - std::vector<DefinedImportData *> &Syms = P.second; + std::vector<DefinedImportData *> &Syms = KV.second; std::sort(Syms.begin(), Syms.end(), [](DefinedImportData *A, DefinedImportData *B) { return A->getName() < B->getName(); @@ -383,21 +387,14 @@ uint64_t IdataContents::getIATSize() { // See Microsoft PE/COFF spec 5.4 for details. std::vector<Chunk *> IdataContents::getChunks() { create(); - std::vector<Chunk *> V; + // The loader assumes a specific order of data. // Add each type in the correct order. - for (std::unique_ptr<Chunk> &C : Dirs) - V.push_back(C.get()); - for (std::unique_ptr<Chunk> &C : Lookups) - V.push_back(C.get()); - for (std::unique_ptr<Chunk> &C : Addresses) - V.push_back(C.get()); - for (std::unique_ptr<Chunk> &C : Hints) - V.push_back(C.get()); - for (auto &P : DLLNames) { - std::unique_ptr<Chunk> &C = P.second; - V.push_back(C.get()); - } + std::vector<Chunk *> V; + V.insert(V.end(), Dirs.begin(), Dirs.end()); + V.insert(V.end(), Addresses.begin(), Addresses.end()); + V.insert(V.end(), Hints.begin(), Hints.end()); + V.insert(V.end(), DLLNames.begin(), DLLNames.end()); return V; } @@ -406,65 +403,50 @@ void IdataContents::create() { // Create .idata contents for each DLL. for (std::vector<DefinedImportData *> &Syms : V) { - StringRef Name = Syms[0]->getDLLName(); - // Create lookup and address tables. If they have external names, // we need to create HintName chunks to store the names. // If they don't (if they are import-by-ordinals), we store only // ordinal values to the table. - size_t Base = Lookups.size(); + size_t Base = Addresses.size(); for (DefinedImportData *S : Syms) { uint16_t Ord = S->getOrdinal(); if (S->getExternalName().empty()) { - Lookups.push_back(make_unique<OrdinalOnlyChunk>(Ord)); - Addresses.push_back(make_unique<OrdinalOnlyChunk>(Ord)); + Addresses.push_back(make<OrdinalOnlyChunk>(Ord)); continue; } - auto C = make_unique<HintNameChunk>(S->getExternalName(), Ord); - Lookups.push_back(make_unique<LookupChunk>(C.get())); - Addresses.push_back(make_unique<LookupChunk>(C.get())); - Hints.push_back(std::move(C)); + auto *C = make<HintNameChunk>(S->getExternalName(), Ord); + Addresses.push_back(make<LookupChunk>(C)); + Hints.push_back(C); } // Terminate with null values. - Lookups.push_back(make_unique<NullChunk>(ptrSize())); - Addresses.push_back(make_unique<NullChunk>(ptrSize())); + Addresses.push_back(make<NullChunk>(ptrSize())); for (int I = 0, E = Syms.size(); I < E; ++I) - Syms[I]->setLocation(Addresses[Base + I].get()); + Syms[I]->setLocation(Addresses[Base + I]); // Create the import table header. - if (!DLLNames.count(Name)) - DLLNames[Name] = make_unique<StringChunk>(Name); - auto Dir = make_unique<ImportDirectoryChunk>(DLLNames[Name].get()); - Dir->LookupTab = Lookups[Base].get(); - Dir->AddressTab = Addresses[Base].get(); - Dirs.push_back(std::move(Dir)); + DLLNames.push_back(make<StringChunk>(Syms[0]->getDLLName())); + auto *Dir = make<ImportDirectoryChunk>(DLLNames.back()); + Dir->AddressTab = Addresses[Base]; + Dirs.push_back(Dir); } // Add null terminator. - Dirs.push_back(make_unique<NullChunk>(sizeof(ImportDirectoryTableEntry))); + Dirs.push_back(make<NullChunk>(sizeof(ImportDirectoryTableEntry))); } std::vector<Chunk *> DelayLoadContents::getChunks() { std::vector<Chunk *> V; - for (std::unique_ptr<Chunk> &C : Dirs) - V.push_back(C.get()); - for (std::unique_ptr<Chunk> &C : Names) - V.push_back(C.get()); - for (std::unique_ptr<Chunk> &C : HintNames) - V.push_back(C.get()); - for (auto &P : DLLNames) { - std::unique_ptr<Chunk> &C = P.second; - V.push_back(C.get()); - } + V.insert(V.end(), Dirs.begin(), Dirs.end()); + V.insert(V.end(), Names.begin(), Names.end()); + V.insert(V.end(), HintNames.begin(), HintNames.end()); + V.insert(V.end(), DLLNames.begin(), DLLNames.end()); return V; } std::vector<Chunk *> DelayLoadContents::getDataChunks() { std::vector<Chunk *> V; - for (std::unique_ptr<Chunk> &C : ModuleHandles) - V.push_back(C.get()); - for (std::unique_ptr<Chunk> &C : Addresses) - V.push_back(C.get()); + V.insert(V.end(), ModuleHandles.begin(), ModuleHandles.end()); + V.insert(V.end(), Addresses.begin(), Addresses.end()); return V; } @@ -478,55 +460,51 @@ void DelayLoadContents::create(Defined * // Create .didat contents for each DLL. for (std::vector<DefinedImportData *> &Syms : V) { - StringRef Name = Syms[0]->getDLLName(); - // Create the delay import table header. - if (!DLLNames.count(Name)) - DLLNames[Name] = make_unique<StringChunk>(Name); - auto Dir = make_unique<DelayDirectoryChunk>(DLLNames[Name].get()); + DLLNames.push_back(make<StringChunk>(Syms[0]->getDLLName())); + auto *Dir = make<DelayDirectoryChunk>(DLLNames.back()); size_t Base = Addresses.size(); for (DefinedImportData *S : Syms) { - Chunk *T = newThunkChunk(S, Dir.get()); - auto A = make_unique<DelayAddressChunk>(T); - Addresses.push_back(std::move(A)); - Thunks.push_back(std::unique_ptr<Chunk>(T)); + Chunk *T = newThunkChunk(S, Dir); + auto *A = make<DelayAddressChunk>(T); + Addresses.push_back(A); + Thunks.push_back(T); StringRef ExtName = S->getExternalName(); if (ExtName.empty()) { - Names.push_back(make_unique<OrdinalOnlyChunk>(S->getOrdinal())); + Names.push_back(make<OrdinalOnlyChunk>(S->getOrdinal())); } else { - auto C = make_unique<HintNameChunk>(ExtName, 0); - Names.push_back(make_unique<LookupChunk>(C.get())); - HintNames.push_back(std::move(C)); + auto *C = make<HintNameChunk>(ExtName, 0); + Names.push_back(make<LookupChunk>(C)); + HintNames.push_back(C); } } // Terminate with null values. - Addresses.push_back(make_unique<NullChunk>(8)); - Names.push_back(make_unique<NullChunk>(8)); + Addresses.push_back(make<NullChunk>(8)); + Names.push_back(make<NullChunk>(8)); for (int I = 0, E = Syms.size(); I < E; ++I) - Syms[I]->setLocation(Addresses[Base + I].get()); - auto *MH = new NullChunk(8); + Syms[I]->setLocation(Addresses[Base + I]); + auto *MH = make<NullChunk>(8); MH->setAlign(8); - ModuleHandles.push_back(std::unique_ptr<Chunk>(MH)); + ModuleHandles.push_back(MH); // Fill the delay import table header fields. Dir->ModuleHandle = MH; - Dir->AddressTab = Addresses[Base].get(); - Dir->NameTab = Names[Base].get(); - Dirs.push_back(std::move(Dir)); + Dir->AddressTab = Addresses[Base]; + Dir->NameTab = Names[Base]; + Dirs.push_back(Dir); } // Add null terminator. - Dirs.push_back( - make_unique<NullChunk>(sizeof(delay_import_directory_table_entry))); + Dirs.push_back(make<NullChunk>(sizeof(delay_import_directory_table_entry))); } Chunk *DelayLoadContents::newThunkChunk(DefinedImportData *S, Chunk *Dir) { switch (Config->Machine) { case AMD64: - return new ThunkChunkX64(S, Dir, Helper); + return make<ThunkChunkX64>(S, Dir, Helper); case I386: - return new ThunkChunkX86(S, Dir, Helper); + return make<ThunkChunkX86>(S, Dir, Helper); default: llvm_unreachable("unsupported machine type"); } @@ -537,34 +515,32 @@ EdataContents::EdataContents() { for (Export &E : Config->Exports) MaxOrdinal = std::max(MaxOrdinal, E.Ordinal); - auto *DLLName = new StringChunk(sys::path::filename(Config->OutputFile)); - auto *AddressTab = new AddressTableChunk(MaxOrdinal); + auto *DLLName = make<StringChunk>(sys::path::filename(Config->OutputFile)); + auto *AddressTab = make<AddressTableChunk>(MaxOrdinal); std::vector<Chunk *> Names; for (Export &E : Config->Exports) if (!E.Noname) - Names.push_back(new StringChunk(E.ExportName)); + Names.push_back(make<StringChunk>(E.ExportName)); std::vector<Chunk *> Forwards; for (Export &E : Config->Exports) { if (E.ForwardTo.empty()) continue; - E.ForwardChunk = new StringChunk(E.ForwardTo); + E.ForwardChunk = make<StringChunk>(E.ForwardTo); Forwards.push_back(E.ForwardChunk); } - auto *NameTab = new NamePointersChunk(Names); - auto *OrdinalTab = new ExportOrdinalChunk(Names.size()); - auto *Dir = new ExportDirectoryChunk(MaxOrdinal, Names.size(), DLLName, - AddressTab, NameTab, OrdinalTab); - Chunks.push_back(std::unique_ptr<Chunk>(Dir)); - Chunks.push_back(std::unique_ptr<Chunk>(DLLName)); - Chunks.push_back(std::unique_ptr<Chunk>(AddressTab)); - Chunks.push_back(std::unique_ptr<Chunk>(NameTab)); - Chunks.push_back(std::unique_ptr<Chunk>(OrdinalTab)); - for (Chunk *C : Names) - Chunks.push_back(std::unique_ptr<Chunk>(C)); - for (Chunk *C : Forwards) - Chunks.push_back(std::unique_ptr<Chunk>(C)); + auto *NameTab = make<NamePointersChunk>(Names); + auto *OrdinalTab = make<ExportOrdinalChunk>(Names.size()); + auto *Dir = make<ExportDirectoryChunk>(MaxOrdinal, Names.size(), DLLName, + AddressTab, NameTab, OrdinalTab); + Chunks.push_back(Dir); + Chunks.push_back(DLLName); + Chunks.push_back(AddressTab); + Chunks.push_back(NameTab); + Chunks.push_back(OrdinalTab); + Chunks.insert(Chunks.end(), Names.begin(), Names.end()); + Chunks.insert(Chunks.end(), Forwards.begin(), Forwards.end()); } } // namespace coff Modified: vendor/lld/dist/COFF/DLL.h ============================================================================== --- vendor/lld/dist/COFF/DLL.h Mon May 22 19:44:10 2017 (r318670) +++ vendor/lld/dist/COFF/DLL.h Mon May 22 19:44:12 2017 (r318671) @@ -35,11 +35,10 @@ private: void create(); std::vector<DefinedImportData *> Imports; - std::vector<std::unique_ptr<Chunk>> Dirs; - std::vector<std::unique_ptr<Chunk>> Lookups; - std::vector<std::unique_ptr<Chunk>> Addresses; - std::vector<std::unique_ptr<Chunk>> Hints; - std::map<StringRef, std::unique_ptr<Chunk>> DLLNames; + std::vector<Chunk *> Dirs; + std::vector<Chunk *> Addresses; + std::vector<Chunk *> Hints; + std::vector<Chunk *> DLLNames; }; // Windows-specific. @@ -51,7 +50,7 @@ public: void create(Defined *Helper); std::vector<Chunk *> getChunks(); std::vector<Chunk *> getDataChunks(); - std::vector<std::unique_ptr<Chunk>> &getCodeChunks() { return Thunks; } + ArrayRef<Chunk *> getCodeChunks() { return Thunks; } uint64_t getDirRVA() { return Dirs[0]->getRVA(); } uint64_t getDirSize(); @@ -61,13 +60,13 @@ private: Defined *Helper; std::vector<DefinedImportData *> Imports; - std::vector<std::unique_ptr<Chunk>> Dirs; - std::vector<std::unique_ptr<Chunk>> ModuleHandles; - std::vector<std::unique_ptr<Chunk>> Addresses; - std::vector<std::unique_ptr<Chunk>> Names; - std::vector<std::unique_ptr<Chunk>> HintNames; - std::vector<std::unique_ptr<Chunk>> Thunks; - std::map<StringRef, std::unique_ptr<Chunk>> DLLNames; + std::vector<Chunk *> Dirs; + std::vector<Chunk *> ModuleHandles; + std::vector<Chunk *> Addresses; + std::vector<Chunk *> Names; + std::vector<Chunk *> HintNames; + std::vector<Chunk *> Thunks; + std::vector<Chunk *> DLLNames; }; // Windows-specific. @@ -75,7 +74,7 @@ private: class EdataContents { public: EdataContents(); - std::vector<std::unique_ptr<Chunk>> Chunks; + std::vector<Chunk *> Chunks; }; } // namespace coff Modified: vendor/lld/dist/COFF/Driver.cpp ============================================================================== --- vendor/lld/dist/COFF/Driver.cpp Mon May 22 19:44:10 2017 (r318670) +++ vendor/lld/dist/COFF/Driver.cpp Mon May 22 19:44:12 2017 (r318671) @@ -19,6 +19,8 @@ #include "llvm/ADT/Optional.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Object/ArchiveWriter.h" +#include "llvm/Object/COFFImportFile.h" +#include "llvm/Object/COFFModuleDefinition.h" #include "llvm/Option/Arg.h" #include "llvm/Option/ArgList.h" #include "llvm/Option/Option.h" @@ -35,6 +37,7 @@ #include <future> using namespace llvm; +using namespace llvm::object; using namespace llvm::COFF; using llvm::sys::Process; using llvm::sys::fs::file_magic; @@ -97,12 +100,11 @@ static std::future<MBErrPair> createFutu MemoryBufferRef LinkerDriver::takeBuffer(std::unique_ptr<MemoryBuffer> MB) { MemoryBufferRef MBRef = *MB; - OwningMBs.push_back(std::move(MB)); + make<std::unique_ptr<MemoryBuffer>>(std::move(MB)); // take ownership if (Driver->Tar) Driver->Tar->append(relativeToRoot(MBRef.getBufferIdentifier()), MBRef.getBuffer()); - return MBRef; } @@ -420,6 +422,84 @@ static std::string getMapFile(const opt: 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(); +} + +std::vector<COFFShortExport> createCOFFShortExportFromConfig() { + std::vector<COFFShortExport> Exports; + for (Export &E1 : Config->Exports) { + COFFShortExport E2; + E2.Name = E1.Name; + 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); + } + return Exports; +} + +static void createImportLibrary() { + std::vector<COFFShortExport> Exports = createCOFFShortExportFromConfig(); + std::string DLLName = sys::path::filename(Config->OutputFile); + std::string Path = getImplibPath(); + writeImportLibrary(DLLName, Path, Exports, Config->Machine); +} + +static void parseModuleDefs(StringRef Path) { + std::unique_ptr<MemoryBuffer> MB = check( + MemoryBuffer::getFile(Path, -1, false, true), "could not open " + Path); + MemoryBufferRef MBRef = MB->getMemBufferRef(); + + Expected<COFFModuleDefinition> Def = + parseCOFFModuleDefinition(MBRef, Config->Machine); + if (!Def) + fatal(errorToErrorCode(Def.takeError()).message()); + + COFFModuleDefinition &M = *Def; + if (Config->OutputFile.empty()) + Config->OutputFile = Saver.save(M.OutputFile); + + 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; + E2.Name = Saver.save(E1.Name); + if (E1.isWeak()) + 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); + } +} + std::vector<MemoryBufferRef> getArchiveMembers(Archive *File) { std::vector<MemoryBufferRef> V; Error Err = Error::success(); @@ -821,8 +901,6 @@ void LinkerDriver::link(ArrayRef<const c Config->ManifestInput.push_back(Arg->getValue()); // Handle miscellaneous boolean flags. - if (Args.hasArg(OPT_allowbind_no)) - Config->AllowBind = false; if (Args.hasArg(OPT_allowisolation_no)) Config->AllowIsolation = false; if (Args.hasArg(OPT_dynamicbase_no)) @@ -834,7 +912,6 @@ void LinkerDriver::link(ArrayRef<const c if (Args.hasArg(OPT_nosymtab)) Config->WriteSymtab = false; Config->DumpPdb = Args.hasArg(OPT_dumppdb); - Config->DebugPdb = Args.hasArg(OPT_debugpdb); Config->MapFile = getMapFile(Args); @@ -916,9 +993,7 @@ void LinkerDriver::link(ArrayRef<const c // Handle /def if (auto *Arg = Args.getLastArg(OPT_deffile)) { // parseModuleDefs mutates Config object. - parseModuleDefs( - takeBuffer(check(MemoryBuffer::getFile(Arg->getValue()), - Twine("could not open ") + Arg->getValue()))); + parseModuleDefs(Arg->getValue()); } // Handle /delayload @@ -1038,7 +1113,7 @@ void LinkerDriver::link(ArrayRef<const c // need to create a .lib file. if (!Config->Exports.empty() || Config->DLL) { fixupExports(); - writeImportLibrary(); + createImportLibrary(); assignExportOrdinals(); } Modified: vendor/lld/dist/COFF/Driver.h ============================================================================== --- vendor/lld/dist/COFF/Driver.h Mon May 22 19:44:10 2017 (r318670) +++ vendor/lld/dist/COFF/Driver.h Mon May 22 19:44:12 2017 (r318671) @@ -119,18 +119,11 @@ private: void enqueueTask(std::function<void()> Task); bool run(); - // Driver is the owner of all opened files. - // InputFiles have MemoryBufferRefs to them. - std::vector<std::unique_ptr<MemoryBuffer>> OwningMBs; - std::list<std::function<void()>> TaskQueue; std::vector<StringRef> FilePaths; std::vector<MemoryBufferRef> Resources; }; -void parseModuleDefs(MemoryBufferRef MB); -void writeImportLibrary(); - // Functions below this line are defined in DriverUtils.cpp. void printHelp(const char *Argv0); Modified: vendor/lld/dist/COFF/DriverUtils.cpp ============================================================================== --- vendor/lld/dist/COFF/DriverUtils.cpp Mon May 22 19:44:10 2017 (r318670) +++ vendor/lld/dist/COFF/DriverUtils.cpp Mon May 22 19:44:12 2017 (r318671) @@ -43,7 +43,7 @@ namespace { class Executor { public: - explicit Executor(StringRef S) : Saver(Alloc), Prog(Saver.save(S)) {} + explicit Executor(StringRef S) : Prog(Saver.save(S)) {} void add(StringRef S) { Args.push_back(Saver.save(S)); } void add(std::string &S) { Args.push_back(Saver.save(S)); } void add(Twine S) { Args.push_back(Saver.save(S)); } @@ -67,8 +67,6 @@ public: } private: - BumpPtrAllocator Alloc; - StringSaver Saver; StringRef Prog; std::vector<StringRef> Args; }; Modified: vendor/lld/dist/COFF/InputFiles.cpp ============================================================================== --- vendor/lld/dist/COFF/InputFiles.cpp Mon May 22 19:44:10 2017 (r318670) +++ vendor/lld/dist/COFF/InputFiles.cpp Mon May 22 19:44:12 2017 (r318671) @@ -137,13 +137,13 @@ void ObjectFile::initializeChunks() { // CodeView sections are stored to a different vector because they are // not linked in the regular manner. if (Name == ".debug" || Name.startswith(".debug$")) { - DebugChunks.push_back(new (Alloc) SectionChunk(this, Sec)); + DebugChunks.push_back(make<SectionChunk>(this, Sec)); continue; } if (Sec->Characteristics & llvm::COFF::IMAGE_SCN_LNK_REMOVE) continue; - auto *C = new (Alloc) SectionChunk(this, Sec); + auto *C = make<SectionChunk>(this, Sec); Chunks.push_back(C); SparseChunks[I] = C; } @@ -200,7 +200,7 @@ SymbolBody *ObjectFile::createDefined(CO bool IsFirst) { StringRef Name; if (Sym.isCommon()) { - auto *C = new (Alloc) CommonChunk(Sym); + auto *C = make<CommonChunk>(Sym); Chunks.push_back(C); COFFObj->getSymbolName(Sym, Name); Symbol *S = @@ -221,7 +221,7 @@ SymbolBody *ObjectFile::createDefined(CO if (Sym.isExternal()) return Symtab->addAbsolute(Name, Sym)->body(); else - return new (Alloc) DefinedAbsolute(Name, Sym); + return make<DefinedAbsolute>(Name, Sym); } int32_t SectionNumber = Sym.getSectionNumber(); if (SectionNumber == llvm::COFF::IMAGE_SYM_DEBUG) @@ -258,8 +258,8 @@ SymbolBody *ObjectFile::createDefined(CO Symtab->addRegular(this, Name, SC->isCOMDAT(), Sym.getGeneric(), SC); B = cast<DefinedRegular>(S->body()); } else - B = new (Alloc) DefinedRegular(this, /*Name*/ "", SC->isCOMDAT(), - /*IsExternal*/ false, Sym.getGeneric(), SC); + B = make<DefinedRegular>(this, /*Name*/ "", SC->isCOMDAT(), + /*IsExternal*/ false, Sym.getGeneric(), SC); if (SC->isCOMDAT() && Sym.getValue() == 0 && !AuxP) SC->setSymbol(B); @@ -301,8 +301,8 @@ void ImportFile::parse() { fatal("broken import library"); // Read names and create an __imp_ symbol. - StringRef Name = StringAlloc.save(StringRef(Buf + sizeof(*Hdr))); - StringRef ImpName = StringAlloc.save("__imp_" + Name); + StringRef Name = Saver.save(StringRef(Buf + sizeof(*Hdr))); + StringRef ImpName = Saver.save("__imp_" + Name); const char *NameStart = Buf + sizeof(coff_import_header) + Name.size() + 1; DLLName = StringRef(NameStart); StringRef ExtName; Modified: vendor/lld/dist/COFF/InputFiles.h ============================================================================== --- vendor/lld/dist/COFF/InputFiles.h Mon May 22 19:44:10 2017 (r318670) +++ vendor/lld/dist/COFF/InputFiles.h Mon May 22 19:44:12 2017 (r318671) @@ -130,7 +130,6 @@ private: SymbolBody *createUndefined(COFFSymbolRef Sym); std::unique_ptr<COFFObjectFile> COFFObj; - llvm::BumpPtrAllocator Alloc; const coff_section *SXData = nullptr; // List of all chunks defined by this file. This includes both section @@ -162,8 +161,7 @@ private: // for details about the format. class ImportFile : public InputFile { public: - explicit ImportFile(MemoryBufferRef M) - : InputFile(ImportKind, M), StringAlloc(StringAllocAux) {} + explicit ImportFile(MemoryBufferRef M) : InputFile(ImportKind, M) {} static bool classof(const InputFile *F) { return F->kind() == ImportKind; } DefinedImportData *ImpSym = nullptr; @@ -174,9 +172,6 @@ public: private: void parse() override; - llvm::BumpPtrAllocator StringAllocAux; - llvm::StringSaver StringAlloc; - public: StringRef ExternalName; const coff_import_header *Hdr; Modified: vendor/lld/dist/COFF/Options.td ============================================================================== --- vendor/lld/dist/COFF/Options.td Mon May 22 19:44:10 2017 (r318670) +++ vendor/lld/dist/COFF/Options.td Mon May 22 19:44:12 2017 (r318671) @@ -102,7 +102,6 @@ def nosymtab : F<"nosymtab">; def msvclto : F<"msvclto">; // Flags for debugging -def debugpdb : F<"debugpdb">; def dumppdb : Joined<["/", "-"], "dumppdb">; def lldmap : F<"lldmap">; def lldmap_file : Joined<["/", "-"], "lldmap:">; Modified: vendor/lld/dist/COFF/PDB.cpp ============================================================================== --- vendor/lld/dist/COFF/PDB.cpp Mon May 22 19:44:10 2017 (r318670) +++ vendor/lld/dist/COFF/PDB.cpp Mon May 22 19:44:12 2017 (r318671) @@ -14,7 +14,8 @@ #include "SymbolTable.h" #include "Symbols.h" #include "llvm/DebugInfo/CodeView/CVDebugRecord.h" -#include "llvm/DebugInfo/CodeView/CVTypeDumper.h" +#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" +#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h" #include "llvm/DebugInfo/CodeView/SymbolDumper.h" #include "llvm/DebugInfo/CodeView/TypeDatabase.h" #include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h" @@ -107,6 +108,7 @@ static void mergeDebugT(SymbolTable *Sym BinaryByteStream Stream(Data, support::little); codeview::CVTypeArray Types; BinaryStreamReader Reader(Stream); + SmallVector<TypeIndex, 128> SourceToDest; // Follow type servers. If the same type server is encountered more than // once for this instance of `PDBTypeServerHandler` (for example if many // object files reference the same TypeServer), the types from the @@ -115,8 +117,8 @@ static void mergeDebugT(SymbolTable *Sym Handler.addSearchPath(llvm::sys::path::parent_path(File->getName())); if (auto EC = Reader.readArray(Types, Reader.getLength())) fatal(EC, "Reader::readArray failed"); - if (auto Err = - codeview::mergeTypeStreams(IDTable, TypeTable, &Handler, Types)) + if (auto Err = codeview::mergeTypeStreams(IDTable, TypeTable, SourceToDest, + &Handler, Types)) fatal(Err, "codeview::mergeTypeStreams failed"); } @@ -133,12 +135,11 @@ static void dumpDebugT(ScopedPrinter &W, if (Data.empty()) return; - TypeDatabase TDB(0); - TypeDumpVisitor TDV(TDB, &W, false); + LazyRandomTypeCollection Types(Data, 100); + TypeDumpVisitor TDV(Types, &W, false); // Use a default implementation that does not follow type servers and instead // just dumps the contents of the TypeServer2 record. - CVTypeDumper TypeDumper(TDB); - if (auto EC = TypeDumper.dump(Data, TDV)) + if (auto EC = codeview::visitTypeStream(Types, TDV)) fatal(EC, "CVTypeDumper::dump failed"); } Modified: vendor/lld/dist/COFF/SymbolTable.h ============================================================================== --- vendor/lld/dist/COFF/SymbolTable.h Mon May 22 19:44:10 2017 (r318670) +++ vendor/lld/dist/COFF/SymbolTable.h Mon May 22 19:44:12 2017 (r318671) @@ -15,7 +15,6 @@ #include "llvm/ADT/CachedHashString.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMapInfo.h" -#include "llvm/Support/Allocator.h" #include "llvm/Support/raw_ostream.h" namespace llvm { Modified: vendor/lld/dist/COFF/Writer.cpp ============================================================================== --- vendor/lld/dist/COFF/Writer.cpp Mon May 22 19:44:10 2017 (r318670) +++ vendor/lld/dist/COFF/Writer.cpp Mon May 22 19:44:12 2017 (r318671) @@ -48,8 +48,7 @@ namespace { class DebugDirectoryChunk : public Chunk { public: - DebugDirectoryChunk(const std::vector<std::unique_ptr<Chunk>> &R) - : Records(R) {} + DebugDirectoryChunk(const std::vector<Chunk *> &R) : Records(R) {} size_t getSize() const override { return Records.size() * sizeof(debug_directory); @@ -58,7 +57,7 @@ public: void writeTo(uint8_t *B) const override { auto *D = reinterpret_cast<debug_directory *>(B + OutputSectionOff); - for (const std::unique_ptr<Chunk> &Record : Records) { + for (const Chunk *Record : Records) { D->Characteristics = 0; D->TimeDateStamp = 0; D->MajorVersion = 0; @@ -74,7 +73,7 @@ public: } private: - const std::vector<std::unique_ptr<Chunk>> &Records; + const std::vector<Chunk *> &Records; }; class CVDebugRecordChunk : public Chunk { @@ -142,10 +141,10 @@ private: IdataContents Idata; DelayLoadContents DelayIdata; EdataContents Edata; - std::unique_ptr<SEHTableChunk> SEHTable; + SEHTableChunk *SEHTable = nullptr; - std::unique_ptr<Chunk> DebugDirectory; - std::vector<std::unique_ptr<Chunk>> DebugRecords; + Chunk *DebugDirectory = nullptr; + std::vector<Chunk *> DebugRecords; CVDebugRecordChunk *BuildId = nullptr; ArrayRef<uint8_t> SectionTable; @@ -153,8 +152,6 @@ private: uint32_t PointerToSymbolTable = 0; uint64_t SizeOfImage; uint64_t SizeOfHeaders; - - std::vector<std::unique_ptr<Chunk>> Chunks; }; } // anonymous namespace @@ -258,7 +255,7 @@ void Writer::run() { sortExceptionTable(); writeBuildId(); - if (!Config->PDBPath.empty()) { + if (!Config->PDBPath.empty() && Config->Debug) { const llvm::codeview::DebugInfo *DI = nullptr; if (Config->DebugTypes & static_cast<unsigned>(coff::DebugType::CV)) DI = BuildId->DI; @@ -324,19 +321,19 @@ void Writer::createMiscChunks() { // Create Debug Information Chunks if (Config->Debug) { - DebugDirectory = llvm::make_unique<DebugDirectoryChunk>(DebugRecords); + DebugDirectory = make<DebugDirectoryChunk>(DebugRecords); // TODO(compnerd) create a coffgrp entry if DebugType::CV is not enabled if (Config->DebugTypes & static_cast<unsigned>(coff::DebugType::CV)) { - auto Chunk = llvm::make_unique<CVDebugRecordChunk>(); + auto *Chunk = make<CVDebugRecordChunk>(); - BuildId = Chunk.get(); - DebugRecords.push_back(std::move(Chunk)); + BuildId = Chunk; + DebugRecords.push_back(Chunk); } - RData->addChunk(DebugDirectory.get()); - for (const std::unique_ptr<Chunk> &C : DebugRecords) - RData->addChunk(C.get()); + RData->addChunk(DebugDirectory); + for (Chunk *C : DebugRecords) + RData->addChunk(C); } // Create SEH table. x86-only. @@ -352,8 +349,8 @@ void Writer::createMiscChunks() { Handlers.insert(cast<Defined>(B)); } - SEHTable.reset(new SEHTableChunk(Handlers)); - RData->addChunk(SEHTable.get()); + SEHTable = make<SEHTableChunk>(Handlers); + RData->addChunk(SEHTable); } // Create .idata section for the DLL-imported symbol table. @@ -398,8 +395,8 @@ void Writer::createImportTables() { for (Chunk *C : DelayIdata.getDataChunks()) Sec->addChunk(C); Sec = createSection(".text"); - for (std::unique_ptr<Chunk> &C : DelayIdata.getCodeChunks()) - Sec->addChunk(C.get()); + for (Chunk *C : DelayIdata.getCodeChunks()) + Sec->addChunk(C); } } @@ -407,8 +404,8 @@ void Writer::createExportTable() { if (Config->Exports.empty()) return; OutputSection *Sec = createSection(".edata"); - for (std::unique_ptr<Chunk> &C : Edata.Chunks) - Sec->addChunk(C.get()); + for (Chunk *C : Edata.Chunks) + Sec->addChunk(C); } // The Windows loader doesn't seem to like empty sections, @@ -602,14 +599,19 @@ template <typename PEHeaderTy> void Writ PE->SizeOfStackCommit = Config->StackCommit; PE->SizeOfHeapReserve = Config->HeapReserve; PE->SizeOfHeapCommit = Config->HeapCommit; + + // Import Descriptor Tables and Import Address Tables are merged + // in our output. That's not compatible with the Binding feature + // that is sort of prelinking. Setting this flag to make it clear + // that our outputs are not for the Binding. + PE->DLLCharacteristics = IMAGE_DLL_CHARACTERISTICS_NO_BIND; + if (Config->AppContainer) PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_APPCONTAINER; if (Config->DynamicBase) PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE; if (Config->HighEntropyVA) PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA; - if (!Config->AllowBind) - PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_BIND; if (Config->NxCompat) PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NX_COMPAT; if (!Config->AllowIsolation) Modified: vendor/lld/dist/ELF/InputSection.cpp ============================================================================== --- vendor/lld/dist/ELF/InputSection.cpp Mon May 22 19:44:10 2017 (r318670) +++ vendor/lld/dist/ELF/InputSection.cpp Mon May 22 19:44:12 2017 (r318671) @@ -390,14 +390,28 @@ static uint64_t getAArch64UndefinedRelat } } -template <class ELFT> -static typename ELFT::uint -getRelocTargetVA(uint32_t Type, int64_t A, typename ELFT::uint P, - const SymbolBody &Body, RelExpr Expr) { +// ARM SBREL relocations are of the form S + A - B where B is the static base +// The ARM ABI defines base to be "addressing origin of the output segment +// defining the symbol S". We defined the "addressing origin"/static base to be +// the base of the PT_LOAD segment containing the Body. +// The procedure call standard only defines a Read Write Position Independent +// RWPI variant so in practice we should expect the static base to be the base +// of the RW segment. +static uint64_t getARMStaticBase(const SymbolBody &Body) { + OutputSection *OS = Body.getOutputSection(); + if (!OS || !OS->FirstInPtLoad) + fatal("SBREL relocation to " + Body.getName() + " without static base\n"); + return OS->FirstInPtLoad->Addr; +} + +static uint64_t getRelocTargetVA(uint32_t Type, int64_t A, uint64_t P, + const SymbolBody &Body, RelExpr Expr) { switch (Expr) { case R_ABS: case R_RELAX_GOT_PC_NOPIC: return Body.getVA(A); + case R_ARM_SBREL: + return Body.getVA(A) - getARMStaticBase(Body); case R_GOT: case R_RELAX_TLS_GD_TO_IE_ABS: return Body.getGotVA() + A; @@ -518,7 +532,7 @@ getRelocTargetVA(uint32_t Type, int64_t case R_NEG_TLS: return Out::TlsPhdr->p_memsz - Body.getVA(A); case R_SIZE: - return Body.getSize<ELFT>() + A; + return A; // Body.getSize was already folded into the addend. case R_TLSDESC: return InX::Got->getGlobalDynAddr(Body) + A; case R_TLSDESC_PAGE: @@ -566,7 +580,7 @@ void InputSection::relocateNonAlloc(uint uint64_t SymVA = 0; if (!Sym.isTls() || Out::TlsPhdr) SymVA = SignExtend64<sizeof(typename ELFT::uint) * 8>( - getRelocTargetVA<ELFT>(Type, Addend, AddrLoc, Sym, R_ABS)); + getRelocTargetVA(Type, Addend, AddrLoc, Sym, R_ABS)); Target->relocateOne(BufLoc, Type, SymVA); } } @@ -577,19 +591,28 @@ template <class ELFT> elf::ObjectFile<EL template <class ELFT> void InputSectionBase::relocate(uint8_t *Buf, uint8_t *BufEnd) { + if (Flags & SHF_ALLOC) + relocateAlloc(Buf, BufEnd); + else + relocateNonAlloc<ELFT>(Buf, BufEnd); +} + +template <class ELFT> +void InputSectionBase::relocateNonAlloc(uint8_t *Buf, uint8_t *BufEnd) { // scanReloc function in Writer.cpp constructs Relocations // vector only for SHF_ALLOC'ed sections. For other sections, // we handle relocations directly here. - auto *IS = dyn_cast<InputSection>(this); - if (IS && !(IS->Flags & SHF_ALLOC)) { - if (IS->AreRelocsRela) - IS->relocateNonAlloc<ELFT>(Buf, IS->template relas<ELFT>()); - else - IS->relocateNonAlloc<ELFT>(Buf, IS->template rels<ELFT>()); - return; - } + auto *IS = cast<InputSection>(this); + assert(!(IS->Flags & SHF_ALLOC)); + if (IS->AreRelocsRela) + IS->relocateNonAlloc<ELFT>(Buf, IS->template relas<ELFT>()); + else + IS->relocateNonAlloc<ELFT>(Buf, IS->template rels<ELFT>()); +} - const unsigned Bits = sizeof(typename ELFT::uint) * 8; +void InputSectionBase::relocateAlloc(uint8_t *Buf, uint8_t *BufEnd) { + assert(Flags & SHF_ALLOC); + const unsigned Bits = Config->Wordsize * 8; for (const Relocation &Rel : Relocations) { uint64_t Offset = getOffset(Rel.Offset); uint8_t *BufLoc = Buf + Offset; @@ -597,8 +620,8 @@ void InputSectionBase::relocate(uint8_t uint64_t AddrLoc = getOutputSection()->Addr + Offset; RelExpr Expr = Rel.Expr; - uint64_t TargetVA = SignExtend64<Bits>( - getRelocTargetVA<ELFT>(Type, Rel.Addend, AddrLoc, *Rel.Sym, Expr)); + uint64_t TargetVA = SignExtend64( + getRelocTargetVA(Type, Rel.Addend, AddrLoc, *Rel.Sym, Expr), Bits); switch (Expr) { case R_RELAX_GOT_PC: Modified: vendor/lld/dist/ELF/InputSection.h ============================================================================== --- vendor/lld/dist/ELF/InputSection.h Mon May 22 19:44:10 2017 (r318670) +++ vendor/lld/dist/ELF/InputSection.h Mon May 22 19:44:12 2017 (r318671) @@ -167,6 +167,8 @@ public: template <class ELFT> std::string getObjMsg(uint64_t Offset); template <class ELFT> void relocate(uint8_t *Buf, uint8_t *BufEnd); + void relocateAlloc(uint8_t *Buf, uint8_t *BufEnd); + template <class ELFT> void relocateNonAlloc(uint8_t *Buf, uint8_t *BufEnd); std::vector<Relocation> Relocations; Modified: vendor/lld/dist/ELF/LinkerScript.cpp ============================================================================== --- vendor/lld/dist/ELF/LinkerScript.cpp Mon May 22 19:44:10 2017 (r318670) +++ vendor/lld/dist/ELF/LinkerScript.cpp Mon May 22 19:44:12 2017 (r318671) @@ -440,9 +440,6 @@ void LinkerScript::fabricateDefaultComma // For each OutputSection that needs a VA fabricate an OutputSectionCommand // with an InputSectionDescription describing the InputSections for (OutputSection *Sec : *OutputSections) { - if (!(Sec->Flags & SHF_ALLOC)) - continue; - auto *OSCmd = make<OutputSectionCommand>(Sec->Name); OSCmd->Sec = Sec; SecToCommand[Sec] = OSCmd; Modified: vendor/lld/dist/ELF/MapFile.cpp ============================================================================== --- vendor/lld/dist/ELF/MapFile.cpp Mon May 22 19:44:10 2017 (r318670) +++ vendor/lld/dist/ELF/MapFile.cpp Mon May 22 19:44:12 2017 (r318671) @@ -21,6 +21,8 @@ #include "MapFile.h" #include "InputFiles.h" +#include "LinkerScript.h" +#include "OutputSections.h" #include "Strings.h" #include "SymbolTable.h" #include "Threads.h" @@ -98,7 +100,7 @@ getSymbolStrings(ArrayRef<DefinedRegular } template <class ELFT> -void elf::writeMapFile(ArrayRef<OutputSection *> OutputSections) { +void elf::writeMapFile(llvm::ArrayRef<BaseCommand *> Script) { if (Config->MapFile.empty()) *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** _______________________________________________ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"