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