From c39307dcdf5ba4b2e29788934ea32be258cf05c5 Mon Sep 17 00:00:00 2001 From: Julian Seward Date: Sat, 30 Dec 2006 02:46:07 +0000 Subject: [PATCH] Support 64k pages on ppc32/64-linux (Jakub Jelink, Dave Nomura) git-svn-id: svn://svn.valgrind.org/valgrind/branches/VALGRIND_3_2_BRANCH@6457 --- coregrind/m_aspacemgr/aspacemgr.c | 3 +- coregrind/m_main.c | 31 +++++++++++++++++++ coregrind/m_replacemalloc/vg_replace_malloc.c | 6 +++- coregrind/m_syswrap/syswrap-ppc32-linux.c | 4 +-- coregrind/m_syswrap/syswrap-ppc64-linux.c | 4 +-- coregrind/m_syswrap/syswrap-x86-linux.c | 5 ++- coregrind/m_ume.c | 4 +-- coregrind/pub_core_aspacemgr.h | 9 ++++-- include/vki-amd64-linux.h | 2 ++ include/vki-ppc32-linux.h | 8 +++-- include/vki-ppc64-linux.h | 8 +++-- include/vki-x86-linux.h | 2 ++ 12 files changed, 69 insertions(+), 17 deletions(-) diff --git a/coregrind/m_aspacemgr/aspacemgr.c b/coregrind/m_aspacemgr/aspacemgr.c index c410deccb4..4c555ba7d2 100644 --- a/coregrind/m_aspacemgr/aspacemgr.c +++ b/coregrind/m_aspacemgr/aspacemgr.c @@ -443,8 +443,9 @@ 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. */ 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) res = VG_(do_syscall6)(__NR_mmap, (UWord)start, length, prot, flags, fd, offset); diff --git a/coregrind/m_main.c b/coregrind/m_main.c index 4bb7eea482..bb69553944 100644 --- a/coregrind/m_main.c +++ b/coregrind/m_main.c @@ -1672,6 +1672,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)); } } @@ -2033,6 +2038,9 @@ Int 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); clstack_top = VG_(am_startup)( sp_at_startup ); VG_(debugLog)(1, "main", "Address space manager is running\n"); @@ -2956,6 +2964,11 @@ asm("\n" #error "_start: needs implementation on this platform" #endif +#if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux) +unsigned long VKI_PAGE_SHIFT = 12; +unsigned long VKI_PAGE_SIZE = (1UL << 12); +#endif + /* Avoid compiler warnings: this fn _is_ used, but labelling it 'static' causes gcc to complain it isn't. */ void _start_in_C ( UWord* pArgc ); @@ -2966,6 +2979,24 @@ void _start_in_C ( UWord* pArgc ) HChar** argv = (HChar**)&pArgc[1]; HChar** envp = (HChar**)&pArgc[1+argc+1]; sp_at_startup = (Addr)pArgc; + +# if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux) + { + UWord *sp = &pArgc[1+argc+1]; + /* ppc/ppc64 can be configured with different page sizes. + Determine this early. */ + 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 = main( (Int)argc, argv, envp ); VG_(exit)(r); } diff --git a/coregrind/m_replacemalloc/vg_replace_malloc.c b/coregrind/m_replacemalloc/vg_replace_malloc.c index 4d1783c8c9..b7bc1ee28b 100644 --- a/coregrind/m_replacemalloc/vg_replace_malloc.c +++ b/coregrind/m_replacemalloc/vg_replace_malloc.c @@ -337,7 +337,11 @@ MEMALIGN(m_libc_dot_so_star, memalign); void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( SizeT size ); \ void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( SizeT size ) \ { \ - return VG_REPLACE_FUNCTION_ZU(libcZdsoZa,memalign)(VKI_PAGE_SIZE, size); \ + static int pszB = 0; \ + extern int getpagesize (void); \ + if (pszB == 0) \ + pszB = getpagesize(); \ + return VG_REPLACE_FUNCTION_ZU(libcZdsoZa,memalign)((SizeT)pszB, size); \ } VALLOC(m_libc_dot_so_star, valloc); diff --git a/coregrind/m_syswrap/syswrap-ppc32-linux.c b/coregrind/m_syswrap/syswrap-ppc32-linux.c index e1aca9b256..b0ac2bcca8 100644 --- a/coregrind/m_syswrap/syswrap-ppc32-linux.c +++ b/coregrind/m_syswrap/syswrap-ppc32-linux.c @@ -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); } diff --git a/coregrind/m_syswrap/syswrap-ppc64-linux.c b/coregrind/m_syswrap/syswrap-ppc64-linux.c index 06559e4e3d..9ec7ec07e1 100644 --- a/coregrind/m_syswrap/syswrap-ppc64-linux.c +++ b/coregrind/m_syswrap/syswrap-ppc64-linux.c @@ -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 diff --git a/coregrind/m_syswrap/syswrap-x86-linux.c b/coregrind/m_syswrap/syswrap-x86-linux.c index d7df31ac43..6b13eb7cd4 100644 --- a/coregrind/m_syswrap/syswrap-x86-linux.c +++ b/coregrind/m_syswrap/syswrap-x86-linux.c @@ -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); } diff --git a/coregrind/m_ume.c b/coregrind/m_ume.c index 8ec468f244..481a982bbb 100644 --- a/coregrind/m_ume.c +++ b/coregrind/m_ume.c @@ -553,7 +553,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; @@ -628,7 +628,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 diff --git a/coregrind/pub_core_aspacemgr.h b/coregrind/pub_core_aspacemgr.h index 62ab4640c3..a310b8e7bc 100644 --- a/coregrind/pub_core_aspacemgr.h +++ b/coregrind/pub_core_aspacemgr.h @@ -293,8 +293,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 .. 16 pages +# define VG_STACK_ACTIVE_SZB 131072 // 2 .. 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-amd64-linux.h b/include/vki-amd64-linux.h index 3bb9efd7d1..8e2d31df90 100644 --- a/include/vki-amd64-linux.h +++ b/include/vki-amd64-linux.h @@ -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 diff --git a/include/vki-ppc32-linux.h b/include/vki-ppc32-linux.h index 8e9afa4781..6fecd7c389 100644 --- a/include/vki-ppc32-linux.h +++ b/include/vki-ppc32-linux.h @@ -61,9 +61,11 @@ 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, VKI_PAGE_SIZE; +#define VKI_MAX_PAGE_SHIFT 16 +#define VKI_MAX_PAGE_SIZE (1UL << VKI_PAGE_SHIFT) //---------------------------------------------------------------------- // From linux-2.6.9/include/asm-ppc/signal.h diff --git a/include/vki-ppc64-linux.h b/include/vki-ppc64-linux.h index afb865e19e..b5c9974458 100644 --- a/include/vki-ppc64-linux.h +++ b/include/vki-ppc64-linux.h @@ -62,9 +62,11 @@ 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, VKI_PAGE_SIZE; +#define VKI_MAX_PAGE_SHIFT 16 +#define VKI_MAX_PAGE_SIZE (1UL << VKI_PAGE_SHIFT) //---------------------------------------------------------------------- // From linux-2.6.13/include/asm-ppc64/signal.h diff --git a/include/vki-x86-linux.h b/include/vki-x86-linux.h index a3686206da..5d81c710d9 100644 --- a/include/vki-x86-linux.h +++ b/include/vki-x86-linux.h @@ -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 -- 2.47.2