From nobody@FreeBSD.org  Sun Feb 17 20:57:24 2013
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1])
	by hub.freebsd.org (Postfix) with ESMTP id E65524B5
	for <freebsd-gnats-submit@FreeBSD.org>; Sun, 17 Feb 2013 20:57:24 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from red.freebsd.org (red.freebsd.org [IPv6:2001:4f8:fff6::22])
	by mx1.freebsd.org (Postfix) with ESMTP id A573D85C
	for <freebsd-gnats-submit@FreeBSD.org>; Sun, 17 Feb 2013 20:57:24 +0000 (UTC)
Received: from red.freebsd.org (localhost [127.0.0.1])
	by red.freebsd.org (8.14.5/8.14.5) with ESMTP id r1HKvOpm060556
	for <freebsd-gnats-submit@FreeBSD.org>; Sun, 17 Feb 2013 20:57:24 GMT
	(envelope-from nobody@red.freebsd.org)
Received: (from nobody@localhost)
	by red.freebsd.org (8.14.5/8.14.5/Submit) id r1HKvOnQ060555;
	Sun, 17 Feb 2013 20:57:24 GMT
	(envelope-from nobody)
Message-Id: <201302172057.r1HKvOnQ060555@red.freebsd.org>
Date: Sun, 17 Feb 2013 20:57:24 GMT
From: Damjan Jovanovic <damjan.jov@gmail.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: [patch] Allow loading ELF libraries at their preferred base address (needed for Wine)
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         176216
>Category:       kern
>Synopsis:       [libexec] [patch] Allow loading ELF libraries at their preferred base address (needed for Wine)
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    tijl
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Sun Feb 17 21:00:00 UTC 2013
>Closed-Date:    Tue Mar 05 17:13:38 CET 2013
>Last-Modified:  Tue Mar 05 17:13:38 CET 2013
>Originator:     Damjan Jovanovic
>Release:        9.1
>Organization:
>Environment:
Any
>Description:
FreeBSD's dynamic linker (/libexec/ld-elf.so.1) currently loads libraries by calling mmap() with 0 as the first parameter, causing them to be loaded at whatever address the kernel chooses.

But for maximum compatibility with Windows applications, Wine needs some of its DLLs to be loaded at particular memory addresses (see the comments on https://wiki.freebsd.org/Wine).

With this patch, first mmap() is called with the base address of the library and MAP_FIXED, giving the library a chance to load at the base address it specified, and if this fails then mmap() is called without MAP_FIXED so the library can at least load somewhere else since its preferred memory region is unavailable.

>How-To-Repeat:

>Fix:


Patch attached with submission follows:

Index: libexec/rtld-elf/map_object.c
===================================================================
--- libexec/rtld-elf/map_object.c	(revision 246877)
+++ libexec/rtld-elf/map_object.c	(working copy)
@@ -175,11 +175,22 @@
     base_vaddr = trunc_page(segs[0]->p_vaddr);
     base_vlimit = round_page(segs[nsegs]->p_vaddr + segs[nsegs]->p_memsz);
     mapsize = base_vlimit - base_vaddr;
-    base_addr = hdr->e_type == ET_EXEC ? (caddr_t) base_vaddr : NULL;
+    base_addr = (caddr_t) base_vaddr;
 
-    mapbase = mmap(base_addr, mapsize, PROT_NONE, MAP_ANON | MAP_PRIVATE |
-      MAP_NOCORE, -1, 0);
+    /*
+     * Executables, and libraries whose base_addr isn't 0,
+     * should ideally be loaded at that base_addr.
+     */
+    mapbase = (caddr_t) -1;
+    if (base_addr != 0) {
+        mapbase = mmap(base_addr, mapsize, PROT_NONE, MAP_ANON | MAP_PRIVATE |
+          MAP_NOCORE | MAP_FIXED, -1, 0);
+    }
     if (mapbase == (caddr_t) -1) {
+        mapbase = mmap(base_addr, mapsize, PROT_NONE, MAP_ANON | MAP_PRIVATE |
+          MAP_NOCORE, -1, 0);
+    }
+    if (mapbase == (caddr_t) -1) {
 	_rtld_error("%s: mmap of entire address space failed: %s",
 	  path, rtld_strerror(errno));
 	goto error;


>Release-Note:
>Audit-Trail:

From: Damjan Jovanovic <damjan.jov@gmail.com>
To: bug-followup@freebsd.org
Cc:  
Subject: Re: kern/176216: [libexec] [patch] Allow loading ELF libraries at
 their preferred base address (needed for Wine)
Date: Mon, 18 Feb 2013 07:31:39 +0200

 --bcaec55554485b6f6804d5f90b7c
 Content-Type: text/plain; charset=ISO-8859-1
 
 This is a newer version of the patch that doesn't fail when a library
 can't be loaded at its desired address.
 
 --bcaec55554485b6f6804d5f90b7c
 Content-Type: application/octet-stream; name="ld-elf-base-2.patch"
 Content-Disposition: attachment; filename="ld-elf-base-2.patch"
 Content-Transfer-Encoding: base64
 X-Attachment-Id: f_hdb6qx7v0
 
 SW5kZXg6IGxpYmV4ZWMvcnRsZC1lbGYvbWFwX29iamVjdC5jCj09PT09PT09PT09PT09PT09PT09
 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tIGxpYmV4
 ZWMvcnRsZC1lbGYvbWFwX29iamVjdC5jCShyZXZpc2lvbiAyNDY4NzcpCisrKyBsaWJleGVjL3J0
 bGQtZWxmL21hcF9vYmplY3QuYwkod29ya2luZyBjb3B5KQpAQCAtMTc1LDIwICsxNzUsMzAgQEAK
 ICAgICBiYXNlX3ZhZGRyID0gdHJ1bmNfcGFnZShzZWdzWzBdLT5wX3ZhZGRyKTsKICAgICBiYXNl
 X3ZsaW1pdCA9IHJvdW5kX3BhZ2Uoc2Vnc1tuc2Vnc10tPnBfdmFkZHIgKyBzZWdzW25zZWdzXS0+
 cF9tZW1zeik7CiAgICAgbWFwc2l6ZSA9IGJhc2VfdmxpbWl0IC0gYmFzZV92YWRkcjsKLSAgICBi
 YXNlX2FkZHIgPSBoZHItPmVfdHlwZSA9PSBFVF9FWEVDID8gKGNhZGRyX3QpIGJhc2VfdmFkZHIg
 OiBOVUxMOworICAgIGJhc2VfYWRkciA9IChjYWRkcl90KSBiYXNlX3ZhZGRyOwogCi0gICAgbWFw
 YmFzZSA9IG1tYXAoYmFzZV9hZGRyLCBtYXBzaXplLCBQUk9UX05PTkUsIE1BUF9BTk9OIHwgTUFQ
 X1BSSVZBVEUgfAotICAgICAgTUFQX05PQ09SRSwgLTEsIDApOworICAgIC8qIEZpcnN0IHRyeSBs
 b2FkIGl0IGF0IGl0cyBkZXNpcmVkIGFkZHJlc3MgKi8KKyAgICBtYXBiYXNlID0gKGNhZGRyX3Qp
 IC0xOworICAgIGlmIChiYXNlX2FkZHIgIT0gMCkgeworICAgICAgICBtYXBiYXNlID0gbW1hcChi
 YXNlX2FkZHIsIG1hcHNpemUsIFBST1RfTk9ORSwgTUFQX0FOT04gfCBNQVBfUFJJVkFURSB8Cisg
 ICAgICAgICAgTUFQX05PQ09SRSB8IE1BUF9GSVhFRCwgLTEsIDApOworICAgIH0KICAgICBpZiAo
 bWFwYmFzZSA9PSAoY2FkZHJfdCkgLTEpIHsKKwlpZiAoaGRyLT5lX3R5cGUgPT0gRVRfRVhFQykg
 eworCSAgICBfcnRsZF9lcnJvcigiJXM6IGxvYWRpbmcgYXQgYWRkcmVzcyAlcCBmYWlsZWQiLAor
 CQlwYXRoLCBiYXNlX2FkZHIpOworCSAgICBnb3RvIGVycm9yOworCX0gZWxzZSB7CisJICAgIC8q
 IGxpYnJhcmllcyBjYW4gZ28gYW55d2hlcmUgZWxzZSAqLworCSAgICBtYXBiYXNlID0gbW1hcChi
 YXNlX2FkZHIsIG1hcHNpemUsIFBST1RfTk9ORSwgTUFQX0FOT04gfCBNQVBfUFJJVkFURSB8CisJ
 CU1BUF9OT0NPUkUsIC0xLCAwKTsKKwl9CisgICAgfQorICAgIGlmIChtYXBiYXNlID09IChjYWRk
 cl90KSAtMSkgewogCV9ydGxkX2Vycm9yKCIlczogbW1hcCBvZiBlbnRpcmUgYWRkcmVzcyBzcGFj
 ZSBmYWlsZWQ6ICVzIiwKIAkgIHBhdGgsIHJ0bGRfc3RyZXJyb3IoZXJybm8pKTsKIAlnb3RvIGVy
 cm9yOwogICAgIH0KLSAgICBpZiAoYmFzZV9hZGRyICE9IE5VTEwgJiYgbWFwYmFzZSAhPSBiYXNl
 X2FkZHIpIHsKLQlfcnRsZF9lcnJvcigiJXM6IG1tYXAgcmV0dXJuZWQgd3JvbmcgYWRkcmVzczog
 d2FudGVkICVwLCBnb3QgJXAiLAotCSAgcGF0aCwgYmFzZV9hZGRyLCBtYXBiYXNlKTsKLQlnb3Rv
 IGVycm9yMTsKLSAgICB9CiAKICAgICBmb3IgKGkgPSAwOyBpIDw9IG5zZWdzOyBpKyspIHsKIAkv
 KiBPdmVybGF5IHRoZSBzZWdtZW50IG9udG8gdGhlIHByb3BlciByZWdpb24uICovCg==
 --bcaec55554485b6f6804d5f90b7c--
State-Changed-From-To: open->patched 
State-Changed-By: tijl 
State-Changed-When: Wed Feb 27 10:34:37 CET 2013 
State-Changed-Why:  
Committed to HEAD in r247396. 


Responsible-Changed-From-To: freebsd-bugs->tijl 
Responsible-Changed-By: tijl 
Responsible-Changed-When: Wed Feb 27 10:34:37 CET 2013 
Responsible-Changed-Why:  
Committed to HEAD in r247396. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=176216 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/176216: commit references a PR
Date: Wed, 27 Feb 2013 09:34:18 +0000 (UTC)

 Author: tijl
 Date: Wed Feb 27 09:34:09 2013
 New Revision: 247396
 URL: http://svnweb.freebsd.org/changeset/base/247396
 
 Log:
   Map libraries linked with -Ttext-segment=base_addr at base_addr.
   Normal libraries have base address 0 and are unaffected by this change.
   
   PR:		176216
   Submitted by:	Damjan Jovanovic <damjan.jov@gmail.com>
   Reviewed by:	kib
   MFC after:	1 week
 
 Modified:
   head/libexec/rtld-elf/map_object.c
 
 Modified: head/libexec/rtld-elf/map_object.c
 ==============================================================================
 --- head/libexec/rtld-elf/map_object.c	Wed Feb 27 08:56:57 2013	(r247395)
 +++ head/libexec/rtld-elf/map_object.c	Wed Feb 27 09:34:09 2013	(r247396)
 @@ -175,7 +175,7 @@ map_object(int fd, const char *path, con
      base_vaddr = trunc_page(segs[0]->p_vaddr);
      base_vlimit = round_page(segs[nsegs]->p_vaddr + segs[nsegs]->p_memsz);
      mapsize = base_vlimit - base_vaddr;
 -    base_addr = hdr->e_type == ET_EXEC ? (caddr_t) base_vaddr : NULL;
 +    base_addr = (caddr_t) base_vaddr;
  
      mapbase = mmap(base_addr, mapsize, PROT_NONE, MAP_ANON | MAP_PRIVATE |
        MAP_NOCORE, -1, 0);
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/176216: commit references a PR
Date: Tue,  5 Mar 2013 16:04:40 +0000 (UTC)

 Author: tijl
 Date: Tue Mar  5 16:04:15 2013
 New Revision: 247847
 URL: http://svnweb.freebsd.org/changeset/base/247847
 
 Log:
   MFC r247396:
   
   Map libraries linked with -Ttext-segment=base_addr at base_addr.
   Normal libraries have base address 0 and are unaffected by this change.
   
   PR:		176216
   Submitted by:	Damjan Jovanovic <damjan.jov@gmail.com>
   Reviewed by:	kib
 
 Modified:
   stable/8/libexec/rtld-elf/map_object.c
 Directory Properties:
   stable/8/libexec/rtld-elf/   (props changed)
 
 Modified: stable/8/libexec/rtld-elf/map_object.c
 ==============================================================================
 --- stable/8/libexec/rtld-elf/map_object.c	Tue Mar  5 16:04:07 2013	(r247846)
 +++ stable/8/libexec/rtld-elf/map_object.c	Tue Mar  5 16:04:15 2013	(r247847)
 @@ -148,7 +148,7 @@ map_object(int fd, const char *path, con
      base_vaddr = trunc_page(segs[0]->p_vaddr);
      base_vlimit = round_page(segs[nsegs]->p_vaddr + segs[nsegs]->p_memsz);
      mapsize = base_vlimit - base_vaddr;
 -    base_addr = hdr->e_type == ET_EXEC ? (caddr_t) base_vaddr : NULL;
 +    base_addr = (caddr_t) base_vaddr;
  
      mapbase = mmap(base_addr, mapsize, PROT_NONE, MAP_ANON | MAP_PRIVATE |
        MAP_NOCORE, -1, 0);
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/176216: commit references a PR
Date: Tue,  5 Mar 2013 16:04:18 +0000 (UTC)

 Author: tijl
 Date: Tue Mar  5 16:04:07 2013
 New Revision: 247846
 URL: http://svnweb.freebsd.org/changeset/base/247846
 
 Log:
   MFC r247396:
   
   Map libraries linked with -Ttext-segment=base_addr at base_addr.
   Normal libraries have base address 0 and are unaffected by this change.
   
   PR:		176216
   Submitted by:	Damjan Jovanovic <damjan.jov@gmail.com>
   Reviewed by:	kib
 
 Modified:
   stable/9/libexec/rtld-elf/map_object.c
 Directory Properties:
   stable/9/libexec/rtld-elf/   (props changed)
 
 Modified: stable/9/libexec/rtld-elf/map_object.c
 ==============================================================================
 --- stable/9/libexec/rtld-elf/map_object.c	Tue Mar  5 15:35:57 2013	(r247845)
 +++ stable/9/libexec/rtld-elf/map_object.c	Tue Mar  5 16:04:07 2013	(r247846)
 @@ -175,7 +175,7 @@ map_object(int fd, const char *path, con
      base_vaddr = trunc_page(segs[0]->p_vaddr);
      base_vlimit = round_page(segs[nsegs]->p_vaddr + segs[nsegs]->p_memsz);
      mapsize = base_vlimit - base_vaddr;
 -    base_addr = hdr->e_type == ET_EXEC ? (caddr_t) base_vaddr : NULL;
 +    base_addr = (caddr_t) base_vaddr;
  
      mapbase = mmap(base_addr, mapsize, PROT_NONE, MAP_ANON | MAP_PRIVATE |
        MAP_NOCORE, -1, 0);
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: patched->closed 
State-Changed-By: tijl 
State-Changed-When: Tue Mar 5 17:12:10 CET 2013 
State-Changed-Why:  
Committed to stable/9 (r247846) and stable/8 (r247847). 

http://www.freebsd.org/cgi/query-pr.cgi?pr=176216 
>Unformatted:
