[lld] r197851 - [mach-o] add MachOLinkingContext::configure(type, arch, os)

Nick Kledzik kledzik at apple.com
Fri Dec 20 17:47:17 PST 2013


Author: kledzik
Date: Fri Dec 20 19:47:17 2013
New Revision: 197851

URL: http://llvm.org/viewvc/llvm-project?rev=197851&view=rev
Log:
[mach-o] add MachOLinkingContext::configure(type, arch, os)

It will configure resonable defaults for other settings in the 
MachOLinkingContext object based on the parameters.  

Patch by Joe Ranieri

Modified:
    lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h
    lld/trunk/lib/Driver/DarwinLdDriver.cpp
    lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp

Modified: lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h?rev=197851&r1=197850&r2=197851&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h Fri Dec 20 19:47:17 2013
@@ -30,6 +30,28 @@ public:
   MachOLinkingContext();
   ~MachOLinkingContext();
 
+  enum Arch {
+    arch_unknown,
+    arch_ppc,
+    arch_x86,
+    arch_x86_64,
+    arch_armv6,
+    arch_armv7,
+    arch_armv7s,
+  };
+
+  enum class OS {
+    unknown,
+    macOSX,
+    iOS,
+    iOS_simulator
+  };
+
+  /// Initializes the context to sane default values given the specified output
+  /// file type, arch, os, and minimum os version.  This should be called before
+  /// other setXXX() methods.
+  void configure(HeaderFileType type, Arch arch, OS os, uint32_t minOSVersion);
+
   virtual void addPasses(PassManager &pm);
   virtual bool validateImpl(raw_ostream &diagnostics);
 
@@ -48,27 +70,10 @@ public:
 
   HeaderFileType outputFileType() const { return _outputFileType; }
 
-  enum Arch {
-    arch_unknown,
-    arch_ppc,
-    arch_x86,
-    arch_x86_64,
-    arch_armv6,
-    arch_armv7,
-    arch_armv7s,
-  };
-
-  enum class OS {
-    unknown, macOSX, iOS, iOS_simulator
-  };
-
   Arch arch() const { return _arch; }
   StringRef archName() const { return nameFromArch(_arch); }
   OS os() const { return _os; }
 
-  void setOutputFileType(HeaderFileType type) { _outputFileType = type; }
-  void setArch(Arch arch) { _arch = arch; }
-  bool setOS(OS os, StringRef minOSVersion);
   bool minOS(StringRef mac, StringRef iOS) const;
   void setDoNothing(bool value) { _doNothing = value; }
   bool doNothing() const { return _doNothing; }
@@ -145,7 +150,6 @@ private:
   };
 
   static ArchInfo _s_archInfos[];
-  static const uint64_t unspecifiedPageZeroSize = UINT64_MAX;
 
   HeaderFileType _outputFileType;   // e.g MH_EXECUTE
   bool _outputFileTypeStatic; // Disambiguate static vs dynamic prog

Modified: lld/trunk/lib/Driver/DarwinLdDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/DarwinLdDriver.cpp?rev=197851&r1=197850&r2=197851&view=diff
==============================================================================
--- lld/trunk/lib/Driver/DarwinLdDriver.cpp (original)
+++ lld/trunk/lib/Driver/DarwinLdDriver.cpp Fri Dec 20 19:47:17 2013
@@ -111,30 +111,79 @@ bool DarwinLdDriver::parse(int argc, con
   }
 
   // Figure out output kind ( -dylib, -r, -bundle, -preload, or -static )
+  llvm::MachO::HeaderFileType fileType = llvm::MachO::MH_EXECUTE;
   if ( llvm::opt::Arg *kind = parsedArgs->getLastArg(OPT_dylib, OPT_relocatable,
                                       OPT_bundle, OPT_static, OPT_preload)) {
     switch (kind->getOption().getID()) {
     case OPT_dylib:
-      ctx.setOutputFileType(llvm::MachO::MH_DYLIB);
-      ctx.setGlobalsAreDeadStripRoots(true);
+      fileType = llvm::MachO::MH_DYLIB;
       break;
     case OPT_relocatable:
-      ctx.setPrintRemainingUndefines(false);
-      ctx.setAllowRemainingUndefines(true);
-      ctx.setOutputFileType(llvm::MachO::MH_OBJECT);
+      fileType = llvm::MachO::MH_OBJECT;
       break;
     case OPT_bundle:
-      ctx.setOutputFileType(llvm::MachO::MH_BUNDLE);
+      fileType = llvm::MachO::MH_BUNDLE;
       break;
     case OPT_static:
-      ctx.setOutputFileType(llvm::MachO::MH_EXECUTE);
+      fileType = llvm::MachO::MH_EXECUTE;
       break;
     case OPT_preload:
-      ctx.setOutputFileType(llvm::MachO::MH_PRELOAD);
+      fileType = llvm::MachO::MH_PRELOAD;
       break;
     }
   }
 
+  // Handle -arch xxx
+  MachOLinkingContext::Arch arch = MachOLinkingContext::arch_unknown;
+  if (llvm::opt::Arg *archStr = parsedArgs->getLastArg(OPT_arch)) {
+    arch = MachOLinkingContext::archFromName(archStr->getValue());
+    if (arch == MachOLinkingContext::arch_unknown) {
+      diagnostics << "error: unknown arch named '" << archStr->getValue()
+                  << "'\n";
+      return false;
+    }
+  }
+
+  // Handle -macosx_version_min or -ios_version_min
+  MachOLinkingContext::OS os = MachOLinkingContext::OS::macOSX;
+  uint32_t minOSVersion = 0;
+  if (llvm::opt::Arg *minOS =
+          parsedArgs->getLastArg(OPT_macosx_version_min, OPT_ios_version_min,
+                                 OPT_ios_simulator_version_min)) {
+    switch (minOS->getOption().getID()) {
+    case OPT_macosx_version_min:
+      os = MachOLinkingContext::OS::macOSX;
+      if (MachOLinkingContext::parsePackedVersion(minOS->getValue(),
+                                                  minOSVersion)) {
+        diagnostics << "error: malformed macosx_version_min value\n";
+        return false;
+      }
+      break;
+    case OPT_ios_version_min:
+      os = MachOLinkingContext::OS::iOS;
+      if (MachOLinkingContext::parsePackedVersion(minOS->getValue(),
+                                                  minOSVersion)) {
+        diagnostics << "error: malformed ios_version_min value\n";
+        return false;
+      }
+      break;
+    case OPT_ios_simulator_version_min:
+      os = MachOLinkingContext::OS::iOS_simulator;
+      if (MachOLinkingContext::parsePackedVersion(minOS->getValue(),
+                                                  minOSVersion)) {
+        diagnostics << "error: malformed ios_simulator_version_min value\n";
+        return false;
+      }
+      break;
+    }
+  } else {
+    // No min-os version on command line, check environment variables
+  }
+
+  // Now that there's enough information parsed in, let the linking context
+  // set up default values.
+  ctx.configure(fileType, arch, os, minOSVersion);
+
   // Handle -e xxx
   if (llvm::opt::Arg *entry = parsedArgs->getLastArg(OPT_entry))
     ctx.setEntrySymbolName(entry->getValue());
@@ -192,47 +241,6 @@ bool DarwinLdDriver::parse(int argc, con
   if (llvm::opt::Arg *loader = parsedArgs->getLastArg(OPT_bundle_loader))
     ctx.setBundleLoader(loader->getValue());
 
-  // Handle -arch xxx
-  if (llvm::opt::Arg *archStr = parsedArgs->getLastArg(OPT_arch)) {
-    ctx.setArch(MachOLinkingContext::archFromName(archStr->getValue()));
-    if (ctx.arch() == MachOLinkingContext::arch_unknown) {
-      diagnostics << "error: unknown arch named '" << archStr->getValue()
-                  << "'\n";
-      return false;
-    }
-  }
-
-  // Handle -macosx_version_min or -ios_version_min
-  if (llvm::opt::Arg *minOS = parsedArgs->getLastArg(
-                                               OPT_macosx_version_min,
-                                               OPT_ios_version_min,
-                                               OPT_ios_simulator_version_min)) {
-    switch (minOS->getOption().getID()) {
-    case OPT_macosx_version_min:
-      if (ctx.setOS(MachOLinkingContext::OS::macOSX, minOS->getValue())) {
-        diagnostics << "error: malformed macosx_version_min value\n";
-        return false;
-      }
-      break;
-    case OPT_ios_version_min:
-      if (ctx.setOS(MachOLinkingContext::OS::iOS, minOS->getValue())) {
-        diagnostics << "error: malformed ios_version_min value\n";
-        return false;
-      }
-      break;
-    case OPT_ios_simulator_version_min:
-      if (ctx.setOS(MachOLinkingContext::OS::iOS_simulator,
-                    minOS->getValue())) {
-        diagnostics << "error: malformed ios_simulator_version_min value\n";
-        return false;
-      }
-      break;
-    }
-  }
-  else {
-    // No min-os version on command line, check environment variables
-  }
-
   // Handle -help
   if (parsedArgs->getLastArg(OPT_help)) {
     table.PrintHelp(llvm::outs(), argv[0], "LLVM Darwin Linker", false);

Modified: lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp?rev=197851&r1=197850&r2=197851&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp Fri Dec 20 19:47:17 2013
@@ -121,13 +121,50 @@ uint32_t MachOLinkingContext::cpuSubtype
 MachOLinkingContext::MachOLinkingContext()
     : _outputFileType(MH_EXECUTE), _outputFileTypeStatic(false),
       _doNothing(false), _arch(arch_unknown), _os(OS::macOSX), _osMinVersion(0),
-      _pageZeroSize(unspecifiedPageZeroSize), 
-      _pageSize(4096), 
-      _compatibilityVersion(0), _currentVersion(0),
-      _deadStrippableDylib(false), _kindHandler(nullptr) {}
+      _pageZeroSize(0), _pageSize(4096), _compatibilityVersion(0),
+      _currentVersion(0), _deadStrippableDylib(false), _kindHandler(nullptr) {}
 
 MachOLinkingContext::~MachOLinkingContext() {}
 
+void MachOLinkingContext::configure(HeaderFileType type, Arch arch, OS os,
+                                    uint32_t minOSVersion) {
+  _outputFileType = type;
+  _arch = arch;
+  _os = os;
+  _osMinVersion = minOSVersion;
+
+  switch (_outputFileType) {
+  case llvm::MachO::MH_EXECUTE:
+    // If targeting newer OS, use _main
+    if (minOS("10.8", "6.0")) {
+      _entrySymbolName = "_main";
+    } else {
+      // If targeting older OS, use start (in crt1.o)
+      _entrySymbolName = "start";
+    }
+
+    // __PAGEZERO defaults to 4GB on 64-bit (except for PP64 which lld does not
+    // support) and 4KB on 32-bit.
+    if (is64Bit(_arch)) {
+      _pageZeroSize = 0x100000000;
+    } else {
+      _pageZeroSize = 0x1000;
+    }
+
+    break;
+  case llvm::MachO::MH_DYLIB:
+    _globalsAreDeadStripRoots = true;
+    break;
+  case llvm::MachO::MH_BUNDLE:
+    break;
+  case llvm::MachO::MH_OBJECT:
+    _printRemainingUndefines = false;
+    _allowRemainingUndefines = true;
+  default:
+    break;
+  }
+}
+
 uint32_t MachOLinkingContext::getCPUType() const {
   return cpuTypeFromArch(_arch);
 }
@@ -225,29 +262,8 @@ bool MachOLinkingContext::addUnixThreadL
 }
 
 bool MachOLinkingContext::validateImpl(raw_ostream &diagnostics) {
-  if ((_outputFileType == MH_EXECUTE) && _entrySymbolName.empty()){
-    if (_outputFileTypeStatic) {
-      _entrySymbolName = "start";
-    } else if (addUnixThreadLoadCommand()) {
-      // If targeting older OS, use start (in crt1.o)
-      _entrySymbolName = "start";
-    } else if (addEntryPointLoadCommand()) {
-      // If targeting newer OS, use _main
-      _entrySymbolName = "_main";
-    }
-  }
-
   // TODO: if -arch not specified, look at arch of first .o file.
 
-  // Set default __PAGEZERO for main executables
-  if ((_outputFileType == MH_EXECUTE) && !_outputFileTypeStatic
-                                && (_pageZeroSize == unspecifiedPageZeroSize)) {
-    if (is64Bit(_arch))
-      _pageZeroSize = 0x100000000;
-    else
-      _pageZeroSize = 0x00010000;
-  }
-
   if (_currentVersion && _outputFileType != MH_DYLIB) {
     diagnostics << "error: -current_version can only be used with dylibs\n";
     return false;
@@ -274,11 +290,6 @@ bool MachOLinkingContext::validateImpl(r
   return true;
 }
 
-bool MachOLinkingContext::setOS(OS os, StringRef minOSVersion) {
-  _os = os;
-  return parsePackedVersion(minOSVersion, _osMinVersion);
-}
-
 void MachOLinkingContext::addPasses(PassManager &pm) {
   if (outputFileType() != MH_OBJECT) {
     pm.add(std::unique_ptr<Pass>(new mach_o::GOTPass));





More information about the llvm-commits mailing list