From owner-freebsd-hackers@FreeBSD.ORG Tue Feb 26 20:52:43 2013 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 59768C5D; Tue, 26 Feb 2013 20:52:43 +0000 (UTC) (envelope-from damjan.jov@gmail.com) Received: from mail-lb0-f176.google.com (mail-lb0-f176.google.com [209.85.217.176]) by mx1.freebsd.org (Postfix) with ESMTP id B2C371EEE; Tue, 26 Feb 2013 20:52:42 +0000 (UTC) Received: by mail-lb0-f176.google.com with SMTP id s4so3389420lbc.7 for ; Tue, 26 Feb 2013 12:52:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:mime-version:in-reply-to:references:from:date:message-id :subject:to:cc:content-type; bh=E5cHE9QK6vU7Mk/y/md6C5PLkNxsD9U8RLWGNRdUD0U=; b=csQ4k6m1EJZ2MEiQxVu220b2bCBY6bbZPnO8AUW1YF6E1KYg9WlqrJXx6RipqWzn8H hvnZb2vv/qKKuvfnva7c4gn8ZbuOwRu3dKpEUg4QnGd0Z2tjjOblDgw3ueHuw6uwcFVs Okbt668EVCiXZq3pMG2MZBO31Y6IWXoRdzI9goQBRMe24HyalqlXI1a42a6FZt0y26Ml NElz6sdP6z33LwX79IxhFeUBo3dn1d57rRuuESyQyukm3sEObtfOsB6X2AqV3CZuKZQ7 SnSx/P6BtC5YjEcaczvzdyM/ku9QVoXiV+fGH0qOLLXsr5/0PLcAaXCPiCyKIdmIZctR LdTg== X-Received: by 10.112.49.99 with SMTP id t3mr1132732lbn.108.1361911955946; Tue, 26 Feb 2013 12:52:35 -0800 (PST) MIME-Version: 1.0 Received: by 10.152.20.138 with HTTP; Tue, 26 Feb 2013 12:52:15 -0800 (PST) In-Reply-To: References: <20130220154855.GF2598@kib.kiev.ua> <51253759.70508@coosemans.org> <20130221154433.GY2598@kib.kiev.ua> From: Damjan Jovanovic Date: Tue, 26 Feb 2013 22:52:15 +0200 Message-ID: Subject: Re: [patch] Wine DLL base address patches To: Konstantin Belousov Content-Type: text/plain; charset=ISO-8859-1 Cc: freebsd-hackers@freebsd.org, freebsd-emulation@freebsd.org, Tijl Coosemans X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 26 Feb 2013 20:52:43 -0000 On Fri, Feb 22, 2013 at 5:19 AM, Damjan Jovanovic wrote: > On Thu, Feb 21, 2013 at 5:44 PM, Konstantin Belousov > wrote: >> On Thu, Feb 21, 2013 at 12:57:45AM +0200, Damjan Jovanovic wrote: >>> On Wed, Feb 20, 2013 at 10:51 PM, Tijl Coosemans wrote: >>> > On 20-02-2013 16:48, Konstantin Belousov wrote: >>> >> On Wed, Feb 20, 2013 at 05:29:01PM +0200, Damjan Jovanovic wrote: >>> >>> Hi >>> >>> >>> >>> Wine needs some of its libraries to be loaded at specific base >>> >>> addresses (https://wiki.freebsd.org/Wine), something FreeBSD currently >>> >>> lacks. >>> >>> >>> >>> I've written a patch to the dynamic loader (/libexec/ld-elf.so.1) that >>> >>> loads libraries at their preferred base addresses >>> >>> (http://www.freebsd.org/cgi/query-pr.cgi?pr=176216), as well as a port >>> >>> of Prelink to FreeBSD which Wine uses to set base addresses >>> >>> (http://www.freebsd.org/cgi/query-pr.cgi?pr=176283). Both work :-), >>> >>> the changed dynamic loader doesn't show any problems in a few days of >>> >>> testing, and prelink works with the --reloc-only option as used by >>> >>> Wine. >>> >>> >>> >>> Please review/test/comment/commit. >>> >> >>> >> Unfortunately, it is not safe. MAP_FIXED overrides any previous mappings >>> >> which could exist at the specified address. >>> > >>> > I've simplified the rtld patch to a single line. The second patch makes >>> > Wine use -Ttext-segment linker flag instead of prelink. This requires >>> > binutils from ports, but it's easier than porting prelink. >>> > >>> >>> All of that occurred to me as well. >>> >>> The problem with that one-line rtld patch is that loading an >>> application will now fail if any of its libraries cannot be loaded at >>> their requested address. >> But this is intended behaviour. Also, the default virtaddr base for the >> shared libraries is 0, so the existing binaries should be not affected. > > In that case, and since failing to load a library only causes the > process to exit when starting up and not when it calls dlopen(), I > approve. > >>> >>> The problem with -Ttext-segment (and isn't it just -Ttext?) is that it >>> doesn't seem to work: the base_vaddr seen by rtld will remain 0, and >>> the address listed in /proc/.../map is different from what it should >>> be. Also run "readelf -l" on a library compiled that way and compare >>> with the output of one run through "prelink --reloc-only", you'll see >>> the lowest VirtAddr and PhysAddr in LOAD headers change only with >>> prelink. I really ported prelink because there was no other choice. >> The -Ttext-segment does work. As indicated by Tijl, you need recent >> binutils. I just verified that ld 2.32.1 obeys -Ttext-segment. >> >> You can also take a look at the default linker script to see how >> -Ttext-segment is used, look for SEGMENT_START("text-segment"). >> > > My apologies: I confused -Ttext which is documented but doesn't work, > with -Ttext-segment which is undocumented in FreeBSD 9.1 and might > work. I would test it further, but -CURRENT doesn't installworld > (ERROR: Required auditdistd user is missing, see /usr/src/UPDATING.) > and I am away until next week. > > Prelink is now in Ports. What I'd recommend is checking if the > binaries are the same, and if not, doing a diff between "readelf -a" > outputs of the prelinked binary vs -Ttext-segmented binary. Also run > this a few times and make sure the address is what's expected: > > #include > #include > int main(int argc, char **argv) > { > printf("%p\n", LoadLibrary("KERNEL32")); > return 0; > } > > mingw32-gcc hello.c -o hello.exe > wine hello.exe With binutils 2.23.1 (in ports), comparing the output of "ld -Ttext-segment=0x7b800000" and "prelink --reloc-only 0x7b800000" using diffs of "readelf -a" outputs gives this: - 11: 000000007b800000 0 OBJECT LOCAL DEFAULT 6 _GLOBAL_OFFSET_TABLE_ + 11: 0000000000000000 0 OBJECT LOCAL DEFAULT 6 _GLOBAL_OFFSET_TABLE_ in other words, prelink also shifts the global offset table to the requested base address, ld does not. I don't think this matters since it's only ELF segments that get loaded - sections are irrelevant. "objdump -s" finds no differences. So I am happy with all of Tijl's patches, please commit them.