support darwin/x86_64

This commit is contained in:
Joel Dice 2009-10-14 10:01:37 -06:00
parent 0ae02511c6
commit 7b0378c180
10 changed files with 90 additions and 41 deletions

View File

@ -418,12 +418,12 @@ Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring name,
#ifdef __APPLE__ #ifdef __APPLE__
unsigned size = 32; unsigned size = 32;
char buffer[size]; char buffer[size];
long minorVersion, majorVersion; int32_t minorVersion, majorVersion;
Gestalt(gestaltSystemVersionMajor, &majorVersion); Gestalt(gestaltSystemVersionMajor, &majorVersion);
Gestalt(gestaltSystemVersionMinor, &minorVersion); Gestalt(gestaltSystemVersionMinor, &minorVersion);
snprintf(buffer, size, "%ld.%ld", majorVersion, minorVersion); snprintf(buffer, size, "%d.%d", majorVersion, minorVersion);
r = e->NewStringUTF(buffer); r = e->NewStringUTF(buffer);
#else #else
struct utsname system_id; struct utsname system_id;

View File

@ -1,4 +1,4 @@
MAKEFLAGS = -s #MAKEFLAGS = -s
name = avian name = avian
version = 0.2 version = 0.2

View File

@ -53,7 +53,7 @@ Avian can currently target the following platforms:
Linux (i386 and x86_64) Linux (i386 and x86_64)
Win32 (i386) Win32 (i386)
Mac OS X (i386 and 32-bit PowerPC) Mac OS X (i386, x86_64 and 32-bit PowerPC)
Building Building

View File

@ -12,10 +12,12 @@
#include "stdio.h" #include "stdio.h"
#include "string.h" #include "string.h"
#define MH_MAGIC_64 0xfeedfacf
#define MH_MAGIC 0xfeedface #define MH_MAGIC 0xfeedface
#define MH_OBJECT 1 #define MH_OBJECT 1
#define LC_SEGMENT_64 0x19
#define LC_SEGMENT 1 #define LC_SEGMENT 1
#define LC_SYMTAB 2 #define LC_SYMTAB 2
@ -35,13 +37,19 @@
#define CPU_SUBTYPE_POWERPC_ALL 0 #define CPU_SUBTYPE_POWERPC_ALL 0
#if (BITS_PER_WORD == 64) #if (BITS_PER_WORD == 64)
# define Magic MH_MAGIC_64
# define Segment LC_SEGMENT_64
# define FileHeader mach_header_64 # define FileHeader mach_header_64
# define SegmentCommand segment_command_64 # define SegmentCommand segment_command_64
# define Section section_64 # define Section section_64
# define NList struct nlist_64
#elif (BITS_PER_WORD == 32) #elif (BITS_PER_WORD == 32)
# define Magic MH_MAGIC
# define Segment LC_SEGMENT
# define FileHeader mach_header # define FileHeader mach_header
# define SegmentCommand segment_command # define SegmentCommand segment_command
# define Section section # define Section section
# define NList struct nlist
#else #else
# error # error
#endif #endif
@ -92,6 +100,16 @@ struct section_64 {
uint32_t reserved3; uint32_t reserved3;
}; };
struct nlist_64 {
union {
uint32_t n_strx;
} n_un;
uint8_t n_type;
uint8_t n_sect;
uint16_t n_desc;
uint64_t n_value;
};
struct mach_header { struct mach_header {
uint32_t magic; uint32_t magic;
cpu_type_t cputype; cpu_type_t cputype;
@ -173,7 +191,7 @@ writeObject(const uint8_t* data, unsigned size, FILE* out,
unsigned endNameLength = strlen(endName) + 1; unsigned endNameLength = strlen(endName) + 1;
FileHeader header = { FileHeader header = {
MH_MAGIC, // magic Magic, // magic
cpuType, cpuType,
cpuSubType, cpuSubType,
MH_OBJECT, // filetype, MH_OBJECT, // filetype,
@ -185,7 +203,7 @@ writeObject(const uint8_t* data, unsigned size, FILE* out,
}; };
SegmentCommand segment = { SegmentCommand segment = {
LC_SEGMENT, // cmd Segment, // cmd
sizeof(SegmentCommand) + sizeof(Section), // cmdsize sizeof(SegmentCommand) + sizeof(Section), // cmdsize
"", // segname "", // segname
0, // vmaddr 0, // vmaddr
@ -237,11 +255,11 @@ writeObject(const uint8_t* data, unsigned size, FILE* out,
+ sizeof(Section) + sizeof(Section)
+ sizeof(symtab_command) + sizeof(symtab_command)
+ pad(size) + pad(size)
+ (sizeof(struct nlist) * 2), // stroff + (sizeof(NList) * 2), // stroff
1 + startNameLength + endNameLength, // strsize 1 + startNameLength + endNameLength, // strsize
}; };
struct nlist symbolList[] = { NList symbolList[] = {
{ {
1, // n_un 1, // n_un
N_SECT | N_EXT, // n_type N_SECT | N_EXT, // n_type
@ -284,7 +302,7 @@ bool
MAKE_NAME(writeMachO, BITS_PER_WORD, Object) MAKE_NAME(writeMachO, BITS_PER_WORD, Object)
(uint8_t* data, unsigned size, FILE* out, const char* startName, (uint8_t* data, unsigned size, FILE* out, const char* startName,
const char* endName, const char* architecture, unsigned alignment, const char* endName, const char* architecture, unsigned alignment,
bool, bool executable) bool writable, bool)
{ {
cpu_type_t cpuType; cpu_type_t cpuType;
cpu_subtype_t cpuSubType; cpu_subtype_t cpuSubType;
@ -304,7 +322,7 @@ MAKE_NAME(writeMachO, BITS_PER_WORD, Object)
const char* segmentName; const char* segmentName;
const char* sectionName; const char* sectionName;
if (executable) { if (writable) {
segmentName = "__RWX"; segmentName = "__RWX";
sectionName = "__rwx"; sectionName = "__rwx";
} else { } else {

View File

@ -170,7 +170,7 @@ main(int argc, const char** argv)
fclose(out); fclose(out);
} else { } else {
fprintf(stderr, "unable to open %d\n", argv[2]); fprintf(stderr, "unable to open %s\n", argv[2]);
} }
munmap(data, size); munmap(data, size);

View File

@ -1650,14 +1650,14 @@ collect(Context* c)
c->lastCollectionTime = now; c->lastCollectionTime = now;
fprintf(stderr, fprintf(stderr,
" - collect: %4"LLD"ms; " " - collect: %4dms; "
"total: %4"LLD"ms; " "total: %4dms; "
"run: %4"LLD"ms; " "run: %4dms; "
"total: %4"LLD"ms\n", "total: %4dms\n",
collection, static_cast<int>(collection),
c->totalCollectionTime, static_cast<int>(c->totalCollectionTime),
run, static_cast<int>(run),
c->totalTime - c->totalCollectionTime); static_cast<int>(c->totalTime - c->totalCollectionTime));
fprintf(stderr, fprintf(stderr,
" - gen1: %8d/%8d bytes\n", " - gen1: %8d/%8d bytes\n",

View File

@ -2336,8 +2336,8 @@ wait(Thread* t, object o, int64_t milliseconds)
System::Monitor* m = objectMonitor(t, o, false); System::Monitor* m = objectMonitor(t, o, false);
if (DebugMonitors) { if (DebugMonitors) {
fprintf(stderr, "thread %p waits %"LLD" millis on %p for %x\n", fprintf(stderr, "thread %p waits %d millis on %p for %x\n",
t, milliseconds, m, hash); t, static_cast<int>(milliseconds), m, hash);
} }
if (m and m->owner() == t->systemThread) { if (m and m->owner() == t->systemThread) {

View File

@ -11,6 +11,7 @@
#ifdef __APPLE__ #ifdef __APPLE__
# include "CoreFoundation/CoreFoundation.h" # include "CoreFoundation/CoreFoundation.h"
# undef assert # undef assert
# define _XOPEN_SOURCE
#endif #endif
#include "sys/mman.h" #include "sys/mman.h"
@ -51,22 +52,26 @@ class MutexResource {
pthread_mutex_t* m; pthread_mutex_t* m;
}; };
const int InvalidSignal = -1;
const int VisitSignal = SIGUSR1; const int VisitSignal = SIGUSR1;
#ifdef __APPLE__
const int SegFaultSignal = SIGBUS;
#else
const int SegFaultSignal = SIGSEGV; const int SegFaultSignal = SIGSEGV;
#ifdef __APPLE__
const int AltSegFaultSignal = SIGBUS;
#else
const int AltSegFaultSignal = InvalidSignal;
#endif #endif
const int InterruptSignal = SIGUSR2; const int InterruptSignal = SIGUSR2;
const unsigned VisitSignalIndex = 0; const unsigned VisitSignalIndex = 0;
const unsigned SegFaultSignalIndex = 1; const unsigned SegFaultSignalIndex = 1;
const unsigned InterruptSignalIndex = 2; const unsigned AltSegFaultSignalIndex = 2;
const unsigned InterruptSignalIndex = 3;
class MySystem; class MySystem;
MySystem* system; MySystem* system;
const int signals[] = { VisitSignal, SegFaultSignal, InterruptSignal }; const int signals[] = { VisitSignal, SegFaultSignal, AltSegFaultSignal,
InterruptSignal };
void void
handleSignal(int signal, siginfo_t* info, void* context); handleSignal(int signal, siginfo_t* info, void* context);
@ -553,13 +558,8 @@ class MySystem: public System {
} }
virtual void* tryAllocateExecutable(unsigned sizeInBytes) { virtual void* tryAllocateExecutable(unsigned sizeInBytes) {
#ifdef __x86_64__
const unsigned Extra = MAP_32BIT;
#else
const unsigned Extra = 0;
#endif
void* p = mmap(0, sizeInBytes, PROT_EXEC | PROT_READ void* p = mmap(0, sizeInBytes, PROT_EXEC | PROT_READ
| PROT_WRITE, MAP_PRIVATE | MAP_ANON | Extra, -1, 0); | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
if (p == MAP_FAILED) { if (p == MAP_FAILED) {
return 0; return 0;
@ -607,7 +607,12 @@ class MySystem: public System {
} }
virtual Status handleSegFault(SignalHandler* handler) { virtual Status handleSegFault(SignalHandler* handler) {
return registerHandler(handler, SegFaultSignalIndex); Status s = registerHandler(handler, SegFaultSignalIndex);
if (s == 0 and AltSegFaultSignal != InvalidSignal) {
return registerHandler(handler, AltSegFaultSignalIndex);
} else {
return s;
}
} }
virtual Status visit(System::Thread* st, System::Thread* sTarget, virtual Status visit(System::Thread* st, System::Thread* sTarget,
@ -814,8 +819,13 @@ handleSignal(int signal, siginfo_t* info, void* context)
system->visitLock->notifyAll(t); system->visitLock->notifyAll(t);
} break; } break;
case SegFaultSignal: { case SegFaultSignal:
index = SegFaultSignalIndex; case AltSegFaultSignal: {
if (signal == SegFaultSignal) {
index = SegFaultSignalIndex;
} else {
index = AltSegFaultSignalIndex;
}
bool jump = system->handlers[index]->handleSignal bool jump = system->handlers[index]->handleSignal
(&ip, &base, &stack, &thread); (&ip, &base, &stack, &thread);
@ -829,7 +839,7 @@ handleSignal(int signal, siginfo_t* info, void* context)
sigset_t set; sigset_t set;
sigemptyset(&set); sigemptyset(&set);
sigaddset(&set, SegFaultSignal); sigaddset(&set, signal);
sigprocmask(SIG_UNBLOCK, &set, 0); sigprocmask(SIG_UNBLOCK, &set, 0);
vmJump(ip, base, stack, thread, 0, 0); vmJump(ip, base, stack, thread, 0, 0);

View File

@ -291,7 +291,14 @@ LOCAL(float):
jne LOCAL(exit) jne LOCAL(exit)
LOCAL(copy): LOCAL(copy):
#ifdef __APPLE__
// as of OS X 10.6, Apple is still using an assembler that doesn't
// understand movq SSE,GPR, but movd does the same thing, despite
// the name
movd %xmm0,%rax
#else
movq %xmm0,%rax movq %xmm0,%rax
#endif
LOCAL(exit): LOCAL(exit):
movq %rbp,%rsp movq %rbp,%rsp

View File

@ -56,10 +56,24 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t*,
#elif defined ARCH_x86_64 #elif defined ARCH_x86_64
# define IP_REGISTER(context) (context->uc_mcontext.gregs[REG_RIP]) # ifdef __APPLE__
# define BASE_REGISTER(context) (context->uc_mcontext.gregs[REG_RBP]) # if __DARWIN_UNIX03 && defined(_STRUCT_X86_EXCEPTION_STATE32)
# define STACK_REGISTER(context) (context->uc_mcontext.gregs[REG_RSP]) # define IP_REGISTER(context) (context->uc_mcontext->__ss.__rip)
# define THREAD_REGISTER(context) (context->uc_mcontext.gregs[REG_RBX]) # define BASE_REGISTER(context) (context->uc_mcontext->__ss.__rbp)
# define STACK_REGISTER(context) (context->uc_mcontext->__ss.__rsp)
# define THREAD_REGISTER(context) (context->uc_mcontext->__ss.__rbx)
# else
# define IP_REGISTER(context) (context->uc_mcontext->ss.rip)
# define BASE_REGISTER(context) (context->uc_mcontext->ss.rbp)
# define STACK_REGISTER(context) (context->uc_mcontext->ss.rsp)
# define THREAD_REGISTER(context) (context->uc_mcontext->ss.rbx)
# endif
# else
# define IP_REGISTER(context) (context->uc_mcontext.gregs[REG_RIP])
# define BASE_REGISTER(context) (context->uc_mcontext.gregs[REG_RBP])
# define STACK_REGISTER(context) (context->uc_mcontext.gregs[REG_RSP])
# define THREAD_REGISTER(context) (context->uc_mcontext.gregs[REG_RBX])
# endif
extern "C" uint64_t extern "C" uint64_t
# ifdef PLATFORM_WINDOWS # ifdef PLATFORM_WINDOWS
@ -81,7 +95,7 @@ dynamicCall(void* function, uint64_t* arguments, UNUSED uint8_t* argumentTypes,
} }
# else # else
inline uint64_t inline uint64_t
dynamicCall(void* function, uint64_t* arguments, uint8_t* argumentTypes, dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
unsigned argumentCount, unsigned, unsigned returnType) unsigned argumentCount, unsigned, unsigned returnType)
{ {
const unsigned GprCount = 6; const unsigned GprCount = 6;