[lld] r359192 - lld-link: Implement /swaprun: flag

Nico Weber via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 25 07:02:26 PDT 2019


Author: nico
Date: Thu Apr 25 07:02:26 2019
New Revision: 359192

URL: http://llvm.org/viewvc/llvm-project?rev=359192&view=rev
Log:
lld-link: Implement /swaprun: flag

r191276 added this to old LLD, but it never made it to new LLD -- except
that the flag was in Options.td, so it was silently ignored. I figured
it should be easy to implement, so I did that instead of removing the
flags from Options.td.

I then discovered that link.exe also supports comma-separated lists of
'cd' and 'net', which made the parsing code a bit annoying.

The Alias technique in Options.td is to get nice help output.

Differential Revision: https://reviews.llvm.org/D61067

Modified:
    lld/trunk/COFF/Config.h
    lld/trunk/COFF/Driver.cpp
    lld/trunk/COFF/Driver.h
    lld/trunk/COFF/DriverUtils.cpp
    lld/trunk/COFF/Options.td
    lld/trunk/COFF/Writer.cpp
    lld/trunk/test/COFF/options.test

Modified: lld/trunk/COFF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Config.h?rev=359192&r1=359191&r2=359192&view=diff
==============================================================================
--- lld/trunk/COFF/Config.h (original)
+++ lld/trunk/COFF/Config.h Thu Apr 25 07:02:26 2019
@@ -205,6 +205,8 @@ struct Configuration {
   bool IntegrityCheck = false;
   bool KillAt = false;
   bool Repro = false;
+  bool SwaprunCD = false;
+  bool SwaprunNet = false;
 };
 
 extern Configuration *Config;

Modified: lld/trunk/COFF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=359192&r1=359191&r2=359192&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.cpp (original)
+++ lld/trunk/COFF/Driver.cpp Thu Apr 25 07:02:26 2019
@@ -1375,6 +1375,8 @@ void LinkerDriver::link(ArrayRef<const c
   Config->IntegrityCheck =
       Args.hasFlag(OPT_integritycheck, OPT_integritycheck_no, false);
   Config->NxCompat = Args.hasFlag(OPT_nxcompat, OPT_nxcompat_no, true);
+  for (auto *Arg : Args.filtered(OPT_swaprun))
+    parseSwaprun(Arg->getValue());
   Config->TerminalServerAware =
       !Config->DLL && Args.hasFlag(OPT_tsaware, OPT_tsaware_no, true);
   Config->DebugDwarf = Debug == DebugKind::Dwarf;

Modified: lld/trunk/COFF/Driver.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.h?rev=359192&r1=359191&r2=359192&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.h (original)
+++ lld/trunk/COFF/Driver.h Thu Apr 25 07:02:26 2019
@@ -167,6 +167,9 @@ void parseManifest(StringRef Arg);
 // Parses a string in the form of "level=<string>|uiAccess=<string>"
 void parseManifestUAC(StringRef Arg);
 
+// Parses a string in the form of "cd|net[,(cd|net)]*"
+void parseSwaprun(StringRef Arg);
+
 // Create a resource file containing a manifest XML.
 std::unique_ptr<MemoryBuffer> createManifestRes();
 void createSideBySideManifest();

Modified: lld/trunk/COFF/DriverUtils.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/DriverUtils.cpp?rev=359192&r1=359191&r2=359192&view=diff
==============================================================================
--- lld/trunk/COFF/DriverUtils.cpp (original)
+++ lld/trunk/COFF/DriverUtils.cpp Thu Apr 25 07:02:26 2019
@@ -315,6 +315,27 @@ void parseManifestUAC(StringRef Arg) {
   }
 }
 
+// Parses a string in the form of "cd|net[,(cd|net)]*"
+// Results are directly written to Config.
+void parseSwaprun(StringRef Arg) {
+  do {
+    StringRef Swaprun, NewArg;
+    std::tie(Swaprun, NewArg) = Arg.split(',');
+    if (Swaprun.equals_lower("cd"))
+      Config->SwaprunCD = true;
+    else if (Swaprun.equals_lower("net"))
+      Config->SwaprunNet = true;
+    else if (Swaprun.empty())
+      error("/swaprun: missing argument");
+    else
+      error("/swaprun: invalid argument: " + Swaprun);
+    // To catch trailing commas, e.g. `/spawrun:cd,`
+    if (NewArg.empty() && Arg.endswith(","))
+      error("/swaprun: missing argument");
+    Arg = NewArg;
+  } while (!Arg.empty());
+}
+
 // An RAII temporary file class that automatically removes a temporary file.
 namespace {
 class TemporaryFile {

Modified: lld/trunk/COFF/Options.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Options.td?rev=359192&r1=359191&r2=359192&view=diff
==============================================================================
--- lld/trunk/COFF/Options.td (original)
+++ lld/trunk/COFF/Options.td Thu Apr 25 07:02:26 2019
@@ -103,8 +103,12 @@ def noentry : F<"noentry">,
 def profile : F<"profile">;
 def repro : F<"Brepro">,
     HelpText<"Use a hash of the executable as the PE header timestamp">;
-def swaprun_cd : F<"swaprun:cd">;
-def swaprun_net : F<"swaprun:net">;
+def swaprun : P<"swaprun",
+  "Comma-separated list of 'cd' or 'net'">;
+def swaprun_cd : F<"swaprun:cd">, Alias<swaprun>, AliasArgs<["cd"]>,
+  HelpText<"Make loader run output binary from swap instead of from CD">;
+def swaprun_net : F<"swaprun:net">, Alias<swaprun>, AliasArgs<["net"]>,
+  HelpText<"Make loader run output binary from swap instead of from network">;
 def verbose : F<"verbose">;
 def wholearchive_flag : F<"wholearchive">;
 

Modified: lld/trunk/COFF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Writer.cpp?rev=359192&r1=359191&r2=359192&view=diff
==============================================================================
--- lld/trunk/COFF/Writer.cpp (original)
+++ lld/trunk/COFF/Writer.cpp Thu Apr 25 07:02:26 2019
@@ -1217,6 +1217,10 @@ template <typename PEHeaderTy> void Writ
     COFF->Characteristics |= IMAGE_FILE_DLL;
   if (!Config->Relocatable)
     COFF->Characteristics |= IMAGE_FILE_RELOCS_STRIPPED;
+  if (Config->SwaprunCD)
+    COFF->Characteristics |= IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP;
+  if (Config->SwaprunNet)
+    COFF->Characteristics |= IMAGE_FILE_NET_RUN_FROM_SWAP;
   COFF->SizeOfOptionalHeader =
       sizeof(PEHeaderTy) + sizeof(data_directory) * NumberOfDataDirectory;
 

Modified: lld/trunk/test/COFF/options.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/options.test?rev=359192&r1=359191&r2=359192&view=diff
==============================================================================
--- lld/trunk/test/COFF/options.test (original)
+++ lld/trunk/test/COFF/options.test Thu Apr 25 07:02:26 2019
@@ -50,6 +50,46 @@ NXCOMPAT: IMAGE_DLL_CHARACTERISTICS_NX_C
 # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NONXCOMPAT %s
 NONXCOMPAT-NOT: IMAGE_DLL_CHARACTERISTICS_NX_COMPAT
 
+# RUN: lld-link /out:%t.exe /entry:main /swaprun:CD %t.obj
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=SWAPCD %s
+# RUN: lld-link /out:%t.exe /entry:main /swaprun:cd,net %t.obj
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=SWAPCD %s
+SWAPCD: IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP
+
+# RUN: lld-link /out:%t.exe /entry:main %t.obj
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NOSWAPCD %s
+NOSWAPCD-NOT: IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP
+
+# RUN: lld-link /out:%t.exe /entry:main /swaprun:NeT %t.obj
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=SWAPNET %s
+# RUN: lld-link /out:%t.exe /entry:main /swaprun:net,cd,cd,net %t.obj
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=SWAPNET %s
+SWAPNET: IMAGE_FILE_NET_RUN_FROM_SWAP
+
+# RUN: lld-link /out:%t.exe /entry:main %t.obj
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NOSWAPNET %s
+NOSWAPNET-NOT: IMAGE_FILE_NET_RUN_FROM_SWAP
+
+# RUN: not lld-link /out:%t.exe /entry:main /swaprun: %t.obj 2>&1 | \
+# RUN:     FileCheck -check-prefix=SWAPERR1 %s
+# RUN: not lld-link /out:%t.exe /entry:main /swaprun:cd, %t.obj 2>&1 | \
+# RUN:     FileCheck -check-prefix=SWAPERR1 %s
+# RUN: not lld-link /out:%t.exe /entry:main /swaprun:,, %t.obj 2>&1 | \
+# RUN:     FileCheck -check-prefix=SWAPERR1 %s
+# RUN: not lld-link /out:%t.exe /entry:main /swaprun:,cd %t.obj 2>&1 | \
+# RUN:     FileCheck -check-prefix=SWAPERR1 %s
+SWAPERR1: /swaprun: missing argument
+
+# RUN: not lld-link /out:%t.exe /entry:main /swaprun:foo %t.obj 2>&1 | \
+# RUN:     FileCheck -check-prefix=SWAPERR2 %s
+# RUN: not lld-link /out:%t.exe /entry:main /swaprun:cd,foo,net %t.obj 2>&1 | \
+# RUN:     FileCheck -check-prefix=SWAPERR2 %s
+SWAPERR2: /swaprun: invalid argument: foo
+
+# RUN: not lld-link /out:%t.exe /entry:main /swaprun:cdfoo,net %t.obj 2>&1 | \
+# RUN:     FileCheck -check-prefix=SWAPERR3 %s
+SWAPERR3: /swaprun: invalid argument: cdfoo
+
 # RUN: lld-link /out:%t.exe /entry:main %t.obj
 # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=TSAWARE %s
 # RUN: lld-link /out:%t.exe /entry:main /tsaware %t.obj




More information about the llvm-commits mailing list