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