[lld] r217408 - [mach-o] Add support for -pie and -no_pie

Nick Kledzik kledzik at apple.com
Mon Sep 8 17:17:52 PDT 2014


Author: kledzik
Date: Mon Sep  8 19:17:52 2014
New Revision: 217408

URL: http://llvm.org/viewvc/llvm-project?rev=217408&view=rev
Log:
[mach-o] Add support for -pie and -no_pie

There is a bit (MH_PIE) in the flags field of the mach_header which tells
the kernel is a program was built position independent (for ASLR).  The linker
automatically attempts to build programs PIE if they are built for a recent
OS version.  But the -pie and -no_pie options override that default behavior.

Added:
    lld/trunk/test/mach-o/PIE.yaml
Modified:
    lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h
    lld/trunk/lib/Driver/DarwinLdDriver.cpp
    lld/trunk/lib/Driver/DarwinLdOptions.td
    lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
    lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp

Modified: lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h?rev=217408&r1=217407&r2=217408&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h Mon Sep  8 19:17:52 2014
@@ -104,6 +104,8 @@ public:
   const StringRefVector &frameworkDirs() const { return _frameworkDirs; }
   void setSysLibRoots(const StringRefVector &paths);
   const StringRefVector &sysLibRoots() const { return _syslibRoots; }
+  bool PIE() const { return _pie; }
+  void setPIE(bool pie) { _pie = pie; }
 
   /// \brief Checks whether a given path on the filesystem exists.
   ///
@@ -266,6 +268,7 @@ private:
   HeaderFileType _outputMachOType;   // e.g MH_EXECUTE
   bool _outputMachOTypeStatic; // Disambiguate static vs dynamic prog
   bool _doNothing;            // for -help and -v which just print info
+  bool _pie;
   Arch _arch;
   OS _os;
   uint32_t _osMinVersion;

Modified: lld/trunk/lib/Driver/DarwinLdDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/DarwinLdDriver.cpp?rev=217408&r1=217407&r2=217408&view=diff
==============================================================================
--- lld/trunk/lib/Driver/DarwinLdDriver.cpp (original)
+++ lld/trunk/lib/Driver/DarwinLdDriver.cpp Mon Sep  8 19:17:52 2014
@@ -544,6 +544,52 @@ bool DarwinLdDriver::parse(int argc, con
     }
   }
 
+  // Handle -pie or -no_pie
+  if (llvm::opt::Arg *pie = parsedArgs->getLastArg(OPT_pie, OPT_no_pie)) {
+    switch (ctx.outputMachOType()) {
+    case llvm::MachO::MH_EXECUTE:
+      switch (ctx.os()) {
+      case MachOLinkingContext::OS::macOSX:
+        if ((minOSVersion < 0x000A0500) &&
+            (pie->getOption().getID() == OPT_pie)) {
+          diagnostics << "-pie can only be used when targeting "
+                         "Mac OS X 10.5 or later\n";
+          return false;
+        }
+        break;
+      case MachOLinkingContext::OS::iOS:
+        if ((minOSVersion < 0x00040200) &&
+            (pie->getOption().getID() == OPT_pie)) {
+          diagnostics << "-pie can only be used when targeting "
+                         "iOS 4.2 or later\n";
+          return false;
+        }
+        break;
+      case MachOLinkingContext::OS::iOS_simulator:
+        if (pie->getOption().getID() == OPT_no_pie)
+          diagnostics << "iOS simulator programs must be built PIE\n";
+          return false;
+        break;
+      case MachOLinkingContext::OS::unknown:
+        break;
+      }
+      ctx.setPIE(pie->getOption().getID() == OPT_pie);
+      break;
+    case llvm::MachO::MH_PRELOAD:
+      break;
+    case llvm::MachO::MH_DYLIB:
+    case llvm::MachO::MH_BUNDLE:
+      diagnostics << "warning: " << pie->getSpelling() << " being ignored. "
+                  << "It is only used when linking main executables\n";
+      break;
+    default:
+      diagnostics << pie->getSpelling()
+                  << " can only used when linking main executables\n";
+      return false;
+      break;
+    }
+  }
+
   // Handle input files
   for (auto &arg : *parsedArgs) {
     ErrorOr<StringRef> resolvedPath = StringRef();

Modified: lld/trunk/lib/Driver/DarwinLdOptions.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/DarwinLdOptions.td?rev=217408&r1=217407&r2=217408&view=diff
==============================================================================
--- lld/trunk/lib/Driver/DarwinLdOptions.td (original)
+++ lld/trunk/lib/Driver/DarwinLdOptions.td Mon Sep  8 19:17:52 2014
@@ -55,6 +55,12 @@ def grp_main : OptionGroup<"opts">, Help
 def entry : Separate<["-"], "e">,
      MetaVarName<"<entry-name>">,
      HelpText<"entry symbol name">,Group<grp_main>;
+def pie : Flag<["-"], "pie">,
+     HelpText<"Create Position Independent Executable (for ASLR)">,
+     Group<grp_main>;
+def no_pie : Flag<["-"], "no_pie">,
+     HelpText<"Do not create Position Independent Executable">,
+     Group<grp_main>;
 
 // dylib executable options
 def grp_dylib : OptionGroup<"opts">, HelpText<"DYLIB EXECUTABLE OPTIONS">;

Modified: lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp?rev=217408&r1=217407&r2=217408&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp Mon Sep  8 19:17:52 2014
@@ -132,7 +132,8 @@ bool MachOLinkingContext::isThinObjectFi
 
 MachOLinkingContext::MachOLinkingContext()
     : _outputMachOType(MH_EXECUTE), _outputMachOTypeStatic(false),
-      _doNothing(false), _arch(arch_unknown), _os(OS::macOSX), _osMinVersion(0),
+      _doNothing(false), _pie(false),
+      _arch(arch_unknown), _os(OS::macOSX), _osMinVersion(0),
       _pageZeroSize(0), _pageSize(4096), _compatibilityVersion(0),
       _currentVersion(0), _deadStrippableDylib(false), _printAtoms(false),
       _testingFileUsage(false), _keepPrivateExterns(false),
@@ -165,6 +166,22 @@ void MachOLinkingContext::configure(Head
       _pageZeroSize = 0x1000;
     }
 
+    // Make PIE by default when targetting newer OSs.
+    switch (os) {
+      case OS::macOSX:
+        if (minOSVersion >= 0x000A0700) // MacOSX 10.7
+          _pie = true;
+        break;
+      case OS::iOS:
+        if (minOSVersion >= 0x00040300) // iOS 4.3
+          _pie = true;
+       break;
+       case OS::iOS_simulator:
+        _pie = true;
+       break;
+       case OS::unknown:
+       break;
+    }
     break;
   case llvm::MachO::MH_DYLIB:
     _globalsAreDeadStripRoots = true;

Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp?rev=217408&r1=217407&r2=217408&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp Mon Sep  8 19:17:52 2014
@@ -1120,7 +1120,10 @@ uint32_t Util::fileFlags() {
   if (_context.outputMachOType() == MH_OBJECT) {
     return MH_SUBSECTIONS_VIA_SYMBOLS;
   } else {
-    return MH_DYLDLINK | MH_NOUNDEFS | MH_TWOLEVEL;
+    if ((_context.outputMachOType() == MH_EXECUTE) && _context.PIE())
+      return MH_DYLDLINK | MH_NOUNDEFS | MH_TWOLEVEL | MH_PIE;
+    else
+      return MH_DYLDLINK | MH_NOUNDEFS | MH_TWOLEVEL;
   }
 }
 

Added: lld/trunk/test/mach-o/PIE.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/PIE.yaml?rev=217408&view=auto
==============================================================================
--- lld/trunk/test/mach-o/PIE.yaml (added)
+++ lld/trunk/test/mach-o/PIE.yaml Mon Sep  8 19:17:52 2014
@@ -0,0 +1,44 @@
+# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t  && \
+# RUN: llvm-objdump -macho -private-headers %t | FileCheck %s
+#
+# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -pie -o %t\
+# RUN:  &&  llvm-objdump -macho -private-headers %t | FileCheck %s
+#
+# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -no_pie -o %t\
+# RUN:  &&  llvm-objdump -macho -private-headers %t \
+# RUN:  | FileCheck --check-prefix=CHECK_NO_PIE %s
+#
+# Test various PIE options.
+#
+
+--- !mach-o
+arch:            x86_64
+file-type:       MH_OBJECT
+flags:           [ MH_SUBSECTIONS_VIA_SYMBOLS ]
+has-UUID:        false
+OS:              unknown
+sections:
+  - segment:         __TEXT
+    section:         __text
+    type:            S_REGULAR
+    attributes:      [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
+    address:         0x0000000000000000
+    content:         [ 0xC3 ]
+global-symbols:
+  - name:            _main
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            1
+    value:           0x0000000000000000
+
+--- !mach-o
+arch:            x86_64
+file-type:       MH_DYLIB
+install-name:    /usr/lib/libSystem.B.dylib
+exports:
+  - name:            dyld_stub_binder
+
+...
+
+# CHECK:	          MH_MAGIC_64 {{[0-9a-zA-Z _]+}} TWOLEVEL PIE
+# CHECK_NO_PIE-NOT:	MH_MAGIC_64 {{[0-9a-zA-Z _]+}} TWOLEVEL PIE





More information about the llvm-commits mailing list