From patchwork Mon Apr 4 17:56:50 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rainer Orth X-Patchwork-Id: 89671 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id C3490B6F91 for ; Tue, 5 Apr 2011 03:57:02 +1000 (EST) Received: (qmail 29080 invoked by alias); 4 Apr 2011 17:57:01 -0000 Received: (qmail 29071 invoked by uid 22791); 4 Apr 2011 17:57:00 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL, BAYES_00, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from snape.CeBiTec.Uni-Bielefeld.DE (HELO smtp-relay.CeBiTec.Uni-Bielefeld.DE) (129.70.160.84) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 04 Apr 2011 17:56:55 +0000 Received: from localhost (localhost.CeBiTec.Uni-Bielefeld.DE [127.0.0.1]) by smtp-relay.CeBiTec.Uni-Bielefeld.DE (Postfix) with ESMTP id 58273B2E; Mon, 4 Apr 2011 19:56:54 +0200 (CEST) Received: from smtp-relay.CeBiTec.Uni-Bielefeld.DE ([127.0.0.1]) by localhost (malfoy.CeBiTec.Uni-Bielefeld.DE [127.0.0.1]) (amavisd-new, port 10024) with LMTP id puRd9ufVdkNO; Mon, 4 Apr 2011 19:56:51 +0200 (CEST) Received: from manam.CeBiTec.Uni-Bielefeld.DE (manam.CeBiTec.Uni-Bielefeld.DE [129.70.161.120]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp-relay.CeBiTec.Uni-Bielefeld.DE (Postfix) with ESMTPS id 6E878B2D; Mon, 4 Apr 2011 19:56:51 +0200 (CEST) Received: (from ro@localhost) by manam.CeBiTec.Uni-Bielefeld.DE (8.14.4+Sun/8.14.4/Submit) id p34HupeE021982; Mon, 4 Apr 2011 19:56:51 +0200 (MEST) From: Rainer Orth To: gcc-patches@gcc.gnu.org Cc: Ian Lance Taylor Subject: [libgo] Account for mmap ignoring addr arg without MAP_FIXED (PR go/48240) Date: Mon, 04 Apr 2011 19:56:50 +0200 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.3 (usg-unix-v) MIME-Version: 1.0 X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org As I had suspected, all the go and libgo testsuite failures on 64-bit Solaris 10 were caused by mmap ignoring the addr argument without MAP_FIXED. That's the same problem already solved in gcc/config/host-solaris.c. The following code is inspired from mmap_fixed() there. If this turns out to be a license problem again (although iterating over an address space range page by page is as obvious as it gets), I could recode it along the lines of gcc/config/alpha/host-osf.c (mmap_fixed), but using /proc/self/map and the corresponding ioctl instead. This code is mine (unlike the host-solaris.c one which originated with rth), so I'm free to relicense as I please. It's unfortunately far longer and harder to read, but that might be the price to pay ;-( Bootstrapped on i386-pc-solaris2.11 (where it is unnecessary since mmap honors addr if possible) and i386-pc-solaris2.10 (where it's required for the 64-bit tests). There are several panic: runtime error: invalid memory address or nil pointer dereference for 64-bit Solaris 10 libgo tests, but all the 64-bit go tests pass there, so the fundamental problem is gone. Rainer 2011-04-02 Rainer Orth PR go/48240 * configure.ac: Check for mincore. * configure: Regenerate. * config.h.in: Regenerate. * runtime/mem.c: Include unistd.h. (addrspace_free): New function. (runtime_SysMap): Retry 64-bit runtime_mmap with MAP_FIXED. diff --git a/libgo/configure.ac b/libgo/configure.ac --- a/libgo/configure.ac +++ b/libgo/configure.ac @@ -429,7 +429,7 @@ esac AC_CHECK_HEADERS(sys/mman.h syscall.h sys/epoll.h sys/ptrace.h sys/syscall.h sys/user.h sys/utsname.h) AM_CONDITIONAL(HAVE_SYS_MMAN_H, test "$ac_cv_header_sys_mman_h" = yes) -AC_CHECK_FUNCS(srandom random strerror_r strsignal wait4) +AC_CHECK_FUNCS(srandom random strerror_r strsignal wait4 mincore) AM_CONDITIONAL(HAVE_STRERROR_R, test "$ac_cv_func_strerror_r" = yes) AM_CONDITIONAL(HAVE_WAIT4, test "$ac_cv_func_wait4" = yes) diff --git a/libgo/runtime/mem.c b/libgo/runtime/mem.c --- a/libgo/runtime/mem.c +++ b/libgo/runtime/mem.c @@ -1,4 +1,5 @@ #include +#include #include "runtime.h" #include "malloc.h" @@ -16,6 +17,23 @@ static int dev_zero = -1; #endif +static _Bool +addrspace_free(void *v __attribute__ ((unused)), uintptr n __attribute__ ((unused))) +{ +#ifdef HAVE_MINCORE + size_t page_size = getpagesize(); + size_t off; + char one_byte; + + errno = 0; + for(off = 0; off < n; off += page_size) + if(mincore((char *)v + off, page_size, (char *)&one_byte) != -1 + || errno != ENOMEM) + return 0; +#endif + return 1; +} + void* runtime_SysAlloc(uintptr n) { @@ -109,7 +127,12 @@ runtime_SysMap(void *v, uintptr n) // On 64-bit, we don't actually have v reserved, so tread carefully. if(sizeof(void*) == 8) { p = runtime_mmap(v, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, fd, 0); - if(p != v) { + if(p != v && addrspace_free(v, n)) { + // On some systems, mmap ignores v without + // MAP_FIXED, so retry if the address space is free. + p = runtime_mmap(v, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_FIXED|MAP_PRIVATE, fd, 0); + } + if (p != v) { runtime_printf("runtime: address space conflict: map(%p) = %p\n", v, p); runtime_throw("runtime: address space conflict"); }