ELF: Make .note.GNU-stack more compatible with traditional linkers.

With this patch, lld creates PT_GNU_STACK segments only when all input
files have .note.GNU-stack sections. This is in line with other linkers
with a minor difference (we don't care about .note.GNU-stack rwx bits as
you can always remove .note.GNU-stack sections instead of setting x bit.)

At least, NetBSD loader does not understand PT_GNU_STACK segments and
reject any executables that have the section. This patch makes lld
compatible with such operating systems.

llvm-svn: 253797
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index e3eeddd..8baf28c 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -63,7 +63,7 @@
   bool StripAll;
   bool SysvHash = true;
   bool Verbose;
-  bool ZExecStack;
+  bool ZExecStack = false;
   bool ZNodelete;
   bool ZNow;
   bool ZOrigin;
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index f1aaa5b..c76aa86 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -173,7 +173,6 @@
   Config->SoName = getString(Args, OPT_soname);
   Config->Sysroot = getString(Args, OPT_sysroot);
 
-  Config->ZExecStack = hasZOption(Args, "execstack");
   Config->ZNodelete = hasZOption(Args, "nodelete");
   Config->ZNow = hasZOption(Args, "now");
   Config->ZOrigin = hasZOption(Args, "origin");
@@ -277,6 +276,14 @@
   for (StringRef S : Config->Undefined)
     Symtab.addUndefinedOpt(S);
 
+  // "-z execstack" value is inferred from input object files (it's false
+  // if all input files have .note.GNU-stack section). Explicit options
+  // override the inferred default value.
+  if (hasZOption(Args, "execstack"))
+    Config->ZExecStack = true;
+  if (hasZOption(Args, "noexecstack"))
+    Config->ZExecStack = false;
+
   if (Config->OutputFile.empty())
     Config->OutputFile = "a.out";
 
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index deb5a65..9930f28 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -174,6 +174,7 @@
   uint64_t Size = this->ELFObj.getNumSections();
   Sections.resize(Size);
   unsigned I = -1;
+  bool HasGnuStack = false;
   const ELFFile<ELFT> &Obj = this->ELFObj;
   for (const Elf_Shdr &Sec : Obj.sections()) {
     ++I;
@@ -224,21 +225,25 @@
       }
       break;
     }
-    default: {
+    default:
       ErrorOr<StringRef> NameOrErr = this->ELFObj.getSectionName(&Sec);
       error(NameOrErr);
-      if (*NameOrErr == ".note.GNU-stack")
+      StringRef Name = *NameOrErr;
+      if (Name == ".note.GNU-stack") {
         Sections[I] = &InputSection<ELFT>::Discarded;
-      else if (*NameOrErr == ".eh_frame")
+        HasGnuStack = true;
+      } else if (Name == ".eh_frame") {
         Sections[I] = new (this->Alloc) EHInputSection<ELFT>(this, &Sec);
-      else if (shouldMerge<ELFT>(Sec))
+      } else if (shouldMerge<ELFT>(Sec)) {
         Sections[I] = new (this->Alloc) MergeInputSection<ELFT>(this, &Sec);
-      else
+      } else {
         Sections[I] = new (this->Alloc) InputSection<ELFT>(this, &Sec);
+      }
       break;
     }
-    }
   }
+  if (!HasGnuStack)
+    Config->ZExecStack = true;
 }
 
 template <class ELFT> void elf2::ObjectFile<ELFT>::initializeSymbols() {
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 98e9f24..a993fc2 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -881,10 +881,13 @@
     copyPhdr(PH, Out<ELFT>::Dynamic);
   }
 
-  Elf_Phdr *PH = &Phdrs[++PhdrIdx];
-  PH->p_type = PT_GNU_STACK;
-  PH->p_flags = Config->ZExecStack ? toPhdrFlags(SHF_WRITE | SHF_EXECINSTR)
-                                   : toPhdrFlags(SHF_WRITE);
+  // PT_GNU_STACK is a special section to tell the loader to make the
+  // pages for the stack non-executable.
+  if (!Config->ZExecStack) {
+    Elf_Phdr *PH = &Phdrs[++PhdrIdx];
+    PH->p_type = PT_GNU_STACK;
+    PH->p_flags = PF_R | PF_W;
+  }
 
   // Fix up PT_INTERP as we now know the address of .interp section.
   if (Interp) {
@@ -908,11 +911,13 @@
 // Returns the number of PHDR entries.
 template <class ELFT> int Writer<ELFT>::getPhdrsNum() const {
   bool Tls = false;
-  int I = 3; // 3 for PT_PHDR, first PT_LOAD and PT_GNU_STACK
+  int I = 2; // 2 for PT_PHDR and first PT_LOAD
   if (needsInterpSection())
     ++I;
   if (isOutputDynamic())
     ++I;
+  if (!Config->ZExecStack)
+    ++I;
   uintX_t Last = PF_R;
   for (OutputSectionBase<ELFT> *Sec : OutputSections) {
     if (!needsPhdr<ELFT>(Sec))