I have Android nearly fully functional on the Freerunner. I will be posting patches to this list as I can, but I am in the process of a serious move to another country which will keep me busy until sometime next week. I wanted to get some of the fundamentals out there, however, so that people didn't waste time reproducing work. So, the following patches are for

bionic - Add support for armv4t
dalvik - Ditto
build - Abstract out the armv5 compiler settings so we can override them

I am using gcc 4.2.4 and binutils 2.18 with 1 patch for java exceptions which I am including here as well.

Enjoy!
Sean

diff --git a/libc/Android.mk b/libc/Android.mk
index faca333..67fc01c 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -122,6 +122,7 @@ libc_common_src_files := \
 	stdio/vsnprintf.c \
 	stdio/vsprintf.c \
 	stdio/vscanf.c \
+	stdio/vsscanf.c \
 	stdio/wbuf.c \
 	stdio/wsetup.c \
 	stdlib/_rand48.c \
@@ -200,12 +201,14 @@ libc_common_src_files := \
 	tzcode/localtime.c \
 	tzcode/strftime.c \
 	tzcode/strptime.c \
+	arch-arm/bionic/__clzsi2.S \
 	arch-arm/bionic/__get_pc.S \
 	arch-arm/bionic/__get_sp.S \
 	arch-arm/bionic/_exit_with_stack_teardown.S \
 	arch-arm/bionic/_setjmp.S \
 	arch-arm/bionic/atomics_arm.S \
 	arch-arm/bionic/clone.S \
+	arch-arm/bionic/ffs.S \
 	arch-arm/bionic/memcmp.S \
 	arch-arm/bionic/memcmp16.S \
 	arch-arm/bionic/memcpy.S \
diff --git a/libc/arch-arm/bionic/atomics_arm.S b/libc/arch-arm/bionic/atomics_arm.S
index b2da09f..a05641f 100644
--- a/libc/arch-arm/bionic/atomics_arm.S
+++ b/libc/arch-arm/bionic/atomics_arm.S
@@ -46,9 +46,15 @@ __atomic_dec:
 1: @ atomic_dec
     ldr     r0, [r2]
     mov     r3, #kernel_atomic_base
-    add     lr, pc, #4
     sub     r1, r0, #1
+#ifndef __ARM_ARCH_4__
+    mov     lr, pc
     add     pc, r3, #(kernel_cmpxchg - kernel_atomic_base)
+#else
+    add     ip, r3, #(kernel_cmpxchg - kernel_atomic_base)
+    mov     lr, pc
+    bx      ip
+#endif
     bcc     1b
     add     r0, r1, #1
     ldmia   sp!, {r4, lr}
@@ -60,9 +66,15 @@ __atomic_inc:
 1: @ atomic_inc
     ldr     r0, [r2]
     mov     r3, #kernel_atomic_base
-    add     lr, pc, #4
     add     r1, r0, #1
+#ifndef __ARM_ARCH_4__
+    mov     lr, pc
     add     pc, r3, #(kernel_cmpxchg - kernel_atomic_base)
+#else
+    add     ip, r3, #(kernel_cmpxchg - kernel_atomic_base)
+    mov     lr, pc
+    bx      ip
+#endif
     bcc     1b
     sub     r0, r1, #1
     ldmia   sp!, {r4, lr}
@@ -74,9 +86,15 @@ __atomic_cmpxchg:
     mov     r4, r0          /* r4 = save oldvalue */
 1: @ atomic_cmpxchg
     mov     r3, #kernel_atomic_base
-    add     lr, pc, #4
     mov     r0, r4          /* r0 = oldvalue */
+#ifndef __ARM_ARCH_4__
+    mov     lr, pc
     add     pc, r3, #(kernel_cmpxchg - kernel_atomic_base)
+#else
+    add     ip, r3, #(kernel_cmpxchg - kernel_atomic_base)
+    mov     lr, pc
+    bx      ip
+#endif
     bcs     2f              /* swap was made. we're good, return. */
     ldr     r3, [r2]        /* swap not made, see if it's because *ptr!=oldvalue */
     cmp     r3, r4
@@ -91,9 +109,15 @@ __atomic_cmpxchg:
 __atomic_cmpxchg:
     stmdb   sp!, {r4, lr}
     mov     r4, r0          /* r4 = save oldvalue */
-1:  add     lr, pc, #4
-    mov     r0, r4          /* r0 = oldvalue */
+1:  mov     r0, r4          /* r0 = oldvalue */
+#ifndef __ARM_ARCH_4__
+    mov     lr, pc
     mov     pc, #KUSER_CMPXCHG
+#else
+    mov     ip, #KUSER_CMPXCHG
+    mov     lr, pc
+    bx      ip
+#endif
     bcs     2f              /* swap was made. we're good, return. */
     ldr     r3, [r2]        /* swap not made, see if it's because *ptr!=oldvalue */
     cmp     r3, r4
@@ -106,9 +130,15 @@ __atomic_dec:
     stmdb   sp!, {r4, lr}
     mov     r2, r0          /* address */
 1:  ldr     r0, [r2]        /* oldvalue */
-    add     lr, pc, #4
     sub     r1, r0, #1      /* newvalue = oldvalue - 1 */
+#ifndef __ARM_ARCH_4__
+    mov     lr, pc
     mov     pc, #KUSER_CMPXCHG
+#else
+    mov     ip, #KUSER_CMPXCHG
+    mov     lr, pc
+    bx      ip
+#endif
     bcc     1b              /* no swap, try again until we get it right */
     mov     r0, ip          /* swapped, return the old value */
     ldmia   sp!, {r4, lr}
@@ -119,9 +149,15 @@ __atomic_inc:
     stmdb   sp!, {r4, lr}
     mov     r2, r0          /* address */
 1:  ldr     r0, [r2]        /* oldvalue */
-    add     lr, pc, #4
     add     r1, r0, #1      /* newvalue = oldvalue + 1 */
+#ifndef __ARM_ARCH_4__
+    mov     lr, pc
     mov     pc, #KUSER_CMPXCHG
+#else
+    mov     ip, #KUSER_CMPXCHG
+    mov     lr, pc
+    bx      ip
+#endif
     bcc     1b              /* no swap, try again until we get it right */
     mov     r0, ip          /* swapped, return the old value */
     ldmia   sp!, {r4, lr}
diff --git a/libc/arch-arm/bionic/memcmp.S b/libc/arch-arm/bionic/memcmp.S
index d19dfb9..aa2eb23 100644
--- a/libc/arch-arm/bionic/memcmp.S
+++ b/libc/arch-arm/bionic/memcmp.S
@@ -41,9 +41,10 @@
  */
 
 memcmp:
+#ifndef __ARM_ARCH_4__
         pld         [r0, #0]
         pld         [r1, #0]
-
+#endif
         /* take of the case where length is 0 or the buffers are the same */
         cmp         r0, r1
         cmpne       r2, #0
@@ -52,9 +53,11 @@ memcmp:
 
         /* save registers */
         stmfd       sp!, {r4, lr}
-        
+
+#ifndef __ARM_ARCH_4__
         pld         [r0, #32]
         pld         [r1, #32]
+#endif
 
         /* since r0 hold the result, move the first source
          * pointer somewhere else
@@ -104,8 +107,11 @@ memcmp:
         subs        r2, r2, #(32 + 4)
         bmi         1f
         
-0:      pld         [r4, #64]
+0:
+#ifndef __ARM_ARCH_4__
+        pld         [r4, #64]
         pld         [r1, #64]
+#endif
         ldr         r0, [r4], #4
         ldr         lr, [r1, #4]!
         eors        r0, r0, ip
@@ -192,8 +198,11 @@ memcmp:
         bic         r1, r1, #3
         ldr         lr, [r1], #4
 
-6:      pld         [r1, #64]
+6:
+#ifndef __ARM_ARCH_4__
+        pld         [r1, #64]
         pld         [r4, #64]
+#endif
         mov         ip, lr, lsr #16
         ldr         lr, [r1], #4
         ldr         r0, [r4], #4
diff --git a/libc/arch-arm/bionic/memcmp16.S b/libc/arch-arm/bionic/memcmp16.S
index c6e6d39..f92bca8 100644
--- a/libc/arch-arm/bionic/memcmp16.S
+++ b/libc/arch-arm/bionic/memcmp16.S
@@ -41,8 +41,10 @@
  */
 
 __memcmp16:
+#ifndef __ARM_ARCH_4__
         pld         [r0, #0]
         pld         [r1, #0]
+#endif
 
         /* take of the case where length is nul or the buffers are the same */
         cmp         r0, r1
@@ -64,8 +66,10 @@ __memcmp16:
         bpl         0f
 
         /* small blocks (less then 12 words) */
+#ifndef __ARM_ARCH_4__
         pld         [r0, #32]
         pld         [r1, #32]
+#endif
 
 1:      ldrh        r0, [r3], #2
         ldrh        ip, [r1], #2
@@ -113,8 +117,10 @@ __memcmp16:
         bmi         1f
         
 0:
+#ifndef __ARM_ARCH_4__
         pld         [r3, #64]
         pld         [r1, #64]
+#endif
         ldr         r0, [r3], #4
         ldr         lr, [r1, #4]!
         eors        r0, r0, ip
@@ -195,8 +201,10 @@ __memcmp16:
         sub         r2, r2, #8
 
 6:
+#ifndef __ARM_ARCH_4__
         pld         [r3, #64]
         pld         [r1, #64]
+#endif
         mov         ip, lr, lsr #16
         ldr         lr, [r1], #4
         ldr         r0, [r3], #4
diff --git a/libc/arch-arm/bionic/memcpy.S b/libc/arch-arm/bionic/memcpy.S
index f6e4a7d..41c5a80 100644
--- a/libc/arch-arm/bionic/memcpy.S
+++ b/libc/arch-arm/bionic/memcpy.S
@@ -52,9 +52,11 @@ memcpy:
 
         // preload the destination because we'll align it to a cache line
         // with small writes. Also start the source "pump".
+#ifndef __ARM_ARCH_4__
         pld         [r0, #0]
         pld         [r1, #0]
         pld         [r1, #32]
+#endif
 
 		/* it simplifies things to take care of len<4 early */
 		cmp			r2, #4
@@ -142,7 +144,9 @@ cached_aligned32:
         add         r12, r12, #64
 
 1:      ldmia		r1!, { r4-r11 }
+#ifndef __ARM_ARCH_4__
         pld         [r12, #64]
+#endif
         subs        r2, r2, #32
 
         // NOTE: if r12 is more than 64 ahead of r1, the following ldrhi
@@ -263,7 +267,9 @@ loop16:
         ldr         r12, [r1], #4
 1:      mov         r4, r12
 		ldmia		r1!, {   r5,r6,r7,  r8,r9,r10,r11}
+#ifndef __ARM_ARCH_4__
         pld         [r1, #64]
+#endif
 		subs		r2, r2, #32
         ldrhs       r12, [r1], #4
 		orr			r3, r3, r4,		lsl #16
@@ -290,7 +296,9 @@ loop8:
         ldr         r12, [r1], #4
 1:      mov         r4, r12
 		ldmia		r1!, {   r5,r6,r7,  r8,r9,r10,r11}
+#ifndef __ARM_ARCH_4__
         pld         [r1, #64]
+#endif
 		subs		r2, r2, #32
         ldrhs       r12, [r1], #4
 		orr			r3, r3, r4,		lsl #24
@@ -317,7 +325,9 @@ loop24:
         ldr         r12, [r1], #4
 1:      mov         r4, r12
 		ldmia		r1!, {   r5,r6,r7,  r8,r9,r10,r11}
+#ifndef __ARM_ARCH_4__
         pld         [r1, #64]
+#endif
 		subs		r2, r2, #32
         ldrhs       r12, [r1], #4
 		orr			r3, r3, r4,		lsl #8
diff --git a/libc/arch-arm/bionic/strlen.c b/libc/arch-arm/bionic/strlen.c
index 3d1fe45..3a49b2b 100644
--- a/libc/arch-arm/bionic/strlen.c
+++ b/libc/arch-arm/bionic/strlen.c
@@ -62,7 +62,9 @@ size_t strlen(const char *s)
         "ldr     %[v], [ %[s] ], #4         \n"
         "sub     %[l], %[l], %[s]           \n"
         "0:                                 \n"
+#ifndef __ARM_ARCH_4__
         "pld     [ %[s], #64 ]              \n"
+#endif
         "sub     %[t], %[v], %[mask], lsr #7\n"
         "and     %[t], %[t], %[mask]        \n"
         "bics    %[t], %[t], %[v]           \n"
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index fe7033d..843c774 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -194,6 +194,10 @@
 #define	__used		/* delete */
 #endif
 
+#ifdef __section
+#undef __section
+#endif
+
 #if __GNUC_PREREQ__(2, 7)
 #define	__packed	__attribute__((__packed__))
 #define	__aligned(x)	__attribute__((__aligned__(x)))
@@ -323,6 +327,14 @@
 #endif
 
 /*
+ * There might be some kernel routines marked as "deprecated" in some
+ * include headers.
+ */
+#ifndef __deprecated
+# define __deprecated	/* DO-NOT-USE */
+#endif
+
+/*
  * Macros for manipulating "link sets".  Link sets are arrays of pointers
  * to objects, which are gathered up by the linker.
  *
diff --git a/libc/include/sys/limits.h b/libc/include/sys/limits.h
index 41d02ff..ffa014a 100644
--- a/libc/include/sys/limits.h
+++ b/libc/include/sys/limits.h
@@ -125,8 +125,13 @@
 
 /* Bionic: the following has been optimized out from our processed kernel headers */
 
-#define  CHILD_MAX   999
-#define  OPEN_MAX    256
+#ifndef CHILD_MAX
+#define CHILD_MAX	999
+#endif
+
+#ifndef OPEN_MAX
+#define OPEN_MAX	256
+#endif
 
 /* Bionic-specific definitions */
 
diff --git a/libc/include/sys/tls.h b/libc/include/sys/tls.h
index d59f1c3..9053f7f 100644
--- a/libc/include/sys/tls.h
+++ b/libc/include/sys/tls.h
@@ -70,7 +70,8 @@ extern int __set_tls(void *ptr);
 
 /* get the TLS */
 #ifdef __arm__
-#  define __get_tls() ( *((volatile void **) 0xffff0ff0) )
+typedef void* (__get_tls_t)(void);
+static const __get_tls_t* __get_tls = (const __get_tls_t *)0xffff0fe0;
 #else
 extern void*  __get_tls( void );
 #endif
diff --git a/libc/include/termios.h b/libc/include/termios.h
index 043fe16..e0a93db 100644
--- a/libc/include/termios.h
+++ b/libc/include/termios.h
@@ -36,6 +36,24 @@
 
 __BEGIN_DECLS
 
+/* line disciplines */
+#define N_TTY		0
+#define N_SLIP		1
+#define N_MOUSE		2
+#define N_PPP		3
+#define N_STRIP		4
+#define N_AX25		5
+#define N_X25		6	/* X.25 async */
+#define N_6PACK		7
+#define N_MASC		8	/* Reserved for Mobitex module <[EMAIL PROTECTED]> */
+#define N_R3964		9	/* Reserved for Simatic R3964 module */
+#define N_PROFIBUS_FDL	10	/* Reserved for Profibus <[EMAIL PROTECTED]> */
+#define N_IRDA		11	/* Linux IrDa - http://irda.sourceforge.net/ */
+#define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
+#define N_HDLC		13	/* synchronous HDLC */
+#define N_SYNC_PPP	14
+#define N_HCI		15  /* Bluetooth HCI UART */
+
 /* Redefine these to match their ioctl number */
 #undef  TCSANOW
 #define TCSANOW    TCSETS
@@ -46,6 +64,10 @@ __BEGIN_DECLS
 #undef  TCSAFLUSH
 #define TCSAFLUSH  TCSETSF
 
+#ifndef N_TTY
+#define N_TTY		0
+#endif
+
 static __inline__ int tcgetattr(int fd, struct termios *s)
 {
     return ioctl(fd, TCGETS, s);
diff --git a/linker/Android.mk b/linker/Android.mk
index 5d11148..5a0ad4e 100644
--- a/linker/Android.mk
+++ b/linker/Android.mk
@@ -29,6 +29,7 @@ else
 endif
 
 LOCAL_MODULE:= linker
+LOCAL_ARM_MODE:= arm
 
 LOCAL_STATIC_LIBRARIES := libcutils libc
 
diff --git a/linker/arch/arm/begin.S b/linker/arch/arm/begin.S
index f9b3bac..3a01c19 100644
--- a/linker/arch/arm/begin.S
+++ b/linker/arch/arm/begin.S
@@ -9,7 +9,7 @@ _start:
 	bl	__linker_init
 
 	/* linker init returns the _entry address in the main image */
-	mov	pc, r0
+	bx	r0
 
 	.section .ctors, "wa"
 	.globl __CTOR_LIST__
diff --git a/vm/alloc/clz.c b/vm/alloc/clz.c
index 77376a3..6da5b41 100644
--- a/vm/alloc/clz.c
+++ b/vm/alloc/clz.c
@@ -18,7 +18,7 @@
 
 int clz_impl(unsigned long int x)
 {
-#if defined(__arm__) && !defined(__thumb__)
+#if defined(__arm__) && !defined(__thumb__) && !defined(__ARM_ARCH_4__)
     return __builtin_clz(x);
 #else
     if (!x) return 32;
diff --git a/vm/alloc/clz.h b/vm/alloc/clz.h
index 58096c9..5cc4248 100644
--- a/vm/alloc/clz.h
+++ b/vm/alloc/clz.h
@@ -18,7 +18,7 @@
 
 #include <stdint.h>
 
-#if defined(__arm__) && !defined(__thumb__)
+#if defined(__arm__) && !defined(__thumb__) && !defined(__ARM_ARCH_4__)
 
 #define CLZ(x) __builtin_clz(x)
 
diff --git a/vm/arch/arm/CallEABI.S b/vm/arch/arm/CallEABI.S
index e3d6c6f..5b260ea 100644
--- a/vm/arch/arm/CallEABI.S
+++ b/vm/arch/arm/CallEABI.S
@@ -236,7 +236,12 @@ DBG strcs   ip, [r8]                    @ DEBUG DEBUG
 
     @ call the method
     ldr     ip, [r4, #8]                @ func
+#ifndef __ARM_ARCH_4__
     blx     ip
+#else
+    mov     lr, pc
+    bx      ip
+#endif
 
     @ We're back, result is in r0 or (for long/double) r0-r1.
     @
@@ -254,7 +259,12 @@ DBG strcs   ip, [r8]                    @ DEBUG DEBUG
 
     @ Restore the registers we saved and return (restores lr into pc, and
     @ the initial stack pointer into sp).
+#ifndef __ARM_ARCH_4__
     ldmdb   r4, {r4, r5, r6, r7, r8, r9, sp, pc}
+#else
+    ldmdb   r4, {r4, r5, r6, r7, r8, r9, sp, lr}
+    bx      lr
+#endif
     .fnend
 
 
@@ -384,7 +394,12 @@ common_squeak\num:
     ldr     r0, strSqueak
     mov     r1, #\num
     bl      printf
+#ifndef __ARM_ARCH_4__
     ldmfd   sp!, {r0, r1, r2, r3, ip, pc}
+#else
+    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
+    bx      lr
+#endif
     .endm
 
     SQUEAK  0
diff --git a/vm/arch/arm/CallOldABI.S b/vm/arch/arm/CallOldABI.S
index bdc14eb..de0a2de 100644
--- a/vm/arch/arm/CallOldABI.S
+++ b/vm/arch/arm/CallOldABI.S
@@ -87,7 +87,7 @@ dvmPlatformInvoke:
 	@ rest of the code.  If we don't plan to use a debugger we can speed
 	@ this up a little.
 	mov		ip, sp
-	stmfd	sp!, {r4, r5, r6, fp, ip, lr, pc}
+	stmfd		sp!, {r4, r5, r6, fp, ip, lr, pc}
 	sub		fp, ip, #4			@ set up fp, same way gdb does
 
 	@ We need to push a variable number of arguments onto the stack.
@@ -141,11 +141,15 @@ dvmPlatformInvoke:
 	@ address supplied by the caller.  The value for "pc" is offset by 8
 	@ due to instruction prefetching.
 	@
-	@ This works for the ARM5 architecture.  Earlier versions may require
-	@ a blx here.
+	@ Use bx to make sure interworking is handled properly.
+	@
+	ldr		ip, [r4, #8]
+#ifndef __ARM_ARCH_4__
+	blx		ip
+#else
 	mov		lr, pc
-	ldr		pc, [r4, #8]
-
+	bx		ip
+#endif
 
 	@ We're back, result is in r0 or (for long/double) r0-r1.
 	@
@@ -158,6 +162,11 @@ dvmPlatformInvoke:
 	@ Restore the registers we saved and return.  Note this remaps stuff,
 	@ so that "sp" comes from "ip", "pc" comes from "lr", and the "pc"
 	@ we pushed on evaporates when we restore "sp".
+#ifndef __ARM_ARCH_4__
 	ldmfd	r5, {r4, r5, r6, fp, sp, pc}
+#else
+	ldmfd	r5, {r4, r5, r6, fp, sp, lr}
+	bx	lr
+#endif
 
 #endif /*__ARM_EABI__*/
diff --git a/vm/jdwp/JdwpAdb.c b/vm/jdwp/JdwpAdb.c
index 91a8e47..07afd3b 100644
--- a/vm/jdwp/JdwpAdb.c
+++ b/vm/jdwp/JdwpAdb.c
@@ -135,7 +135,11 @@ static int  receiveClientFd(JdwpNetState*  netState)
     struct cmsghdr*  cmsg;
     struct iovec     iov;
     char             dummy = '!';
-    char             buffer[sizeof(struct cmsghdr)+sizeof(int)];
+    union {
+        struct cmsghdr cm;
+        char buffer[CMSG_SPACE(sizeof(int))];
+    } cm_un;
+
     int              ret;
 
     iov.iov_base       = &dummy;
@@ -145,8 +149,8 @@ static int  receiveClientFd(JdwpNetState*  netState)
     msg.msg_iov        = &iov;
     msg.msg_iovlen     = 1;
     msg.msg_flags      = 0;
-    msg.msg_control    = buffer;
-    msg.msg_controllen = sizeof(buffer);
+    msg.msg_control    = cm_un.buffer;
+    msg.msg_controllen = sizeof(cm_un.buffer);
     
     cmsg = CMSG_FIRSTHDR(&msg);
     cmsg->cmsg_len   = msg.msg_controllen;
diff --git a/vm/mterp/armv5/OP_AGET_WIDE.S b/vm/mterp/armv5/OP_AGET_WIDE.S
index ec346ca..2d2c817 100644
--- a/vm/mterp/armv5/OP_AGET_WIDE.S
+++ b/vm/mterp/armv5/OP_AGET_WIDE.S
@@ -25,7 +25,12 @@
 
 .L${opcode}_finish:
     FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
+#ifndef __ARM_ARCH_4__
     ldrd    r2, [r0, #offArrayObject_contents]  @ r2/r3<- vBB[vCC]
+#else
+    ldr     r2, [r0, #offArrayObject_contents]
+    ldr     r3, [r0, #(offArrayObject_contents+4)]
+#endif
     add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
     GET_INST_OPCODE(ip)                 @ extract opcode from rINST
     stmia   r9, {r2-r3}                 @ vAA/vAA+1<- r2/r3
diff --git a/vm/mterp/armv5/OP_APUT_WIDE.S b/vm/mterp/armv5/OP_APUT_WIDE.S
index 48738cc..f573eea 100644
--- a/vm/mterp/armv5/OP_APUT_WIDE.S
+++ b/vm/mterp/armv5/OP_APUT_WIDE.S
@@ -28,6 +28,11 @@
     FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
     ldmia   r9, {r2-r3}                 @ r2/r3<- vAA/vAA+1
     GET_INST_OPCODE(ip)                 @ extract opcode from rINST
+#ifndef __ARM_ARCH_4__
     strd    r2, [r0, #offArrayObject_contents]  @ r2/r3<- vBB[vCC]
+#else
+    str     r2, [r0, #offArrayObject_contents]  @ r2/r3<- vBB[vCC]
+    str     r3, [r0, #(offArrayObject_contents+4)]  @ r2/r3<- vBB[vCC]
+#endif
     GOTO_OPCODE(ip)                     @ jump to next instruction
 
diff --git a/vm/mterp/armv5/OP_EXECUTE_INLINE.S b/vm/mterp/armv5/OP_EXECUTE_INLINE.S
index 84836cd..58e050c 100644
--- a/vm/mterp/armv5/OP_EXECUTE_INLINE.S
+++ b/vm/mterp/armv5/OP_EXECUTE_INLINE.S
@@ -53,7 +53,12 @@
 0:
     @b       dvmPerformInlineOp4Std
     ldr     r9, .L${opcode}_table       @ table of InlineOperation
+#ifndef __ARM_ARCH_4__
     ldr     pc, [r9, r10, lsl #4]       @ sizeof=16, "func" is first entry
+#else
+    ldr     ip, [r9, r10, lsl #4]       @ sizeof=16, "func" is first entry
+    bx      ip
+#endif
     @ (not reached)
 
 .L${opcode}_table:
diff --git a/vm/mterp/armv5/OP_IGET_WIDE.S b/vm/mterp/armv5/OP_IGET_WIDE.S
index 22377d9..56f597a 100644
--- a/vm/mterp/armv5/OP_IGET_WIDE.S
+++ b/vm/mterp/armv5/OP_IGET_WIDE.S
@@ -34,7 +34,13 @@
     ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
     beq     common_errNullObject        @ object was null
     mov     r2, rINST, lsr #8           @ r2<- A+
+#ifndef __ARM_ARCH_4__
     ldrd    r0, [r9, r3]                @ r0/r1<- obj.field (64-bit align ok)
+#else
+    ldr    r0, [r9, r3]
+    add	   r1, r3, #4
+    ldr    r1, [r9, r1]
+#endif
     and     r2, r2, #15                 @ r2<- A
     FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
     add     r3, rFP, r2, lsl #2         @ r3<- &fp[A]
diff --git a/vm/mterp/armv5/OP_IGET_WIDE_QUICK.S b/vm/mterp/armv5/OP_IGET_WIDE_QUICK.S
index ece7e7a..1a7d98d 100644
--- a/vm/mterp/armv5/OP_IGET_WIDE_QUICK.S
+++ b/vm/mterp/armv5/OP_IGET_WIDE_QUICK.S
@@ -7,7 +7,13 @@
     cmp     r3, #0                      @ check object for null
     mov     r2, rINST, lsr #8           @ r2<- A(+)
     beq     common_errNullObject        @ object was null
+#ifndef __ARM_ARCH_4__
     ldrd    r0, [r3, r1]                @ r0<- obj.field (64 bits, aligned)
+#else
+    ldr    r0, [r3, r1]
+    add	   r1, r1, #4
+    ldr    r1, [r3, r1]
+#endif
     and     r2, r2, #15
     FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
     add     r3, rFP, r2, lsl #2         @ r3<- &fp[A]
diff --git a/vm/mterp/armv5/OP_IPUT_WIDE.S b/vm/mterp/armv5/OP_IPUT_WIDE.S
index 75465ec..d439da8 100644
--- a/vm/mterp/armv5/OP_IPUT_WIDE.S
+++ b/vm/mterp/armv5/OP_IPUT_WIDE.S
@@ -35,7 +35,13 @@
     beq     common_errNullObject        @ object was null
     FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
     ldmia   r2, {r0-r1}                 @ r0/r1<- fp[A]
-    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
+#ifndef __ARM_ARCH_4__
     strd    r0, [r9, r3]                @ obj.field (64 bits, aligned)<- r0
+#else
+    str     r0, [r9, r3]                @ obj.field (64 bits, aligned)<- r0
+    add     ip, r3, #4
+    str     r1, [r9, ip]                @ obj.field (64 bits, aligned)<- r0
+#endif
+    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
     GOTO_OPCODE(ip)                     @ jump to next instruction
 
diff --git a/vm/mterp/armv5/OP_IPUT_WIDE_QUICK.S b/vm/mterp/armv5/OP_IPUT_WIDE_QUICK.S
index 290591c..fc54af6 100644
--- a/vm/mterp/armv5/OP_IPUT_WIDE_QUICK.S
+++ b/vm/mterp/armv5/OP_IPUT_WIDE_QUICK.S
@@ -11,7 +11,13 @@
     beq     common_errNullObject        @ object was null
     FETCH(r3, 1)                        @ r3<- field byte offset
     FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
+#ifndef __ARM_ARCH_4__
     strd    r0, [r2, r3]                @ obj.field (64 bits, aligned)<- r0/r1
+#else
+    str     r0, [r2, r3]                @ obj.field (64 bits, aligned)<- r0/r1
+    add     ip, r3, #4
+    str     r1, [r2, ip]                @ obj.field (64 bits, aligned)<- r0/r1
+#endif
     GET_INST_OPCODE(ip)                 @ extract opcode from rINST
     GOTO_OPCODE(ip)                     @ jump to next instruction
 
diff --git a/vm/mterp/armv5/OP_SGET_WIDE.S b/vm/mterp/armv5/OP_SGET_WIDE.S
index 1f93a2f..317ba70 100644
--- a/vm/mterp/armv5/OP_SGET_WIDE.S
+++ b/vm/mterp/armv5/OP_SGET_WIDE.S
@@ -14,7 +14,12 @@
     beq     .L${opcode}_resolve         @ yes, do resolve
 .L${opcode}_finish:
     mov     r1, rINST, lsr #8           @ r1<- AA
+#ifndef __ARM_ARCH_4__
     ldrd    r2, [r0, #offStaticField_value] @ r2/r3<- field value (aligned)
+#else
+    ldr     r2, [r0, #offStaticField_value]
+    ldr     r3, [r0, #(offStaticField_value+4)]
+#endif
     add     r1, rFP, r1, lsl #2         @ r1<- &fp[AA]
     FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
     stmia   r1, {r2-r3}                 @ vAA/vAA+1<- r2/r3
diff --git a/vm/mterp/armv5/OP_SPUT_WIDE.S b/vm/mterp/armv5/OP_SPUT_WIDE.S
index a7bc5f2..86cc83b 100644
--- a/vm/mterp/armv5/OP_SPUT_WIDE.S
+++ b/vm/mterp/armv5/OP_SPUT_WIDE.S
@@ -18,7 +18,12 @@
     FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
     ldmia   r9, {r2-r3}                 @ r2/r3<- vAA/vAA+1
     GET_INST_OPCODE(ip)                 @ extract opcode from rINST
+#ifndef __ARM_ARCH_4__
     strd    r2, [r0, #offStaticField_value] @ field<- vAA/vAA+1
+#else
+    str     r2, [r0, #offStaticField_value] @ field<- vAA/vAA+1
+    str     r3, [r0, #(offStaticField_value+4)] @ field<- vAA/vAA+1
+#endif
     GOTO_OPCODE(ip)                     @ jump to next instruction
 %break
 
diff --git a/vm/mterp/armv5/entry.S b/vm/mterp/armv5/entry.S
index a1e3b4e..056db11 100644
--- a/vm/mterp/armv5/entry.S
+++ b/vm/mterp/armv5/entry.S
@@ -107,8 +107,12 @@ dvmMterpStdBail:
     ldr     sp, [r0, #offGlue_bailPtr]      @ sp<- saved SP
     mov     r0, r1                          @ return the changeInterp value
     add     sp, sp, #4                      @ un-align 64
+#ifndef __ARM_ARCH_4__
     ldmfd   sp!, {r4-r10,fp,pc}             @ restore 9 regs
-
+#else
+    ldmfd   sp!, {r4-r10,fp,lr}             @ restore 9 regs
+    bx      lr
+#endif
 
 /*
  * String references.
diff --git a/vm/mterp/armv5/footer.S b/vm/mterp/armv5/footer.S
index 5efb24a..5545a5d 100644
--- a/vm/mterp/armv5/footer.S
+++ b/vm/mterp/armv5/footer.S
@@ -68,7 +68,7 @@ common_periodicChecks:
     bne     3f                          @ debugger/profiler, switch interp
 #endif
 
-    mov     pc, lr                      @ nothing to do, return
+    bx      lr                          @ nothing to do, return
 
 2:  @ check suspend
     ldr     r0, [rGLUE, #offGlue_self]  @ r0<- glue->self
@@ -245,8 +245,14 @@ dalvik_mterp:
 .Lskip:
 #endif
 
+#ifndef __ARM_ARCH_4__
     mov     lr, pc                      @ set return addr
     ldr     pc, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc
+#else
+    ldr     ip, [r2, #offMethod_nativeFunc] @ methodToCall->nativeFunc
+    mov     lr, pc                      @ set return addr
+    bx      ip
+#endif
 
     @ native return; r9=self, r10=newSaveArea
     @ equivalent to dvmPopJniLocals
@@ -559,7 +565,12 @@ common_squeak\num:
     ldr     r0, strSqueak
     mov     r1, #\num
     bl      printf
+#ifndef __ARM_ARCH_4__
     ldmfd   sp!, {r0, r1, r2, r3, ip, pc}
+#else
+    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
+    bx      lr
+#endif
     .endm
 
     SQUEAK  0
@@ -577,7 +588,12 @@ common_printNum:
     mov     r1, r0
     ldr     r0, strSqueak
     bl      printf
+#ifndef __ARM_ARCH_4__
     ldmfd   sp!, {r0, r1, r2, r3, ip, pc}
+#else
+    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
+    bx      lr
+#endif
 
 /*
  * Print a newline, preserving registers.
@@ -586,7 +602,12 @@ common_printNewline:
     stmfd   sp!, {r0, r1, r2, r3, ip, lr}
     ldr     r0, strNewline
     bl      printf
+#ifndef __ARM_ARCH_4__
     ldmfd   sp!, {r0, r1, r2, r3, ip, pc}
+#else
+    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
+    bx      lr
+#endif
 
     /*
      * Print the 32-bit quantity in r0 as a hex value, preserving registers.
@@ -596,7 +617,12 @@ common_printHex:
     mov     r1, r0
     ldr     r0, strPrintHex
     bl      printf
+#ifndef __ARM_ARCH_4__
     ldmfd   sp!, {r0, r1, r2, r3, ip, pc}
+#else
+    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
+    bx      lr
+#endif
 
 /*
  * Print the 64-bit quantity in r0-r1, preserving registers.
@@ -607,7 +633,12 @@ common_printLong:
     mov     r2, r0
     ldr     r0, strPrintLong
     bl      printf
+#ifndef __ARM_ARCH_4__
     ldmfd   sp!, {r0, r1, r2, r3, ip, pc}
+#else
+    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
+    bx      lr
+#endif
 
 /*
  * Print full method info.  Pass the Method* in r0.  Preserves regs.
@@ -615,7 +646,12 @@ common_printLong:
 common_printMethod:
     stmfd   sp!, {r0, r1, r2, r3, ip, lr}
     bl      dvmMterpPrintMethod
+#ifndef __ARM_ARCH_4__
     ldmfd   sp!, {r0, r1, r2, r3, ip, pc}
+#else
+    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
+    bx      lr
+#endif
 
 /*
  * Call a C helper function that dumps regs and possibly some
@@ -625,7 +661,12 @@ common_printMethod:
 common_dumpRegs:
     stmfd   sp!, {r0, r1, r2, r3, ip, lr}
     bl      dvmMterpDumpArmRegs
+#ifndef __ARM_ARCH_4__
     ldmfd   sp!, {r0, r1, r2, r3, ip, pc}
+#else
+    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
+    bx      lr
+#endif
     .endif
 
 
diff --git a/vm/mterp/out/InterpAsm-armv5.S b/vm/mterp/out/InterpAsm-armv5.S
index 1e776ca..e48b360 100644
--- a/vm/mterp/out/InterpAsm-armv5.S
+++ b/vm/mterp/out/InterpAsm-armv5.S
@@ -284,8 +284,12 @@ dvmMterpStdBail:
     ldr     sp, [r0, #offGlue_bailPtr]      @ sp<- saved SP
     mov     r0, r1                          @ return the changeInterp value
     add     sp, sp, #4                      @ un-align 64
+#ifndef __ARM_ARCH_4__
     ldmfd   sp!, {r4-r10,fp,pc}             @ restore 9 regs
-
+#else
+    ldmfd   sp!, {r4-r10,fp,lr}             @ restore 9 regs
+    bx      lr
+#endif
 
 /*
  * String references.
@@ -2650,7 +2654,12 @@ dalvik_inst:
     beq     .LOP_SGET_WIDE_resolve         @ yes, do resolve
 .LOP_SGET_WIDE_finish:
     mov     r1, rINST, lsr #8           @ r1<- AA
+#ifndef __ARM_ARCH_4__
     ldrd    r2, [r0, #offStaticField_value] @ r2/r3<- field value (aligned)
+#else
+    ldr     r2, [r0, #offStaticField_value]
+    ldr     r3, [r0, #(offStaticField_value+4)]
+#endif
     add     r1, rFP, r1, lsl #2         @ r1<- &fp[AA]
     FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
     stmia   r1, {r2-r3}                 @ vAA/vAA+1<- r2/r3
@@ -2831,7 +2840,12 @@ dalvik_inst:
     FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
     ldmia   r9, {r2-r3}                 @ r2/r3<- vAA/vAA+1
     GET_INST_OPCODE(ip)                 @ extract opcode from rINST
+#ifndef __ARM_ARCH_4__
     strd    r2, [r0, #offStaticField_value] @ field<- vAA/vAA+1
+#else
+    str     r2, [r0, #offStaticField_value] @ field<- vAA/vAA+1
+    str     r3, [r0, #(offStaticField_value+4)] @ field<- vAA/vAA+1
+#endif
     GOTO_OPCODE(ip)                     @ jump to next instruction
 
 /* ------------------------------ */
@@ -7461,7 +7475,13 @@ d2i_doconv:
     cmp     r3, #0                      @ check object for null
     mov     r2, rINST, lsr #8           @ r2<- A(+)
     beq     common_errNullObject        @ object was null
+#ifndef __ARM_ARCH_4__
     ldrd    r0, [r3, r1]                @ r0<- obj.field (64 bits, aligned)
+#else
+    ldr    r0, [r3, r1]
+    add	   r1, r1, #4
+    ldr    r1, [r3, r1]
+#endif
     and     r2, r2, #15
     FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
     add     r3, rFP, r2, lsl #2         @ r3<- &fp[A]
@@ -7527,7 +7547,13 @@ d2i_doconv:
     beq     common_errNullObject        @ object was null
     FETCH(r3, 1)                        @ r3<- field byte offset
     FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
+#ifndef __ARM_ARCH_4__
     strd    r0, [r2, r3]                @ obj.field (64 bits, aligned)<- r0/r1
+#else
+    str     r0, [r2, r3]                @ obj.field (64 bits, aligned)<- r0/r1
+    add     ip, r3, #4
+    str     r1, [r2, ip]                @ obj.field (64 bits, aligned)<- r0/r1
+#endif
     GET_INST_OPCODE(ip)                 @ extract opcode from rINST
     GOTO_OPCODE(ip)                     @ jump to next instruction
 
@@ -8315,7 +8341,12 @@ OP_CMPG_FLOAT_nan:
 
 .LOP_AGET_WIDE_finish:
     FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
+#ifndef __ARM_ARCH_4__
     ldrd    r2, [r0, #offArrayObject_contents]  @ r2/r3<- vBB[vCC]
+#else
+    ldr     r2, [r0, #offArrayObject_contents]
+    ldr     r3, [r0, #(offArrayObject_contents+4)]
+#endif
     add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
     GET_INST_OPCODE(ip)                 @ extract opcode from rINST
     stmia   r9, {r2-r3}                 @ vAA/vAA+1<- r2/r3
@@ -8328,7 +8359,12 @@ OP_CMPG_FLOAT_nan:
     FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
     ldmia   r9, {r2-r3}                 @ r2/r3<- vAA/vAA+1
     GET_INST_OPCODE(ip)                 @ extract opcode from rINST
+#ifndef __ARM_ARCH_4__
     strd    r2, [r0, #offArrayObject_contents]  @ r2/r3<- vBB[vCC]
+#else
+    str     r2, [r0, #offArrayObject_contents]  @ r2/r3<- vBB[vCC]
+    str     r3, [r0, #(offArrayObject_contents+4)]  @ r2/r3<- vBB[vCC]
+#endif
     GOTO_OPCODE(ip)                     @ jump to next instruction
 
 
@@ -8387,7 +8423,13 @@ OP_CMPG_FLOAT_nan:
     ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
     beq     common_errNullObject        @ object was null
     mov     r2, rINST, lsr #8           @ r2<- A+
+#ifndef __ARM_ARCH_4__
     ldrd    r0, [r9, r3]                @ r0/r1<- obj.field (64-bit align ok)
+#else
+    ldr    r0, [r9, r3]
+    add	   r1, r3, #4
+    ldr    r1, [r9, r1]
+#endif
     and     r2, r2, #15                 @ r2<- A
     FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
     add     r3, rFP, r2, lsl #2         @ r3<- &fp[A]
@@ -8538,8 +8580,14 @@ OP_CMPG_FLOAT_nan:
     beq     common_errNullObject        @ object was null
     FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
     ldmia   r2, {r0-r1}                 @ r0/r1<- fp[A]
-    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
+#ifndef __ARM_ARCH_4__
     strd    r0, [r9, r3]                @ obj.field (64 bits, aligned)<- r0
+#else
+    str     r0, [r9, r3]                @ obj.field (64 bits, aligned)<- r0
+    add     ip, r3, #4
+    str     r1, [r9, ip]                @ obj.field (64 bits, aligned)<- r0
+#endif
+    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
     GOTO_OPCODE(ip)                     @ jump to next instruction
 
 
@@ -9196,7 +9244,12 @@ d2l_doconv:
 0:
     @b       dvmPerformInlineOp4Std
     ldr     r9, .LOP_EXECUTE_INLINE_table       @ table of InlineOperation
+#ifndef __ARM_ARCH_4__
     ldr     pc, [r9, r10, lsl #4]       @ sizeof=16, "func" is first entry
+#else
+    ldr     ip, [r9, r10, lsl #4]       @ sizeof=16, "func" is first entry
+    bx      ip
+#endif
     @ (not reached)
 
 .LOP_EXECUTE_INLINE_table:
@@ -9278,7 +9331,7 @@ common_periodicChecks:
     bne     3f                          @ debugger/profiler, switch interp
 #endif
 
-    mov     pc, lr                      @ nothing to do, return
+    bx      lr                          @ nothing to do, return
 
 2:  @ check suspend
     ldr     r0, [rGLUE, #offGlue_self]  @ r0<- glue->self
@@ -9455,8 +9508,14 @@ dalvik_mterp:
 .Lskip:
 #endif
 
+#ifndef __ARM_ARCH_4__
     mov     lr, pc                      @ set return addr
     ldr     pc, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc
+#else
+    ldr     ip, [r2, #offMethod_nativeFunc] @ methodToCall->nativeFunc
+    mov     lr, pc                      @ set return addr
+    bx      ip
+#endif
 
     @ native return; r9=self, r10=newSaveArea
     @ equivalent to dvmPopJniLocals
@@ -9769,7 +9828,12 @@ common_squeak\num:
     ldr     r0, strSqueak
     mov     r1, #\num
     bl      printf
+#ifndef __ARM_ARCH_4__
     ldmfd   sp!, {r0, r1, r2, r3, ip, pc}
+#else
+    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
+    bx      lr
+#endif
     .endm
 
     SQUEAK  0
@@ -9787,7 +9851,12 @@ common_printNum:
     mov     r1, r0
     ldr     r0, strSqueak
     bl      printf
+#ifndef __ARM_ARCH_4__
     ldmfd   sp!, {r0, r1, r2, r3, ip, pc}
+#else
+    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
+    bx      lr
+#endif
 
 /*
  * Print a newline, preserving registers.
@@ -9796,7 +9865,12 @@ common_printNewline:
     stmfd   sp!, {r0, r1, r2, r3, ip, lr}
     ldr     r0, strNewline
     bl      printf
+#ifndef __ARM_ARCH_4__
     ldmfd   sp!, {r0, r1, r2, r3, ip, pc}
+#else
+    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
+    bx      lr
+#endif
 
     /*
      * Print the 32-bit quantity in r0 as a hex value, preserving registers.
@@ -9806,7 +9880,12 @@ common_printHex:
     mov     r1, r0
     ldr     r0, strPrintHex
     bl      printf
+#ifndef __ARM_ARCH_4__
     ldmfd   sp!, {r0, r1, r2, r3, ip, pc}
+#else
+    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
+    bx      lr
+#endif
 
 /*
  * Print the 64-bit quantity in r0-r1, preserving registers.
@@ -9817,7 +9896,12 @@ common_printLong:
     mov     r2, r0
     ldr     r0, strPrintLong
     bl      printf
+#ifndef __ARM_ARCH_4__
     ldmfd   sp!, {r0, r1, r2, r3, ip, pc}
+#else
+    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
+    bx      lr
+#endif
 
 /*
  * Print full method info.  Pass the Method* in r0.  Preserves regs.
@@ -9825,7 +9909,12 @@ common_printLong:
 common_printMethod:
     stmfd   sp!, {r0, r1, r2, r3, ip, lr}
     bl      dvmMterpPrintMethod
+#ifndef __ARM_ARCH_4__
     ldmfd   sp!, {r0, r1, r2, r3, ip, pc}
+#else
+    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
+    bx      lr
+#endif
 
 /*
  * Call a C helper function that dumps regs and possibly some
@@ -9835,7 +9924,12 @@ common_printMethod:
 common_dumpRegs:
     stmfd   sp!, {r0, r1, r2, r3, ip, lr}
     bl      dvmMterpDumpArmRegs
+#ifndef __ARM_ARCH_4__
     ldmfd   sp!, {r0, r1, r2, r3, ip, pc}
+#else
+    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
+    bx      lr
+#endif
     .endif
 
 
diff --git a/core/combo/linux-arm.mk b/core/combo/linux-arm.mk
index adb82d3..1aec673 100644
--- a/core/combo/linux-arm.mk
+++ b/core/combo/linux-arm.mk
@@ -46,15 +46,17 @@ ifneq ($(wildcard $($(combo_target)CC)),)
 $(combo_target)LIBGCC := $(shell $($(combo_target)CC) -mthumb-interwork -print-libgcc-file-name)
 endif
 
+$(combo_target)ARCH_CFLAGS := \
+			-march=armv5te -mtune=xscale -msoft-float \
+			-mthumb-interwork -fstack-protector \
+ 			-D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ \
+			-D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__
+
+$(combo_target)KERNEL_HEADERS = system/kernel_headers
+
 $(combo_target)GLOBAL_CFLAGS += \
-			-march=armv5te -mtune=xscale \
-			-msoft-float -fpic \
-			-mthumb-interwork \
-			-ffunction-sections \
-			-funwind-tables \
-			-fstack-protector \
-			-D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ \
-			-D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ \
+			$($(combo_target)ARCH_CFLAGS) \
+			-fpic -ffunction-sections -funwind-tables \
 			-include $(call select-android-config-h,linux-arm)
 
 $(combo_target)GLOBAL_CPPFLAGS += -fvisibility-inlines-hidden
diff --git a/core/prelink-linux-arm.map b/core/prelink-linux-arm.map
index d4ebf43..ebaa3ac 100644
--- a/core/prelink-linux-arm.map
+++ b/core/prelink-linux-arm.map
@@ -32,13 +32,13 @@ libwpa_client.so        0xADC00000
 libnetutils.so          0xADB00000
 
 # core dalvik runtime support
-libandroid_servers.so   0xAD900000
-libicudata.so           0xAD600000
+libandroid_servers.so   0xADA00000
+libicudata.so           0xAD700000
 libicuuc.so             0xAD500000
 libicui18n.so           0xAD400000
 libandroid_runtime.so   0xAD300000
 libnativehelper.so      0xAD200000
-libdvm-ARM.so           0xAD100000
+libdvm-ARM.so           0xAD180000
 libdvm.so               0xAD000000
 
 # graphics
@@ -52,6 +52,7 @@ libui.so                0xAC400000
 libsgl.so               0xAC000000
 
 # audio
+libasound.so            0xAB800000
 libaudio.so             0xAB700000
 libsonivox.so           0xAB600000
 libsoundpool.so         0xAB500000
@@ -77,8 +78,8 @@ libcamera.so            0xA9680000
 libqcamera.so           0xA9400000
 
 # pv libraries
-libpvasf.so                   0xA7BC0000
-libpvasfreg.so                0xA7B70000
+libpvasf.so                   0xA7BD0000
+libpvasfreg.so                0xA7B80000
 libopencoredownload.so        0xA7B40000
 libopencoredownloadreg.so     0xA7B00000
 libopencorenet_support.so     0xA7A00000
2007-09-04  Andrew Haley  <[EMAIL PROTECTED]>

	* decl.c (java_init_decl_processing): Call "__cxa_end_cleanup"
	when using the ARM EABI.

2007-08-29  Andrew Haley  <[EMAIL PROTECTED]>

        * config/arm/libgcc-bpabi.ver: Add _Unwind_Backtrace as GCC_4.3.0.

2007-08-08  Andrew Haley  <[EMAIL PROTECTED]>

	* config/arm/libunwind.S (UNWIND_WRAPPER _Unwind_Backtrace): New.
	* config/arm/unwind-arm.h (__gnu_Unwind_Backtrace): New.
	* config/arm/unwind-arm.c (__gnu_Unwind_Backtrace): New.

--- gcc/java/decl.c	(revision 128085)
+++ gcc/java/decl.c	(revision 128088)
@@ -1075,7 +1075,10 @@ java_init_decl_processing (void)
   eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
                                              ? "__gcj_personality_sj0"
                                              : "__gcj_personality_v0");
-  default_init_unwind_resume_libfunc ();
+  if (targetm.arm_eabi_unwinder)
+    unwind_resume_libfunc = init_one_libfunc ("__cxa_end_cleanup");
+  else
+    default_init_unwind_resume_libfunc ();
 
   lang_eh_runtime_type = do_nothing;
 
--- gcc/config/arm/libunwind.S	(revision 128085)
+++ gcc/config/arm/libunwind.S	(revision 128088)
@@ -237,5 +237,6 @@ UNWIND_WRAPPER _Unwind_RaiseException 1
 UNWIND_WRAPPER _Unwind_Resume 1
 UNWIND_WRAPPER _Unwind_Resume_or_Rethrow 1
 UNWIND_WRAPPER _Unwind_ForcedUnwind 3
+UNWIND_WRAPPER _Unwind_Backtrace 2
 
-#endif  /* __symbian__ */
+#endif  /* ndef __symbian__ */
--- gcc/config/arm/libgcc-bpabi.ver	(revision 128085)
+++ gcc/config/arm/libgcc-bpabi.ver	(revision 128088)
@@ -81,3 +81,11 @@ GCC_3.5 {
   # GNU-specific entry point.
   __gnu_unwind_frame
 }
+
+%exclude {
+  _Unwind_Backtrace
+}
+%inherit GCC_4.3.0 GCC_4.2.0
+GCC_4.3.0 {
+  _Unwind_Backtrace
+}
--- gcc/config/arm/unwind-arm.c	(revision 128085)
+++ gcc/config/arm/unwind-arm.c	(revision 128088)
@@ -950,6 +950,66 @@ _Unwind_DeleteException (_Unwind_Excepti
 }
 
 
+/* Perform stack backtrace through unwind data.  */
+_Unwind_Reason_Code
+__gnu_Unwind_Backtrace(_Unwind_Trace_Fn trace, void * trace_argument,
+		       phase2_vrs * entry_vrs);
+_Unwind_Reason_Code
+__gnu_Unwind_Backtrace(_Unwind_Trace_Fn trace, void * trace_argument,
+		       phase2_vrs * entry_vrs)
+{
+  phase1_vrs saved_vrs;
+  _Unwind_Reason_Code code;
+
+  _Unwind_Control_Block ucb;
+  _Unwind_Control_Block *ucbp = &ucb;
+
+  /* Set the pc to the call site.  */
+  entry_vrs->core.r[R_PC] = entry_vrs->core.r[R_LR];
+
+  /* Save the core registers.  */
+  saved_vrs.core = entry_vrs->core;
+  /* Set demand-save flags.  */
+  saved_vrs.demand_save_flags = ~(_uw) 0;
+  
+  do
+    {
+      /* Find the entry for this routine.  */
+      if (get_eit_entry (ucbp, saved_vrs.core.r[R_PC]) != _URC_OK)
+	{
+	  code = _URC_FAILURE;
+	  break;
+	}
+
+      /* The dwarf unwinder assumes the context structure holds things
+	 like the function and LSDA pointers.  The ARM implementation
+	 caches these in the exception header (UCB).  To avoid
+	 rewriting everything we make the virtual IP register point at
+	 the UCB.  */
+      _Unwind_SetGR((_Unwind_Context *)&saved_vrs, 12, (_Unwind_Ptr) ucbp);
+
+      /* Call trace function.  */
+      if ((*trace) ((_Unwind_Context *) &saved_vrs, trace_argument) 
+	  != _URC_NO_REASON)
+	{
+	  code = _URC_FAILURE;
+	  break;
+	}
+
+      /* Call the pr to decide what to do.  */
+      code = ((personality_routine) UCB_PR_ADDR (ucbp))
+	(_US_VIRTUAL_UNWIND_FRAME | _US_FORCE_UNWIND, 
+	 ucbp, (void *) &saved_vrs);
+    }
+  while (code != _URC_END_OF_STACK
+	 && code != _URC_FAILURE);
+
+ finish:
+  restore_non_core_regs (&saved_vrs);
+  return code;
+}
+
+
 /* Common implementation for ARM ABI defined personality routines.
    ID is the index of the personality routine, other arguments are as defined
    by __aeabi_unwind_cpp_pr{0,1,2}.  */
--- gcc/config/arm/unwind-arm.h	(revision 128085)
+++ gcc/config/arm/unwind-arm.h	(revision 128088)
@@ -205,6 +205,13 @@ extern "C" {
 	_Unwind_Control_Block *, struct _Unwind_Context *, void *);
   _Unwind_Reason_Code _Unwind_ForcedUnwind (_Unwind_Control_Block *,
 					    _Unwind_Stop_Fn, void *);
+  /* @@@ Use unwind data to perform a stack backtrace.  The trace callback
+     is called for every stack frame in the call chain, but no cleanup
+     actions are performed.  */
+  typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn) (_Unwind_Context *, void *);
+  _Unwind_Reason_Code _Unwind_Backtrace(_Unwind_Trace_Fn,
+					void*);
+
   _Unwind_Word _Unwind_GetCFA (struct _Unwind_Context *);
   void _Unwind_Complete(_Unwind_Control_Block *ucbp);
   void _Unwind_DeleteException (_Unwind_Exception *);
_______________________________________________
devel mailing list
[email protected]
https://lists.openmoko.org/mailman/listinfo/devel

Reply via email to