diff options
| author | Eric Beckmann <ecbeckmann@google.com> | 2017-06-16 21:13:24 +0000 |
|---|---|---|
| committer | Eric Beckmann <ecbeckmann@google.com> | 2017-06-16 21:13:24 +0000 |
| commit | d135e8c039757a839ab5c4f75dd7ca2eb82ae9f3 (patch) | |
| tree | e298ac6fafb4ac1feee45b296891a4f8f7762f76 /llvm | |
| parent | 6bc14c65ad3e237cfb034ed569358f40e3b45318 (diff) | |
| download | bcm5719-llvm-d135e8c039757a839ab5c4f75dd7ca2eb82ae9f3.tar.gz bcm5719-llvm-d135e8c039757a839ab5c4f75dd7ca2eb82ae9f3.zip | |
Switch external cvtres.exe for llvm's own resource library.
In this patch, I flip the switch in DriverUtils from using the external
cvtres.exe tool to using the Windows Resource library in llvm.
I also fixed a bug where .rsrc sections were marked as discardable
memory and therefore were placed in the wrong order in the final PE.
Furthermore, I modified WindowsResource to write the coff directly to a
memory buffer instead of to file, also had it use the machine types
already declared in COFF.h instead creating my own enum.
Finally, I flipped the switch to allow all unit tests that had
previously run only on windows due to a winres dependency to run
cross-platform.
Reviewers: zturner, ruiu
Subscribers: llvm-commits, hiraditya
Differential Revision: https://reviews.llvm.org/D34265
llvm-svn: 305592
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/include/llvm/Object/WindowsResource.h | 7 | ||||
| -rw-r--r-- | llvm/lib/Object/WindowsResource.cpp | 53 | ||||
| -rw-r--r-- | llvm/tools/llvm-cvtres/llvm-cvtres.cpp | 33 |
3 files changed, 47 insertions, 46 deletions
diff --git a/llvm/include/llvm/Object/WindowsResource.h b/llvm/include/llvm/Object/WindowsResource.h index 4839013c822..65ee912829c 100644 --- a/llvm/include/llvm/Object/WindowsResource.h +++ b/llvm/include/llvm/Object/WindowsResource.h @@ -45,14 +45,10 @@ namespace llvm { -class FileOutputBuffer; - namespace object { class WindowsResource; -enum class Machine { UNKNOWN, ARM, X64, X86 }; - class ResourceEntryRef { public: Error moveNext(bool &End); @@ -185,7 +181,8 @@ private: std::vector<std::vector<UTF16>> StringTable; }; -Error writeWindowsResourceCOFF(StringRef OutputFile, Machine MachineType, +Error writeWindowsResourceCOFF(std::unique_ptr<MemoryBuffer> &OutputBuffer, + llvm::COFF::MachineTypes MachineType, const WindowsResourceParser &Parser); } // namespace object diff --git a/llvm/lib/Object/WindowsResource.cpp b/llvm/lib/Object/WindowsResource.cpp index 3f6080d48f9..1b62f510690 100644 --- a/llvm/lib/Object/WindowsResource.cpp +++ b/llvm/lib/Object/WindowsResource.cpp @@ -21,6 +21,8 @@ #include <sstream> #include <system_error> +using namespace llvm; + namespace llvm { namespace object { @@ -305,7 +307,8 @@ uint32_t WindowsResourceParser::TreeNode::getTreeSize() const { class WindowsResourceCOFFWriter { public: - WindowsResourceCOFFWriter(StringRef OutputFile, Machine MachineType, + WindowsResourceCOFFWriter(std::unique_ptr<MemoryBuffer> &OutputBuffer, + COFF::MachineTypes MachineType, const WindowsResourceParser &Parser, Error &E); Error write(); @@ -323,10 +326,10 @@ private: void writeDirectoryTree(); void writeDirectoryStringTable(); void writeFirstSectionRelocations(); - std::unique_ptr<FileOutputBuffer> Buffer; - uint8_t *BufferStart; + std::unique_ptr<MemoryBuffer> &OutputBuffer; + char *BufferStart; uint64_t CurrentOffset = 0; - Machine MachineType; + COFF::MachineTypes MachineType; const WindowsResourceParser::TreeNode &Resources; const ArrayRef<std::vector<uint8_t>> Data; uint64_t FileSize; @@ -343,20 +346,14 @@ private: }; WindowsResourceCOFFWriter::WindowsResourceCOFFWriter( - StringRef OutputFile, Machine MachineType, + std::unique_ptr<MemoryBuffer> &OutputBuffer, COFF::MachineTypes MachineType, const WindowsResourceParser &Parser, Error &E) - : MachineType(MachineType), Resources(Parser.getTree()), - Data(Parser.getData()), StringTable(Parser.getStringTable()) { + : OutputBuffer(OutputBuffer), MachineType(MachineType), + Resources(Parser.getTree()), Data(Parser.getData()), + StringTable(Parser.getStringTable()) { performFileLayout(); - ErrorOr<std::unique_ptr<FileOutputBuffer>> BufferOrErr = - FileOutputBuffer::create(OutputFile, FileSize); - if (!BufferOrErr) { - E = errorCodeToError(BufferOrErr.getError()); - return; - } - - Buffer = std::move(*BufferOrErr); + OutputBuffer = std::move(MemoryBuffer::getNewMemBuffer(FileSize)); } void WindowsResourceCOFFWriter::performFileLayout() { @@ -421,7 +418,7 @@ static std::time_t getTime() { } Error WindowsResourceCOFFWriter::write() { - BufferStart = Buffer->getBufferStart(); + BufferStart = const_cast<char *>(OutputBuffer->getBufferStart()); writeCOFFHeader(); writeFirstSectionHeader(); @@ -431,10 +428,6 @@ Error WindowsResourceCOFFWriter::write() { writeSymbolTable(); writeStringTable(); - if (auto EC = Buffer->commit()) { - return errorCodeToError(EC); - } - return Error::success(); } @@ -443,13 +436,13 @@ void WindowsResourceCOFFWriter::writeCOFFHeader() { auto *Header = reinterpret_cast<llvm::object::coff_file_header *>(BufferStart); switch (MachineType) { - case Machine::ARM: + case COFF::IMAGE_FILE_MACHINE_ARMNT: Header->Machine = llvm::COFF::IMAGE_FILE_MACHINE_ARMNT; break; - case Machine::X64: + case COFF::IMAGE_FILE_MACHINE_AMD64: Header->Machine = llvm::COFF::IMAGE_FILE_MACHINE_AMD64; break; - case Machine::X86: + case COFF::IMAGE_FILE_MACHINE_I386: Header->Machine = llvm::COFF::IMAGE_FILE_MACHINE_I386; break; default: @@ -481,7 +474,8 @@ void WindowsResourceCOFFWriter::writeFirstSectionHeader() { SectionOneHeader->Characteristics = llvm::COFF::IMAGE_SCN_ALIGN_1BYTES; SectionOneHeader->Characteristics += llvm::COFF::IMAGE_SCN_CNT_INITIALIZED_DATA; - SectionOneHeader->Characteristics += llvm::COFF::IMAGE_SCN_MEM_DISCARDABLE; + SectionOneHeader->Characteristics += + llvm::COFF::IMAGE_SCN_CNT_INITIALIZED_DATA; SectionOneHeader->Characteristics += llvm::COFF::IMAGE_SCN_MEM_READ; } @@ -715,13 +709,13 @@ void WindowsResourceCOFFWriter::writeFirstSectionRelocations() { Reloc->VirtualAddress = RelocationAddresses[i]; Reloc->SymbolTableIndex = NextSymbolIndex++; switch (MachineType) { - case Machine::ARM: + case COFF::IMAGE_FILE_MACHINE_ARMNT: Reloc->Type = llvm::COFF::IMAGE_REL_ARM_ADDR32NB; break; - case Machine::X64: + case COFF::IMAGE_FILE_MACHINE_AMD64: Reloc->Type = llvm::COFF::IMAGE_REL_AMD64_ADDR32NB; break; - case Machine::X86: + case COFF::IMAGE_FILE_MACHINE_I386: Reloc->Type = llvm::COFF::IMAGE_REL_I386_DIR32NB; break; default: @@ -731,10 +725,11 @@ void WindowsResourceCOFFWriter::writeFirstSectionRelocations() { } } -Error writeWindowsResourceCOFF(StringRef OutputFile, Machine MachineType, +Error writeWindowsResourceCOFF(std::unique_ptr<MemoryBuffer> &OutputBuffer, + COFF::MachineTypes MachineType, const WindowsResourceParser &Parser) { Error E = Error::success(); - WindowsResourceCOFFWriter Writer(OutputFile, MachineType, Parser, E); + WindowsResourceCOFFWriter Writer(OutputBuffer, MachineType, Parser, E); if (E) return E; return Writer.write(); diff --git a/llvm/tools/llvm-cvtres/llvm-cvtres.cpp b/llvm/tools/llvm-cvtres/llvm-cvtres.cpp index 1e463399a59..4aaf455fa45 100644 --- a/llvm/tools/llvm-cvtres/llvm-cvtres.cpp +++ b/llvm/tools/llvm-cvtres/llvm-cvtres.cpp @@ -114,21 +114,21 @@ int main(int argc_, const char *argv_[]) { bool Verbose = InputArgs.hasArg(OPT_VERBOSE); - Machine MachineType; + COFF::MachineTypes MachineType; if (InputArgs.hasArg(OPT_MACHINE)) { std::string MachineString = InputArgs.getLastArgValue(OPT_MACHINE).upper(); - MachineType = StringSwitch<Machine>(MachineString) - .Case("ARM", Machine::ARM) - .Case("X64", Machine::X64) - .Case("X86", Machine::X86) - .Default(Machine::UNKNOWN); - if (MachineType == Machine::UNKNOWN) + MachineType = StringSwitch<COFF::MachineTypes>(MachineString) + .Case("ARM", COFF::IMAGE_FILE_MACHINE_ARMNT) + .Case("X64", COFF::IMAGE_FILE_MACHINE_AMD64) + .Case("X86", COFF::IMAGE_FILE_MACHINE_I386) + .Default(COFF::IMAGE_FILE_MACHINE_UNKNOWN); + if (MachineType == COFF::IMAGE_FILE_MACHINE_UNKNOWN) reportError("Unsupported machine architecture"); } else { if (Verbose) outs() << "Machine architecture not specified; assumed X64.\n"; - MachineType = Machine::X64; + MachineType = COFF::IMAGE_FILE_MACHINE_AMD64; } std::vector<std::string> InputFiles = InputArgs.getAllArgValues(OPT_INPUT); @@ -149,10 +149,10 @@ int main(int argc_, const char *argv_[]) { if (Verbose) { outs() << "Machine: "; switch (MachineType) { - case Machine::ARM: + case COFF::IMAGE_FILE_MACHINE_ARMNT: outs() << "ARM\n"; break; - case Machine::X86: + case COFF::IMAGE_FILE_MACHINE_I386: outs() << "X86\n"; break; default: @@ -196,8 +196,17 @@ int main(int argc_, const char *argv_[]) { Parser.printTree(errs()); } - error( - llvm::object::writeWindowsResourceCOFF(OutputFile, MachineType, Parser)); + std::unique_ptr<MemoryBuffer> OutputBuffer; + error(llvm::object::writeWindowsResourceCOFF(OutputBuffer, MachineType, + Parser)); + auto FileOrErr = + FileOutputBuffer::create(OutputFile, OutputBuffer->getBufferSize()); + if (!FileOrErr) + reportError(OutputFile, FileOrErr.getError()); + std::unique_ptr<FileOutputBuffer> FileBuffer = std::move(*FileOrErr); + std::copy(OutputBuffer->getBufferStart(), OutputBuffer->getBufferEnd(), + FileBuffer->getBufferStart()); + error(FileBuffer->commit()); if (Verbose) { Expected<object::OwningBinary<object::Binary>> BinaryOrErr = |

