[lld] r306941 - Revert "Revert "Replace trivial use of external rc.exe by writing our own .res file.""
Eric Christopher via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 30 21:35:17 PDT 2017
On Fri, Jun 30, 2017 at 9:00 PM Eric Beckmann via llvm-commits <
llvm-commits at lists.llvm.org> wrote:
> Author: ecbeckmann
> Date: Fri Jun 30 20:59:54 2017
> New Revision: 306941
>
> URL: http://llvm.org/viewvc/llvm-project?rev=306941&view=rev
> Log:
> Revert "Revert "Replace trivial use of external rc.exe by writing our own
> .res file.""
>
> Summary:
> This reverts commit 51931072a7c9a52540baf76fc30ef391d2529a2f.
>
>
Since we're still on svn please use svn revision numbers when you revert
something :)
Thanks!
-eric
> This revert was originally done because the integrations of the new
> WindowsResource library into LLD was causing error in chromium, due to
> bugs in how resource sections were handled. These bugs were fixed,
> meaning that the features may be reintegrated.
>
> Subscribers: hiraditya, llvm-commits
>
> Differential Revision: https://reviews.llvm.org/D34922
>
> Modified:
> lld/trunk/COFF/DriverUtils.cpp
> lld/trunk/test/COFF/combined-resources.test
> lld/trunk/test/COFF/def-name.test
> lld/trunk/test/COFF/dll.test
> lld/trunk/test/COFF/dllimport-gc.test
> lld/trunk/test/COFF/manifestinput.test
> lld/trunk/test/COFF/noentry.test
> lld/trunk/test/COFF/out.test
> lld/trunk/test/COFF/resource.test
> lld/trunk/test/lit.cfg
>
> Modified: lld/trunk/COFF/DriverUtils.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/DriverUtils.cpp?rev=306941&r1=306940&r2=306941&view=diff
>
> ==============================================================================
> --- lld/trunk/COFF/DriverUtils.cpp (original)
> +++ lld/trunk/COFF/DriverUtils.cpp Fri Jun 30 20:59:54 2017
> @@ -20,12 +20,15 @@
> #include "Symbols.h"
> #include "llvm/ADT/Optional.h"
> #include "llvm/ADT/StringSwitch.h"
> +#include "llvm/BinaryFormat/COFF.h"
> #include "llvm/Object/COFF.h"
> +#include "llvm/Object/WindowsResource.h"
> #include "llvm/Option/Arg.h"
> #include "llvm/Option/ArgList.h"
> #include "llvm/Option/Option.h"
> #include "llvm/Support/CommandLine.h"
> #include "llvm/Support/FileUtilities.h"
> +#include "llvm/Support/MathExtras.h"
> #include "llvm/Support/Process.h"
> #include "llvm/Support/Program.h"
> #include "llvm/Support/raw_ostream.h"
> @@ -41,6 +44,9 @@ namespace lld {
> namespace coff {
> namespace {
>
> +const uint16_t SUBLANG_ENGLISH_US = 0x0409;
> +const uint16_t RT_MANIFEST = 24;
> +
> class Executor {
> public:
> explicit Executor(StringRef S) : Prog(Saver.save(S)) {}
> @@ -257,26 +263,6 @@ void parseManifestUAC(StringRef Arg) {
> }
> }
>
> -// Quote each line with "". Existing double-quote is converted
> -// to two double-quotes.
> -static void quoteAndPrint(raw_ostream &Out, StringRef S) {
> - while (!S.empty()) {
> - StringRef Line;
> - std::tie(Line, S) = S.split("\n");
> - if (Line.empty())
> - continue;
> - Out << '\"';
> - for (int I = 0, E = Line.size(); I != E; ++I) {
> - if (Line[I] == '\"') {
> - Out << "\"\"";
> - } else {
> - Out << Line[I];
> - }
> - }
> - Out << "\"\n";
> - }
> -}
> -
> // An RAII temporary file class that automatically removes a temporary
> file.
> namespace {
> class TemporaryFile {
> @@ -390,38 +376,64 @@ static std::string createManifestXml() {
> return readFile(File2.Path);
> }
>
> +static std::unique_ptr<MemoryBuffer>
> +createMemoryBufferForManifestRes(size_t ManifestSize) {
> + size_t ResSize = alignTo(object::WIN_RES_MAGIC_SIZE +
> + object::WIN_RES_NULL_ENTRY_SIZE +
> + sizeof(object::WinResHeaderPrefix) +
> + sizeof(object::WinResIDs) +
> + sizeof(object::WinResHeaderSuffix) +
> + ManifestSize,
> + object::WIN_RES_DATA_ALIGNMENT);
> + return MemoryBuffer::getNewMemBuffer(ResSize);
> +}
> +
> +static void writeResFileHeader(char *&Buf) {
> + memcpy(Buf, COFF::WinResMagic, sizeof(COFF::WinResMagic));
> + Buf += sizeof(COFF::WinResMagic);
> + memset(Buf, 0, object::WIN_RES_NULL_ENTRY_SIZE);
> + Buf += object::WIN_RES_NULL_ENTRY_SIZE;
> +}
> +
> +static void writeResEntryHeader(char *&Buf, size_t ManifestSize) {
> + // Write the prefix.
> + auto *Prefix = reinterpret_cast<object::WinResHeaderPrefix *>(Buf);
> + Prefix->DataSize = ManifestSize;
> + Prefix->HeaderSize = sizeof(object::WinResHeaderPrefix) +
> + sizeof(object::WinResIDs) +
> + sizeof(object::WinResHeaderSuffix);
> + Buf += sizeof(object::WinResHeaderPrefix);
> +
> + // Write the Type/Name IDs.
> + auto *IDs = reinterpret_cast<object::WinResIDs *>(Buf);
> + IDs->setType(RT_MANIFEST);
> + IDs->setName(Config->ManifestID);
> + Buf += sizeof(object::WinResIDs);
> +
> + // Write the suffix.
> + auto *Suffix = reinterpret_cast<object::WinResHeaderSuffix *>(Buf);
> + Suffix->DataVersion = 0;
> + Suffix->MemoryFlags = object::WIN_RES_PURE_MOVEABLE;
> + Suffix->Language = SUBLANG_ENGLISH_US;
> + Suffix->Version = 0;
> + Suffix->Characteristics = 0;
> + Buf += sizeof(object::WinResHeaderSuffix);
> +}
> +
> // Create a resource file containing a manifest XML.
> std::unique_ptr<MemoryBuffer> createManifestRes() {
> - // Create a temporary file for the resource script file.
> - TemporaryFile RCFile("manifest", "rc");
> + std::string Manifest = createManifestXml();
>
> - // Open the temporary file for writing.
> - std::error_code EC;
> - raw_fd_ostream Out(RCFile.Path, EC, sys::fs::F_Text);
> - if (EC)
> - fatal(EC, "failed to open " + RCFile.Path);
> + std::unique_ptr<MemoryBuffer> Res =
> + createMemoryBufferForManifestRes(Manifest.size());
>
> - // Write resource script to the RC file.
> - Out << "#define LANG_ENGLISH 9\n"
> - << "#define SUBLANG_DEFAULT 1\n"
> - << "#define APP_MANIFEST " << Config->ManifestID << "\n"
> - << "#define RT_MANIFEST 24\n"
> - << "LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT\n"
> - << "APP_MANIFEST RT_MANIFEST {\n";
> - quoteAndPrint(Out, createManifestXml());
> - Out << "}\n";
> - Out.close();
> -
> - // Create output resource file.
> - TemporaryFile ResFile("output-resource", "res");
> -
> - Executor E("rc.exe");
> - E.add("/fo");
> - E.add(ResFile.Path);
> - E.add("/nologo");
> - E.add(RCFile.Path);
> - E.run();
> - return ResFile.getMemoryBuffer();
> + char *Buf = const_cast<char *>(Res->getBufferStart());
> + writeResFileHeader(Buf);
> + writeResEntryHeader(Buf, Manifest.size());
> +
> + // Copy the manifest data into the .res file.
> + std::copy(Manifest.begin(), Manifest.end(), Buf);
> + return Res;
> }
>
> void createSideBySideManifest() {
> @@ -592,40 +604,22 @@ void checkFailIfMismatch(StringRef Arg)
> // using cvtres.exe.
> std::unique_ptr<MemoryBuffer>
> convertResToCOFF(const std::vector<MemoryBufferRef> &MBs) {
> - // Create an output file path.
> - TemporaryFile File("resource-file", "obj");
> + object::WindowsResourceParser Parser;
>
> - // Execute cvtres.exe.
> - Executor E("cvtres.exe");
> - E.add("/machine:" + machineToStr(Config->Machine));
> - E.add("/readonly");
> - E.add("/nologo");
> - E.add("/out:" + Twine(File.Path));
> -
> - // We must create new files because the memory buffers we have may have
> no
> - // underlying file still existing on the disk.
> - // It happens if it was created from a TemporaryFile, which usually
> delete
> - // the file just after creating the MemoryBuffer.
> - std::vector<TemporaryFile> ResFiles;
> - ResFiles.reserve(MBs.size());
> for (MemoryBufferRef MB : MBs) {
> - // We store the temporary file in a vector to avoid deletion
> - // before running cvtres
> - ResFiles.emplace_back("resource-file", "res");
> - TemporaryFile& ResFile = ResFiles.back();
> - // Write the content of the resource in a temporary file
> - std::error_code EC;
> - raw_fd_ostream OS(ResFile.Path, EC, sys::fs::F_None);
> - if (EC)
> - fatal(EC, "failed to open " + ResFile.Path);
> - OS << MB.getBuffer();
> - OS.close();
> -
> - E.add(ResFile.Path);
> + std::unique_ptr<object::Binary> Bin = check(object::createBinary(MB));
> + object::WindowsResource *RF =
> dyn_cast<object::WindowsResource>(Bin.get());
> + if (!RF)
> + fatal("cannot compile non-resource file as resource");
> + if (auto EC = Parser.parse(RF))
> + fatal(EC, "failed to parse .res file");
> }
>
> - E.run();
> - return File.getMemoryBuffer();
> + Expected<std::unique_ptr<MemoryBuffer>> E =
> + llvm::object::writeWindowsResourceCOFF(Config->Machine, Parser);
> + if (!E)
> + fatal(errorToErrorCode(E.takeError()), "failed to write .res to
> COFF");
> + return std::move(E.get());
> }
>
> // Run MSVC link.exe for given in-memory object files.
>
> Modified: lld/trunk/test/COFF/combined-resources.test
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/combined-resources.test?rev=306941&r1=306940&r2=306941&view=diff
>
> ==============================================================================
> --- lld/trunk/test/COFF/combined-resources.test (original)
> +++ lld/trunk/test/COFF/combined-resources.test Fri Jun 30 20:59:54 2017
> @@ -4,8 +4,6 @@
> // > rc /fo combined-resources.res /nologo combined-resources.rc
> // > rc /fo combined-resources-2.res /nologo combined-resources-2.rc
>
> -# REQUIRES: winres
> -
> # RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj
> # RUN: lld-link /out:%t.exe /entry:main %t.obj %p/Inputs/resource.res \
> # RUN: %p/Inputs/combined-resources.res
> %p/Inputs/combined-resources-2.res
>
> Modified: lld/trunk/test/COFF/def-name.test
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/def-name.test?rev=306941&r1=306940&r2=306941&view=diff
>
> ==============================================================================
> --- lld/trunk/test/COFF/def-name.test (original)
> +++ lld/trunk/test/COFF/def-name.test Fri Jun 30 20:59:54 2017
> @@ -1,5 +1,3 @@
> -# REQUIRES: winres
> -
> # RUN: rm -rf %t
> # RUN: mkdir -p %t
> # RUN: cd %t
>
> Modified: lld/trunk/test/COFF/dll.test
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/dll.test?rev=306941&r1=306940&r2=306941&view=diff
>
> ==============================================================================
> --- lld/trunk/test/COFF/dll.test (original)
> +++ lld/trunk/test/COFF/dll.test Fri Jun 30 20:59:54 2017
> @@ -1,5 +1,3 @@
> -# REQUIRES: winres
> -
> # RUN: yaml2obj < %p/Inputs/export.yaml > %t.obj
> # RUN: lld-link /out:%t.dll /dll %t.obj /export:exportfn1
> /export:exportfn2 \
> # RUN: /export:mangled
>
> Modified: lld/trunk/test/COFF/dllimport-gc.test
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/dllimport-gc.test?rev=306941&r1=306940&r2=306941&view=diff
>
> ==============================================================================
> --- lld/trunk/test/COFF/dllimport-gc.test (original)
> +++ lld/trunk/test/COFF/dllimport-gc.test Fri Jun 30 20:59:54 2017
> @@ -1,5 +1,3 @@
> -# REQUIRES: winres
> -
> # RUN: yaml2obj < %p/Inputs/export.yaml > %t-lib.obj
> # RUN: lld-link /out:%t.dll /dll %t-lib.obj /implib:%t.lib
> /export:exportfn1
>
>
> Modified: lld/trunk/test/COFF/manifestinput.test
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/manifestinput.test?rev=306941&r1=306940&r2=306941&view=diff
>
> ==============================================================================
> --- lld/trunk/test/COFF/manifestinput.test (original)
> +++ lld/trunk/test/COFF/manifestinput.test Fri Jun 30 20:59:54 2017
> @@ -1,4 +1,4 @@
> -# REQUIRES: winres
> +# REQUIRES: win_mt
>
> # RUN: yaml2obj %p/Inputs/ret42.yaml > %t.obj
> # RUN: lld-link /out:%t.exe /entry:main \
> @@ -8,3 +8,28 @@
>
> CHECK: <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
> CHECK: <assembly xmlns="urn:schemas-microsoft-com:asm.v1"
> manifestVersion="1.0"><dependency><dependentAssembly><assemblyIdentity
> type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0"
> processorArchitecture="*" publicKeyToken="6595b64144ccf1df"
> language="*"></assemblyIdentity></dependentAssembly></dependency><trustInfo><security><requestedPrivileges><requestedExecutionLevel
> level="requireAdministrator"
> uiAccess="false"></requestedExecutionLevel></requestedPrivileges></security></trustInfo></assembly>
> +
> +# RUN: yaml2obj %p/Inputs/ret42.yaml > %t.obj
> +# RUN: lld-link /out:%t.exe /entry:main \
> +# RUN: /manifest:embed \
> +# RUN: /manifestuac:"level='requireAdministrator'" \
> +# RUN: /manifestinput:%p/Inputs/manifestinput.test %t.obj
> +# RUN: llvm-readobj -coff-resources -file-headers %t.exe | FileCheck %s \
> +# RUN: -check-prefix TEST_EMBED
> +
> +TEST_EMBED: ResourceTableRVA: 0x1000
> +TEST_EMBED-NEXT: ResourceTableSize: 0x298
> +TEST_EMBED-DAG: Resources [
> +TEST_EMBED-NEXT: Total Number of Resources: 1
> +TEST_EMBED-DAG: Number of String Entries: 0
> +TEST_EMBED-NEXT: Number of ID Entries: 1
> +TEST_EMBED-NEXT: Type: kRT_MANIFEST (ID 24) [
> +TEST_EMBED-NEXT: Table Offset: 0x18
> +TEST_EMBED-NEXT: Number of String Entries: 0
> +TEST_EMBED-NEXT: Number of ID Entries: 1
> +TEST_EMBED-NEXT: Name: (ID 1) [
> +TEST_EMBED-NEXT: Table Offset: 0x30
> +TEST_EMBED-NEXT: Number of String Entries: 0
> +TEST_EMBED-NEXT: Number of ID Entries: 1
> +TEST_EMBED-NEXT: Language: (ID 1033) [
> +TEST_EMBED-NEXT: Entry Offset: 0x48
>
> Modified: lld/trunk/test/COFF/noentry.test
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/noentry.test?rev=306941&r1=306940&r2=306941&view=diff
>
> ==============================================================================
> --- lld/trunk/test/COFF/noentry.test (original)
> +++ lld/trunk/test/COFF/noentry.test Fri Jun 30 20:59:54 2017
> @@ -1,5 +1,3 @@
> -# REQUIRES: winres
> -
> # RUN: yaml2obj < %p/Inputs/export.yaml > %t.obj
> # RUN: lld-link /out:%t.dll /dll %t.obj
> # RUN: llvm-readobj -file-headers %t.dll | FileCheck -check-prefix=ENTRY
> %s
>
> Modified: lld/trunk/test/COFF/out.test
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/out.test?rev=306941&r1=306940&r2=306941&view=diff
>
> ==============================================================================
> --- lld/trunk/test/COFF/out.test (original)
> +++ lld/trunk/test/COFF/out.test Fri Jun 30 20:59:54 2017
> @@ -1,4 +1,3 @@
> -# REQUIRES: winres
> # RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj
>
> # RUN: mkdir -p %T/out/tmp
>
> Modified: lld/trunk/test/COFF/resource.test
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/resource.test?rev=306941&r1=306940&r2=306941&view=diff
>
> ==============================================================================
> --- lld/trunk/test/COFF/resource.test (original)
> +++ lld/trunk/test/COFF/resource.test Fri Jun 30 20:59:54 2017
> @@ -1,5 +1,3 @@
> -# REQUIRES: winres
> -
> # RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj
> # RUN: lld-link /out:%t.exe /entry:main %t.obj %p/Inputs/resource.res
>
>
> Modified: lld/trunk/test/lit.cfg
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/lit.cfg?rev=306941&r1=306940&r2=306941&view=diff
>
> ==============================================================================
> --- lld/trunk/test/lit.cfg (original)
> +++ lld/trunk/test/lit.cfg Fri Jun 30 20:59:54 2017
> @@ -264,8 +264,7 @@ llvm_config_cmd.wait()
> # Set a fake constant version so that we get consitent output.
> config.environment['LLD_VERSION'] = 'LLD 1.0'
>
> -# Check if Windows resource file compiler exists.
> -cvtres = lit.util.which('cvtres', config.environment['PATH'])
> -rc = lit.util.which('rc', config.environment['PATH'])
> -if cvtres and rc:
> - config.available_features.add('winres')
> +# Indirectly check if the mt.exe Microsoft utility exists by searching for
> +# cvtres, which always accompanies it.
> +if lit.util.which('cvtres', config.environment['PATH']):
> + config.available_features.add('win_mt')
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170701/6c092977/attachment.html>
More information about the llvm-commits
mailing list