]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Merge (from 3_2_BRANCH) r6457/8 (Support 64k pages on ppc32/64-linux
authorJulian Seward <jseward@acm.org>
Sat, 30 Dec 2006 17:45:08 +0000 (17:45 +0000)
committerJulian Seward <jseward@acm.org>
Sat, 30 Dec 2006 17:45:08 +0000 (17:45 +0000)
(Jakub Jelink, Dave Nomura) )

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@6459

15 files changed:
coregrind/m_aspacemgr/aspacemgr-common.c
coregrind/m_main.c
coregrind/m_replacemalloc/vg_replace_malloc.c
coregrind/m_syswrap/syswrap-ppc32-linux.c
coregrind/m_syswrap/syswrap-ppc64-linux.c
coregrind/m_syswrap/syswrap-x86-linux.c
coregrind/m_ume.c
coregrind/m_vki.c
coregrind/pub_core_aspacemgr.h
include/vki/vki-amd64-linux.h
include/vki/vki-ppc32-linux.h
include/vki/vki-ppc64-linux.h
include/vki/vki-x86-linux.h
memcheck/tests/memalign_test.c
memcheck/tests/memalign_test.stderr.exp

index 42355dd9d6ddeaeec91b5f46bfa8fac2f8196e3c..f422864b688a75cb6e66578e90e290183a8c3c55 100644 (file)
@@ -151,8 +151,10 @@ SysRes VG_(am_do_mmap_NO_NOTIFY)( Addr start, SizeT length, UInt prot,
    SysRes res;
    aspacem_assert(VG_IS_PAGE_ALIGNED(offset));
 #  if defined(VGP_x86_linux) || defined(VGP_ppc32_linux)
+   /* mmap2 uses 4096 chunks even if actual page size is bigger. */
+   aspacem_assert((offset % 4096) == 0);
    res = VG_(do_syscall6)(__NR_mmap2, (UWord)start, length,
-                          prot, flags, fd, offset / VKI_PAGE_SIZE);
+                          prot, flags, fd, offset / 4096);
 #  elif defined(VGP_amd64_linux) || defined(VGP_ppc64_linux) \
         || defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
    res = VG_(do_syscall6)(__NR_mmap, (UWord)start, length, 
index 7aba9e68bc7df19e9eefb0dc94fedc06fff9c66a..4b267cdcd67b2aee63fc9a8ec216c834408526a1 100644 (file)
@@ -895,6 +895,11 @@ static void print_preamble(Bool logging_to_fd, const char* toolname)
          LibVEX_ppVexArch   ( vex_arch ),
          LibVEX_ppVexHwCaps ( vex_arch, vex_archinfo.hwcaps )
       );
+      VG_(message)(
+         Vg_DebugMsg, 
+         "Page sizes: currently %d, max supported %d\n", 
+         (Int)VKI_PAGE_SIZE, (Int)VKI_MAX_PAGE_SIZE
+      );
       VG_(message)(Vg_DebugMsg, "Valgrind library directory: %s", VG_(libdir));
    }
 }
@@ -1256,6 +1261,11 @@ Int valgrind_main ( Int argc, HChar **argv, HChar **envp )
    //   p: logging, plausible-stack
    //--------------------------------------------------------------
    VG_(debugLog)(1, "main", "Starting the address space manager\n");
+   vg_assert(VKI_PAGE_SIZE     == 4096 || VKI_PAGE_SIZE     == 65536);
+   vg_assert(VKI_MAX_PAGE_SIZE == 4096 || VKI_MAX_PAGE_SIZE == 65536);
+   vg_assert(VKI_PAGE_SIZE <= VKI_MAX_PAGE_SIZE);
+   vg_assert(VKI_PAGE_SIZE     == (1 << VKI_PAGE_SHIFT));
+   vg_assert(VKI_MAX_PAGE_SIZE == (1 << VKI_MAX_PAGE_SHIFT));
    the_iicii.clstack_top = VG_(am_startup)( the_iicii.sp_at_startup );
    VG_(debugLog)(1, "main", "Address space manager is running\n");
 
@@ -2249,6 +2259,13 @@ asm("\n"
 #error "_start: needs implementation on this platform"
 #endif
 
+/* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
+#define _GNU_SOURCE
+#define _FILE_OFFSET_BITS 64
+/* This is in order to get AT_NULL and AT_PAGESIZE. */
+#include <elf.h>
+/* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
+
 /* Avoid compiler warnings: this fn _is_ used, but labelling it
    'static' causes gcc to complain it isn't. */
 void _start_in_C_linux ( UWord* pArgc );
@@ -2264,6 +2281,25 @@ void _start_in_C_linux ( UWord* pArgc )
 
    the_iicii.sp_at_startup = (Addr)pArgc;
 
+#  if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
+   {
+      /* ppc/ppc64 can be configured with different page sizes.
+         Determine this early.  This is an ugly hack and really should
+         be moved into valgrind_main. */
+      UWord *sp = &pArgc[1+argc+1];
+      while (*sp++ != 0)
+         ;
+      for (; *sp != AT_NULL && *sp != AT_PAGESZ; sp += 2);
+      if (*sp == AT_PAGESZ) {
+         VKI_PAGE_SIZE = sp[1];
+         for (VKI_PAGE_SHIFT = 12;
+              VKI_PAGE_SHIFT <= VKI_MAX_PAGE_SHIFT; VKI_PAGE_SHIFT++)
+            if (VKI_PAGE_SIZE == (1UL << VKI_PAGE_SHIFT))
+         break;
+      }
+   }
+#  endif
+
    r = valgrind_main( (Int)argc, argv, envp );
    /* NOTREACHED */
    VG_(exit)(r);
index 95ba9cc26b27d948bd1ae2f28a50e5a4764fe386..0a8e6be26472a4c4a16838aa1a40171dfb5f4cac 100644 (file)
@@ -45,7 +45,7 @@
    ------------------------------------------------------------------ */
 
 #include "pub_core_basics.h"
-#include "pub_core_vki.h"           // VKI_EINVAL, VKI_ENOMEM, VKI_PAGE_SIZE
+#include "pub_core_vki.h"           // VKI_EINVAL, VKI_ENOMEM
 #include "pub_core_clreq.h"         // for VALGRIND_INTERNAL_PRINTF,
                                     //   VALGRIND_NON_SIMD_CALL[12]
 #include "pub_core_debuginfo.h"     // needed for pub_core_redir.h :(
@@ -455,7 +455,12 @@ MEMALIGN(m_libc_soname, memalign);
    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( SizeT size ); \
    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( SizeT size )  \
    { \
-      return VG_REPLACE_FUNCTION_ZU(m_libc_soname,memalign)(VKI_PAGE_SIZE, size); \
+      static int pszB = 0; \
+      extern int getpagesize (void); \
+      if (pszB == 0) \
+         pszB = getpagesize(); \
+      return VG_REPLACE_FUNCTION_ZU(m_libc_soname,memalign) \
+                ((SizeT)pszB, size); \
    }
 
 VALLOC(m_libc_soname, valloc);
index 4f2d416c77889eee2c8bc6fe9f3d63680a715fa3..f7fd293ca84be5760a48f064eb15db409641c946 100644 (file)
@@ -673,7 +673,7 @@ PRE(sys_mmap2)
    SysRes r;
 
    // Exactly like old_mmap() except:
-   //  - the file offset is specified in pagesize units rather than bytes,
+   //  - the file offset is specified in 4K units rather than bytes,
    //    so that it can be used for files bigger than 2^32 bytes.
    PRINT("sys_mmap2 ( %p, %llu, %d, %d, %d, %d )",
          ARG1, (ULong)ARG2, ARG3, ARG4, ARG5, ARG6 );
@@ -683,7 +683,7 @@ PRE(sys_mmap2)
                  unsigned long, fd,    unsigned long, offset);
 
    r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5, 
-                                       VKI_PAGE_SIZE * (Off64T)ARG6 );
+                                       4096 * (Off64T)ARG6 );
    SET_STATUS_from_SysRes(r);
 }
 
index 8350daadd536779e446ec39808d8b635ef6cee0b..c9b78d5ae788ba70fab66fee483e02de39b569be 100644 (file)
@@ -701,7 +701,7 @@ PRE(sys_mmap)
 //zz    SysRes r;
 //zz 
 //zz    // Exactly like old_mmap() except:
-//zz    //  - the file offset is specified in pagesize units rather than bytes,
+//zz    //  - the file offset is specified in 4K units rather than bytes,
 //zz    //    so that it can be used for files bigger than 2^32 bytes.
 //zz    PRINT("sys_mmap2 ( %p, %llu, %d, %d, %d, %d )",
 //zz          ARG1, (ULong)ARG2, ARG3, ARG4, ARG5, ARG6 );
@@ -711,7 +711,7 @@ PRE(sys_mmap)
 //zz                  unsigned long, fd,    unsigned long, offset);
 //zz 
 //zz    r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5, 
-//zz                                        VKI_PAGE_SIZE * (Off64T)ARG6 );
+//zz                                        4096 * (Off64T)ARG6 );
 //zz    SET_STATUS_from_SysRes(r);
 //zz }
 //zz 
index 1980d87502e4b4b46563bb2f436db7ca05f07d1c..a5d239cb48799e1a19555484341867b8c7dd80a8 100644 (file)
@@ -1300,6 +1300,9 @@ PRE(sys_mmap2)
    //  - all 6 args are passed in regs, rather than in a memory-block.
    //  - the file offset is specified in pagesize units rather than bytes,
    //    so that it can be used for files bigger than 2^32 bytes.
+   // pagesize or 4K-size units in offset?  For ppc32/64-linux, this is
+   // 4K-sized.  Assert that the page size is 4K here for safety.
+   vg_assert(VKI_PAGE_SIZE == 4096);
    PRINT("sys_mmap2 ( %p, %llu, %d, %d, %d, %d )",
          ARG1, (ULong)ARG2, ARG3, ARG4, ARG5, ARG6 );
    PRE_REG_READ6(long, "mmap2",
@@ -1308,7 +1311,7 @@ PRE(sys_mmap2)
                  unsigned long, fd,    unsigned long, offset);
 
    r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5, 
-                                       VKI_PAGE_SIZE * (Off64T)ARG6 );
+                                       4096 * (Off64T)ARG6 );
    SET_STATUS_from_SysRes(r);
 }
 
index 380727d94a1cd6d3b8ce72b5238c5dafd270ed1f..339bf606841302457f9161335c99fe8c1c724c20 100644 (file)
@@ -565,7 +565,7 @@ static Int do_exec_inner(const HChar* exe, ExeInfo* info);
 /* returns: 0 = success, non-0 is failure */
 static Int load_script(Int fd, const HChar* name, ExeInfo* info)
 {
-   Char  hdr[VKI_PAGE_SIZE];
+   Char  hdr[VKI_MAX_PAGE_SIZE];
    Int   len = VKI_PAGE_SIZE;
    Int   eol;
    Char* interp;
@@ -640,7 +640,7 @@ SysRes VG_(pre_exec_check)(const HChar* exe_name, Int* out_fd)
 {
    Int fd, ret;
    SysRes res;
-   Char  buf[VKI_PAGE_SIZE];
+   Char  buf[VKI_MAX_PAGE_SIZE];
    SizeT bufsz = VKI_PAGE_SIZE, fsz;
 
    // Check it's readable
index 7cd88e7aaefc4a3e35bb14776d6a48a9b6c941ce..80357469cdbed4d31ce82e8f2dde9a27049ed62a 100644 (file)
 /* We have pub_{core,tool}_vki.h.  This is the matching implementation
    for that interface.  In fact there is no implementation, as the
    sole purpose of the module is to export types and constants
-   describing the kernel interface, so this file is empty. */
+   describing the kernel interface, so this file is nearly empty. */
+
+
+/* ppc32/64-linux determines page size at startup, hence m_vki is
+   the logical place to store that info. */
+
+#if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
+unsigned long VKI_PAGE_SHIFT = 12;
+unsigned long VKI_PAGE_SIZE  = 1UL << 12;
+#endif
 
 
 /*--------------------------------------------------------------------*/
index 63a65867d80f851993db162534b7b98142cd561c..13aa9c93c96cbc0141ea7886887c0d9411b4c7aa 100644 (file)
@@ -368,8 +368,13 @@ extern Bool VG_(am_relocate_nooverlap_client)( /*OUT*/Bool* need_discard,
 // stacks.  The address space manager provides and suitably
 // protects such stacks.
 
-#define VG_STACK_GUARD_SZB  8192   // 2 pages
-#define VG_STACK_ACTIVE_SZB 65536  // 16 pages
+#if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
+# define VG_STACK_GUARD_SZB  65536  // 1 or 16 pages
+# define VG_STACK_ACTIVE_SZB 131072 // 2 or 32 pages
+#else
+# define VG_STACK_GUARD_SZB  8192   // 2 pages
+# define VG_STACK_ACTIVE_SZB 65536  // 16 pages
+#endif
 
 typedef
    struct {
index 3bb9efd7d13cde38d7beffda7938977dc22cae61..8e2d31df9057db2112b54616ba90b85e31092021 100644 (file)
@@ -59,6 +59,8 @@ typedef unsigned int vki_u32;
 
 #define VKI_PAGE_SHIFT 12
 #define VKI_PAGE_SIZE  (1UL << VKI_PAGE_SHIFT)
+#define VKI_MAX_PAGE_SHIFT     VKI_PAGE_SHIFT
+#define VKI_MAX_PAGE_SIZE      VKI_PAGE_SIZE
 
 //----------------------------------------------------------------------
 // From linux-2.6.9/include/asm-x86_64/signal.h
index 827e13268eb5f60863a11dff8acf9df8c1cee8b0..1155980cc8af645e64979937de11f4468117a856 100644 (file)
@@ -61,9 +61,12 @@ typedef struct {
 // From linux-2.6.9/include/asm-ppc/page.h
 //----------------------------------------------------------------------
 
-/* PAGE_SHIFT determines the page size */
-#define VKI_PAGE_SHIFT 12
-#define VKI_PAGE_SIZE  (1UL << VKI_PAGE_SHIFT)
+/* PAGE_SHIFT determines the page size, unfortunately
+   page size might vary between 32-bit and 64-bit ppc kernels */
+extern unsigned long VKI_PAGE_SHIFT;
+extern unsigned long VKI_PAGE_SIZE;
+#define VKI_MAX_PAGE_SHIFT     16
+#define VKI_MAX_PAGE_SIZE      (1UL << VKI_MAX_PAGE_SHIFT)
 
 //----------------------------------------------------------------------
 // From linux-2.6.9/include/asm-ppc/signal.h
index 4f1882bad3089cad85d8fcfd69ea9125467a49bc..7fc7aeed450351e2aabc3d7439b5ae1c79d89815 100644 (file)
@@ -62,9 +62,12 @@ typedef unsigned int vki_u32;
 // From linux-2.6.13/include/asm-ppc64/page.h
 //----------------------------------------------------------------------
 
-/* PAGE_SHIFT determines the page size */
-#define VKI_PAGE_SHIFT  12
-#define VKI_PAGE_SIZE   (1UL << VKI_PAGE_SHIFT)
+/* PAGE_SHIFT determines the page size, unfortunately
+   page size might vary between 32-bit and 64-bit ppc kernels */
+extern unsigned long VKI_PAGE_SHIFT;
+extern unsigned long VKI_PAGE_SIZE;
+#define VKI_MAX_PAGE_SHIFT     16
+#define VKI_MAX_PAGE_SIZE      (1UL << VKI_MAX_PAGE_SHIFT)
 
 //----------------------------------------------------------------------
 // From linux-2.6.13/include/asm-ppc64/signal.h
index a3686206dac3ac25089051bdfd1dd81b6e6498a5..5d81c710d9bfd373d8ad55567c869299af6c2203 100644 (file)
@@ -60,6 +60,8 @@ typedef unsigned int vki_u32;
 /* PAGE_SHIFT determines the page size */
 #define VKI_PAGE_SHIFT 12
 #define VKI_PAGE_SIZE  (1UL << VKI_PAGE_SHIFT)
+#define VKI_MAX_PAGE_SHIFT     VKI_PAGE_SHIFT
+#define VKI_MAX_PAGE_SIZE      VKI_PAGE_SIZE
 
 //----------------------------------------------------------------------
 // From linux-2.6.8.1/include/asm-i386/signal.h
index a24808c55aea5e3122c1d4ba875b365267c34c38..a9c8784cc8f1f57022d33fe7a251459ef7c2e4fe 100644 (file)
@@ -1,13 +1,21 @@
 
 #include <stdlib.h>
 #include <stdio.h>
+#include <unistd.h>
+#include <assert.h>
 
 int main ( void )
 {
   void* a[10];
   int i;
+  unsigned long pszB = sysconf(_SC_PAGE_SIZE);
+  assert(sizeof(long) == sizeof(void*));
+  assert(pszB == 4096 || pszB == 65536);
+
   for (i = 0; i < 10; i++) {
     a[i] = valloc(11111 * (i+1));
+    /* check valloc really is returning page-aligned memory */
+    assert( (((unsigned long)(a[i])) % pszB) == 0 );
     //    printf("I acquire %p\n", a[i]);
   }
   for (i = 0; i < 10; i++) {
index 4eb281cdb2e75f4c6930b4115e9093a28209d0dc..461980d803b6c0a355e34873d6883869f1f1bb66 100644 (file)
@@ -1,6 +1,6 @@
 Invalid free() / delete / delete[]
    at 0x........: free (vg_replace_malloc.c:...)
-   by 0x........: main (memalign_test.c:17)
+   by 0x........: main (memalign_test.c:25)
  Address 0x........ is 0 bytes inside a block of size 111,110 free'd
    at 0x........: free (vg_replace_malloc.c:...)
-   by 0x........: main (memalign_test.c:15)
+   by 0x........: main (memalign_test.c:23)