From owner-freebsd-bugs@freebsd.org Tue May 19 03:12:36 2020 Return-Path: Delivered-To: freebsd-bugs@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 0C9A02F8D63 for ; Tue, 19 May 2020 03:12:36 +0000 (UTC) (envelope-from bugzilla-noreply@freebsd.org) Received: from mailman.nyi.freebsd.org (mailman.nyi.freebsd.org [IPv6:2610:1c1:1:606c::50:13]) by mx1.freebsd.org (Postfix) with ESMTP id 49R1CR6g9Rz3Zy7 for ; Tue, 19 May 2020 03:12:35 +0000 (UTC) (envelope-from bugzilla-noreply@freebsd.org) Received: by mailman.nyi.freebsd.org (Postfix) id E4C6E2F9306; Tue, 19 May 2020 03:12:35 +0000 (UTC) Delivered-To: bugs@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id E49172F918E for ; Tue, 19 May 2020 03:12:35 +0000 (UTC) (envelope-from bugzilla-noreply@freebsd.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 49R1CR5qdnz3ZwC for ; Tue, 19 May 2020 03:12:35 +0000 (UTC) (envelope-from bugzilla-noreply@freebsd.org) Received: from kenobi.freebsd.org (kenobi.freebsd.org [IPv6:2610:1c1:1:606c::50:1d]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id C397D2C325 for ; Tue, 19 May 2020 03:12:35 +0000 (UTC) (envelope-from bugzilla-noreply@freebsd.org) Received: from kenobi.freebsd.org ([127.0.1.5]) by kenobi.freebsd.org (8.15.2/8.15.2) with ESMTP id 04J3CZ7Y030670 for ; Tue, 19 May 2020 03:12:35 GMT (envelope-from bugzilla-noreply@freebsd.org) Received: (from www@localhost) by kenobi.freebsd.org (8.15.2/8.15.2/Submit) id 04J3CZaq030662 for bugs@FreeBSD.org; Tue, 19 May 2020 03:12:35 GMT (envelope-from bugzilla-noreply@freebsd.org) X-Authentication-Warning: kenobi.freebsd.org: www set sender to bugzilla-noreply@freebsd.org using -f From: bugzilla-noreply@freebsd.org To: bugs@FreeBSD.org Subject: [Bug 246561] [PATCH] rtld-elf: dlinfo() returns wrong address in RTLD_DI_LINKMAP's l_addr (breaking Wine, gdb, etc.) Date: Tue, 19 May 2020 03:12:34 +0000 X-Bugzilla-Reason: AssignedTo X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: Base System X-Bugzilla-Component: bin X-Bugzilla-Version: 12.1-STABLE X-Bugzilla-Keywords: X-Bugzilla-Severity: Affects Some People X-Bugzilla-Who: damjan.jov@gmail.com X-Bugzilla-Status: New X-Bugzilla-Resolution: X-Bugzilla-Priority: --- X-Bugzilla-Assigned-To: bugs@FreeBSD.org X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: bug_id short_desc product version rep_platform op_sys bug_status bug_severity priority component assigned_to reporter Message-ID: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: https://bugs.freebsd.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.33 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 19 May 2020 03:12:36 -0000 https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D246561 Bug ID: 246561 Summary: [PATCH] rtld-elf: dlinfo() returns wrong address in RTLD_DI_LINKMAP's l_addr (breaking Wine, gdb, etc.) Product: Base System Version: 12.1-STABLE Hardware: Any OS: Any Status: New Severity: Affects Some People Priority: --- Component: bin Assignee: bugs@FreeBSD.org Reporter: damjan.jov@gmail.com Several low-level applications need access to ELF internals. For example Wi= ne recently began calling ELF initializers for Winelibs within itself instead = of having the dynamic linker do it. To do this, it calls the dlinfo() function with request RTLD_DI_LINKMAP, and searches the .dynamic section pointed to = by link_map.l_ld for a custom tag with Winelib initializers. However ELF libraries can be loaded at a different address to the one they expected (relocation), so the pointer stored in the initializer tag is not necessarily pointing to the correct address. We have to add the offset from= the expected base address to the actual base address to it to determine the relocated address (in the rtld-elf code, this is the "relocbase" variable). On most implementations of dlinfo(), the link_map.l_addr field stores this offset. However on FreeBSD, link_map.l_addr stores the absolute base address where the library was loaded instead ("mapbase"). A separate l_offs field w= as apparently added to return relocbase, but it only exists on MIPS. Wine recently began crashing on startup because it was adding l_addr to the pointers in initializers, but since l_addr is mapbase instead of relocbase = on FreeBSD, it was relocating them to wrong addresses. NetBSD changed their dynamic linker to return relocbase in l_addr in 2002 (https://github.com/NetBSD/src/commit/d1351c627c5f4d5ac41a3f680243d57293e0c= e1f). GNU always returned relocbase. Illumos returns relocbase. Only FreeBSD retu= rns mapbase. Can we please change rtld-elf to return relocbase? Either we can change l_a= ddr itself to return relocbase like NetBSD did: diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index 2d15560fb908..647626e3a41d 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -3951,7 +3951,7 @@ linkmap_add(Obj_Entry *obj) struct link_map *prev; obj->linkmap.l_name =3D obj->path; - obj->linkmap.l_addr =3D obj->mapbase; + obj->linkmap.l_addr =3D obj->relocbase; obj->linkmap.l_ld =3D obj->dynamic; #ifdef __mips__ /* GDB needs load offset on MIPS to use the symbols */ or we can remove that "#ifdef __mips__" further down and return l_offs on a= ll platforms, and patch applications to use that instead (like was apparently already done for GDB on MIPS). (Of course, being an ABI-breaking change, it= can only be done in CURRENT.) I eventually found a way to work out relocbase from mapbase within Wine (https://source.winehq.org/git/wine.git/blobdiff/0f31e48e9ba28ba8c0aee06785= 67d6b47e3c63aa..0fd3f0266e05f6afa710fa2b5a254b0ed88bac0f:/dlls/ntdll/loader= .c), and the latest Wine Git is no longer crashing on startup. But I am not convinced that approach will always work, because it requires the first PT_= LOAD segment to start at address 0 in the file, and I don't see that being requi= red by the ELF specification. Detailed discussion: https://bugs.winehq.org/show_bug.cgi?id=3D49139 --=20 You are receiving this mail because: You are the assignee for the bug.=