diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2016-01-13 20:06:04 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2016-01-13 20:06:04 +0000 |
commit | b289257c7f3ed78b7d3971c596d7c60a9050c705 (patch) | |
tree | d6b57e29a5a86347a020d6f0cae76cc2d0f3bf8d /COFF | |
parent | fba2c04f31e119eacf142fcbbaabd5a9e63a39ed (diff) | |
download | src-b289257c7f3ed78b7d3971c596d7c60a9050c705.tar.gz src-b289257c7f3ed78b7d3971c596d7c60a9050c705.zip |
Vendor import of lld trunk r257626:vendor/lld/lld-trunk-r257626
Notes
Notes:
svn path=/vendor/lld/dist/; revision=293846
svn path=/vendor/lld/lld-trunk-r257626/; revision=293847; tag=vendor/lld/lld-trunk-r257626
Diffstat (limited to 'COFF')
-rw-r--r-- | COFF/CMakeLists.txt | 2 | ||||
-rw-r--r-- | COFF/Chunks.cpp | 2 | ||||
-rw-r--r-- | COFF/Chunks.h | 4 | ||||
-rw-r--r-- | COFF/Config.h | 7 | ||||
-rw-r--r-- | COFF/DLL.cpp | 21 | ||||
-rw-r--r-- | COFF/Driver.cpp | 2 | ||||
-rw-r--r-- | COFF/DriverUtils.cpp | 31 | ||||
-rw-r--r-- | COFF/InputFiles.cpp | 1 | ||||
-rw-r--r-- | COFF/Writer.cpp | 17 |
9 files changed, 67 insertions, 20 deletions
diff --git a/COFF/CMakeLists.txt b/COFF/CMakeLists.txt index 78dc34eff96e..3f31ba9ba1fb 100644 --- a/COFF/CMakeLists.txt +++ b/COFF/CMakeLists.txt @@ -2,7 +2,7 @@ set(LLVM_TARGET_DEFINITIONS Options.td) tablegen(LLVM Options.inc -gen-opt-parser-defs) add_public_tablegen_target(COFFOptionsTableGen) -add_llvm_library(lldCOFF +add_lld_library(lldCOFF Chunks.cpp DLL.cpp Driver.cpp diff --git a/COFF/Chunks.cpp b/COFF/Chunks.cpp index 50bf55be269b..f9f768d69866 100644 --- a/COFF/Chunks.cpp +++ b/COFF/Chunks.cpp @@ -310,7 +310,7 @@ void SEHTableChunk::writeTo(uint8_t *Buf) const { 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. - Data.resize(RoundUpToAlignment((End - Begin) * 2 + 8, 4)); + Data.resize(align((End - Begin) * 2 + 8, 4)); uint8_t *P = Data.data(); write32le(P, Page); write32le(P + 4, Data.size()); diff --git a/COFF/Chunks.h b/COFF/Chunks.h index 60b8e76f8230..274135516eb9 100644 --- a/COFF/Chunks.h +++ b/COFF/Chunks.h @@ -326,6 +326,10 @@ public: uint8_t Type; }; +inline uint64_t align(uint64_t Value, uint64_t Align) { + return llvm::RoundUpToAlignment(Value, Align); +} + } // namespace coff } // namespace lld diff --git a/COFF/Config.h b/COFF/Config.h index 409ede648636..9cfccadba5fa 100644 --- a/COFF/Config.h +++ b/COFF/Config.h @@ -25,6 +25,7 @@ using llvm::COFF::WindowsSubsystem; using llvm::StringRef; class DefinedAbsolute; class DefinedRelative; +class StringChunk; class Undefined; // Short aliases. @@ -42,6 +43,12 @@ struct Export { bool Data = false; bool Private = 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. + // ForwardTo is set to "dllname.bar" part. Usually empty. + StringRef ForwardTo; + StringChunk *ForwardChunk = nullptr; + // True if this /export option was in .drectves section. bool Directives = false; StringRef SymbolName; diff --git a/COFF/DLL.cpp b/COFF/DLL.cpp index 40ca5cf61dc2..8f3383d75c7b 100644 --- a/COFF/DLL.cpp +++ b/COFF/DLL.cpp @@ -45,7 +45,7 @@ public: size_t getSize() const override { // Starts with 2 byte Hint field, followed by a null-terminated string, // ends with 0 or 1 byte padding. - return RoundUpToAlignment(Name.size() + 3, 2); + return align(Name.size() + 3, 2); } void writeTo(uint8_t *Buf) const override { @@ -320,8 +320,12 @@ public: void writeTo(uint8_t *Buf) const override { for (Export &E : Config->Exports) { - auto *D = cast<Defined>(E.Sym->repl()); - write32le(Buf + OutputSectionOff + E.Ordinal * 4, D->getRVA()); + uint8_t *P = Buf + OutputSectionOff + E.Ordinal * 4; + if (E.ForwardChunk) { + write32le(P, E.ForwardChunk->getRVA()); + } else { + write32le(P, cast<Defined>(E.Sym->repl())->getRVA()); + } } } @@ -539,6 +543,15 @@ EdataContents::EdataContents() { for (Export &E : Config->Exports) if (!E.Noname) Names.push_back(new StringChunk(E.ExportName)); + + std::vector<Chunk *> Forwards; + for (Export &E : Config->Exports) { + if (E.ForwardTo.empty()) + continue; + E.ForwardChunk = new 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, @@ -550,6 +563,8 @@ EdataContents::EdataContents() { 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)); } } // namespace coff diff --git a/COFF/Driver.cpp b/COFF/Driver.cpp index f528dafd9857..4cacf0ff552a 100644 --- a/COFF/Driver.cpp +++ b/COFF/Driver.cpp @@ -586,6 +586,8 @@ void LinkerDriver::link(llvm::ArrayRef<const char *> ArgsArr) { // Windows specific -- Make sure we resolve all dllexported symbols. for (Export &E : Config->Exports) { + if (!E.ForwardTo.empty()) + continue; E.Sym = addUndefined(E.Name); if (!E.Directives) Symtab.mangleMaybe(E.Sym); diff --git a/COFF/DriverUtils.cpp b/COFF/DriverUtils.cpp index 391a8ab66420..014fee7fefd7 100644 --- a/COFF/DriverUtils.cpp +++ b/COFF/DriverUtils.cpp @@ -321,7 +321,8 @@ void createSideBySideManifest() { } // Parse a string in the form of -// "<name>[=<internalname>][,@ordinal[,NONAME]][,DATA][,PRIVATE]". +// "<name>[=<internalname>][,@ordinal[,NONAME]][,DATA][,PRIVATE]" +// or "<name>=<dllname>.<name>". // Used for parsing /export arguments. Export parseExport(StringRef Arg) { Export E; @@ -329,12 +330,25 @@ Export parseExport(StringRef Arg) { std::tie(E.Name, Rest) = Arg.split(","); if (E.Name.empty()) goto err; + if (E.Name.find('=') != StringRef::npos) { - std::tie(E.ExtName, E.Name) = E.Name.split("="); + StringRef X, Y; + std::tie(X, Y) = E.Name.split("="); + + // If "<name>=<dllname>.<name>". + if (Y.find(".") != StringRef::npos) { + E.Name = X; + E.ForwardTo = Y; + return E; + } + + E.ExtName = X; + E.Name = Y; if (E.Name.empty()) goto err; } + // If "<name>=<internalname>[,@ordinal[,NONAME]][,DATA][,PRIVATE]" while (!Rest.empty()) { StringRef Tok; std::tie(Tok, Rest) = Rest.split(","); @@ -388,15 +402,22 @@ void fixupExports() { } for (Export &E : Config->Exports) { - if (Undefined *U = cast_or_null<Undefined>(E.Sym->WeakAlias)) { + if (!E.ForwardTo.empty()) { + E.SymbolName = E.Name; + } else if (Undefined *U = cast_or_null<Undefined>(E.Sym->WeakAlias)) { E.SymbolName = U->getName(); } else { E.SymbolName = E.Sym->getName(); } } - for (Export &E : Config->Exports) - E.ExportName = undecorate(E.ExtName.empty() ? E.Name : E.ExtName); + for (Export &E : Config->Exports) { + if (!E.ForwardTo.empty()) { + E.ExportName = undecorate(E.Name); + } else { + E.ExportName = undecorate(E.ExtName.empty() ? E.Name : E.ExtName); + } + } // Uniquefy by name. std::map<StringRef, Export *> Map; diff --git a/COFF/InputFiles.cpp b/COFF/InputFiles.cpp index 23fc2a085122..23af1e89c34d 100644 --- a/COFF/InputFiles.cpp +++ b/COFF/InputFiles.cpp @@ -23,7 +23,6 @@ using namespace llvm::COFF; using namespace llvm::object; using namespace llvm::support::endian; -using llvm::RoundUpToAlignment; using llvm::Triple; using llvm::support::ulittle32_t; using llvm::sys::fs::file_magic; diff --git a/COFF/Writer.cpp b/COFF/Writer.cpp index a74b316b87a4..5575c8d6b320 100644 --- a/COFF/Writer.cpp +++ b/COFF/Writer.cpp @@ -163,13 +163,13 @@ void OutputSection::addChunk(Chunk *C) { Chunks.push_back(C); C->setOutputSection(this); uint64_t Off = Header.VirtualSize; - Off = RoundUpToAlignment(Off, C->getAlign()); + Off = align(Off, C->getAlign()); C->setRVA(Off); C->setOutputSectionOff(Off); Off += C->getSize(); Header.VirtualSize = Off; if (C->hasData()) - Header.SizeOfRawData = RoundUpToAlignment(Off, SectorSize); + Header.SizeOfRawData = align(Off, SectorSize); } void OutputSection::addPermissions(uint32_t C) { @@ -448,15 +448,14 @@ void Writer::createSymbolAndStringTable() { OutputSection *LastSection = OutputSections.back(); // We position the symbol table to be adjacent to the end of the last section. uint64_t FileOff = - LastSection->getFileOff() + - RoundUpToAlignment(LastSection->getRawSize(), SectorSize); + LastSection->getFileOff() + align(LastSection->getRawSize(), SectorSize); if (!OutputSymtab.empty()) { PointerToSymbolTable = FileOff; FileOff += OutputSymtab.size() * sizeof(coff_symbol16); } if (!Strtab.empty()) FileOff += Strtab.size() + 4; - FileSize = RoundUpToAlignment(FileOff, SectorSize); + FileSize = align(FileOff, SectorSize); } // Visits all sections to assign incremental, non-overlapping RVAs and @@ -467,7 +466,7 @@ void Writer::assignAddresses() { sizeof(coff_section) * OutputSections.size(); SizeOfHeaders += Config->is64() ? sizeof(pe32plus_header) : sizeof(pe32_header); - SizeOfHeaders = RoundUpToAlignment(SizeOfHeaders, SectorSize); + SizeOfHeaders = align(SizeOfHeaders, SectorSize); uint64_t RVA = 0x1000; // The first page is kept unmapped. FileSize = SizeOfHeaders; // Move DISCARDABLE (or non-memory-mapped) sections to the end of file because @@ -481,10 +480,10 @@ void Writer::assignAddresses() { addBaserels(Sec); Sec->setRVA(RVA); Sec->setFileOffset(FileSize); - RVA += RoundUpToAlignment(Sec->getVirtualSize(), PageSize); - FileSize += RoundUpToAlignment(Sec->getRawSize(), SectorSize); + RVA += align(Sec->getVirtualSize(), PageSize); + FileSize += align(Sec->getRawSize(), SectorSize); } - SizeOfImage = SizeOfHeaders + RoundUpToAlignment(RVA - 0x1000, PageSize); + SizeOfImage = SizeOfHeaders + align(RVA - 0x1000, PageSize); } template <typename PEHeaderTy> void Writer::writeHeader() { |