* New option --aspace-minaddr=<address> allows to (possibly) make
  use of some more memory by decreasing the default value
  or solve some conflicts with system libraries by increasing the value.
  See user manual for details.

Note that the lowest accepted possible value is 0x1000, which is
the current value used by Macos in 32bits.
On linux, 0x10000 (64KB) seems to cause not much conflicts.

Default values are unchanged (i.e. are the same as when there
was no clo option).



git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13901 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/NEWS b/NEWS
index a5be437..950d16e 100644
--- a/NEWS
+++ b/NEWS
@@ -34,6 +34,12 @@
   - A new monitor command "v.set hostvisibility" that allows GDB server
     to provide access to Valgrind internal host status/memory.
 
+* New option --aspace-minaddr=<address> allows to (possibly) make
+  use of some more memory by decreasing the default value above which
+  Valgrind maps memory or solve some conflicts with system libraries
+  by increasing the value.
+  See user manual for details.
+ 
 * ==================== FIXED BUGS ====================
 
 The following bugs have been fixed or resolved.  Note that "n-i-bz"
diff --git a/coregrind/m_aspacemgr/aspacemgr-linux.c b/coregrind/m_aspacemgr/aspacemgr-linux.c
index 1e5245b..2633f4f 100644
--- a/coregrind/m_aspacemgr/aspacemgr-linux.c
+++ b/coregrind/m_aspacemgr/aspacemgr-linux.c
@@ -105,6 +105,9 @@
      to some low-ish value at startup (64M) and aspacem_maxAddr is
      derived from the stack pointer at system startup.  This seems a
      reliable way to establish the initial boundaries.
+     A command line option allows to change the value of aspacem_minAddr,
+     so as to allow memory hungry applications to use the lowest
+     part of the memory.
 
      64-bit Linux is similar except for the important detail that the
      upper boundary is set to 64G.  The reason is so that all
@@ -316,6 +319,19 @@
 
 /* Limits etc */
 
+
+Addr VG_(clo_aspacem_minAddr)
+#if defined(VGO_darwin)
+# if VG_WORDSIZE == 4
+   = (Addr) 0x00001000;
+# else
+   = (Addr) 0x100000000;  // 4GB page zero
+# endif
+#else
+   = (Addr) 0x04000000; // 64M
+#endif
+
+
 // The smallest address that aspacem will try to allocate
 static Addr aspacem_minAddr = 0;
 
@@ -1629,16 +1645,16 @@
    nsegments[0]    = seg;
    nsegments_used  = 1;
 
+   aspacem_minAddr = VG_(clo_aspacem_minAddr);
+
 #if defined(VGO_darwin)
 
 # if VG_WORDSIZE == 4
-   aspacem_minAddr = (Addr) 0x00001000;
    aspacem_maxAddr = (Addr) 0xffffffff;
 
    aspacem_cStart = aspacem_minAddr;
    aspacem_vStart = 0xf0000000;  // 0xc0000000..0xf0000000 available
 # else
-   aspacem_minAddr = (Addr) 0x100000000;  // 4GB page zero
    aspacem_maxAddr = (Addr) 0x7fffffffffff;
 
    aspacem_cStart = aspacem_minAddr;
@@ -1657,8 +1673,6 @@
                     "        sp_at_startup = 0x%010llx (supplied)\n", 
                     (ULong)sp_at_startup );
 
-   aspacem_minAddr = (Addr) 0x04000000; // 64M
-
 #  if VG_WORDSIZE == 8
      aspacem_maxAddr = (Addr)0x1000000000ULL - 1; // 64G
 #    ifdef ENABLE_INNER
@@ -1671,7 +1685,7 @@
      aspacem_maxAddr = VG_PGROUNDDN( sp_at_startup ) - 1;
 #  endif
 
-   aspacem_cStart = aspacem_minAddr; // 64M
+   aspacem_cStart = aspacem_minAddr;
    aspacem_vStart = VG_PGROUNDUP(aspacem_minAddr 
                                  + (aspacem_maxAddr - aspacem_minAddr + 1) / 2);
 #  ifdef ENABLE_INNER
diff --git a/coregrind/m_main.c b/coregrind/m_main.c
index 51ff326..ee83a22 100644
--- a/coregrind/m_main.c
+++ b/coregrind/m_main.c
@@ -179,6 +179,7 @@
 "           program counters in max <number> frames) [0]\n"
 "    --num-transtab-sectors=<number> size of translated code cache [%d]\n"
 "           more sectors may increase performance, but use more memory.\n"
+"    --aspace-minaddr=0xPP     avoid mapping memory below 0xPP [guessed]\n"
 "    --show-emwarns=no|yes     show warnings about emulation limits? [no]\n"
 "    --require-text-symbol=:sonamepattern:symbolpattern    abort run if the\n"
 "                              stated shared object doesn't have the stated\n"
@@ -493,10 +494,11 @@
       else if VG_STREQ(     arg, "-d")                   {}
       else if VG_STREQN(17, arg, "--max-stackframe=")    {}
       else if VG_STREQN(17, arg, "--main-stacksize=")    {}
-      else if VG_STREQN(12, arg,  "--sim-hints=")        {}
+      else if VG_STREQN(12, arg, "--sim-hints=")         {}
       else if VG_STREQN(15, arg, "--profile-heap=")      {}
       else if VG_STREQN(20, arg, "--core-redzone-size=") {}
       else if VG_STREQN(15, arg, "--redzone-size=")      {}
+      else if VG_STREQN(17, arg, "--aspace-minaddr=")    {}
 
       /* Obsolete options. Report an error and exit */
       else if VG_STREQN(34, arg, "--vex-iropt-precise-memory-exns=no") {
@@ -1542,10 +1544,12 @@
    //--------------------------------------------------------------
    /* Start the debugging-log system ASAP.  First find out how many 
       "-d"s were specified.  This is a pre-scan of the command line.  Also
-      get --profile-heap=yes, --core-redzone-size, --redzone-size which are
-      needed by the time we start up dynamic memory management.  */
+      get --profile-heap=yes, --core-redzone-size, --redzone-size
+      --aspace-minaddr which are needed by the time we start up dynamic
+      memory management.  */
    loglevel = 0;
    for (i = 1; i < argc; i++) {
+      const HChar* tmp_str;
       if (argv[i][0] != '-') break;
       if VG_STREQ(argv[i], "--") break;
       if VG_STREQ(argv[i], "-d") loglevel++;
@@ -1554,6 +1558,23 @@
                      0, MAX_CLO_REDZONE_SZB) {}
       if VG_BINT_CLO(argv[i], "--redzone-size", VG_(clo_redzone_size),
                      0, MAX_CLO_REDZONE_SZB) {}
+      if VG_STR_CLO(argv[i], "--aspace-minaddr", tmp_str) {
+#        if VG_WORDSIZE == 4
+         const Addr max = (Addr) 0x40000000; // 1Gb
+#        else
+         const Addr max = (Addr) 0x200000000; // 8Gb
+#        endif
+         Bool ok = VG_(parse_Addr) (&tmp_str, &VG_(clo_aspacem_minAddr));
+         if (!ok)
+            VG_(fmsg_bad_option)(argv[i], "Invalid address\n");
+
+         if (!VG_IS_PAGE_ALIGNED(VG_(clo_aspacem_minAddr))
+             || VG_(clo_aspacem_minAddr) < (Addr) 0x1000
+             || VG_(clo_aspacem_minAddr) > max) // 1Gb
+            VG_(fmsg_bad_option)(argv[i], 
+                                 "Must be a page aligned address between "
+                                 "0x1000 and 0x%lx\n", max);
+      }
    }
 
    /* ... and start the debug logger.  Now we can safely emit logging
diff --git a/coregrind/pub_core_options.h b/coregrind/pub_core_options.h
index 83eef25..0f56a63 100644
--- a/coregrind/pub_core_options.h
+++ b/coregrind/pub_core_options.h
@@ -297,6 +297,10 @@
 /* Max number of sectors that will be used by the translation code cache. */
 extern UInt VG_(clo_num_transtab_sectors);
 
+/* Only client requested fixed mapping can be done below 
+   VG_(clo_aspacem_minAddr). */
+extern Addr VG_(clo_aspacem_minAddr);
+
 /* Delay startup to allow GDB to be attached?  Default: NO */
 extern Bool VG_(clo_wait_for_gdb);
 
diff --git a/docs/xml/manual-core.xml b/docs/xml/manual-core.xml
index dda3cfa..c7f8e1a 100644
--- a/docs/xml/manual-core.xml
+++ b/docs/xml/manual-core.xml
@@ -2062,6 +2062,35 @@
    </listitem>
   </varlistentry>
 
+  <varlistentry id="opt.aspace-minaddr" xreflabel="----aspace-minaddr">
+    <term>
+      <option><![CDATA[--aspace-minaddr=<address> [default: depends
+      on the platform] ]]></option>
+    </term>
+    <listitem>
+      <para>To avoid potential conflicts with some system libraries,
+      Valgrind does not use the address space
+      below <option>--aspace-minaddr</option> value, keeping it
+      reserved in case a library specifically requests memory in this
+      region.  So, some "pessimistic" value is guessed by Valgrind
+      depending on the platform. On linux, by default, Valgrind avoids
+      using the first 64MB even if typically there is no conflict in
+      this complete zone.  You can use the
+      option <option>--aspace-minaddr</option> to have your memory
+      hungry application benefitting from more of this lower memory.
+      On the other hand, if you encounter a conflict, increasing
+      aspace-minaddr value might solve it. Conflicts will typically
+      manifest themselves with mmap failures in the low range of the
+      address space. The
+      provided <computeroutput>address</computeroutput> must be page
+      aligned and must be equal or bigger to 0x1000 (4KB). To find the
+      default value on your platform, do something such as
+      <computeroutput>valgrind -d -d date 2&gt;&amp;1 | grep -i minaddr</computeroutput>. Values lower than 0x10000 (64KB) are known to create problems
+      on some distributions.
+      </para>
+   </listitem>
+  </varlistentry>
+
   <varlistentry id="opt.show-emwarns" xreflabel="--show-emwarns">
     <term>
       <option><![CDATA[--show-emwarns=<yes|no> [default: no] ]]></option>
diff --git a/none/tests/cmdline1.stdout.exp b/none/tests/cmdline1.stdout.exp
index 0bdd5e6..35cfea1 100644
--- a/none/tests/cmdline1.stdout.exp
+++ b/none/tests/cmdline1.stdout.exp
@@ -92,6 +92,7 @@
            program counters in max <number> frames) [0]
     --num-transtab-sectors=<number> size of translated code cache [16]
            more sectors may increase performance, but use more memory.
+    --aspace-minaddr=0xPP     avoid mapping memory below 0xPP [guessed]
     --show-emwarns=no|yes     show warnings about emulation limits? [no]
     --require-text-symbol=:sonamepattern:symbolpattern    abort run if the
                               stated shared object doesn't have the stated
diff --git a/none/tests/cmdline2.stdout.exp b/none/tests/cmdline2.stdout.exp
index bc47f1e..956a51c 100644
--- a/none/tests/cmdline2.stdout.exp
+++ b/none/tests/cmdline2.stdout.exp
@@ -92,6 +92,7 @@
            program counters in max <number> frames) [0]
     --num-transtab-sectors=<number> size of translated code cache [16]
            more sectors may increase performance, but use more memory.
+    --aspace-minaddr=0xPP     avoid mapping memory below 0xPP [guessed]
     --show-emwarns=no|yes     show warnings about emulation limits? [no]
     --require-text-symbol=:sonamepattern:symbolpattern    abort run if the
                               stated shared object doesn't have the stated