<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>