Haiku

From WineHQ Wiki
Jump to: navigation, search

Haiku

Haiku is an open source operating system inspired by the Be Operating System. Haiku is fast, simple to use, easy to learn and yet very powerful.

Problems

The first problem you'll run into is missing libpthread, libc and libm. However, they aren't missing, they are just one lib, libroot. AJ won't fix Wine to support libroot, understandable as it would lead to some ugly checks in winegcc/winebuild. Haiku won't add dummy libs because the POSIX Standard doesn't force them to have those libs and it's the nature of Haiku to only have libroot.

Also note that LD_LIBRARY_PATH is not supported, so you need to modify LIBRARY_PATH.

Build

To get around these problems, do:

ln -s /system/lib/libroot.so /system/lib/libpthread.so
ln -s /system/lib/libroot.so /system/lib/libc.so
ln -s /system/lib/libroot.so /system/lib/libm.so
ln -s /system/lib/libroot.so /boot/develop/abi/x86/gcc2/tools/gcc-2.95.3-haiku-100818/lib/libpthread.so
ln -s /system/lib/libroot.so /boot/develop/abi/x86/gcc2/tools/gcc-2.95.3-haiku-100818/lib/libc.so
ln -s /system/lib/libroot.so /boot/develop/abi/x86/gcc2/tools/gcc-2.95.3-haiku-100818/lib/libm.so
./configure --without-x --without-freetype --disable-tests
LIBRARY_PATH=$LIBRARY_PATH:/path/to/buildtree/libs/wine make

You will have other problems, such as missing ELF structures and compiler crashes.

Running

If you worked around all of the problems while compiling you can close all open applications and try to run Wine:

LIBRARY_PATH=$LIBRARY_PATH:/path/to/buildtree/libs/wine ./wine cmd

It won't work and your system will become unstable, you need to reboot. The reason is that Wine expects for most mmap calls to succeed, but also that mmap returns the requested memory address. Haiku doesn't mmap 0x7ffe0000 for us with errorcode 0x80000000 (B_NO_MEMORY). This ends in an nearly endless loop of Wine trying to map memory. You can see this with:

LIBRARY_PATH=$LIBRARY_PATH:/path/to/buildtree/libs/wine strace ./loader/wine cmd

With gdb I analysed which part of the Wine code does that:

LIBRARY_PATH=$LIBRARY_PATH:/path/to/buildtree/libs/wine gdb ./loader/wine

It is reserve_area in libs/wine/mmap.c that tries to halve the size of the mapping until it succeeds, which will never happen.

What Wine needs from Haiku

  • in general: LDT support, m(un)lock, pthread_attr_setstack, a fix for the Address Space Layout problem
  • dbghelp: Elf32_Ehdr, Elf32_Shdr, Elf32_Phdr, Elf32_Dyn, DT_DEBUG, DT_NULL, SHT_NULL, SHT_NOBITS, SHT_SYMTAB, SHT_DYNSYM, SHT_DYNAMIC, STT_NOTYPE, STT_FILE, STT_OBJECT, STT_FUNC, SHN_UNDEF, STB_LOCAL, ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3, EI_CLASS, ELFCLASS32, ELFCLASS64, PT_LOAD
  • network related: ESOCKTNOSUPPORT, ETOOMANYREFS
  • ntdll: SIGIO, an improved ucontext_t

Address Space Layouts

OS Kernel space Shared memory User space
Haiku 0x80000000-0xFFFFFFFFF 0x00000000-0x7FFF0000
BeOS 0x00000000-0x7FFFFFFFF 0x80000000-0xFFFFFFFFF
Linux 0xC0000000-0xFFFFFFFFF 0x00000000-0xBFFFFFFFF
Windows 9x 0xC0000000-0xFFFFFFFFF 0x80000000-0xBFFFFFFFF 0x00000000-0x7FFFFFFFF
Windows NT 0xC0000000-0xFFFFFFFFF 0x00000000-0xBFFFFFFFF

more detailed information on the layout of Haiku:

0x00000000 - 0x00100000 Reserved, only allocated upon explicit request.
0x00100000 - 0x18000000 Free range for general area allocations. The kernel maps the
                        runtime loader into this range, the runtime loader creates
                        its small heap here, and executable and libraries are
                        generally mapped here as well.
0x18000000 - 0x48000000 Heap (pre-reserved). General area allocations will start
                        using the unused part of this range once other free ranges
                        have been exhausted.
0x48000000 - 0x6fff0000 Free range for general area allocations.
0x6fff0000 - 0x70000000 Used for kernel-userland communication.
0x70000000 - 0x7efef000 Pre-reserved for thread stacks.
0x7efef000 - 0x7fff0000 main thread stack
0x7fff0000              userland address space top

here is the listarea part for "wine cmd" breaking in main() from loader/wine:

  ID                             name   address     size   alloc. #-cow  #-in #-out
------------------------------------------------------------------------------------
5791            runtime_loader_seg0ro  00100000    14000        0     0     0     0
5792            runtime_loader_seg1rw  00114000     1000     1000     0     0     0
5793              runtime_loader_bss1  00115000     1000        0     0     0     0
5794                         rld heap  00116000    10000     3000     0     0     0
5795                      _rld_debug_  00126000     1000     1000     0     0     0
5796                      wine_seg0ro  00200000     1000     1000     0     0     0
5797                      wine_seg1rw  00201000     2000     2000     0     0     0
5798            libwine.so.1.0_seg0ro  00203000   12a000        0     0     0     0
5799            libwine.so.1.0_seg1rw  0032d000     4000     3000     0     0     0
5800            libwine.so.1.0_seg2rw  00331000    13000        0     0     0     0
5801                libroot.so_seg0ro  00344000    c5000     5000     0     0     0
5802                libroot.so_seg1rw  00409000    12000    12000     0     0     0
5803                libroot.so_seg2rw  0041b000    38000     7000     0     0     0
5804                             heap  18000000    40000    2c000     0     0     0
5789                        user area  6fff0000     4000     4000     0     0     0
5790                   wine_223_stack  7efee000  1002000     4000     0     0     0


maybe a preloader could help here?

00010000-68000000 ---p 00000000 00:00 0 
7bf00000-7bf02000 r-xp 00000000 08:02 20845388                           /winepath/loader/wine
7bf02000-7bf04000 rw-p 00001000 08:02 20845388                           /winepath/loader/wine
7c400000-7c402000 r-xp 00001000 08:02 20845262                           /winepath/loader/wine-preloader
7c402000-7c403000 rw-p 00002000 08:02 20845262                           /winepath/loader/wine-preloader
7f000000-7ffff000 ---p 00000000 00:00 0 
7ffff000-80000000 r-xp 00000000 00:00 0 
80000000-82000000 ---p 00000000 00:00 0 
f772b000-f7747000 r-xp 00000000 08:01 195                                /lib32/ld-2.13.so
f7747000-f7749000 rw-p 0001b000 08:01 195                                /lib32/ld-2.13.so
f7749000-f774a000 r-xp 00000000 00:00 0                                  [vdso]
ffdcc000-ffded000 rw-p 00000000 00:00 0                                  [stack]

that's on Linux at the end of preloaders wld_start. One main difference is the stack position. When haiku switches to gcc4 and breaks backwards compatibility they maybe also can change the memory layout?

See also

Thread on haiku-development mailing list from June 2014

Patchseries: configure.ac: fix libpthread detection on Haiku

older Patch

Bug 20116

Bug 4606 at Haiku

Bug 7502 at Haiku (missing LDT table)

Bug 9205 at Haiku (needed mmap improvements)