COFF: Add miscellaneous boolean flags.
authorRui Ueyama <ruiu@google.com>
Tue, 16 Jun 2015 23:13:00 +0000 (23:13 +0000)
committerRui Ueyama <ruiu@google.com>
Tue, 16 Jun 2015 23:13:00 +0000 (23:13 +0000)
llvm-svn: 239864

lld/COFF/Config.h
lld/COFF/Driver.cpp
lld/COFF/Writer.cpp
lld/test/COFF/options.test [new file with mode: 0644]

index d40fdaa..9fe5777 100644 (file)
@@ -51,6 +51,12 @@ public:
   uint32_t MinorImageVersion = 0;
   uint32_t MajorOSVersion = 6;
   uint32_t MinorOSVersion = 0;
+  bool DynamicBase = true;
+  bool HighEntropyVA = true;
+  bool AllowBind = true;
+  bool NxCompat = true;
+  bool AllowIsolation = true;
+  bool TerminalServerAware = true;
 };
 
 extern Configuration *Config;
index 8e74a65..b739ca9 100644 (file)
@@ -226,8 +226,14 @@ bool LinkerDriver::link(int Argc, const char *Argv[]) {
     Config->EntryName = Arg->getValue();
 
   // Handle /fixed
-  if (Args->hasArg(OPT_fixed))
+  if (Args->hasArg(OPT_fixed)) {
+    if (Args->hasArg(OPT_dynamicbase)) {
+      llvm::errs() << "/fixed must not be specified with /dynamicbase\n";
+      return false;
+    }
     Config->Relocatable = false;
+    Config->DynamicBase = false;
+  }
 
   // Handle /machine
   auto MTOrErr = getMachineType(Args.get());
@@ -318,6 +324,14 @@ bool LinkerDriver::link(int Argc, const char *Argv[]) {
     return false;
   }
 
+  // Handle miscellaneous boolean flags.
+  if (Args->hasArg(OPT_allowbind_no))      Config->AllowBind = false;
+  if (Args->hasArg(OPT_allowisolation_no)) Config->AllowIsolation = false;
+  if (Args->hasArg(OPT_dynamicbase_no))    Config->DynamicBase = false;
+  if (Args->hasArg(OPT_highentropyva_no))  Config->HighEntropyVA = false;
+  if (Args->hasArg(OPT_nxcompat_no))       Config->NxCompat = false;
+  if (Args->hasArg(OPT_tsaware_no))        Config->TerminalServerAware = false;
+
   // Create a list of input files. Files can be given as arguments
   // for /defaultlib option.
   std::vector<StringRef> InputPaths;
index 811e3b7..4e23677 100644 (file)
@@ -270,8 +270,18 @@ void Writer::writeHeader() {
   PE->SizeOfStackCommit = Config->StackCommit;
   PE->SizeOfHeapReserve = Config->HeapReserve;
   PE->SizeOfHeapCommit = Config->HeapCommit;
-  if (Config->Relocatable)
-    PE->DLLCharacteristics = IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE;
+  if (Config->DynamicBase)
+    PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE;
+  if (Config->HighEntropyVA)
+    PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA;
+  if (!Config->AllowBind)
+    PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_BIND;
+  if (Config->NxCompat)
+    PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NX_COMPAT;
+  if (!Config->AllowIsolation)
+    PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION;
+  if (Config->TerminalServerAware)
+    PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE;
   PE->NumberOfRvaAndSize = NumberfOfDataDirectory;
   if (OutputSection *Text = findSection(".text")) {
     PE->BaseOfCode = Text->getRVA();
diff --git a/lld/test/COFF/options.test b/lld/test/COFF/options.test
new file mode 100644 (file)
index 0000000..dfd884b
--- /dev/null
@@ -0,0 +1,51 @@
+# RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj
+
+# RUN: lld -flavor link /out:%t.exe %t.obj
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=BIND %s
+# RUN: lld -flavor link /allowbind /out:%t.exe %t.obj
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=BIND %s
+BIND-NOT: IMAGE_DLL_CHARACTERISTICS_NO_BIND
+
+# RUN: lld -flavor link /allowbind:no /out:%t.exe %t.obj
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NOBIND %s
+NOBIND: IMAGE_DLL_CHARACTERISTICS_NO_BIND
+
+# RUN: lld -flavor link /out:%t.exe %t.obj
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=ISO %s
+# RUN: lld -flavor link /allowisolation /out:%t.exe %t.obj
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=ISO %s
+ISO-NOT: IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION
+
+# RUN: lld -flavor link /allowisolation:no /out:%t.exe %t.obj
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NOISO %s
+NOISO: IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION
+
+# RUN: lld -flavor link /out:%t.exe %t.obj
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=ENT %s
+# RUN: lld -flavor link /highentropyva /out:%t.exe %t.obj
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=ENT %s
+ENT: IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA
+
+# RUN: lld -flavor link /highentropyva:no %t.obj
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NOENT %s
+NOENT-NOT: IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA
+
+# RUN: lld -flavor link %t.obj
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NXCOMPAT %s
+# RUN: lld -flavor link /nxcompat %t.obj
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NXCOMPAT %s
+NXCOMPAT: IMAGE_DLL_CHARACTERISTICS_NX_COMPAT
+
+# RUN: lld -flavor link /nxcompat:no %t.obj
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NONXCOMPAT %s
+NONXCOMPAT-NOT: IMAGE_DLL_CHARACTERISTICS_NX_COMPAT
+
+# RUN: lld -flavor link %t.obj
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=TSAWARE %s
+# RUN: lld -flavor link /tsaware %t.obj
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=TSAWARE %s
+TSAWARE: IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE
+
+# RUN: lld -flavor link /tsaware:no %t.obj
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NOTSAWARE %s
+NOTSAWARE-NOT: IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE