Merge (from 3_2_BRANCH) r6457/8 (Support 64k pages on ppc32/64-linux
(Jakub Jelink, Dave Nomura) )
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@6459 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/m_aspacemgr/aspacemgr-common.c b/coregrind/m_aspacemgr/aspacemgr-common.c
index 42355dd..f422864 100644
--- a/coregrind/m_aspacemgr/aspacemgr-common.c
+++ b/coregrind/m_aspacemgr/aspacemgr-common.c
@@ -151,8 +151,10 @@
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,
diff --git a/coregrind/m_main.c b/coregrind/m_main.c
index 7aba9e6..4b267cd 100644
--- a/coregrind/m_main.c
+++ b/coregrind/m_main.c
@@ -895,6 +895,11 @@
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 @@
// 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 @@
#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 @@
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);
diff --git a/coregrind/m_replacemalloc/vg_replace_malloc.c b/coregrind/m_replacemalloc/vg_replace_malloc.c
index 95ba9cc..0a8e6be 100644
--- a/coregrind/m_replacemalloc/vg_replace_malloc.c
+++ b/coregrind/m_replacemalloc/vg_replace_malloc.c
@@ -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 @@
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);
diff --git a/coregrind/m_syswrap/syswrap-ppc32-linux.c b/coregrind/m_syswrap/syswrap-ppc32-linux.c
index 4f2d416..f7fd293 100644
--- a/coregrind/m_syswrap/syswrap-ppc32-linux.c
+++ b/coregrind/m_syswrap/syswrap-ppc32-linux.c
@@ -673,7 +673,7 @@
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 @@
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);
}
diff --git a/coregrind/m_syswrap/syswrap-ppc64-linux.c b/coregrind/m_syswrap/syswrap-ppc64-linux.c
index 8350daa..c9b78d5 100644
--- a/coregrind/m_syswrap/syswrap-ppc64-linux.c
+++ b/coregrind/m_syswrap/syswrap-ppc64-linux.c
@@ -701,7 +701,7 @@
//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 @@
//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
diff --git a/coregrind/m_syswrap/syswrap-x86-linux.c b/coregrind/m_syswrap/syswrap-x86-linux.c
index 1980d87..a5d239c 100644
--- a/coregrind/m_syswrap/syswrap-x86-linux.c
+++ b/coregrind/m_syswrap/syswrap-x86-linux.c
@@ -1300,6 +1300,9 @@
// - 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 @@
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);
}
diff --git a/coregrind/m_ume.c b/coregrind/m_ume.c
index 380727d..339bf60 100644
--- a/coregrind/m_ume.c
+++ b/coregrind/m_ume.c
@@ -565,7 +565,7 @@
/* 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 @@
{
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
diff --git a/coregrind/m_vki.c b/coregrind/m_vki.c
index 7cd88e7..8035746 100644
--- a/coregrind/m_vki.c
+++ b/coregrind/m_vki.c
@@ -35,7 +35,16 @@
/* 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
/*--------------------------------------------------------------------*/
diff --git a/coregrind/pub_core_aspacemgr.h b/coregrind/pub_core_aspacemgr.h
index 63a6586..13aa9c9 100644
--- a/coregrind/pub_core_aspacemgr.h
+++ b/coregrind/pub_core_aspacemgr.h
@@ -368,8 +368,13 @@
// 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 {
diff --git a/include/vki/vki-amd64-linux.h b/include/vki/vki-amd64-linux.h
index 3bb9efd..8e2d31d 100644
--- a/include/vki/vki-amd64-linux.h
+++ b/include/vki/vki-amd64-linux.h
@@ -59,6 +59,8 @@
#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
diff --git a/include/vki/vki-ppc32-linux.h b/include/vki/vki-ppc32-linux.h
index 827e132..1155980 100644
--- a/include/vki/vki-ppc32-linux.h
+++ b/include/vki/vki-ppc32-linux.h
@@ -61,9 +61,12 @@
// 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
diff --git a/include/vki/vki-ppc64-linux.h b/include/vki/vki-ppc64-linux.h
index 4f1882b..7fc7aee 100644
--- a/include/vki/vki-ppc64-linux.h
+++ b/include/vki/vki-ppc64-linux.h
@@ -62,9 +62,12 @@
// 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
diff --git a/include/vki/vki-x86-linux.h b/include/vki/vki-x86-linux.h
index a368620..5d81c71 100644
--- a/include/vki/vki-x86-linux.h
+++ b/include/vki/vki-x86-linux.h
@@ -60,6 +60,8 @@
/* 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
diff --git a/memcheck/tests/memalign_test.c b/memcheck/tests/memalign_test.c
index a24808c..a9c8784 100644
--- a/memcheck/tests/memalign_test.c
+++ b/memcheck/tests/memalign_test.c
@@ -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++) {
diff --git a/memcheck/tests/memalign_test.stderr.exp b/memcheck/tests/memalign_test.stderr.exp
index 4eb281c..461980d 100644
--- a/memcheck/tests/memalign_test.stderr.exp
+++ b/memcheck/tests/memalign_test.stderr.exp
@@ -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)