[lld] r193207 - [PECOFF] Emit the side-by-side manifest file.

Rui Ueyama ruiu at google.com
Tue Oct 22 15:58:07 PDT 2013


Author: ruiu
Date: Tue Oct 22 17:58:07 2013
New Revision: 193207

URL: http://llvm.org/viewvc/llvm-project?rev=193207&view=rev
Log:
[PECOFF] Emit the side-by-side manifest file.

Added:
    lld/trunk/test/pecoff/manifest.test
Modified:
    lld/trunk/lib/Driver/WinLinkDriver.cpp

Modified: lld/trunk/lib/Driver/WinLinkDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkDriver.cpp?rev=193207&r1=193206&r2=193207&view=diff
==============================================================================
--- lld/trunk/lib/Driver/WinLinkDriver.cpp (original)
+++ lld/trunk/lib/Driver/WinLinkDriver.cpp Tue Oct 22 17:58:07 2013
@@ -27,6 +27,7 @@
 #include "llvm/Option/Option.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Process.h"
+#include "llvm/Support/raw_ostream.h"
 
 namespace lld {
 
@@ -204,6 +205,46 @@ StringRef replaceExtension(PECOFFLinking
   return ctx.allocateString(val.str());
 }
 
+// Create a side-by-side manifest file. The manifest file will convey some
+// information to the linker, such as whether the binary needs to run as
+// Administrator or not. Instead of being placed in the PE/COFF header, it's in
+// XML format for some reason -- I guess it's probably because it's invented in
+// the early dot-com era.
+//
+// Instead of having the linker emit a manifest file as a separate file, you
+// could have the linker embed the contents of XML into the resource section of
+// the executable. The feature is not implemented in LLD yet, though.
+bool createManifestFile(PECOFFLinkingContext &ctx, raw_ostream &diagnostics) {
+  std::string errorInfo;
+  llvm::raw_fd_ostream out(ctx.getManifestOutputPath().data(), errorInfo);
+  if (!errorInfo.empty()) {
+    diagnostics << "Failed to open " << ctx.getManifestOutputPath() << ": "
+                << errorInfo << "\n";
+    return false;
+  }
+  out << "<?xml version=\"1.0\" standalone=\"yes\"?>\n"
+      << "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\"\n"
+      << "          manifestVersion=\"1.0\">\n"
+      << "  <trustinfo>\n"
+      << "    <security>\n"
+      << "      <requestedPrivileges>\n"
+      << "         <requestedExecutionLevel level=" << ctx.getManifestLevel()
+      << " uiAccess=" << ctx.getManifestUiAccess() << "/>\n"
+      << "      </requestedPrivileges>\n"
+      << "    </security>\n"
+      << "  </trustinfo>\n";
+  const std::string &dependency = ctx.getManifestDependency();
+  if (!dependency.empty()) {
+    out << "  <dependency>\n"
+        << "    <dependentAssembly>\n"
+        << "      <assemblyIdentity " << dependency << " />\n"
+        << "    </dependentAssembly>\n"
+        << "  </dependency>\n";
+  }
+  out << "</assembly>\n";
+  return true;
+}
+
 // Handle /failifmismatch option.
 bool handleFailIfMismatchOption(StringRef option,
                                 std::map<StringRef, StringRef> &mustMatch,
@@ -673,6 +714,11 @@ WinLinkDriver::parse(int argc, const cha
   for (auto &e : inputElements)
     ctx.inputGraph().addInputElement(std::move(e));
 
+  // Create the side-by-side manifest file if needed.
+  if (!isReadingDirectiveSection && ctx.getCreateManifest())
+    if (!createManifestFile(ctx, diagnostics))
+      return false;
+
   // Validate the combination of options used.
   return ctx.validate(diagnostics);
 }

Added: lld/trunk/test/pecoff/manifest.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/manifest.test?rev=193207&view=auto
==============================================================================
--- lld/trunk/test/pecoff/manifest.test (added)
+++ lld/trunk/test/pecoff/manifest.test Tue Oct 22 17:58:07 2013
@@ -0,0 +1,54 @@
+# RUN: yaml2obj %p/Inputs/nop.obj.yaml > %t.obj
+
+# RUN: lld -flavor link /out:%t1.exe /subsystem:console /force /opt:noref \
+# RUN:   -- %t.obj
+# RUN: FileCheck -check-prefix=MANIFEST %s < %t1.exe.manifest
+
+MANIFEST: ?xml version="1.0" standalone="yes"?>
+MANIFEST: <assembly xmlns="urn:schemas-microsoft-com:asm.v1"
+MANIFEST:           manifestVersion="1.0">
+MANIFEST:   <trustinfo>
+MANIFEST:     <security>
+MANIFEST:       <requestedPrivileges>
+MANIFEST:          <requestedExecutionLevel level='asInvoker' uiAccess='false'/>
+MANIFEST:       </requestedPrivileges>
+MANIFEST:     </security>
+MANIFEST:   </trustinfo>
+MANIFEST: </assembly>
+
+# RUN: lld -flavor link /out:%t2.exe /subsystem:console /force /opt:noref \
+# RUN:   /manifestuac:"level='requireAdministrator' uiAccess='true'" -- %t.obj
+# RUN: FileCheck -check-prefix=UAC %s < %t2.exe.manifest
+
+UAC: ?xml version="1.0" standalone="yes"?>
+UAC: <assembly xmlns="urn:schemas-microsoft-com:asm.v1"
+UAC:           manifestVersion="1.0">
+UAC:   <trustinfo>
+UAC:     <security>
+UAC:       <requestedPrivileges>
+UAC:          <requestedExecutionLevel level='requireAdministrator' uiAccess='true'/>
+UAC:       </requestedPrivileges>
+UAC:     </security>
+UAC:   </trustinfo>
+UAC: </assembly>
+
+# RUN: lld -flavor link /out:%t3.exe /subsystem:console /force /opt:noref \
+# RUN:   /manifestdependency:"foo='bar'" -- %t.obj
+# RUN: FileCheck -check-prefix=DEPENDENCY %s < %t3.exe.manifest
+
+DEPENDENCY: ?xml version="1.0" standalone="yes"?>
+DEPENDENCY: <assembly xmlns="urn:schemas-microsoft-com:asm.v1"
+DEPENDENCY:           manifestVersion="1.0">
+DEPENDENCY:   <trustinfo>
+DEPENDENCY:     <security>
+DEPENDENCY:       <requestedPrivileges>
+DEPENDENCY:          <requestedExecutionLevel level='asInvoker' uiAccess='false'/>
+DEPENDENCY:       </requestedPrivileges>
+DEPENDENCY:     </security>
+DEPENDENCY:   </trustinfo>
+DEPENDENCY:   <dependency>
+DEPENDENCY:     <dependentAssembly>
+DEPENDENCY:       <assemblyIdentity foo='bar' />
+DEPENDENCY:     </dependentAssembly>
+DEPENDENCY:   </dependency>
+DEPENDENCY: </assembly>





More information about the llvm-commits mailing list