[lld] r307226 - Revert "Revert "Revert "Replace trivial use of external rc.exe by writing our own .res file."""

Eric Beckmann via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 5 16:45:50 PDT 2017


Author: ecbeckmann
Date: Wed Jul  5 16:45:50 2017
New Revision: 307226

URL: http://llvm.org/viewvc/llvm-project?rev=307226&view=rev
Log:
Revert "Revert "Revert "Replace trivial use of external rc.exe by writing our own .res file."""

This reverts commit 5fecbbbe5049665d86834cf69d8f75db4f392308.

The initial revert was done in order to prevent ongoing errors on
chromium bots such as CrWinClangLLD.  However, this was done haphazardly
and I didn't realize there were test and compilation failures, so this
revert was reverted.  Now that those have been fixed, we can revert the
revert of the revert.

Modified:
    lld/trunk/COFF/DriverUtils.cpp
    lld/trunk/test/COFF/manifestinput.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=307226&r1=307225&r2=307226&view=diff
==============================================================================
--- lld/trunk/COFF/DriverUtils.cpp (original)
+++ lld/trunk/COFF/DriverUtils.cpp Wed Jul  5 16:45:50 2017
@@ -20,7 +20,6 @@
 #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"
@@ -28,7 +27,6 @@
 #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"
@@ -44,9 +42,6 @@ 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)) {}
@@ -266,6 +261,26 @@ 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 {
@@ -379,64 +394,38 @@ 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() {
-  std::string Manifest = createManifestXml();
+  // Create a temporary file for the resource script file.
+  TemporaryFile RCFile("manifest", "rc");
 
-  std::unique_ptr<MemoryBuffer> Res =
-      createMemoryBufferForManifestRes(Manifest.size());
+  // 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);
 
-  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;
+  // 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();
 }
 
 void createSideBySideManifest() {

Modified: lld/trunk/test/COFF/manifestinput.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/manifestinput.test?rev=307226&r1=307225&r2=307226&view=diff
==============================================================================
--- lld/trunk/test/COFF/manifestinput.test (original)
+++ lld/trunk/test/COFF/manifestinput.test Wed Jul  5 16:45:50 2017
@@ -8,28 +8,3 @@
 
 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/lit.cfg
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/lit.cfg?rev=307226&r1=307225&r2=307226&view=diff
==============================================================================
--- lld/trunk/test/lit.cfg (original)
+++ lld/trunk/test/lit.cfg Wed Jul  5 16:45:50 2017
@@ -264,7 +264,6 @@ llvm_config_cmd.wait()
 # Set a fake constant version so that we get consitent output.
 config.environment['LLD_VERSION'] = 'LLD 1.0'
 
-# 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']):
+# Check if the mt.exe Microsoft utility exists.
+if lit.util.which('mt.exe', config.environment['PATH']):
     config.available_features.add('win_mt')




More information about the llvm-commits mailing list