[PATH] Change how MachOLinkingContext initializes defaults

Joe Ranieri joe at alacatialabs.com
Tue Nov 26 18:22:01 PST 2013


Currently MachOLinkingContext::validateImpl tries to detect invalid
values and also set default values for things that the user has not
explicitly set. The attached patch splits out initialization into its
own function should be called once the file type, operating system,
and architecture are all known. Later calls to the MachOLinkingContext
by the driver (or users of the library) can overwrite these values and
validateImp doesn't have to perform any guessing games.

-- Joe Ranieri
-------------- next part --------------
diff --git a/include/lld/ReaderWriter/MachOLinkingContext.h b/include/lld/ReaderWriter/MachOLinkingContext.h
index a26ddc1..dde8b50 100644
--- a/include/lld/ReaderWriter/MachOLinkingContext.h
+++ b/include/lld/ReaderWriter/MachOLinkingContext.h
@@ -29,6 +29,10 @@ class MachOLinkingContext : public LinkingContext {
 public:
   MachOLinkingContext();
   ~MachOLinkingContext();
+  
+  /// Initializes the context to sane default values given the current output
+  /// file type, arch, os, and minimum os version.
+  void initialize();
 
   virtual void addPasses(PassManager &pm);
   virtual ErrorOr<Reference::Kind> relocKindFromString(StringRef str) const;
diff --git a/lib/Driver/DarwinLdDriver.cpp b/lib/Driver/DarwinLdDriver.cpp
index c6c7c81..f7ad286 100644
--- a/lib/Driver/DarwinLdDriver.cpp
+++ b/lib/Driver/DarwinLdDriver.cpp
@@ -128,6 +128,51 @@ bool DarwinLdDriver::parse(int argc, const char *argv[],
     }
   }
 
+  // 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
+  }
+  
+  // Now that there's enough information parsed in, let the linking context
+  // set up default values.
+  ctx.initialize();
+
   // Handle -e xxx
   if (llvm::opt::Arg *entry = parsedArgs->getLastArg(OPT_entry))
     ctx.setEntrySymbolName(entry->getValue());
@@ -185,47 +230,6 @@ bool DarwinLdDriver::parse(int argc, const char *argv[],
   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);
diff --git a/lib/ReaderWriter/MachO/MachOLinkingContext.cpp b/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
index f5dc5c7..6c5ca10 100644
--- a/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
+++ b/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
@@ -121,6 +121,39 @@ MachOLinkingContext::MachOLinkingContext()
 
 MachOLinkingContext::~MachOLinkingContext() {}
 
+void MachOLinkingContext::initialize() {
+  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);
 }
@@ -218,29 +251,8 @@ bool MachOLinkingContext::addUnixThreadLoadCommand() const {
 }
 
 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;


More information about the llvm-commits mailing list