# This patch contains various fixes for the thumb code handling in GCC 3.4.4 # # Most of these are minor fixes to code which is either missing (Linux thumb # div0, thumb clear instruction cache) or uses the wrong return mechanism # (libffi) # # There is also a significant design problem with the _call_via_rx code - # it cannot be in a shared library because a call via PLT simply won't # work (for _call_via_ip) and is very inefficient anyway. # # This is fixed in uclibc simply by incorporating the code into crti.S # (an extra 30 bytes for the 15 functions) even though not all link units # require all the code - there is so little of it. That doesn't work with # the crti.asm here because it is linked with libgcc.a which already defines # these symbols # --- gcc-3.4.4/gcc/config/arm/t-linux.orig 2005-08-09 08:55:02.181797492 -0700 +++ gcc-3.4.4/gcc/config/arm/t-linux 2005-08-09 08:58:22.766419486 -0700 @@ -7,6 +7,7 @@ LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx \ _negdf2 _addsubdf3 _muldivdf3 _cmpdf2 _unorddf2 _fixdfsi _fixunsdfsi \ _truncdfsf2 _negsf2 _addsubsf3 _muldivsf3 _cmpsf2 _unordsf2 \ + _call_via_rX \ _fixsfsi _fixunssfsi # MULTILIB_OPTIONS = mhard-float/msoft-float --- gcc-3.4.4/.pc/gcc34-thumb-support.patch/gcc/config/arm/lib1funcs.asm 2004-01-15 08:56:34.000000000 -0800 +++ gcc-3.4.4/gcc/config/arm/lib1funcs.asm 2005-09-21 21:32:03.376927755 -0700 @@ -811,13 +811,18 @@ /* Constants taken from and */ #define SIGFPE 8 +#if !defined __thumb__ #define __NR_SYSCALL_BASE 0x900000 +#else +#define __NR_SYSCALL_BASE 0 +#endif #define __NR_getpid (__NR_SYSCALL_BASE+ 20) #define __NR_kill (__NR_SYSCALL_BASE+ 37) .code 32 FUNC_START div0 +#if ! defined __thumb__ stmfd sp!, {r1, lr} swi __NR_getpid cmn r0, #1000 @@ -825,6 +830,28 @@ mov r1, #SIGFPE swi __NR_kill RETLDM r1 +#else + push {r1, r7, lr} + mov r7, #__NR_getpid + swi 0 + @ above the compare is with -1000, but the standard syscall + @ macro checks for -1..-125 + add r0, #125 + bcs 90f + sub r0, #125 + mov r1, #SIGFPE + mov r7, #__NR_kill + swi 0 +90: +#if __ARM_ARCH__ > 4 + pop {r1, r7, pc} +#else + @ on 4T that won't work + pop {r1, r7} + pop {r3} + bx r3 +#endif +#endif FUNC_END div0 @@ -845,14 +872,14 @@ code here switches to the correct mode before executing the function. */ .text - .align 0 + .align 1 .force_thumb .macro call_via register THUMB_FUNC_START _call_via_\register + .hidden SYM (_call_via_\register) bx \register - nop SIZE (_call_via_\register) .endm @@ -903,6 +930,7 @@ .code 16 THUMB_FUNC_START _interwork_call_via_\register + .hidden SYM (_interwork_call_via_\register) bx pc nop --- gcc-3.4.4/.pc/gcc34-thumb-support.patch/gcc/config/arm/linux-gas.h 2003-06-19 14:47:06.000000000 -0700 +++ gcc-3.4.4/gcc/config/arm/linux-gas.h 2005-09-20 16:09:55.027862200 -0700 @@ -56,6 +56,7 @@ /* Clear the instruction cache from `beg' to `end'. This makes an inline system call to SYS_cacheflush. */ +#if !defined(__thumb__) #define CLEAR_INSN_CACHE(BEG, END) \ { \ register unsigned long _beg __asm ("a1") = (unsigned long) (BEG); \ @@ -65,3 +66,18 @@ : "=r" (_beg) \ : "0" (_beg), "r" (_end), "r" (_flg)); \ } +#else +#define CLEAR_INSN_CACHE(BEG, END) \ +{ \ + register unsigned long _beg __asm ("a1") = (unsigned long) (BEG); \ + register unsigned long _end __asm ("a2") = (unsigned long) (END); \ + register unsigned long _flg __asm ("a3") = 0; \ + register unsigned long _swi __asm ("a4") = 0xf0002; \ + __asm __volatile ("push {r7}\n" \ + " mov r7,a4\n" \ + " swi 0 @ sys_cacheflush\n" \ + " pop {r7}\n" \ + : "=r" (_beg) \ + : "0" (_beg), "r" (_end), "r" (_flg), "r" (_swi)); \ +} +#endif --- gcc-3.4.4/.pc/gcc34-thumb-support.patch/libffi/src/arm/sysv.S 2003-10-21 12:01:55.000000000 -0700 +++ gcc-3.4.4/libffi/src/arm/sysv.S 2005-09-20 16:09:55.027862200 -0700 @@ -41,6 +41,14 @@ #define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x): #endif +/* Get the correct return instruction */ +#if defined(__ARM_ARCH_4T__) || defined(__ARM_ARCH_5__) \ + || defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_5TE__) +#define RET bx r +#else +#define RET mov pc, +#endif + .text # a1: ffi_prep_args @@ -66,7 +74,7 @@ # And call mov lr, pc - mov pc, ip + RET ip # move first 4 parameters in registers ldr a1, [sp, #0]