[lld] r193141 - [PECOFF] Parse /manifest command line option.

Rui Ueyama ruiu at google.com
Mon Oct 21 20:49:35 PDT 2013


Author: ruiu
Date: Mon Oct 21 22:49:35 2013
New Revision: 193141

URL: http://llvm.org/viewvc/llvm-project?rev=193141&view=rev
Log:
[PECOFF] Parse /manifest command line option.

The manifest file is an XML file that conveys some information to the loader,
such as whether the executable needs to run as Administrator or not. This patch
is to parse command line option for manifest file.

Actual XML file generation will be done in a separate patch.

Modified:
    lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h
    lld/trunk/lib/Driver/WinLinkDriver.cpp
    lld/trunk/lib/Driver/WinLinkOptions.td
    lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp

Modified: lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h?rev=193141&r1=193140&r2=193141&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h Mon Oct 21 22:49:35 2013
@@ -38,6 +38,8 @@ public:
         _allowBind(true), _allowIsolation(true), _swapRunFromCD(false),
         _swapRunFromNet(false), _baseRelocationEnabled(true),
         _terminalServerAware(true), _dynamicBaseEnabled(true),
+        _createManifest(true), _embedManifest(false), _manifestId(1),
+        _manifestLevel("'asInvoker'"), _manifestUiAccess(false),
         _imageType(ImageType::IMAGE_EXE) {
     setDeadStripping(true);
   }
@@ -147,6 +149,21 @@ public:
   void setDynamicBaseEnabled(bool val) { _dynamicBaseEnabled = val; }
   bool getDynamicBaseEnabled() const { return _dynamicBaseEnabled; }
 
+  void setCreateManifest(bool val) { _createManifest = val; }
+  bool getCreateManifest() const { return _createManifest; }
+
+  void setEmbedManifest(bool val) { _embedManifest = val; }
+  bool getEmbedManifest() const { return _embedManifest; }
+
+  void setManifestId(int val) { _manifestId = val; }
+  int getManifestId() const { return _manifestId; }
+
+  void setManifestLevel(std::string val) { _manifestLevel = std::move(val); }
+  const std::string &getManifestLevel() const { return _manifestLevel; }
+
+  void setManifestUiAccess(bool val) { _manifestUiAccess = val; }
+  bool getManifestUiAccess() const { return _manifestUiAccess; }
+
   void setImageType(ImageType type) { _imageType = type; }
   ImageType getImageType() const { return _imageType; }
 
@@ -205,6 +222,11 @@ private:
   bool _baseRelocationEnabled;
   bool _terminalServerAware;
   bool _dynamicBaseEnabled;
+  bool _createManifest;
+  bool _embedManifest;
+  int _manifestId;
+  std::string _manifestLevel;
+  bool _manifestUiAccess;
   ImageType _imageType;
 
   // The set to store /nodefaultlib arguments.

Modified: lld/trunk/lib/Driver/WinLinkDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkDriver.cpp?rev=193141&r1=193140&r2=193141&view=diff
==============================================================================
--- lld/trunk/lib/Driver/WinLinkDriver.cpp (original)
+++ lld/trunk/lib/Driver/WinLinkDriver.cpp Mon Oct 21 22:49:35 2013
@@ -139,6 +139,33 @@ llvm::COFF::MachineTypes stringToMachine
       .Default(llvm::COFF::IMAGE_FILE_MACHINE_UNKNOWN);
 }
 
+// Parse /manifest:EMBED[,ID=#]|NO.
+bool parseManifest(StringRef option, raw_ostream &diagnostics, bool &enable,
+                   bool &embed, int &id) {
+  std::string optionLower = option.lower();
+  if (optionLower == "no") {
+    enable = false;
+    return true;
+  }
+  if (!StringRef(optionLower).startswith("embed"))
+    goto parse_error;
+
+  embed = true;
+  optionLower = optionLower.substr(strlen("embed"));
+  if (optionLower.empty())
+    return true;
+  if (!StringRef(optionLower).startswith(",id="))
+    goto parse_error;
+  optionLower = optionLower.substr(strlen(",id="));
+  if (StringRef(optionLower).getAsInteger(0, id))
+    goto parse_error;
+  return true;
+
+parse_error:
+  diagnostics << "Unknown argument for /manifest: " << option << "\n";
+  return false;
+}
+
 // Handle /failifmismatch option.
 bool handleFailIfMismatchOption(StringRef option,
                                 std::map<StringRef, StringRef> &mustMatch,
@@ -395,6 +422,23 @@ WinLinkDriver::parse(int argc, const cha
       break;
     }
 
+    case OPT_manifest:
+      // Do nothing. This is default.
+      break;
+
+    case OPT_manifest_colon: {
+      // Parse /manifest:EMBED[,ID=#]|NO.
+      bool enable = true;
+      bool embed = false;
+      int id = 1;
+      if (!parseManifest(inputArg->getValue(), diagnostics, enable, embed, id))
+        return false;
+      ctx.setCreateManifest(enable);
+      ctx.setEmbedManifest(embed);
+      ctx.setManifestId(id);
+      break;
+    }
+
     case OPT_failifmismatch:
       if (handleFailIfMismatchOption(inputArg->getValue(), failIfMismatchMap,
                                      diagnostics))

Modified: lld/trunk/lib/Driver/WinLinkOptions.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkOptions.td?rev=193141&r1=193140&r2=193141&view=diff
==============================================================================
--- lld/trunk/lib/Driver/WinLinkOptions.td (original)
+++ lld/trunk/lib/Driver/WinLinkOptions.td Mon Oct 21 22:49:35 2013
@@ -31,6 +31,10 @@ def machine : P<"machine", "Specify targ
 def version : P<"version", "Specify a version number in the PE header">;
 def subsystem : P<"subsystem", "Specify subsystem">;
 
+def manifest : F<"manifest">;
+def manifest_colon : P<"manifest", "Create manifest file">;
+def manifestuac : P<"manifestuac", "User access control">;
+
 // We cannot use multiclass P because class name "incl" is different
 // from its command line option name. We do this because "include" is
 // a reserved keyword in tablegen.

Modified: lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp?rev=193141&r1=193140&r2=193141&view=diff
==============================================================================
--- lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp (original)
+++ lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp Mon Oct 21 22:49:35 2013
@@ -60,6 +60,11 @@ TEST_F(WinLinkParserTest, Basic) {
   EXPECT_TRUE(_context.getBaseRelocationEnabled());
   EXPECT_TRUE(_context.isTerminalServerAware());
   EXPECT_TRUE(_context.getDynamicBaseEnabled());
+  EXPECT_TRUE(_context.getCreateManifest());
+  EXPECT_FALSE(_context.getEmbedManifest());
+  EXPECT_EQ(1, _context.getManifestId());
+  EXPECT_EQ("'asInvoker'", _context.getManifestLevel());
+  EXPECT_EQ(false, _context.getManifestUiAccess());
   EXPECT_TRUE(_context.deadStrip());
   EXPECT_FALSE(_context.logInputFiles());
 }
@@ -367,6 +372,41 @@ TEST_F(WinLinkParserTest, FailIfMismatch
 }
 
 //
+// Tests for /manifest.
+//
+TEST_F(WinLinkParserTest, Manifest_Default) {
+  EXPECT_TRUE(parse("link.exe", "/manifest", "a.out", nullptr));
+  EXPECT_TRUE(_context.getCreateManifest());
+  EXPECT_FALSE(_context.getEmbedManifest());
+  EXPECT_EQ(1, _context.getManifestId());
+  EXPECT_EQ("'asInvoker'", _context.getManifestLevel());
+  EXPECT_EQ(false, _context.getManifestUiAccess());
+}
+
+TEST_F(WinLinkParserTest, Manifest_No) {
+  EXPECT_TRUE(parse("link.exe", "/manifest:no", "a.out", nullptr));
+  EXPECT_FALSE(_context.getCreateManifest());
+}
+
+TEST_F(WinLinkParserTest, Manifest_Embed) {
+  EXPECT_TRUE(parse("link.exe", "/manifest:embed", "a.out", nullptr));
+  EXPECT_TRUE(_context.getCreateManifest());
+  EXPECT_TRUE(_context.getEmbedManifest());
+  EXPECT_EQ(1, _context.getManifestId());
+  EXPECT_EQ("'asInvoker'", _context.getManifestLevel());
+  EXPECT_EQ(false, _context.getManifestUiAccess());
+}
+
+TEST_F(WinLinkParserTest, Manifest_Embed_ID42) {
+  EXPECT_TRUE(parse("link.exe", "/manifest:embed,id=42", "a.out", nullptr));
+  EXPECT_TRUE(_context.getCreateManifest());
+  EXPECT_TRUE(_context.getEmbedManifest());
+  EXPECT_EQ(42, _context.getManifestId());
+  EXPECT_EQ("'asInvoker'", _context.getManifestLevel());
+  EXPECT_EQ(false, _context.getManifestUiAccess());
+}
+
+//
 // Test for command line flags that are ignored.
 //
 





More information about the llvm-commits mailing list