On Mon, 02 Feb 2015 22:20:57 +0200 David Naylor dbn@freebsd.org wrote:
FreeBSD prefers to use a 0x200000 (super) page alignment however this causes the image base to be displaced from the requested 0x7b800000. Forcing a smaller page size ensures FreeBSD can place the image starting at 0x7b800000.
Just to clarify, the output of "readelf -l kernel32.dll.so" gives this:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align LOAD 0x000000 0x7b800000 0x7b800000 0x0c9e74 0x0c9e74 R E 0x200000 LOAD 0x0ca000 0x7baca000 0x7baca000 0x1a7eb0 0x1a8550 RW 0x200000
The segments have an alignment of 0x200000 bytes. This places the first segment at 0x7b800000 and the second at 0x7ba00000+Offset. With a MemSiz of 0x1a8550 this pushes the second segment over 0x7bc00000 where ntdll has been mapped already so loading kernel32 at 0x7b800000 fails.
The patch forces a smaller alignment so the second segment fits below 0x7bc00000.
On Tue, 3 Feb 2015 10:16:33 +0100 Tijl Coosemans tijl@FreeBSD.org wrote:
On Mon, 02 Feb 2015 22:20:57 +0200 David Naylor dbn@freebsd.org wrote:
FreeBSD prefers to use a 0x200000 (super) page alignment however this causes the image base to be displaced from the requested 0x7b800000. Forcing a smaller page size ensures FreeBSD can place the image starting at 0x7b800000.
Just to clarify, the output of "readelf -l kernel32.dll.so" gives this:
Can somebody run this command on Linux with kernel32.dll.so from a wine64 build and post the output? FreeBSD also uses GNU binutils so I would expect the problem to exist on Linux as well.
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align LOAD 0x000000 0x7b800000 0x7b800000 0x0c9e74 0x0c9e74 R E 0x200000 LOAD 0x0ca000 0x7baca000 0x7baca000 0x1a7eb0 0x1a8550 RW 0x200000
The segments have an alignment of 0x200000 bytes. This places the first segment at 0x7b800000 and the second at 0x7ba00000+Offset. With a MemSiz of 0x1a8550 this pushes the second segment over 0x7bc00000 where ntdll has been mapped already so loading kernel32 at 0x7b800000 fails.
The patch forces a smaller alignment so the second segment fits below 0x7bc00000.
On Mon, Feb 16, 2015 at 4:47 AM, Tijl Coosemans tijl@freebsd.org wrote:
On Tue, 3 Feb 2015 10:16:33 +0100 Tijl Coosemans tijl@FreeBSD.org wrote:
On Mon, 02 Feb 2015 22:20:57 +0200 David Naylor dbn@freebsd.org wrote:
FreeBSD prefers to use a 0x200000 (super) page alignment however this causes the image base to be displaced from the requested 0x7b800000. Forcing a smaller page size ensures FreeBSD can place the image starting at 0x7b800000.
Just to clarify, the output of "readelf -l kernel32.dll.so" gives this:
Can somebody run this command on Linux with kernel32.dll.so from a wine64 build and post the output? FreeBSD also uses GNU binutils so I would expect the problem to exist on Linux as well.
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align LOAD 0x000000 0x7b800000 0x7b800000 0x0c9e74 0x0c9e74 R E 0x200000 LOAD 0x0ca000 0x7baca000 0x7baca000 0x1a7eb0 0x1a8550 RW 0x200000
The segments have an alignment of 0x200000 bytes. This places the first segment at 0x7b800000 and the second at 0x7ba00000+Offset. With a MemSiz of 0x1a8550 this pushes the second segment over 0x7bc00000 where ntdll has been mapped already so loading kernel32 at 0x7b800000 fails.
The patch forces a smaller alignment so the second segment fits below 0x7bc00000.
This is from wine-1.7.34: [austin@localhost ~]$ readelf -l /opt/wine6432/wine-1.7.34/lib64/wine/ kernel32.dll.so
Elf file type is DYN (Shared object file) Entry point 0x7b827080 There are 7 program headers, starting at offset 64
Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align LOAD 0x0000000000000000 0x000000007b800000 0x000000007b800000 0x00000000000ce49c 0x00000000000ce49c R E 200000 LOAD 0x00000000000cf3c8 0x000000007bacf3c8 0x000000007bacf3c8 0x00000000001a8088 0x00000000001a8828 RW 200000 DYNAMIC 0x00000000000cfd88 0x000000007bacfd88 0x000000007bacfd88 0x00000000000001e0 0x00000000000001e0 RW 8 NOTE 0x00000000000001c8 0x000000007b8001c8 0x000000007b8001c8 0x0000000000000024 0x0000000000000024 R 4 GNU_EH_FRAME 0x00000000000ac1c0 0x000000007b8ac1c0 0x000000007b8ac1c0 0x0000000000004a44 0x0000000000004a44 R 4 GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 RW 10 GNU_RELRO 0x00000000000cf3c8 0x000000007bacf3c8 0x000000007bacf3c8 0x0000000000000c38 0x0000000000000c38 R 1
Section to Segment mapping: Segment Sections... 00 .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame 01 .init_array .fini_array .jcr .data.rel.ro .dynamic .got .got.plt .data .bss 02 .dynamic 03 .note.gnu.build-id 04 .eh_frame_hdr 05 06 .init_array .fini_array .jcr .data.rel.ro .dynamic .got [austin@localhost ~]$ file /opt/wine6432/wine-1.7.34/lib64/wine/ kernel32.dll.so /opt/wine6432/wine-1.7.34/lib64/wine/kernel32.dll.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=5769ec1e68c8f3e7445f1b2370d457a52d3507f4, not stripped
On Tue, 17 Feb 2015 01:35:36 -0600 Austin English austinenglish@gmail.com wrote:
On Mon, Feb 16, 2015 at 4:47 AM, Tijl Coosemans tijl@freebsd.org wrote:
On Tue, 3 Feb 2015 10:16:33 +0100 Tijl Coosemans tijl@FreeBSD.org wrote:
On Mon, 02 Feb 2015 22:20:57 +0200 David Naylor dbn@freebsd.org wrote:
FreeBSD prefers to use a 0x200000 (super) page alignment however this causes the image base to be displaced from the requested 0x7b800000. Forcing a smaller page size ensures FreeBSD can place the image starting at 0x7b800000.
Just to clarify, the output of "readelf -l kernel32.dll.so" gives this:
Can somebody run this command on Linux with kernel32.dll.so from a wine64 build and post the output? FreeBSD also uses GNU binutils so I would expect the problem to exist on Linux as well.
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align LOAD 0x000000 0x7b800000 0x7b800000 0x0c9e74 0x0c9e74 R E 0x200000 LOAD 0x0ca000 0x7baca000 0x7baca000 0x1a7eb0 0x1a8550 RW 0x200000
The segments have an alignment of 0x200000 bytes. This places the first segment at 0x7b800000 and the second at 0x7ba00000+Offset. With a MemSiz of 0x1a8550 this pushes the second segment over 0x7bc00000 where ntdll has been mapped already so loading kernel32 at 0x7b800000 fails.
The patch forces a smaller alignment so the second segment fits below 0x7bc00000.
This is from wine-1.7.34: [austin@localhost ~]$ readelf -l /opt/wine6432/wine-1.7.34/lib64/wine/ kernel32.dll.so
Elf file type is DYN (Shared object file) Entry point 0x7b827080 There are 7 program headers, starting at offset 64
Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align LOAD 0x0000000000000000 0x000000007b800000 0x000000007b800000 0x00000000000ce49c 0x00000000000ce49c R E 200000 LOAD 0x00000000000cf3c8 0x000000007bacf3c8 0x000000007bacf3c8 0x00000000001a8088 0x00000000001a8828 RW 200000 DYNAMIC 0x00000000000cfd88 0x000000007bacfd88 0x000000007bacfd88 0x00000000000001e0 0x00000000000001e0 RW 8 NOTE 0x00000000000001c8 0x000000007b8001c8 0x000000007b8001c8 0x0000000000000024 0x0000000000000024 R 4 GNU_EH_FRAME 0x00000000000ac1c0 0x000000007b8ac1c0 0x000000007b8ac1c0 0x0000000000004a44 0x0000000000004a44 R 4 GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 RW 10 GNU_RELRO 0x00000000000cf3c8 0x000000007bacf3c8 0x000000007bacf3c8 0x0000000000000c38 0x0000000000000c38 R 1
Section to Segment mapping: Segment Sections... 00 .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame 01 .init_array .fini_array .jcr .data.rel.ro .dynamic .got .got.plt .data .bss 02 .dynamic 03 .note.gnu.build-id 04 .eh_frame_hdr 05 06 .init_array .fini_array .jcr .data.rel.ro .dynamic .got [austin@localhost ~]$ file /opt/wine6432/wine-1.7.34/lib64/wine/ kernel32.dll.so /opt/wine6432/wine-1.7.34/lib64/wine/kernel32.dll.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=5769ec1e68c8f3e7445f1b2370d457a52d3507f4, not stripped
Thanks, so the same problem exists. The second LOAD segment runs over 0x7bc00000. If you run 'winedbg notepad' and enter 'info share' at the winedbg prompt you'll find that kernel32.dll isn't loaded at 0x7b800000 like it should be. The patch fixes that.