http://bugs.winehq.org/show_bug.cgi?id=30134
Bug #: 30134 Summary: Wine on ARM: .init/.text sections passed to assembler need directives to allow for mixed/pure arm32/thumb2 builds (.init section thumb2 libc ctors vs. Wine arm32 ctor) Product: Wine Version: 1.4 Platform: arm OS/Version: Linux Status: NEW Severity: normal Priority: P2 Component: tools AssignedTo: wine-bugs@winehq.org ReportedBy: focht@gmx.net Classification: Unclassified
Hello,
Wine on ARM - some food ;-) I have some ARM machines "pets" at home, ranging from low spec ARM7TDMI (ARMv4T) to Cortex-A8 (ARMv7-A) and Cortex-A9 MPCore dual and quad flavours - currently considered high spec - until Cortex-A15 shows up.
The dual/quad Cortex-A9 machines which I use for work/development are running recent 3.1/3.2 Linux kernels and distros, mostly based on Linaro builds. Good enough to build Wine with decent speed - slower than i3/i5 multicore but comparable to my Atom-based machines. The difference: 3 watts (quad core A9) vs. 35 watts (dual core Atom with 4 hyperthreads) under full load (idle load ratio is even worse).
Linaro toolchains are used to build Wine, they have a default profile for Cortex-A9 Thumb-2 NEON (CFLAGS="-gdwarf-2" was passed to Wine).
--- snip --- $ gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/arm-linux-gnueabi/4.6.1/lto-wrapper Target: arm-linux-gnueabi Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.6.1-9ubuntu3' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-plugin --enable-objc-gc --enable-multilib --disable-sjlj-exceptions --with-arch=armv7-a --with-float=softfp --with-fpu=vfpv3-d16 --with-mode=thumb --disable-werror --enable-checking=release --build=arm-linux-gnueabi --host=arm-linux-gnueabi --target=arm-linux-gnueabi Thread model: posix gcc version 4.6.1 (Ubuntu/Linaro 4.6.1-9ubuntu3) ... $ as -v GNU assembler version 2.21.53 (arm-linux-gnueabi) using BFD version (GNU Binutils for Ubuntu) 2.21.53.20110810 --- snip ---
Running "wineboot" to create a fresh WINEPREFIX gives:
--- snip --- $ wineboot wine: created the configuration directory '/home/linaro/.wine' fixme:seh:RtlUnwind Not implemented on ARM err:module:attach_process_dlls "ntdll.dll" failed to initialize, aborting err:seh:segv_handler Got unexpected trap 0 fixme:seh:RtlUnwind Not implemented on ARM err:module:attach_process_dlls "ntdll.dll" failed to initialize, aborting err:seh:segv_handler Got unexpected trap 0 Segmentation fault --- snip ---
Gdb session:
--- snip --- $ gdb wine GNU gdb (Ubuntu/Linaro 7.3-0ubuntu2) 7.3-2011.08 ... (gdb) run wineboot Starting program: /home/linaro/projects/wine/wine-install/bin/wine wineboot [Thread debugging using libthread_db enabled] fixme:seh:RtlUnwind Not implemented on ARM err:module:attach_process_dlls "ntdll.dll" failed to initialize, aborting err:seh:segv_handler Got unexpected trap 0
Program received signal SIGSEGV, Segmentation fault. 0x40280000 in __wine_spec_pe_header () from /home/linaro/projects/wine/wine-install/bin/../lib/wine/ntdll.dll.so (gdb) bt #0 0x40280000 in __wine_spec_pe_header () from /home/linaro/projects/wine/wine-install/bin/../lib/wine/ntdll.dll.so #1 0x4027182a in _init () from /home/linaro/projects/wine/wine-install/bin/../lib/wine/ntdll.dll.so #2 0x402de0e6 in __wine_spec_dll_entry (inst=Cannot access memory at address 0xbf2903cb ) at /home/linaro/projects/wine/wine-git/dlls/winecrt0/dll_entry.c:37 Cannot access memory at address 0xbf2903db ... (gdb) info reg r0 0x1 1 r1 0x407d4380 1081951104 r2 0x354 852 r3 0x0 0 r4 0xbeffe2d0 3204440784 r5 0xbeffed70 3204443504 r6 0x88c1 35009 r7 0xbf2903bf 3207136191 r8 0x0 0 r9 0x0 0 r10 0x4001e000 1073864704 r11 0x0 0 r12 0x402f6328 1076847400 sp 0x40d6fc38 0x40d6fc38 lr 0x4027182b 1076303915 pc 0x40280000 0x40280000 <__wine_spec_pe_header+59344> cpsr 0xf0030 983088 --- snip ---
cpsr "T" bit is set so we are in thumb mode.
Disassembly of ".init" section shows thumb2 code due to toolchain defaults.
--- snip --- (gdb) disas 0x4027182a Dump of assembler code for function _init: 0x40271824 <+0>: push {r3, lr} 0x40271826 <+2>: bl 0x402831c0 <call_gmon_start> 0x4027182a <+6>: nop 0x4027182c <+8>: b 0x40282830 <__wine_spec_pe_header+69632> __wine_spec_pe_header: ... 0x40d88604 <+69628>: andeq r0, r0, r0 0x40d88608 <+69632>: blx 0x40db3eac <__wine_spec_init_ctor> 0x40d8860c <+69636>: pop {r3, pc} --- snip ---
The long branch at 0x4027182c (part of .init section that belongs to Wine) was assembled as 32 bit ARM code because GNU assembler will generate 32 bit ARM code by default if not told otherwise (Wine doesn't explicitly emit directives for sections nor passes additional options to "as")
Before and after entering "call_gmon_start" it was thumb mode, hence no veneer required to do a mode switch (thumb <-> arm).
--- snip --- $ ls -la /usr/lib/*/crt* -rw-r--r-- 1 root root 1588 2012-03-07 05:21 /usr/lib/arm-linux-gnueabi/crt1.o -rw-r--r-- 1 root root 1216 2012-03-07 05:21 /usr/lib/arm-linux-gnueabi/crti.o -rw-r--r-- 1 root root 884 2012-03-07 05:21 /usr/lib/arm-linux-gnueabi/crtn.o -rw-r--r-- 1 root root 1588 2012-03-07 05:26 /usr/lib/arm-linux-gnueabihf/crt1.o -rw-r--r-- 1 root root 1216 2012-03-07 05:26 /usr/lib/arm-linux-gnueabihf/crti.o -rw-r--r-- 1 root root 884 2012-03-07 05:26 /usr/lib/arm-linux-gnueabihf/crtn.o --- snip ---
--- snip --- $ objdump -x /usr/lib/arm-linux-gnueabi/crti.o
/usr/lib/arm-linux-gnueabi/crti.o: file format elf32-littlearm /usr/lib/arm-linux-gnueabi/crti.o architecture: arm, flags 0x00000011: HAS_RELOC, HAS_SYMS start address 0x00000000 private flags = 5000000: [Version5 EABI] ... RELOCATION RECORDS FOR [.text]: OFFSET TYPE VALUE 0000000a R_ARM_THM_JUMP24 __gmon_start__ 00000010 R_ARM_GOTPC _GLOBAL_OFFSET_TABLE_ 00000014 R_ARM_GOT32 __gmon_start__
RELOCATION RECORDS FOR [.init]: OFFSET TYPE VALUE 00000002 R_ARM_THM_CALL call_gmon_start --- snip ---
"call_gmon_start" code from libc's initfini, obviously thumb/thumb2:
--- snip --- $ objdump -d /usr/lib/arm-linux-gnueabi/crti.o
/usr/lib/arm-linux-gnueabi/crti.o: file format elf32-littlearm
Disassembly of section .text:
00000000 <call_gmon_start>: 0: 4b03 ldr r3, [pc, #12] ; (10 <call_gmon_start+0x10>) 2: 4a04 ldr r2, [pc, #16] ; (14 <call_gmon_start+0x14>) 4: 447b add r3, pc 6: 589b ldr r3, [r3, r2] 8: b10b cbz r3, e <call_gmon_start+0xe> a: f7ff bffe b.w 0 <__gmon_start__> e: 4770 bx lr 10: 00000008 .word 0x00000008 14: 00000000 .word 0x00000000
Disassembly of section .init:
00000000 <_init>: 0: b508 push {r3, lr} 2: f7ff fffe bl 0 <_init> 6: bf00 nop
Disassembly of section .fini:
00000000 <_fini>: 0: b508 push {r3, lr} 2: bf00 nop --- snip ---
--- snip --- (gdb) disas Dump of assembler code for function call_gmon_start: 0x402831c0 <+0>: ldr r3, [pc, #12] ; (0x402831d0 <call_gmon_start+16>) 0x402831c2 <+2>: ldr r2, [pc, #16] ; (0x402831d4 <call_gmon_start+20>) 0x402831c4 <+4>: add r3, pc 0x402831c6 <+6>: ldr r3, [r3, r2] 0x402831c8 <+8>: cbz r3, 0x402831ce <call_gmon_start+14> 0x402831ca <+10>: b.w 0x40282cc4 => 0x402831ce <+14>: bx lr 0x402831d0 <+16>: andeq r2, r7, r8, lsr lr 0x402831d4 <+20>: andeq r0, r0, r4, asr r3 End of assembler dump. (gdb) info reg r0 0x1 1 r1 0x407d4380 1081951104 r2 0x354 852 r3 0x0 0 r4 0xbeffe2d0 3204440784 r5 0xbeffed70 3204443504 r6 0x88c1 35009 r7 0x40d6fc40 1087831104 r8 0x0 0 r9 0x0 0 r10 0x4001e000 1073864704 r11 0x0 0 r12 0x402f6328 1076847400 sp 0x40d6fc38 0x40d6fc38 lr 0x4027182b 1076303915 pc 0x402831ce 0x402831ce <call_gmon_start+14> cpsr 0x800f0030 -2146500560 --- snip ---
"bx lr" (return from subroutine): due to cpsr "T" bit already set, it will remain in thumb mode.
--- snip --- (gdb) si 0x4027182a in _init () from /home/linaro/projects/wine/wine-install/bin/../lib/wine/ntdll.dll.so (gdb) disas Dump of assembler code for function _init: 0x40271824 <+0>: push {r3, lr} 0x40271826 <+2>: bl 0x402831c0 <call_gmon_start> => 0x4027182a <+6>: nop 0x4027182c <+8>: b 0x40282830 <__wine_spec_pe_header+69632> End of assembler dump. (gdb) info reg r0 0x1 1 r1 0x407d4380 1081951104 r2 0x354 852 r3 0x0 0 r4 0xbeffe2d0 3204440784 r5 0xbeffed70 3204443504 r6 0x88c1 35009 r7 0x40d6fc40 1087831104 r8 0x0 0 r9 0x0 0 r10 0x4001e000 1073864704 r11 0x0 0 r12 0x402f6328 1076847400 sp 0x40d6fc38 0x40d6fc38 lr 0x4027182b 1076303915 pc 0x4027182a 0x4027182a <_init+6> cpsr 0x800f0030 -2146500560 --- snip ---
Still in thumb mode (16 bit nop). The next long branch was originally assembled s 32 bit ARM opcode (through Wine's assembler invocation) and is not valid for thumb mode.
--- snip --- (gdb) disas Dump of assembler code for function _init: 0x40271824 <+0>: push {r3, lr} 0x40271826 <+2>: bl 0x402831c0 <call_gmon_start> 0x4027182a <+6>: nop => 0x4027182c <+8>: b 0x40282830 <__wine_spec_pe_header+69632> End of assembler dump. (gdb) si 0x4027182e in _init () from /home/linaro/projects/wine/wine-install/bin/../lib/wine/ntdll.dll.so --- snip ---
It's interpreted as two distinct 16 bit thumb opcodes, hence not doing as intended (branch over 64 KiB).
Regards
http://bugs.winehq.org/show_bug.cgi?id=30134
--- Comment #1 from Anastasius Focht focht@gmx.net 2012-03-10 19:14:53 CST --- Hello,
for good overview/porting guide regarding thumb2 see:
https://wiki.edubuntu.org/ARM/Thumb2PortingHowto
Back to the problem ...
If I force 32 bit ARM code generation through the build system, passing "-marm" to compiler CFLAGS, overriding compiler's default "-mthumb" it won't work here.
Looking at the intermediate assembler file (-save-temps):
--- snip --- /* File generated automatically from /home/linaro/projects/wine/wine-git/dlls/ntdll/ntdll.spec; do not edit! */ /* This file can be copied, modified and distributed without restriction. */
.section ".init","ax"
b 1f __wine_spec_pe_header: .skip 69632 1:
.data .align 2 .globl __wine_spec_nt_header .hidden __wine_spec_nt_header __wine_spec_nt_header: .L__wine_spec_rva_base: .long 0x4550 ... .long 0,0
.section .rodata .globl __wine_spec_file_name .hidden __wine_spec_file_name __wine_spec_file_name: .L__wine_spec_file_name: .string "ntdll.dll"
.section ".init","ax" bl __wine_spec_init_ctor --- snip ---
There is no explicit ".arm" (.code 32) or ".thumb" (.code 16) directive for the sections. As already said: the GNU assembler will generate 32 bit ARM object code from .s file by default if not told otherwise.
Due to the way the toolchain and userland was built (armv7 thumb2), userland libraries such as libc and the compiler support libraries such as libgcc will still contain thumb-2 instructions even if the compiler was invoked with "-marm".
Running "wineboot" again built with CFLAGS="-marm":
--- snip --- Program received signal SIGSEGV, Segmentation fault. 0x40280000 in __wine_spec_pe_header () from /home/linaro/projects/wine/wine-install/bin/../lib/wine/ntdll.dll.so (gdb) bt #0 0x40280000 in __wine_spec_pe_header () from /home/linaro/projects/wine/wine-install/bin/../lib/wine/ntdll.dll.so #1 0x4027682a in _init () from /home/linaro/projects/wine/wine-install/bin/../lib/wine/ntdll.dll.so #2 0x4030ceb0 in __wine_spec_dll_entry (inst=0x40280000, reason=1, reserved=0x1) at /home/linaro/projects/wine/wine-git/dlls/winecrt0/dll_entry.c:37 #3 0x402b9154 in call_dll_entry_point (proc=0x4030ce38 <__wine_spec_dll_entry>, module=0x40280000, reason=1, reserved=0x1) at /home/linaro/projects/wine/wine-git/dlls/ntdll/loader.c:175 #4 0x402bba94 in MODULE_InitDLL (wm=0x40803158, reason=1, lpReserved=0x1) at /home/linaro/projects/wine/wine-git/dlls/ntdll/loader.c:978 #5 0x402bbf2c in process_attach (wm=0x40803158, lpReserved=0x1) at /home/linaro/projects/wine/wine-git/dlls/ntdll/loader.c:1067 #6 0x402bbeb0 in process_attach (wm=0x40803200, lpReserved=0x1) at /home/linaro/projects/wine/wine-git/dlls/ntdll/loader.c:1059 #7 0x402bbeb0 in process_attach (wm=0x408035e8, lpReserved=0x1) at /home/linaro/projects/wine/wine-git/dlls/ntdll/loader.c:1059 #8 0x402bbeb0 in process_attach (wm=0x40803698, lpReserved=0x1) at /home/linaro/projects/wine/wine-git/dlls/ntdll/loader.c:1059 #9 0x402c0ca8 in attach_process_dlls (wm=0x40803698) at /home/linaro/projects/wine/wine-git/dlls/ntdll/loader.c:2541 #10 0x40028e4c in wine_call_on_stack () at /home/linaro/projects/wine/wine-git/libs/wine/port.c:60 #11 0x40028e4c in wine_call_on_stack () at /home/linaro/projects/wine/wine-git/libs/wine/port.c:60 --- snip ---
Whoops.
If we now look at disassembly:
--- snip --- (gdb) disas Dump of assembler code for function __wine_spec_dll_entry: 0x4030ce38 <+0>: push {r11, lr} 0x4030ce3c <+4>: add r11, sp, #4 0x4030ce40 <+8>: sub sp, sp, #24 ... 0x4030cea0 <+104>: mov r0, r2 0x4030cea4 <+108>: mov r1, r3 0x4030cea8 <+112>: mov r2, #0 0x4030ceac <+116>: bl 0x4030e250 <___init_veneer> 0x4030ceb0 <+120>: ldr r0, [r11, #-16] 0x4030ceb4 <+124>: ldr r1, [r11, #-20] 0x4030ceb8 <+128>: ldr r2, [r11, #-24] 0x4030cebc <+132>: bl 0x402c19a4 <DllMain> 0x4030cec0 <+136>: str r0, [r11, #-8] --- snip ---
32 bit ARM code with thumb interworking veneers. The veneers are necessary because libc/libgcc is still thumb2 code, hence it needs mode switching.
The veneer will do the arm->thumb mode switch:
--- snip --- => 0x4030e250 <+0>: ldr r12, [pc, #4] ; 0x4030e25c <___init_veneer+12> 0x4030e254 <+4>: add r12, pc, r12 0x4030e258 <+8>: bx r12 0x4030e25c <+12>: ; <UNDEFINED> instruction: 0xfff685c9 ... (gdb) disas 0x40276825 Dump of assembler code for function _init: 0x40276824 <+0>: push {r3, lr} 0x40276826 <+2>: bl 0x402881c0 <call_gmon_start> 0x4027682a <+6>: nop 0x4027682c <+8>: b 0x40287830 <__wine_spec_pe_header+69632> --- snip ---
To fix the ".init" section problem for "thumb" toolchains/userlands there are several approaches.
One is to explicitly insert ".thumb" directive to ".init" section (along with ".syntax unified" to use unified assembler syntax).
Unfortunately this will break some stuff.
http://source.winehq.org/git/wine.git/blob/6f84e89d2dbb7fb18e921fa82782d200a...
--- snip --- 451 default: 452 output( "\n\t.section ".init","ax"\n" ); ... 465 output( "__wine_spec_pe_header:\n" ); 466 output( "\t.skip %u\n", 65536 + page_size ); 467 output( "1:\n" ); --- snip ---
"b 1f" -> 16-bit thumb branch can't encode the range required by __wine_spec_pe_header padding (64 KiB).
If you are on armv6t2+ machines (like Cortex-A series) you can use thumb2 long branch here. The 32-bit thumb2 long branch encoding has a range of +/-16MiB,
--- snip --- .syntax unified .thumb b.w 1f ... 1: --- snip ---
For machines < armv6t2 (no thumb2 support) you have to encode the long branch differently, ex:
--- snip --- add r12, pc, #5 add r12, r12, #69632 ; 0x11000 bx r12 --- snip ---
It might be useful to separate the current shared code snippets between CPU_ARM and CPU_POWERPC to allow handling of ARM-specifics better. This is also needed for proper insertion of section attributes for assembler.
Defining ".init" as ".thumb" and inserting proper thumb(2) branch, "wineboot" still fails:
--- snip --- Program received signal SIGSEGV, Segmentation fault. 0x40931b40 in NtCurrentTeb () from /home/linaro/projects/wine/wine-install/bin/../lib/wine/kernel32.dll.so (gdb) bt #0 0x40931b40 in NtCurrentTeb () from /home/linaro/projects/wine/wine-install/bin/../lib/wine/kernel32.dll.so #1 0x4097666c in __wine_kernel_init () at /home/linaro/projects/wine/wine-git/dlls/kernel32/process.c:1138 #2 0x402c1d1c in __wine_process_init () at /home/linaro/projects/wine/wine-git/dlls/ntdll/loader.c:2877 #3 0x40026ff8 in wine_init (argc=2, argv=0xbefff764, error=0xbefff20c "", error_size=1024) at /home/linaro/projects/wine/wine-git/libs/wine/loader.c:831 #4 0x00008bbc in main (argc=2, argv=0xbefff764) at /home/linaro/projects/wine/wine-git/loader/main.c:230 --- snip ---
Whoops.
--- snip --- (gdb) disas 0x4097666c Dump of assembler code for function __wine_kernel_init: 0x40976640 <+0>: push {r4, r5, r11, lr} 0x40976644 <+4>: add r11, sp, #12 0x40976648 <+8>: sub sp, sp, #3680 ; 0xe60 0x4097664c <+12>: sub sp, sp, #8 0x40976650 <+16>: ldr r4, [pc, #1916] ; 0x40976dd4 <__wine_kernel_init+1940> 0x40976654 <+20>: add r4, pc, r4 0x40976658 <+24>: ldr r3, [pc, #1912] ; 0x40976dd8 <__wine_kernel_init+1944> 0x4097665c <+28>: ldr r3, [r4, r3] 0x40976660 <+32>: ldr r3, [r3] 0x40976664 <+36>: str r3, [r11, #-16] 0x40976668 <+40>: bl 0x409a06d8 <__NtCurrentTeb_veneer> 0x4097666c <+44>: mov r3, r0 ... (gdb) disas 0x409a06d8 Dump of assembler code for function __NtCurrentTeb_veneer: 0x409a06d8 <+0>: ldr r12, [pc, #4] ; 0x409a06e4 <__NtCurrentTeb_veneer+12> 0x409a06dc <+4>: add r12, pc, r12 0x409a06e0 <+8>: bx r12 0x409a06e4 <+12>: ; <UNDEFINED> instruction: 0xfff91459 End of assembler dump. ... (gdb) disas NtCurrentTeb Dump of assembler code for function NtCurrentTeb: 0x402ef578 <+0>: push {r11, lr} 0x402ef57c <+4>: add r11, sp, #4 0x402ef580 <+8>: ldr r3, [pc, #24] ; 0x402ef5a0 <NtCurrentTeb+40> 0x402ef584 <+12>: add r3, pc, r3 0x402ef588 <+16>: ldr r3, [r3] 0x402ef58c <+20>: mov r0, r3 0x402ef590 <+24>: bl 0x402881b0 0x402ef594 <+28>: mov r3, r0 0x402ef598 <+32>: mov r0, r3 0x402ef59c <+36>: pop {r11, pc} --- snip ---
It seems the import thunks are now considered thumb (same .s spec file) but the actual function code was generated as separate .o with 32 bit ARM code through C compiler (-marm).
".arm" directives have to be explicitly emitted for import thunks ".text" section (output_immediate_import_thunks). Also: output_delayed_import_thunks, output_stubs (basically everything that outputs "\t.text\n" passed to assembler).
With that changes applied Wine builtin programs (wineboot, notepad) finally start in thumb2 userland (though compiled as arm32, except for .init part) ;-)
Well, it is possible to create a full thumb2 Wine build but that requires more work, emitting more section directives and revising ARM inline assembler code.
You might ask: why not rebuilding the target toolchain with "--with-mode=arm" instead of "--with-mode=thumb ..."?
The toolchain is arm-linux target hence glibc has already been compiled and provides the crti.o startup file as thumb2 (chicken and egg problem).
For arm32 crti.o startup file I would have to create a compiler for arm-elf target. I could hack arm-linux toolchain target to also include building of crti.o but that isn't really feasible ...
Regards
http://bugs.winehq.org/show_bug.cgi?id=30134
André H. nerv@dawncrow.de changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |nerv@dawncrow.de
--- Comment #2 from André H. nerv@dawncrow.de 2012-03-27 12:03:02 CDT --- Help, why didn't someone CCed the ARM Guy on that bug???
Anyway, never expected the famous AF to try out my ARM port. The problem looks familiar: "On ARM-Ubuntu it most likely will not run because of compiler problems (if compiled on that platform)" from http://wiki.winehq.org/ARM?action=recall&rev=36
I gave up while debugging and thought it's a compiler bug as it works when compiling inside scratchbox.
--- scratchbox --- gcc -v Using built-in specs. Reading specs from /scratchbox/compilers/cs2007q3-glibc2.5-arm7/gcc.specs rename spec cpp to old_cpp rename spec cc1 to old_cc1 rename spec link to old_link rename spec mflib to old_mflib Target: arm-none-linux-gnueabi Configured with: /home/jhakala/cs2007q3-sb8/arm/src/gcc-4.2/configure --build=i686-pc-linux-gnu --host=i686-pc-linux-gnu --target=arm-none-linux-gnueabi --enable-threads --disable-libmudflap --disable-libssp --disable-libgomp --disable-libstdcxx-pch --with-gnu-as --with-gnu-ld --enable-languages=c,c++ --enable-shared --enable-symvers=gnu --enable-__cxa_atexit --disable-nls --prefix=/opt/maemo --with-sysroot=/opt/maemo/arm-none-linux-gnueabi/libc --with-build-sysroot=/home/jhakala/cs2007q3-sb8/arm/install/arm-none-linux-gnueabi/libc --with-build-time-tools=/home/jhakala/cs2007q3-sb8/arm/install/arm-none-linux-gnueabi/bin Thread model: posix gcc version 4.2.1 --- /scratchbox ---
---> no --with-mode=... (seems to default to arm then)
--- linaro@pandaboard --- gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib/arm-linux-gnueabi/gcc/arm-linux-gnueabi/4.5.2/lto-wrapper Target: arm-linux-gnueabi Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.5.2-8ubuntu4' --with-bugurl=file:///usr/share/doc/gcc-4.5/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.5 --enable-shared --enable-multiarch --with-multiarch-defaults=arm-linux-gnueabi --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib/arm-linux-gnueabi --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.5 --libdir=/usr/lib/arm-linux-gnueabi --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-plugin --enable-gold --enable-ld=default --with-plugin-ld=ld.gold --enable-objc-gc --disable-sjlj-exceptions --with-arch=armv7-a --with-float=softfp --with-fpu=vfpv3-d16 --with-mode=thumb --disable-werror --enable-checking=release --build=arm-linux-gnueabi --host=arm-linux-gnueabi --target=arm-linux-gnueabi Thread model: posix gcc version 4.5.2 (Ubuntu/Linaro 4.5.2-8ubuntu4) --- /linaro@pandaboard ---
---> --with-mode=thumb
So what we are doing is --- spec32.c --- output( "\tb 1f\n" ); --- /spec32.c --- which places "b 1f" into an assembler file. The question is why the hell the assembler places that as arm32 instruction directly behind thumb instructions??? it should know better (that's why i still think that might be a compiler/assembler bug)! Aside that we should really change our code to be more foolproof. Now we can - after that really good analysis. I'll have a look a that and further on the import thunk thing, but i don't fully understand:
--- quote --- It seems the import thunks are now considered thumb (same .s spec file) but the actual function code was generated as separate .o with 32 bit ARM code through C compiler (-marm). --- /quote ---
spec file? thumb?
Thanks for the bug report, the analysis and further explanations :) For the future: Be free to CC me on ARM related bugs.
http://bugs.winehq.org/show_bug.cgi?id=30134
--- Comment #3 from André H. nerv@dawncrow.de 2012-03-28 10:48:56 CDT --- Created attachment 39577 --> http://bugs.winehq.org/attachment.cgi?id=39577 ugly hack
this patch makes the linaro toolchain working, not sure if all of it is needed.
http://bugs.winehq.org/show_bug.cgi?id=30134
--- Comment #4 from André H. nerv@dawncrow.de 2012-03-28 15:33:33 CDT --- i had some ideas for the different problems: * use something like __attribute__((__arm__)) in WINAPI, but sadly gcc doesn't have an attribute to define arm/thumb per function... * forward -marm to the assembler, but sadly the linaro as only has -mthumb option!?
not sure if something like CPU_THUMB is nice to see in winebuild? further i'd like to stay as compatible as i can to other ARMs like in bug 21192, so if possible no bx or blx.
AF, any thoughts?
http://bugs.winehq.org/show_bug.cgi?id=30134
--- Comment #5 from Anastasius Focht focht@gmx.net 2012-03-28 17:22:49 CDT --- Hello André,
your patch is what I basically did to get Wine working with thumb2 userlands ;-)
--- quote --- * forward -marm to the assembler, but sadly the linaro as only has -mthumb option!? --- quote ---
The assembler will compile in arm mode unless it is told to use thumb mode. It's the toolchain (compiler) default that can be "-mthumb" but usually not the assembler that was built as part of binutils. One exception can be binutils/toolchains that target Thumb-only processors like cortex M3.
--- quote --- * use something like __attribute__((__arm__)) in WINAPI, but sadly gcc doesn't have an attribute to define arm/thumb per function... --- quote ---
For inline assembly you can always control this by emitting directives like .thumb_func (unified syntax). For pure C code I don't see a need for this. The compiler/linker will take care of everything, generate code for arm<->thumb switches where needed (branch with instruction set change/interworking veneers).
To handle the special case of arm vs. thumb crti/crtn.o in .init section you could use "__thumb2__" when you want to emit the snippet with thumb2-only "b.w". Toolchains that default to "thumb2" define it:
--- snip --- linaro@linaro-ubuntu-desktop:~$ gcc -dM -E - < /dev/null | grep thumb #define __thumb2__ 1 #define __thumb__ 1 --- snip ---
When not defined use arm 32 bit branch as of now. The thumb1 case (<armv7/armv6t2) can be handled later if really needed.
The "blx" in "wine_call_on_stack" is fine. No one really wants to build/run Wine on pre-armv5 targets.
--- quote --- not sure if something like CPU_THUMB is nice to see in winebuild? --- quote ---
Where do you need that? I think CPU_ARM should be enough for now. There are several ways to determine/handle instruction set/mode switches where needed.
Regards
http://bugs.winehq.org/show_bug.cgi?id=30134
--- Comment #6 from Anastasius Focht focht@gmx.net 2012-03-28 17:38:04 CDT --- Created attachment 39585 --> http://bugs.winehq.org/attachment.cgi?id=39585 wine 1.5 running on i.mx6q sabrelite
Wine built with default -mthumb and .init section patch while winebuild generated thunks/imports passed to assembler still compile as arm (no harm as veneers are automagically inserted).
http://bugs.winehq.org/show_bug.cgi?id=30134
--- Comment #7 from Anastasius Focht focht@gmx.net 2012-03-28 17:41:15 CDT --- Created attachment 39586 --> http://bugs.winehq.org/attachment.cgi?id=39586 wine 1.5 running on omap4 pandaboard
Wine built with same spec (thumb) ... Though I have some issue with audio and some graphics artifacts to sort out on Pandaboard :|
http://bugs.winehq.org/show_bug.cgi?id=30134
--- Comment #8 from André H. nerv@dawncrow.de 2012-03-29 15:00:01 CDT --- the point is: as long as we don't know how much native applications WOA(Windows on ARM) will have that we could run, ARM is a good winelib target for all ARMs. And there are also >=armv5 that don't support thumb, so i don't like b.w, blx and so on.
i played a bit with: case CPU_ARM: output( "\tldr r0,[pc,#0]\n" ); output( "\tmov pc, r0\n" ); output( "\t.long 1f\n" ); and forcing "as" to -mthumb (that code can be compiled to arm and thumb) without good results... maybe you can debug that further...
further we can't just do a "#ifdef __thumb2__" in winebuild's spec32.c, because winebuild is also for crosscompiling and that would break it. And the toolchain doesn't tell by it's name that it's targets thumb(2) so we can't introduce CPU_THUMB... Sadly we can't cleanly detect what crti.o is compiled for...
the blx in libwine maybe can be activated per "#ifdef __thumb2__", but first we need to fix the winebuild problem in a clean way. I'm running out of ideas. thoughts?
http://bugs.winehq.org/show_bug.cgi?id=30134
--- Comment #9 from André H. nerv@dawncrow.de 2012-04-12 16:18:04 CDT --- small step: http://source.winehq.org/git/wine.git/commitdiff/db09c6c393ff7bdef842f67e62e...
http://bugs.winehq.org/show_bug.cgi?id=30134
--- Comment #10 from Anastasius Focht focht@gmx.net 2012-04-12 18:44:54 CDT --- Hello André,
--- quote --- small step --- quote ---
for man ... one giant leap for mankind ;-)
Not sure if it's worth to pursue full Thumb1 compatibility for all "generated" code passed to assembler. Everything else will be Thumb2 anyway when built with modern toolchains using Cortex-A profiles.
From what I've read, native Windows-on-ARM apps/code will make use of Thumb2
instruction set which actually makes sense if you look at the required minimum specs for Windows on ARM (ARMv7 and above). Not taking advantage of the instruction set just wastes lots of potential (code density).
Some links:
http://blogs.msdn.com/b/b8/archive/2012/02/09/building-windows-for-the-arm-p...
http://www.bitcrazed.com/post/2011/09/20/Visual-Studio-11-Developer-Preview-...
(disassembly screenshot indicates Thumb2).
--- quote --- i played a bit with: case CPU_ARM: output( "\tldr r0,[pc,#0]\n" ); output( "\tmov pc, r0\n" ); output( "\t.long 1f\n" );
and forcing "as" to -mthumb (that code can be compiled to arm and thumb) without good results... maybe you can debug that further... --- quote ---
You need something that gets it right for ARM, "old" Thumb1 and Thumb2 without mode switching.
You could make use of "ADR" pseudo instruction. Something like this might work:
--- snip --- adr r0, 2f ldr r0, [r0] mov pc, r0 .align 2: .long 1f __wine_spec_pe_header: .skip xxx 1: ... --- snip ---
Regards
http://bugs.winehq.org/show_bug.cgi?id=30134
--- Comment #11 from André H. nerv@dawncrow.de 2012-04-18 13:55:09 CDT --- i "asked linaro": https://ask.linaro.org/questions/1119/crtio-instruction-set-and-init-section...
http://bugs.winehq.org/show_bug.cgi?id=30134
--- Comment #12 from André H. nerv@dawncrow.de 2012-04-29 15:13:12 CDT --- http://source.winehq.org/patches/data/85848 http://source.winehq.org/patches/data/85849 http://source.winehq.org/patches/data/85850 http://source.winehq.org/patches/data/85853
http://bugs.winehq.org/show_bug.cgi?id=30134
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- Fixed by SHA1| |f93d3ad2f557df43af165468a09 | |10c9d9a3015e0 Status|NEW |RESOLVED Resolution| |FIXED
--- Comment #13 from Anastasius Focht focht@gmx.net 2012-04-30 15:27:44 CDT --- Hello André,
thanks for the work! Fixed by commits:
http://source.winehq.org/git/wine.git/commitdiff/2a58169dbc41e0110bce7839b52... (ntdll: Correctly handle Thumb exceptions on ARM)
http://source.winehq.org/git/wine.git/commitdiff/833b655ae62ef7c6e2bd9b5713e... (winebuild: Expect a Thumb mode toolchain on ARM)
http://source.winehq.org/git/wine.git/commitdiff/33ca051472db9f6730afedef532... (configure: Check for Thumb2 on ARM and compile always in ARM mode)
http://source.winehq.org/git/wine.git/commitdiff/f93d3ad2f557df43af165468a09... (libwine: Always use Thumb instructions on ARM)
Now Wine compiles and runs out of the box with Linaro gcc 4.6.x toolchain defaults (thumb2).
PandaBoard (OMAP4 - Cortex A9 dual) SabreLite board (i.mx6 - Cortex A9 quad)
Both are upgraded to Ubuntu 12.04 LTS (GNU/Linux 3.2.0-1000-linaro armv7l)
Notepad, regedit ... hurraay!
Now we need some Windows on ARM apps ;-)
Regards
http://bugs.winehq.org/show_bug.cgi?id=30134
André H. nerv@dawncrow.de changed:
What |Removed |Added ---------------------------------------------------------------------------- Fixed by SHA1|f93d3ad2f557df43af165468a09 |833b655ae62ef7c6e2bd9b5713e |10c9d9a3015e0 |0063a0000988b
--- Comment #14 from André H. nerv@dawncrow.de 2012-05-01 09:18:40 CDT --- (In reply to comment #13)
Hello André,
thanks for the work!
np ;)
Notepad, regedit ... hurraay!
Now we need some Windows on ARM apps ;-)
get VS11 beta and have fun, note that you need to apply a patch for http://bugs.winehq.org/show_bug.cgi?id=29730 also for running apps, as msvc*110 need it (yes, the ARM versions of msvc*110)
http://bugs.winehq.org/show_bug.cgi?id=30134
Alexandre Julliard julliard@winehq.org changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |CLOSED
--- Comment #15 from Alexandre Julliard julliard@winehq.org 2012-05-11 13:21:18 CDT --- Closing bugs fixed in 1.5.4.
http://bugs.winehq.org/show_bug.cgi?id=30134
--- Comment #16 from André H. nerv@dawncrow.de 2012-06-25 13:29:36 CDT --- see also: http://source.winehq.org/git/wine.git/commitdiff/e7730053f3c859b53df27738610...
This let's us compile on linaro _and_ other toolchains e.g. the fedora one. We might get problems with copy protections, but let's wait until we need to fix them on ARM ;)