add support for Apple iOS on ARM

Most tests are passing, but not all, so this still needs more work.
This commit is contained in:
Joel Dice
2011-08-10 19:21:48 -06:00
parent 4b9cb4f4e4
commit e5a8d5c824
6 changed files with 110 additions and 27 deletions

View File

@ -43,7 +43,9 @@
# define SO_PREFIX "lib" # define SO_PREFIX "lib"
# ifdef __APPLE__ # ifdef __APPLE__
# define SO_SUFFIX ".jnilib" # define SO_SUFFIX ".jnilib"
# ifndef ARCH_arm
# include <CoreServices/CoreServices.h> # include <CoreServices/CoreServices.h>
# endif
# else # else
# define SO_SUFFIX ".so" # define SO_SUFFIX ".so"
# endif # endif
@ -558,7 +560,7 @@ Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring name,
r = e->NewStringUTF("Linux"); r = e->NewStringUTF("Linux");
#endif #endif
} else if (strcmp(chars, "os.version") == 0) { } else if (strcmp(chars, "os.version") == 0) {
#ifdef __APPLE__ #if (defined __APPLE__) && (! defined ARCH_arm)
unsigned size = 32; unsigned size = 32;
char buffer[size]; char buffer[size];
#ifdef ARCH_x86_64 #ifdef ARCH_x86_64

View File

@ -229,15 +229,26 @@ endif
ifeq ($(arch),arm) ifeq ($(arch),arm)
asm = arm asm = arm
pointer-size = 4 pointer-size = 4
ifneq ($(platform),darwin)
cflags += -marm -Wno-psabi cflags += -marm -Wno-psabi
endif
ifneq ($(arch),$(build-arch)) ifneq ($(arch),$(build-arch))
ifeq ($(platform),darwin)
ios-bin = /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin
cxx = $(ios-bin)/g++
cc = $(ios-bin)/gcc
ar = $(ios-bin)/ar
ranlib = $(ios-bin)/ranlib
strip = $(ios-bin)/strip
else
cxx = arm-linux-gnueabi-g++ cxx = arm-linux-gnueabi-g++
cc = arm-linux-gnueabi-gcc cc = arm-linux-gnueabi-gcc
ar = arm-linux-gnueabi-ar ar = arm-linux-gnueabi-ar
ranlib = arm-linux-gnueabi-ranlib ranlib = arm-linux-gnueabi-ranlib
strip = arm-linux-gnueabi-strip strip = arm-linux-gnueabi-strip
endif endif
endif
endif endif
ifeq ($(platform),darwin) ifeq ($(platform),darwin)
@ -263,8 +274,10 @@ ifeq ($(platform),darwin)
endif endif
version-script-flag = version-script-flag =
lflags = $(common-lflags) -ldl -framework CoreFoundation \ lflags = $(common-lflags) -ldl -framework CoreFoundation
-framework CoreServices ifneq ($(arch),arm)
lflags += -framework CoreServices
endif
ifeq ($(bootimage),true) ifeq ($(bootimage),true)
bootimage-lflags = -Wl,-segprot,__RWX,rwx,rwx bootimage-lflags = -Wl,-segprot,__RWX,rwx,rwx
endif endif
@ -273,6 +286,18 @@ ifeq ($(platform),darwin)
so-suffix = .dylib so-suffix = .dylib
shared = -dynamiclib shared = -dynamiclib
ifeq ($(arch),arm)
ifeq ($(build-arch),powerpc)
converter-cflags += -DOPPOSITE_ENDIAN
endif
flags = -arch armv6 -isysroot \
/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/
openjdk-extra-cflags += $(flags)
cflags += $(flags)
asmflags += $(flags)
lflags += $(flags)
endif
ifeq ($(arch),powerpc) ifeq ($(arch),powerpc)
ifneq (,$(filter i386 x86_64 arm,$(build-arch))) ifneq (,$(filter i386 x86_64 arm,$(build-arch)))
converter-cflags += -DOPPOSITE_ENDIAN converter-cflags += -DOPPOSITE_ENDIAN

View File

@ -11,8 +11,16 @@
.text .text
.globl vmNativeCall #define LOCAL(x) .L##x
vmNativeCall:
#ifdef __APPLE__
# define GLOBAL(x) _##x
#else
# define GLOBAL(x) x
#endif
.globl GLOBAL(vmNativeCall)
GLOBAL(vmNativeCall):
/* /*
arguments: arguments:
r0 -> r4 : function r0 -> r4 : function
@ -32,12 +40,12 @@ vmNativeCall:
// setup stack arguments if necessary // setup stack arguments if necessary
sub sp, sp, r5 // allocate stack sub sp, sp, r5 // allocate stack
mov ip, sp mov ip, sp
.Lloop: LOCAL(loop):
tst r3, r3 tst r3, r3
ldrne r0, [r2], #4 ldrne r0, [r2], #4
strne r0, [ip], #4 strne r0, [ip], #4
subne r3, r3, #4 subne r3, r3, #4
bne .Lloop bne LOCAL(loop)
// setup argument registers if necessary // setup argument registers if necessary
tst r6, r6 tst r6, r6
@ -48,8 +56,8 @@ vmNativeCall:
ldmfd sp!, {r4-r6, pc} // restore non-volatile regs and return ldmfd sp!, {r4-r6, pc} // restore non-volatile regs and return
.globl vmJump .globl GLOBAL(vmJump)
vmJump: GLOBAL(vmJump):
mov lr, r0 mov lr, r0
ldr r0, [sp] ldr r0, [sp]
ldr r1, [sp, #4] ldr r1, [sp, #4]
@ -60,8 +68,8 @@ vmJump:
#define CHECKPOINT_THREAD 4 #define CHECKPOINT_THREAD 4
#define CHECKPOINT_STACK 24 #define CHECKPOINT_STACK 24
.globl vmRun .globl GLOBAL(vmRun)
vmRun: GLOBAL(vmRun):
// r0: function // r0: function
// r1: arguments // r1: arguments
// r2: checkpoint // r2: checkpoint
@ -76,8 +84,8 @@ vmRun:
blx r12 blx r12
.globl vmRun_returnAddress .globl GLOBAL(vmRun_returnAddress)
vmRun_returnAddress: GLOBAL(vmRun_returnAddress):
add sp, sp, #12 add sp, sp, #12
ldmfd sp!, {r4-r11, lr} ldmfd sp!, {r4-r11, lr}
bx lr bx lr

View File

@ -14,12 +14,44 @@
#include "types.h" #include "types.h"
#include "common.h" #include "common.h"
#define VA_LIST(x) (&(x)) #ifdef __APPLE__
# include "libkern/OSAtomic.h"
# include "libkern/OSCacheControl.h"
# include "mach/mach_types.h"
# include "mach/arm/thread_act.h"
# include "mach/arm/thread_status.h"
#define IP_REGISTER(context) (context->uc_mcontext.arm_pc) # define THREAD_STATE ARM_THREAD_STATE
#define STACK_REGISTER(context) (context->uc_mcontext.arm_sp) # define THREAD_STATE_TYPE arm_thread_state_t
#define THREAD_REGISTER(context) (context->uc_mcontext.arm_ip) # define THREAD_STATE_COUNT ARM_THREAD_STATE_COUNT
#define LINK_REGISTER(context) (context->uc_mcontext.arm_lr)
# if __DARWIN_UNIX03 && defined(_STRUCT_ARM_EXCEPTION_STATE)
# define FIELD(x) __##x
# else
# define FIELD(x) x
# endif
# define THREAD_STATE_IP(state) ((state).FIELD(pc))
# define THREAD_STATE_STACK(state) ((state).FIELD(sp))
# define THREAD_STATE_THREAD(state) ((state).FIELD(r[8]))
# define THREAD_STATE_LINK(state) ((state).FIELD(lr))
# define IP_REGISTER(context) \
THREAD_STATE_IP(context->uc_mcontext->FIELD(ss))
# define STACK_REGISTER(context) \
THREAD_STATE_STACK(context->uc_mcontext->FIELD(ss))
# define THREAD_REGISTER(context) \
THREAD_STATE_THREAD(context->uc_mcontext->FIELD(ss))
# define LINK_REGISTER(context) \
THREAD_STATE_LINK(context->uc_mcontext->FIELD(ss))
#else // not __APPLE__
# define IP_REGISTER(context) (context->uc_mcontext.arm_pc)
# define STACK_REGISTER(context) (context->uc_mcontext.arm_sp)
# define THREAD_REGISTER(context) (context->uc_mcontext.arm_ip)
# define LINK_REGISTER(context) (context->uc_mcontext.arm_lr)
#endif
#define VA_LIST(x) (&(x))
extern "C" uint64_t extern "C" uint64_t
vmNativeCall(void* function, unsigned stackTotal, void* memoryTable, vmNativeCall(void* function, unsigned stackTotal, void* memoryTable,
@ -60,19 +92,29 @@ loadMemoryBarrier()
inline void inline void
syncInstructionCache(const void* start, unsigned size) syncInstructionCache(const void* start, unsigned size)
{ {
#ifdef __APPLE__
sys_icache_invalidate(const_cast<void*>(start), size);
#else
__clear_cache __clear_cache
(const_cast<void*>(start), (const_cast<void*>(start),
const_cast<uint8_t*>(static_cast<const uint8_t*>(start) + size)); const_cast<uint8_t*>(static_cast<const uint8_t*>(start) + size));
#endif
} }
#ifndef __APPLE__
typedef int (__kernel_cmpxchg_t)(int oldval, int newval, int *ptr); typedef int (__kernel_cmpxchg_t)(int oldval, int newval, int *ptr);
#define __kernel_cmpxchg (*(__kernel_cmpxchg_t *)0xffff0fc0) # define __kernel_cmpxchg (*(__kernel_cmpxchg_t *)0xffff0fc0)
#endif
inline bool inline bool
atomicCompareAndSwap32(uint32_t* p, uint32_t old, uint32_t new_) atomicCompareAndSwap32(uint32_t* p, uint32_t old, uint32_t new_)
{ {
#ifdef __APPLE__
return OSAtomicCompareAndSwap32(old, new_, reinterpret_cast<int32_t*>(p));
#else
int r = __kernel_cmpxchg(static_cast<int>(old), static_cast<int>(new_), reinterpret_cast<int*>(p)); int r = __kernel_cmpxchg(static_cast<int>(old), static_cast<int>(new_), reinterpret_cast<int*>(p));
return (!r ? true : false); return (!r ? true : false);
#endif
} }
inline bool inline bool

View File

@ -33,10 +33,12 @@
#define CPU_TYPE_I386 7 #define CPU_TYPE_I386 7
#define CPU_TYPE_X86_64 (CPU_TYPE_I386 | CPU_ARCH_ABI64) #define CPU_TYPE_X86_64 (CPU_TYPE_I386 | CPU_ARCH_ABI64)
#define CPU_TYPE_POWERPC 18 #define CPU_TYPE_POWERPC 18
#define CPU_TYPE_ARM 12
#define CPU_SUBTYPE_I386_ALL 3 #define CPU_SUBTYPE_I386_ALL 3
#define CPU_SUBTYPE_X86_64_ALL CPU_SUBTYPE_I386_ALL #define CPU_SUBTYPE_X86_64_ALL CPU_SUBTYPE_I386_ALL
#define CPU_SUBTYPE_POWERPC_ALL 0 #define CPU_SUBTYPE_POWERPC_ALL 0
#define CPU_SUBTYPE_ARM_V6 6
#if (BITS_PER_WORD == 64) #if (BITS_PER_WORD == 64)
# define Magic MH_MAGIC_64 # define Magic MH_MAGIC_64
@ -317,6 +319,9 @@ MAKE_NAME(writeMachO, BITS_PER_WORD, Object)
} else if (strcmp(architecture, "powerpc") == 0) { } else if (strcmp(architecture, "powerpc") == 0) {
cpuType = CPU_TYPE_POWERPC; cpuType = CPU_TYPE_POWERPC;
cpuSubType = CPU_SUBTYPE_POWERPC_ALL; cpuSubType = CPU_SUBTYPE_POWERPC_ALL;
} else if (strcmp(architecture, "arm") == 0) {
cpuType = CPU_TYPE_ARM;
cpuSubType = CPU_SUBTYPE_ARM_V6;
} else { } else {
fprintf(stderr, "unsupported architecture: %s\n", architecture); fprintf(stderr, "unsupported architecture: %s\n", architecture);
return false; return false;

View File

@ -89,7 +89,8 @@ writeObject(uint8_t* data, unsigned size, FILE* out, const char* startName,
(data, size, out, startName, endName, architecture, alignment, (data, size, out, startName, endName, architecture, alignment,
writable, executable); writable, executable);
} else if (strcmp("i386", architecture) == 0 } else if (strcmp("i386", architecture) == 0
or strcmp("powerpc", architecture) == 0) or strcmp("powerpc", architecture) == 0
or strcmp("arm", architecture) == 0)
{ {
found = true; found = true;
success = writeMachO32Object success = writeMachO32Object