[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