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

View File

@ -229,14 +229,25 @@ endif
ifeq ($(arch),arm)
asm = arm
pointer-size = 4
cflags += -marm -Wno-psabi
ifneq ($(platform),darwin)
cflags += -marm -Wno-psabi
endif
ifneq ($(arch),$(build-arch))
cxx = arm-linux-gnueabi-g++
cc = arm-linux-gnueabi-gcc
ar = arm-linux-gnueabi-ar
ranlib = arm-linux-gnueabi-ranlib
strip = arm-linux-gnueabi-strip
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++
cc = arm-linux-gnueabi-gcc
ar = arm-linux-gnueabi-ar
ranlib = arm-linux-gnueabi-ranlib
strip = arm-linux-gnueabi-strip
endif
endif
endif
@ -263,8 +274,10 @@ ifeq ($(platform),darwin)
endif
version-script-flag =
lflags = $(common-lflags) -ldl -framework CoreFoundation \
-framework CoreServices
lflags = $(common-lflags) -ldl -framework CoreFoundation
ifneq ($(arch),arm)
lflags += -framework CoreServices
endif
ifeq ($(bootimage),true)
bootimage-lflags = -Wl,-segprot,__RWX,rwx,rwx
endif
@ -273,6 +286,18 @@ ifeq ($(platform),darwin)
so-suffix = .dylib
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)
ifneq (,$(filter i386 x86_64 arm,$(build-arch)))
converter-cflags += -DOPPOSITE_ENDIAN

View File

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

View File

@ -14,12 +14,44 @@
#include "types.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 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)
# define THREAD_STATE ARM_THREAD_STATE
# define THREAD_STATE_TYPE arm_thread_state_t
# define THREAD_STATE_COUNT ARM_THREAD_STATE_COUNT
# 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
vmNativeCall(void* function, unsigned stackTotal, void* memoryTable,
@ -60,19 +92,29 @@ loadMemoryBarrier()
inline void
syncInstructionCache(const void* start, unsigned size)
{
#ifdef __APPLE__
sys_icache_invalidate(const_cast<void*>(start), size);
#else
__clear_cache
(const_cast<void*>(start),
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);
#define __kernel_cmpxchg (*(__kernel_cmpxchg_t *)0xffff0fc0)
# define __kernel_cmpxchg (*(__kernel_cmpxchg_t *)0xffff0fc0)
#endif
inline bool
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));
return (!r ? true : false);
#endif
}
inline bool

View File

@ -33,10 +33,12 @@
#define CPU_TYPE_I386 7
#define CPU_TYPE_X86_64 (CPU_TYPE_I386 | CPU_ARCH_ABI64)
#define CPU_TYPE_POWERPC 18
#define CPU_TYPE_ARM 12
#define CPU_SUBTYPE_I386_ALL 3
#define CPU_SUBTYPE_X86_64_ALL CPU_SUBTYPE_I386_ALL
#define CPU_SUBTYPE_POWERPC_ALL 0
#define CPU_SUBTYPE_ARM_V6 6
#if (BITS_PER_WORD == 64)
# define Magic MH_MAGIC_64
@ -317,6 +319,9 @@ MAKE_NAME(writeMachO, BITS_PER_WORD, Object)
} else if (strcmp(architecture, "powerpc") == 0) {
cpuType = CPU_TYPE_POWERPC;
cpuSubType = CPU_SUBTYPE_POWERPC_ALL;
} else if (strcmp(architecture, "arm") == 0) {
cpuType = CPU_TYPE_ARM;
cpuSubType = CPU_SUBTYPE_ARM_V6;
} else {
fprintf(stderr, "unsupported architecture: %s\n", architecture);
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,
writable, executable);
} else if (strcmp("i386", architecture) == 0
or strcmp("powerpc", architecture) == 0)
or strcmp("powerpc", architecture) == 0
or strcmp("arm", architecture) == 0)
{
found = true;
success = writeMachO32Object