From owner-freebsd-current@FreeBSD.ORG Sat Sep 11 18:00:16 2004 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 660B516A4CE; Sat, 11 Sep 2004 18:00:16 +0000 (GMT) Received: from green.homeunix.org (pcp04368961pcs.nrockv01.md.comcast.net [69.140.212.7]) by mx1.FreeBSD.org (Postfix) with ESMTP id 6AD5043D49; Sat, 11 Sep 2004 18:00:14 +0000 (GMT) (envelope-from green@green.homeunix.org) Received: from green.homeunix.org (green@localhost [127.0.0.1]) by green.homeunix.org (8.13.1/8.13.1) with ESMTP id i8BI05PC021435; Sat, 11 Sep 2004 14:00:05 -0400 (EDT) (envelope-from green@green.homeunix.org) Received: (from green@localhost) by green.homeunix.org (8.13.1/8.13.1/Submit) id i8BI008L021434; Sat, 11 Sep 2004 14:00:00 -0400 (EDT) (envelope-from green) Date: Sat, 11 Sep 2004 14:00:00 -0400 From: Brian Fundakowski Feldman To: Anish Mistry Message-ID: <20040911180000.GX928@green.homeunix.org> References: <47158390.20040827112834@ulstu.ru> <200409060149.35764.mistry.7@osu.edu> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <200409060149.35764.mistry.7@osu.edu> User-Agent: Mutt/1.5.6i cc: Alan Cox cc: anvir@ulstu.ru cc: Gerald Pfeifer cc: freebsd-current@freebsd.org Subject: Re: Wine and mmap X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 11 Sep 2004 18:00:16 -0000 On Mon, Sep 06, 2004 at 01:49:35AM -0400, Anish Mistry wrote: > On Sunday 05 September 2004 05:15 pm, Gerald Pfeifer wrote: > > [ John, sorry for the duplicate message; this is the correct one. ] > > > > On Fri, 27 Aug 2004, John Birrell wrote: > > > Anish Mistry has developed a patch to choose an > > > appropriate mmap address. He posted it to -current. I haven't had time to > > > test it. > > > > Thanks for the note. Will you have time to test/commit this before 5.3? > > > > Anish, do you have any news on this patch? (Wine has been broken for a > > couple of months now, and it would be great to have at least 5.3 fixed.) > > > Well I guess this is my lucky day. Apply the attached patch for vm_mmap to > your kernel and patch the August wine sources with the wine-mmap.patch and > compile and install wine (be sure to use gmake). This is working on my dev > system with 6-CURRENT as of Saturday night. > The wine mmap patch just doesn't reserve the DOS area so DOS programs may not > work. This seems to just work around a side effect of the kernel mmap patch. > I still think that the kernel mmap patch has issues so I'm hoping Alan can > give us some feedback. > Anyway this worked for me, YMMV. Do these combined work for you, minus any modifications to mmap(2)? I do not feel that the kernel mmap(2) should be modified in this manner, that it is a strictly userland problem. Index: lib/libpthread/thread/thr_stack.c =================================================================== RCS file: /usr/ncvs/src/lib/libpthread/thread/thr_stack.c,v retrieving revision 1.8 diff -u -r1.8 thr_stack.c --- lib/libpthread/thread/thr_stack.c 14 Sep 2003 22:39:44 -0000 1.8 +++ lib/libpthread/thread/thr_stack.c 11 Sep 2004 17:17:32 -0000 @@ -61,7 +61,7 @@ * Base address of the last stack allocated (including its red zone, if * there is one). Stacks are allocated contiguously, starting beyond the * top of the main stack. When a new stack is created, a red zone is - * typically created (actually, the red zone is simply left unmapped) above + * typically created (actually, the red zone is mapped with PROT_NONE) above * the top of the stack, such that the stack will not be able to grow all * the way to the bottom of the next stack. This isn't fool-proof. It is * possible for a stack to grow by a large amount, such that it grows into @@ -134,6 +134,7 @@ kse_critical_t crit; size_t stacksize; size_t guardsize; + char *stackaddr; /* * Round up stack size to nearest multiple of _thr_page_size so @@ -194,7 +195,7 @@ _thr_guard_default; /* Allocate a new stack. */ - attr->stackaddr_attr = last_stack - stacksize; + stackaddr = last_stack - stacksize - guardsize; /* * Even if stack allocation fails, we don't want to try to @@ -209,11 +210,20 @@ KSE_LOCK_RELEASE(curkse, &_thread_list_lock); _kse_critical_leave(crit); - /* Map the stack, but not the guard page: */ - if ((attr->stackaddr_attr = mmap(attr->stackaddr_attr, - stacksize, PROT_READ | PROT_WRITE, MAP_STACK, - -1, 0)) == MAP_FAILED) - attr->stackaddr_attr = NULL; + /* Map the stack and guard page together, and split guard + page from allocated space: */ + if ((stackaddr = mmap(stackaddr, stacksize+guardsize, + PROT_READ | PROT_WRITE, MAP_STACK, + -1, 0)) != MAP_FAILED && + (guardsize == 0 || + mprotect(stackaddr, guardsize, PROT_NONE) == 0)) { + stackaddr += guardsize; + } else { + if (stackaddr != MAP_FAILED) + munmap(stackaddr, stacksize + guardsize); + stackaddr = NULL; + } + attr->stackaddr_attr = stackaddr; } if (attr->stackaddr_attr != NULL) return (0); Index: libexec/rtld-elf/map_object.c =================================================================== RCS file: /usr/ncvs/src/libexec/rtld-elf/map_object.c,v retrieving revision 1.15 diff -u -r1.15 map_object.c --- libexec/rtld-elf/map_object.c 3 Aug 2004 08:50:58 -0000 1.15 +++ libexec/rtld-elf/map_object.c 11 Sep 2004 17:41:28 -0000 @@ -46,12 +46,15 @@ * Map a shared object into memory. The "fd" argument is a file descriptor, * which must be open on the object and positioned at its beginning. * The "path" argument is a pathname that is used only for error messages. + * The "low_addr" argument allows for addresses below the normal data + * area start to be used for mapping if no space is available above. * * The return value is a pointer to a newly-allocated Obj_Entry structure * for the shared object. Returns NULL on failure. */ Obj_Entry * -map_object(int fd, const char *path, const struct stat *sb) +map_object(int fd, const char *path, const struct stat *sb, + unsigned long low_addr) { Obj_Entry *obj; Elf_Ehdr *hdr; @@ -152,6 +155,15 @@ mapbase = mmap(base_addr, mapsize, convert_prot(segs[0]->p_flags), convert_flags(segs[0]->p_flags), fd, base_offset); + /* + * If requested and out of space for the library, try again below + * the normal minimum data segment address. + */ + if (mapbase == (caddr_t) -1 && base_addr == NULL && low_addr != 0) { + base_addr = (caddr_t) low_addr; + mapbase = mmap(base_addr, mapsize, convert_prot(segs[0]->p_flags), + convert_flags(segs[0]->p_flags), fd, base_offset); + } if (mapbase == (caddr_t) -1) { _rtld_error("%s: mmap of entire address space failed: %s", path, strerror(errno)); Index: libexec/rtld-elf/rtld.c =================================================================== RCS file: /usr/ncvs/src/libexec/rtld-elf/rtld.c,v retrieving revision 1.99 diff -u -r1.99 rtld.c --- libexec/rtld-elf/rtld.c 4 Aug 2004 19:12:14 -0000 1.99 +++ libexec/rtld-elf/rtld.c 11 Sep 2004 17:51:00 -0000 @@ -143,6 +143,9 @@ static char *ld_library_path; /* Environment variable for search path */ static char *ld_preload; /* Environment variable for libraries to load first */ +static unsigned long ld_library_low_addr; /* Environment variable for + alternate data area to + try to map into */ static char *ld_tracing; /* Called from ldd to print libs */ static Obj_Entry *obj_list; /* Head of linked list of shared objects */ static Obj_Entry **obj_tail; /* Link field of last object in list */ @@ -287,6 +290,14 @@ ld_bind_now = getenv(LD_ "BIND_NOW"); if (trust) { + const char *env_low_addr = getenv(LD_ "LIBRARY_LOW_ADDR"); + if (env_low_addr != NULL) { + char *low_addr_endptr = NULL; + errno = 0; + ld_library_low_addr = strtoul(env_low_addr, &low_addr_endptr, 0); + if (*low_addr_endptr != '\0' || errno != 0) + ld_library_low_addr = 0; + } ld_debug = getenv(LD_ "DEBUG"); libmap_disable = getenv(LD_ "LIBMAP_DISABLE") != NULL; ld_library_path = getenv(LD_ "LIBRARY_PATH"); @@ -308,7 +319,7 @@ if (aux_info[AT_EXECFD] != NULL) { /* Load the main program. */ int fd = aux_info[AT_EXECFD]->a_un.a_val; dbg("loading main program"); - obj_main = map_object(fd, argv0, NULL); + obj_main = map_object(fd, argv0, NULL, 0); close(fd); if (obj_main == NULL) die(); @@ -1249,7 +1260,7 @@ if (obj == NULL) { /* First use of this object, so we must map it in */ dbg("loading \"%s\"", path); - obj = map_object(fd, path, &sb); + obj = map_object(fd, path, &sb, ld_library_low_addr); close(fd); if (obj == NULL) { free(path); Index: libexec/rtld-elf/rtld.h =================================================================== RCS file: /usr/ncvs/src/libexec/rtld-elf/rtld.h,v retrieving revision 1.34 diff -u -r1.34 rtld.h --- libexec/rtld-elf/rtld.h 3 Aug 2004 08:50:58 -0000 1.34 +++ libexec/rtld-elf/rtld.h 11 Sep 2004 17:41:45 -0000 @@ -209,7 +209,8 @@ } SymCache; extern void _rtld_error(const char *, ...) __printflike(1, 2); -extern Obj_Entry *map_object(int, const char *, const struct stat *); +extern Obj_Entry *map_object(int, const char *, const struct stat *, + unsigned long); extern void *xcalloc(size_t); extern void *xmalloc(size_t); extern char *xstrdup(const char *); -- Brian Fundakowski Feldman \'[ FreeBSD ]''''''''''\ <> green@FreeBSD.org \ The Power to Serve! \ Opinions expressed are my own. \,,,,,,,,,,,,,,,,,,,,,,\