[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