[lld] r221584 - [ELF] Support -z max-page-size option

Shankar Easwaran shankare at codeaurora.org
Mon Nov 10 06:54:43 PST 2014


Author: shankare
Date: Mon Nov 10 08:54:43 2014
New Revision: 221584

URL: http://llvm.org/viewvc/llvm-project?rev=221584&view=rev
Log:
[ELF] Support -z max-page-size option

The GNU linker allows the user to change the page size by using the option -z
max-page-size.

Modified:
    lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h
    lld/trunk/lib/Driver/GnuLdDriver.cpp
    lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp

Modified: lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h?rev=221584&r1=221583&r2=221584&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h Mon Nov 10 08:54:43 2014
@@ -58,7 +58,19 @@ public:
   };
 
   llvm::Triple getTriple() const { return _triple; }
-  virtual uint64_t getPageSize() const { return 0x1000; }
+
+  // Page size.
+  virtual uint64_t getPageSize() const {
+    if (_maxPageSizeOptionSet)
+      return _maxPageSize;
+    return 0x1000;
+  }
+  virtual void setMaxPageSize(uint64_t pagesize) {
+    _maxPageSize = pagesize;
+    _maxPageSizeOptionSet = true;
+  }
+  virtual uint64_t maxPageSize() const { return _maxPageSize; }
+
   OutputMagic getOutputMagic() const { return _outputMagic; }
   uint16_t getOutputELFType() const { return _outputELFType; }
   uint16_t getOutputMachine() const;
@@ -308,6 +320,9 @@ protected:
   bool _mergeRODataToTextSegment;
   bool _demangle;
   bool _alignSegments;
+  bool _maxPageSizeOptionSet;
+  uint64_t _maxPageSize;
+
   OutputMagic _outputMagic;
   StringRefVector _inputSearchPaths;
   std::unique_ptr<Writer> _writer;

Modified: lld/trunk/lib/Driver/GnuLdDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/GnuLdDriver.cpp?rev=221584&r1=221583&r2=221584&view=diff
==============================================================================
--- lld/trunk/lib/Driver/GnuLdDriver.cpp (original)
+++ lld/trunk/lib/Driver/GnuLdDriver.cpp Mon Nov 10 08:54:43 2014
@@ -15,6 +15,7 @@
 
 #include "lld/Driver/Driver.h"
 #include "lld/Driver/GnuLdInputGraph.h"
+#include "lld/Support/NumParse.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/STLExtras.h"
@@ -151,6 +152,22 @@ static bool parseDefsymAsAlias(StringRef
   return !target.empty();
 }
 
+// Parses dashz options for max-page-size.
+static bool parseZOption(StringRef opt, uint64_t &val) {
+  size_t equalPos = opt.find('=');
+  if (equalPos == 0 || equalPos == StringRef::npos)
+    return false;
+  StringRef value = opt.substr(equalPos + 1);
+  ErrorOr<uint64_t> parsedVal = lld::parseNum(value, false /*No Extensions*/);
+  if (!parsedVal)
+    return false;
+  // Dont allow a value of 0 for max-page-size.
+  val = parsedVal.get();
+  if (!val)
+    return false;
+  return true;
+}
+
 llvm::ErrorOr<StringRef> ELFFileNode::getPath(const LinkingContext &) const {
   if (_attributes._isDashlPrefix)
     return _elfLinkingContext.searchLibrary(_path);
@@ -471,7 +488,25 @@ bool GnuLdDriver::parse(int argc, const
       StringRef extOpt = inputArg->getValue();
       if (extOpt == "muldefs")
         ctx->setAllowDuplicates(true);
-      else
+      else if (extOpt.startswith("max-page-size")) {
+        // Parse -z max-page-size option.
+        // The default page size is considered the minimum page size the user
+        // can set, check the user input if its atleast the minimum page size
+        // and doesnot exceed the maximum page size allowed for the target.
+        uint64_t maxPageSize = 0;
+
+        // Error if the page size user set is less than the maximum page size
+        // and greather than the default page size and the user page size is a
+        // modulo of the default page size.
+        if ((!parseZOption(extOpt, maxPageSize)) ||
+            (maxPageSize < ctx->getPageSize()) ||
+            (maxPageSize > ctx->maxPageSize()) ||
+            (!maxPageSize % ctx->maxPageSize())) {
+          diagnostics << "invalid option: " << extOpt << "\n";
+          return false;
+        }
+        ctx->setMaxPageSize(maxPageSize);
+      } else
         diagnostics << "warning: ignoring unknown argument for -z: " << extOpt
                     << "\n";
       break;

Modified: lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp?rev=221584&r1=221583&r2=221584&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp Mon Nov 10 08:54:43 2014
@@ -62,7 +62,8 @@ ELFLinkingContext::ELFLinkingContext(
       _mergeCommonStrings(false), _runLayoutPass(true),
       _useShlibUndefines(true), _dynamicLinkerArg(false),
       _noAllowDynamicLibraries(false), _mergeRODataToTextSegment(true),
-      _demangle(true), _alignSegments(true), _outputMagic(OutputMagic::DEFAULT),
+      _demangle(true), _alignSegments(true), _maxPageSizeOptionSet(false),
+      _maxPageSize(0x10000), _outputMagic(OutputMagic::DEFAULT),
       _sysrootPath("") {}
 
 void ELFLinkingContext::addPasses(PassManager &pm) {





More information about the llvm-commits mailing list