mirror of
https://github.com/corda/corda.git
synced 2025-05-29 13:44:25 +00:00
Merge branch 'master' of oss.readytalk.com:/var/local/git/avian into armvfp
Conflicts: src/arm.cpp
This commit is contained in:
commit
b96fc05a61
2
.gitignore
vendored
2
.gitignore
vendored
@ -5,3 +5,5 @@ build
|
|||||||
.project
|
.project
|
||||||
.settings
|
.settings
|
||||||
bin
|
bin
|
||||||
|
/lib
|
||||||
|
/distrib
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2009-2010, Avian Contributors
|
/* Copyright (c) 2009-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2009-2010, Avian Contributors
|
/* Copyright (c) 2009-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2010, Avian Contributors
|
/* Copyright (c) 2010-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2009-2010, Avian Contributors
|
/* Copyright (c) 2009-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2009, Avian Contributors
|
/* Copyright (c) 2009-2012, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
@ -10,8 +10,16 @@
|
|||||||
|
|
||||||
package avian;
|
package avian;
|
||||||
|
|
||||||
|
import sun.misc.Unsafe;
|
||||||
|
|
||||||
public abstract class Machine {
|
public abstract class Machine {
|
||||||
|
|
||||||
|
private static final Unsafe unsafe = Unsafe.getUnsafe();
|
||||||
|
|
||||||
public static native void dumpHeap(String outputFile);
|
public static native void dumpHeap(String outputFile);
|
||||||
|
|
||||||
|
public static Unsafe getUnsafe() {
|
||||||
|
return unsafe;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2009-2010, Avian Contributors
|
/* Copyright (c) 2009-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2010, Avian Contributors
|
/* Copyright (c) 2010-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2009, Avian Contributors
|
/* Copyright (c) 2009-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2010, Avian Contributors
|
/* Copyright (c) 2008-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2010, Avian Contributors
|
/* Copyright (c) 2008-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2010, Avian Contributors
|
/* Copyright (c) 2008-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
26
classpath/avian/http/Handler.java
Normal file
26
classpath/avian/http/Handler.java
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/* Copyright (c) 2012, Avian Contributors
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
that the above copyright notice and this permission notice appear
|
||||||
|
in all copies.
|
||||||
|
|
||||||
|
There is NO WARRANTY for this software. See license.txt for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
package avian.http;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLStreamHandler;
|
||||||
|
import java.net.URLConnection;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
public class Handler extends URLStreamHandler {
|
||||||
|
protected URLConnection openConnection(URL url) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2011, Avian Contributors
|
/* Copyright (c) 2008-2012, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
@ -32,10 +32,13 @@
|
|||||||
# define STAT _wstat
|
# define STAT _wstat
|
||||||
# define STRUCT_STAT struct _stat
|
# define STRUCT_STAT struct _stat
|
||||||
# define MKDIR(path, mode) _wmkdir(path)
|
# define MKDIR(path, mode) _wmkdir(path)
|
||||||
|
# define CHMOD(path, mode) _wchmod(path, mode)
|
||||||
# define UNLINK _wunlink
|
# define UNLINK _wunlink
|
||||||
# define RENAME _wrename
|
# define RENAME _wrename
|
||||||
# define OPEN_MASK O_BINARY
|
# define OPEN_MASK O_BINARY
|
||||||
|
|
||||||
|
# define CHECK_X_OK R_OK
|
||||||
|
|
||||||
# ifdef _MSC_VER
|
# ifdef _MSC_VER
|
||||||
# define S_ISREG(x) ((x) & _S_IFREG)
|
# define S_ISREG(x) ((x) & _S_IFREG)
|
||||||
# define S_ISDIR(x) ((x) & _S_IFDIR)
|
# define S_ISDIR(x) ((x) & _S_IFDIR)
|
||||||
@ -45,7 +48,6 @@
|
|||||||
# define R_OK 4
|
# define R_OK 4
|
||||||
# else
|
# else
|
||||||
# define OPEN _wopen
|
# define OPEN _wopen
|
||||||
# define CREAT _wcreat
|
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# define GET_CHARS GetStringChars
|
# define GET_CHARS GetStringChars
|
||||||
@ -67,11 +69,13 @@ typedef wchar_t char_t;
|
|||||||
# define STAT stat
|
# define STAT stat
|
||||||
# define STRUCT_STAT struct stat
|
# define STRUCT_STAT struct stat
|
||||||
# define MKDIR mkdir
|
# define MKDIR mkdir
|
||||||
# define CREAT creat
|
# define CHMOD chmod
|
||||||
# define UNLINK unlink
|
# define UNLINK unlink
|
||||||
# define RENAME rename
|
# define RENAME rename
|
||||||
# define OPEN_MASK 0
|
# define OPEN_MASK 0
|
||||||
|
|
||||||
|
# define CHECK_X_OK X_OK
|
||||||
|
|
||||||
# define GET_CHARS GetStringUTFChars
|
# define GET_CHARS GetStringUTFChars
|
||||||
# define RELEASE_CHARS ReleaseStringUTFChars
|
# define RELEASE_CHARS ReleaseStringUTFChars
|
||||||
|
|
||||||
@ -96,12 +100,6 @@ OPEN(string_t path, int mask, int mode)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int
|
|
||||||
CREAT(string_t path, int mode)
|
|
||||||
{
|
|
||||||
return OPEN(path, _O_CREAT, mode);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
@ -178,7 +176,8 @@ inline Mapping*
|
|||||||
map(JNIEnv* e, string_t path)
|
map(JNIEnv* e, string_t path)
|
||||||
{
|
{
|
||||||
Mapping* result = 0;
|
Mapping* result = 0;
|
||||||
HANDLE file = CreateFileW(path, FILE_READ_DATA, FILE_SHARE_READ, 0,
|
HANDLE file = CreateFileW(path, FILE_READ_DATA,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
|
||||||
OPEN_EXISTING, 0, 0);
|
OPEN_EXISTING, 0, 0);
|
||||||
if (file != INVALID_HANDLE_VALUE) {
|
if (file != INVALID_HANDLE_VALUE) {
|
||||||
unsigned size = GetFileSize(file, 0);
|
unsigned size = GetFileSize(file, 0);
|
||||||
@ -317,7 +316,19 @@ extern "C" JNIEXPORT jstring JNICALL
|
|||||||
Java_java_io_File_toAbsolutePath(JNIEnv* e UNUSED, jclass, jstring path)
|
Java_java_io_File_toAbsolutePath(JNIEnv* e UNUSED, jclass, jstring path)
|
||||||
{
|
{
|
||||||
#ifdef PLATFORM_WINDOWS
|
#ifdef PLATFORM_WINDOWS
|
||||||
// todo
|
string_t chars = getChars(e, path);
|
||||||
|
if (chars) {
|
||||||
|
const unsigned BufferSize = MAX_PATH;
|
||||||
|
char_t buffer[BufferSize];
|
||||||
|
DWORD success = GetFullPathNameW(chars, BufferSize, buffer, 0);
|
||||||
|
releaseChars(e, path, chars);
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
return e->NewString
|
||||||
|
(reinterpret_cast<const jchar*>(buffer), wcslen(buffer));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
#else
|
#else
|
||||||
jstring result = path;
|
jstring result = path;
|
||||||
@ -388,21 +399,26 @@ Java_java_io_File_mkdir(JNIEnv* e, jclass, jstring path)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
extern "C" JNIEXPORT jboolean JNICALL
|
||||||
Java_java_io_File_createNewFile(JNIEnv* e, jclass, jstring path)
|
Java_java_io_File_createNewFile(JNIEnv* e, jclass, jstring path)
|
||||||
{
|
{
|
||||||
|
bool result = false;
|
||||||
string_t chars = getChars(e, path);
|
string_t chars = getChars(e, path);
|
||||||
if (chars) {
|
if (chars) {
|
||||||
if (not exists(chars)) {
|
if (not exists(chars)) {
|
||||||
int fd = CREAT(chars, 0600);
|
int fd = OPEN(chars, O_CREAT | O_WRONLY | O_EXCL, 0600);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
throwNewErrno(e, "java/io/IOException");
|
if (errno != EEXIST) {
|
||||||
|
throwNewErrno(e, "java/io/IOException");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
result = true;
|
||||||
doClose(e, fd);
|
doClose(e, fd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
releaseChars(e, path, chars);
|
releaseChars(e, path, chars);
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
extern "C" JNIEXPORT void JNICALL
|
||||||
@ -442,6 +458,64 @@ Java_java_io_File_canWrite(JNIEnv* e, jclass, jstring path)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT jboolean JNICALL
|
||||||
|
Java_java_io_File_canExecute(JNIEnv* e, jclass, jstring path)
|
||||||
|
{
|
||||||
|
string_t chars = getChars(e, path);
|
||||||
|
if (chars) {
|
||||||
|
int r = ACCESS(chars, CHECK_X_OK);
|
||||||
|
releaseChars(e, path, chars);
|
||||||
|
return (r == 0);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef PLATFORM_WINDOWS
|
||||||
|
extern "C" JNIEXPORT jboolean JNICALL
|
||||||
|
Java_java_io_File_setExecutable(JNIEnv* e, jclass, jstring path, jboolean executable, jboolean ownerOnly)
|
||||||
|
{
|
||||||
|
string_t chars = getChars(e, path);
|
||||||
|
if(chars) {
|
||||||
|
jboolean v;
|
||||||
|
int mask;
|
||||||
|
if(ownerOnly) {
|
||||||
|
mask = S_IXUSR;
|
||||||
|
} else {
|
||||||
|
mask = S_IXUSR | S_IXGRP | S_IXOTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
STRUCT_STAT s;
|
||||||
|
int r = STAT(chars, &s);
|
||||||
|
if(r == 0) {
|
||||||
|
int mode = s.st_mode;
|
||||||
|
if(executable) {
|
||||||
|
mode |= mask;
|
||||||
|
} else {
|
||||||
|
mode &= ~mask;
|
||||||
|
}
|
||||||
|
if(CHMOD(chars, mode) != 0) {
|
||||||
|
v = false;
|
||||||
|
} else {
|
||||||
|
v = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
v = false;
|
||||||
|
}
|
||||||
|
releaseChars(e, path, chars);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // ifndef PLATFORM_WINDOWS
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT jboolean JNICALL
|
||||||
|
Java_java_io_File_setExecutable(JNIEnv*, jclass, jstring, jboolean executable, jboolean)
|
||||||
|
{
|
||||||
|
return executable;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
extern "C" JNIEXPORT jboolean JNICALL
|
extern "C" JNIEXPORT jboolean JNICALL
|
||||||
Java_java_io_File_rename(JNIEnv* e, jclass, jstring old, jstring new_)
|
Java_java_io_File_rename(JNIEnv* e, jclass, jstring old, jstring new_)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2011, Avian Contributors
|
/* Copyright (c) 2008-2012, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
@ -631,6 +631,36 @@ Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring name,
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// System.getEnvironment() implementation
|
||||||
|
// TODO: For Win32, replace usage of deprecated _environ and add Unicode
|
||||||
|
// support (neither of which is likely to be of great importance).
|
||||||
|
#ifdef AVIAN_IOS
|
||||||
|
namespace {
|
||||||
|
const char* environ[] = { 0 };
|
||||||
|
}
|
||||||
|
#elif defined __APPLE__
|
||||||
|
# include <crt_externs.h>
|
||||||
|
# define environ (*_NSGetEnviron())
|
||||||
|
#else
|
||||||
|
extern char** environ;
|
||||||
|
#endif
|
||||||
|
extern "C" JNIEXPORT jobjectArray JNICALL
|
||||||
|
Java_java_lang_System_getEnvironment(JNIEnv* env, jclass) {
|
||||||
|
int length;
|
||||||
|
for (length = 0; environ[length] != 0; ++length) ;
|
||||||
|
|
||||||
|
jobjectArray stringArray =
|
||||||
|
env->NewObjectArray(length, env->FindClass("java/lang/String"),
|
||||||
|
env->NewStringUTF(""));
|
||||||
|
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
jobject varString = env->NewStringUTF(environ[i]);
|
||||||
|
env->SetObjectArrayElement(stringArray, i, varString);
|
||||||
|
}
|
||||||
|
|
||||||
|
return stringArray;
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT jlong JNICALL
|
extern "C" JNIEXPORT jlong JNICALL
|
||||||
Java_java_lang_System_currentTimeMillis(JNIEnv*, jclass)
|
Java_java_lang_System_currentTimeMillis(JNIEnv*, jclass)
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2010, Avian Contributors
|
/* Copyright (c) 2010-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2009, Avian Contributors
|
/* Copyright (c) 2008-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2009, Avian Contributors
|
/* Copyright (c) 2008-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2010, Avian Contributors
|
/* Copyright (c) 2008-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008, Avian Contributors
|
/* Copyright (c) 2008-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008, Avian Contributors
|
/* Copyright (c) 2008-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2010, Avian Contributors
|
/* Copyright (c) 2008-2012, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
@ -35,6 +35,43 @@ public class File implements Serializable {
|
|||||||
this(parent.getPath() + FileSeparator + child);
|
this(parent.getPath() + FileSeparator + child);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static File createTempFile(String prefix, String suffix)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
return createTempFile(prefix, suffix, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static File createTempFile(String prefix, String suffix,
|
||||||
|
File directory)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
if(directory == null) {
|
||||||
|
directory = new File(System.getProperty("java.io.tmpdir"));
|
||||||
|
}
|
||||||
|
if(suffix == null) {
|
||||||
|
suffix = ".tmp";
|
||||||
|
}
|
||||||
|
File ret;
|
||||||
|
long state = System.currentTimeMillis();
|
||||||
|
|
||||||
|
do {
|
||||||
|
ret = generateFile(directory, prefix, state, suffix);
|
||||||
|
state *= 7;
|
||||||
|
state += 3;
|
||||||
|
} while(ret == null);
|
||||||
|
ret.createNewFile();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static File generateFile(File directory, String prefix, long state, String suffix) {
|
||||||
|
File ret = new File(directory, prefix + state + suffix);
|
||||||
|
if(ret.exists()) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static String normalize(String path) {
|
private static String normalize(String path) {
|
||||||
if ("\\".equals(FileSeparator)) {
|
if ("\\".equals(FileSeparator)) {
|
||||||
return path.replace('/', '\\');
|
return path.replace('/', '\\');
|
||||||
@ -76,6 +113,22 @@ public class File implements Serializable {
|
|||||||
public boolean canWrite() {
|
public boolean canWrite() {
|
||||||
return canWrite(path);
|
return canWrite(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static native boolean canExecute(String path);
|
||||||
|
|
||||||
|
public boolean canExecute() {
|
||||||
|
return canExecute(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static native boolean setExecutable(String path, boolean executable, boolean ownerOnly);
|
||||||
|
|
||||||
|
public boolean setExecutable(boolean executable) {
|
||||||
|
return setExecutable(executable, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean setExecutable(boolean executable, boolean ownerOnly) {
|
||||||
|
return setExecutable(path, executable, ownerOnly);
|
||||||
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
int index = path.lastIndexOf(FileSeparator);
|
int index = path.lastIndexOf(FileSeparator);
|
||||||
@ -151,15 +204,10 @@ public class File implements Serializable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static native void createNewFile(String path) throws IOException;
|
private static native boolean createNewFile(String path) throws IOException;
|
||||||
|
|
||||||
public boolean createNewFile() {
|
public boolean createNewFile() throws IOException {
|
||||||
try {
|
return createNewFile(path);
|
||||||
createNewFile(path);
|
|
||||||
return true;
|
|
||||||
} catch (IOException e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static native void delete(String path) throws IOException;
|
public static native void delete(String path) throws IOException;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2010, Avian Contributors
|
/* Copyright (c) 2008-2012, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
@ -16,6 +16,7 @@ public class FileInputStream extends InputStream {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
private int fd;
|
private int fd;
|
||||||
|
private int remaining;
|
||||||
|
|
||||||
public FileInputStream(FileDescriptor fd) {
|
public FileInputStream(FileDescriptor fd) {
|
||||||
this.fd = fd.value;
|
this.fd = fd.value;
|
||||||
@ -23,12 +24,17 @@ public class FileInputStream extends InputStream {
|
|||||||
|
|
||||||
public FileInputStream(String path) throws IOException {
|
public FileInputStream(String path) throws IOException {
|
||||||
fd = open(path);
|
fd = open(path);
|
||||||
|
remaining = (int) new File(path).length();
|
||||||
}
|
}
|
||||||
|
|
||||||
public FileInputStream(File file) throws IOException {
|
public FileInputStream(File file) throws IOException {
|
||||||
this(file.getPath());
|
this(file.getPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int available() throws IOException {
|
||||||
|
return remaining;
|
||||||
|
}
|
||||||
|
|
||||||
private static native int open(String path) throws IOException;
|
private static native int open(String path) throws IOException;
|
||||||
|
|
||||||
private static native int read(int fd) throws IOException;
|
private static native int read(int fd) throws IOException;
|
||||||
@ -39,7 +45,11 @@ public class FileInputStream extends InputStream {
|
|||||||
public static native void close(int fd) throws IOException;
|
public static native void close(int fd) throws IOException;
|
||||||
|
|
||||||
public int read() throws IOException {
|
public int read() throws IOException {
|
||||||
return read(fd);
|
int c = read(fd);
|
||||||
|
if (c >= 0 && remaining > 0) {
|
||||||
|
-- remaining;
|
||||||
|
}
|
||||||
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int read(byte[] b, int offset, int length) throws IOException {
|
public int read(byte[] b, int offset, int length) throws IOException {
|
||||||
@ -51,7 +61,11 @@ public class FileInputStream extends InputStream {
|
|||||||
throw new ArrayIndexOutOfBoundsException();
|
throw new ArrayIndexOutOfBoundsException();
|
||||||
}
|
}
|
||||||
|
|
||||||
return read(fd, b, offset, length);
|
int c = read(fd, b, offset, length);
|
||||||
|
if (c > 0 && remaining > 0) {
|
||||||
|
remaining -= c;
|
||||||
|
}
|
||||||
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008, Avian Contributors
|
/* Copyright (c) 2008-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2010, Avian Contributors
|
/* Copyright (c) 2008-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2010, Avian Contributors
|
/* Copyright (c) 2008-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008, Avian Contributors
|
/* Copyright (c) 2008-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008, Avian Contributors
|
/* Copyright (c) 2008-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008, Avian Contributors
|
/* Copyright (c) 2008-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2009, Avian Contributors
|
/* Copyright (c) 2008-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2010, Avian Contributors
|
/* Copyright (c) 2008-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2010, Avian Contributors
|
/* Copyright (c) 2008-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2010, Avian Contributors
|
/* Copyright (c) 2008-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008, Avian Contributors
|
/* Copyright (c) 2008-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2009, Avian Contributors
|
/* Copyright (c) 2008-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
13
classpath/java/lang/ReflectiveOperationException.java
Normal file
13
classpath/java/lang/ReflectiveOperationException.java
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
/* Copyright (c) 2012, Avian Contributors
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
that the above copyright notice and this permission notice appear
|
||||||
|
in all copies.
|
||||||
|
|
||||||
|
There is NO WARRANTY for this software. See license.txt for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
package java.lang;
|
||||||
|
|
||||||
|
public class ReflectiveOperationException extends Exception { }
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2010, Avian Contributors
|
/* Copyright (c) 2008-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
21
classpath/java/lang/RuntimePermission.java
Normal file
21
classpath/java/lang/RuntimePermission.java
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/* Copyright (c) 2012, Avian Contributors
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
that the above copyright notice and this permission notice appear
|
||||||
|
in all copies.
|
||||||
|
|
||||||
|
There is NO WARRANTY for this software. See license.txt for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
package java.lang;
|
||||||
|
|
||||||
|
import java.security.BasicPermission;
|
||||||
|
|
||||||
|
public class RuntimePermission extends BasicPermission {
|
||||||
|
|
||||||
|
public RuntimePermission(String name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2010, Avian Contributors
|
/* Copyright (c) 2008-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2010, Avian Contributors
|
/* Copyright (c) 2008-2012, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
@ -17,12 +17,15 @@ import java.io.BufferedOutputStream;
|
|||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Hashtable;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
public abstract class System {
|
public abstract class System {
|
||||||
private static final long NanoTimeBaseInMillis = currentTimeMillis();
|
private static final long NanoTimeBaseInMillis = currentTimeMillis();
|
||||||
|
|
||||||
private static Property properties;
|
private static Property properties;
|
||||||
|
private static Map<String, String> environment;
|
||||||
|
|
||||||
private static SecurityManager securityManager;
|
private static SecurityManager securityManager;
|
||||||
// static {
|
// static {
|
||||||
@ -145,4 +148,37 @@ public abstract class System {
|
|||||||
this.next = next;
|
this.next = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getenv(String name) throws NullPointerException,
|
||||||
|
SecurityException {
|
||||||
|
if (getSecurityManager() != null) { // is this allowed?
|
||||||
|
getSecurityManager().
|
||||||
|
checkPermission(new RuntimePermission("getenv." + name));
|
||||||
|
}
|
||||||
|
return getenv().get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<String, String> getenv() throws SecurityException {
|
||||||
|
if (getSecurityManager() != null) { // is this allowed?
|
||||||
|
getSecurityManager().checkPermission(new RuntimePermission("getenv.*"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (environment == null) { // build environment table
|
||||||
|
String[] vars = getEnvironment();
|
||||||
|
environment = new Hashtable<String, String>(vars.length);
|
||||||
|
for (String var : vars) { // parse name-value pairs
|
||||||
|
int equalsIndex = var.indexOf('=');
|
||||||
|
// null names and values are forbidden
|
||||||
|
if (equalsIndex != -1 && equalsIndex < var.length() - 1) {
|
||||||
|
environment.put(var.substring(0, equalsIndex),
|
||||||
|
var.substring(equalsIndex + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return environment;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the native process environment. */
|
||||||
|
private static native String[] getEnvironment();
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2010, Avian Contributors
|
/* Copyright (c) 2008-2012, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
@ -145,8 +145,8 @@ public class Thread implements Runnable {
|
|||||||
|
|
||||||
private static native boolean interrupt(long peer);
|
private static native boolean interrupt(long peer);
|
||||||
|
|
||||||
public boolean interrupted() {
|
public static boolean interrupted() {
|
||||||
return interrupted(peer);
|
return interrupted(currentThread().peer);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static native boolean interrupted(long peer);
|
private static native boolean interrupted(long peer);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2010, Avian Contributors
|
/* Copyright (c) 2008-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2009, Avian Contributors
|
/* Copyright (c) 2009-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2009, Avian Contributors
|
/* Copyright (c) 2008-2010, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2009-2010, Avian Contributors
|
/* Copyright (c) 2009-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2009, Avian Contributors
|
/* Copyright (c) 2008-2012, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
@ -81,7 +81,9 @@ public final class URL {
|
|||||||
private static URLStreamHandler findHandler(String protocol)
|
private static URLStreamHandler findHandler(String protocol)
|
||||||
throws MalformedURLException
|
throws MalformedURLException
|
||||||
{
|
{
|
||||||
if ("resource".equals(protocol)) {
|
if ("http".equals(protocol) || "https".equals(protocol)) {
|
||||||
|
return new avian.http.Handler();
|
||||||
|
} else if ("resource".equals(protocol)) {
|
||||||
return new avian.resource.Handler();
|
return new avian.resource.Handler();
|
||||||
} else if ("file".equals(protocol)) {
|
} else if ("file".equals(protocol)) {
|
||||||
return new avian.file.Handler();
|
return new avian.file.Handler();
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008, Avian Contributors
|
/* Copyright (c) 2008-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008, Avian Contributors
|
/* Copyright (c) 2008-2012, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
@ -38,9 +38,9 @@ public abstract class URLStreamHandler {
|
|||||||
host = s.substring(0, slash);
|
host = s.substring(0, slash);
|
||||||
} else {
|
} else {
|
||||||
host = s.substring(0, colon);
|
host = s.substring(0, colon);
|
||||||
port = Integer.parseInt(s.substring(colon + 1), slash);
|
port = Integer.parseInt(s.substring(colon + 1, slash));
|
||||||
}
|
}
|
||||||
s = s.substring(slash + 1);
|
s = s.substring(slash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008, Avian Contributors
|
/* Copyright (c) 2008-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008, Avian Contributors
|
/* Copyright (c) 2008-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2010, Avian Contributors
|
/* Copyright (c) 2010-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
13
classpath/java/nio/channels/ClosedSelectorException.java
Normal file
13
classpath/java/nio/channels/ClosedSelectorException.java
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
/* Copyright (c) 2012, Avian Contributors
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
that the above copyright notice and this permission notice appear
|
||||||
|
in all copies.
|
||||||
|
|
||||||
|
There is NO WARRANTY for this software. See license.txt for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
package java.nio.channels;
|
||||||
|
|
||||||
|
public class ClosedSelectorException extends IllegalStateException { }
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2010, Avian Contributors
|
/* Copyright (c) 2008-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2010, Avian Contributors
|
/* Copyright (c) 2008-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2010, Avian Contributors
|
/* Copyright (c) 2008-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2010, Avian Contributors
|
/* Copyright (c) 2008-2012, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
@ -15,7 +15,7 @@ import java.util.Iterator;
|
|||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
|
|
||||||
class SocketSelector extends Selector {
|
class SocketSelector extends Selector {
|
||||||
protected long state;
|
protected volatile long state;
|
||||||
protected final Object lock = new Object();
|
protected final Object lock = new Object();
|
||||||
protected boolean woken = false;
|
protected boolean woken = false;
|
||||||
|
|
||||||
@ -31,7 +31,7 @@ class SocketSelector extends Selector {
|
|||||||
|
|
||||||
public Selector wakeup() {
|
public Selector wakeup() {
|
||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
if (! woken) {
|
if (isOpen() && (! woken)) {
|
||||||
woken = true;
|
woken = true;
|
||||||
|
|
||||||
natWakeup(state);
|
natWakeup(state);
|
||||||
@ -66,6 +66,10 @@ class SocketSelector extends Selector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int doSelect(long interval) throws IOException {
|
public int doSelect(long interval) throws IOException {
|
||||||
|
if (! isOpen()) {
|
||||||
|
throw new ClosedSelectorException();
|
||||||
|
}
|
||||||
|
|
||||||
selectedKeys.clear();
|
selectedKeys.clear();
|
||||||
|
|
||||||
if (clearWoken()) interval = -1;
|
if (clearWoken()) interval = -1;
|
||||||
@ -106,8 +110,13 @@ class SocketSelector extends Selector {
|
|||||||
return selectedKeys.size();
|
return selectedKeys.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() {
|
public synchronized void close() {
|
||||||
natClose(state);
|
synchronized (lock) {
|
||||||
|
if (isOpen()) {
|
||||||
|
natClose(state);
|
||||||
|
state = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static native long natInit();
|
private static native long natInit();
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2009, Avian Contributors
|
/* Copyright (c) 2009-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2009, Avian Contributors
|
/* Copyright (c) 2009-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2009, Avian Contributors
|
/* Copyright (c) 2008-2012, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2009, Avian Contributors
|
/* Copyright (c) 2008-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2010, Avian Contributors
|
/* Copyright (c) 2008-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008, Avian Contributors
|
/* Copyright (c) 2008-2010, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2010, Avian Contributors
|
/* Copyright (c) 2008-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008, Avian Contributors
|
/* Copyright (c) 2008-2012, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
@ -13,7 +13,9 @@ package java.util;
|
|||||||
public class Random {
|
public class Random {
|
||||||
private static final long Mask = 0x5DEECE66DL;
|
private static final long Mask = 0x5DEECE66DL;
|
||||||
|
|
||||||
private static long nextSeed = 0;
|
private static final long InitialSeed = 123456789987654321L;
|
||||||
|
|
||||||
|
private static long nextSeed = InitialSeed;
|
||||||
|
|
||||||
private long seed;
|
private long seed;
|
||||||
|
|
||||||
@ -22,7 +24,13 @@ public class Random {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Random() {
|
public Random() {
|
||||||
setSeed((nextSeed++) ^ System.currentTimeMillis());
|
synchronized (Random.class) {
|
||||||
|
setSeed(nextSeed ^ System.currentTimeMillis());
|
||||||
|
nextSeed *= 123456789987654321L;
|
||||||
|
if (nextSeed == 0) {
|
||||||
|
nextSeed = InitialSeed;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSeed(long seed) {
|
public void setSeed(long seed) {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2009, Avian Contributors
|
/* Copyright (c) 2009-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2009, Avian Contributors
|
/* Copyright (c) 2008-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2009, Avian Contributors
|
/* Copyright (c) 2008-2010, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2009, Avian Contributors
|
/* Copyright (c) 2009-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2009, Avian Contributors
|
/* Copyright (c) 2009-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008, Avian Contributors
|
/* Copyright (c) 2008-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008, Avian Contributors
|
/* Copyright (c) 2008-2012, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
@ -14,4 +14,8 @@ public abstract class ZipEntry {
|
|||||||
public abstract String getName();
|
public abstract String getName();
|
||||||
public abstract int getCompressedSize();
|
public abstract int getCompressedSize();
|
||||||
public abstract int getSize();
|
public abstract int getSize();
|
||||||
|
|
||||||
|
public boolean isDirectory() {
|
||||||
|
return getName().endsWith("/");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2009, Avian Contributors
|
/* Copyright (c) 2008-2012, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
@ -86,7 +86,7 @@ public class ZipFile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public InputStream getInputStream(ZipEntry entry) throws IOException {
|
public InputStream getInputStream(ZipEntry entry) throws IOException {
|
||||||
int pointer = ((MyEntry) entry).pointer();
|
final int pointer = ((MyEntry) entry).pointer();
|
||||||
int method = compressionMethod(window, pointer);
|
int method = compressionMethod(window, pointer);
|
||||||
int size = compressedSize(window, pointer);
|
int size = compressedSize(window, pointer);
|
||||||
InputStream in = new MyInputStream(file, fileData(window, pointer), size);
|
InputStream in = new MyInputStream(file, fileData(window, pointer), size);
|
||||||
@ -99,7 +99,35 @@ public class ZipFile {
|
|||||||
return in;
|
return in;
|
||||||
|
|
||||||
case Deflated:
|
case Deflated:
|
||||||
return new InflaterInputStream(in, new Inflater(true));
|
return new InflaterInputStream(in, new Inflater(true)) {
|
||||||
|
int remaining = uncompressedSize(window, pointer);
|
||||||
|
|
||||||
|
public int read() throws IOException {
|
||||||
|
int c = super.read();
|
||||||
|
if (c >= 0) {
|
||||||
|
-- remaining;
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int read(byte[] buffer) throws IOException {
|
||||||
|
return read(buffer, 0, buffer.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int read(byte[] buffer, int offset, int length)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
int c = super.read(buffer, offset, length);
|
||||||
|
if (c > 0) {
|
||||||
|
remaining -= c;
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int available() {
|
||||||
|
return remaining;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new IOException();
|
throw new IOException();
|
||||||
|
50
classpath/sun/misc/Unsafe.java
Normal file
50
classpath/sun/misc/Unsafe.java
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
package sun.misc;
|
||||||
|
|
||||||
|
public final class Unsafe {
|
||||||
|
private void Unsafe() { }
|
||||||
|
|
||||||
|
private static final Unsafe Instance = new Unsafe();
|
||||||
|
|
||||||
|
public static Unsafe getUnsafe() {
|
||||||
|
return Instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public native long allocateMemory(long bytes);
|
||||||
|
|
||||||
|
public native void setMemory
|
||||||
|
(Object base, long offset, long count, byte value);
|
||||||
|
|
||||||
|
public native void freeMemory(long address);
|
||||||
|
|
||||||
|
public native byte getByte(long address);
|
||||||
|
|
||||||
|
public native void putByte(long address, byte x);
|
||||||
|
|
||||||
|
public native short getShort(long address);
|
||||||
|
|
||||||
|
public native void putShort(long address, short x);
|
||||||
|
|
||||||
|
public native char getChar(long address);
|
||||||
|
|
||||||
|
public native void putChar(long address, char x);
|
||||||
|
|
||||||
|
public native int getInt(long address);
|
||||||
|
|
||||||
|
public native void putInt(long address, int x);
|
||||||
|
|
||||||
|
public native long getLong(long address);
|
||||||
|
|
||||||
|
public native void putLong(long address, long x);
|
||||||
|
|
||||||
|
public native float getFloat(long address);
|
||||||
|
|
||||||
|
public native void putFloat(long address, float x);
|
||||||
|
|
||||||
|
public native double getDouble(long address);
|
||||||
|
|
||||||
|
public native void putDouble(long address, double x);
|
||||||
|
|
||||||
|
public native long getAddress(long address);
|
||||||
|
|
||||||
|
public native void putAddress(long address, long x);
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
Copyright (c) 2008-2011, Avian Contributors
|
Copyright (c) 2008-2012, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
245
makefile
245
makefile
@ -18,9 +18,11 @@ build-platform := \
|
|||||||
| sed 's/^cygwin.*$$/cygwin/')
|
| sed 's/^cygwin.*$$/cygwin/')
|
||||||
|
|
||||||
arch = $(build-arch)
|
arch = $(build-arch)
|
||||||
|
target-arch = $(arch)
|
||||||
bootimage-platform = \
|
bootimage-platform = \
|
||||||
$(subst cygwin,windows,$(subst mingw32,windows,$(build-platform)))
|
$(subst cygwin,windows,$(subst mingw32,windows,$(build-platform)))
|
||||||
platform = $(bootimage-platform)
|
platform = $(bootimage-platform)
|
||||||
|
target-platform = $(platform)
|
||||||
|
|
||||||
mode = fast
|
mode = fast
|
||||||
process = compile
|
process = compile
|
||||||
@ -51,6 +53,8 @@ test-build = $(build)/test
|
|||||||
src = src
|
src = src
|
||||||
classpath-src = classpath
|
classpath-src = classpath
|
||||||
test = test
|
test = test
|
||||||
|
win32 ?= $(root)/win32
|
||||||
|
win64 ?= $(root)/win64
|
||||||
|
|
||||||
classpath = avian
|
classpath = avian
|
||||||
|
|
||||||
@ -111,8 +115,13 @@ ifneq ($(openjdk),)
|
|||||||
else
|
else
|
||||||
options := $(options)-openjdk
|
options := $(options)-openjdk
|
||||||
test-executable = $(shell pwd)/$(executable-dynamic)
|
test-executable = $(shell pwd)/$(executable-dynamic)
|
||||||
library-path = \
|
ifeq ($(build-platform),darwin)
|
||||||
$(library-path-variable)=$(build):$(openjdk)/jre/lib/$(openjdk-arch)
|
library-path = \
|
||||||
|
$(library-path-variable)=$(build):$(openjdk)/jre/lib
|
||||||
|
else
|
||||||
|
library-path = \
|
||||||
|
$(library-path-variable)=$(build):$(openjdk)/jre/lib/$(openjdk-arch)
|
||||||
|
endif
|
||||||
javahome = "$$($(native-path) "$(openjdk)/jre")"
|
javahome = "$$($(native-path) "$(openjdk)/jre")"
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@ -183,8 +192,10 @@ endif
|
|||||||
build-cflags = $(common-cflags) -fPIC -fvisibility=hidden \
|
build-cflags = $(common-cflags) -fPIC -fvisibility=hidden \
|
||||||
"-I$(JAVA_HOME)/include/linux" -I$(src) -pthread
|
"-I$(JAVA_HOME)/include/linux" -I$(src) -pthread
|
||||||
|
|
||||||
converter-cflags = -D__STDC_CONSTANT_MACROS -Isrc/binaryToObject \
|
converter-cflags = -D__STDC_CONSTANT_MACROS -Isrc/binaryToObject -Isrc/ \
|
||||||
-fno-rtti -fno-exceptions
|
-fno-rtti -fno-exceptions \
|
||||||
|
-DAVIAN_TARGET_ARCH=AVIAN_ARCH_UNKNOWN \
|
||||||
|
-DAVIAN_TARGET_PLATFORM=AVIAN_PLATFORM_UNKNOWN
|
||||||
|
|
||||||
cflags = $(build-cflags)
|
cflags = $(build-cflags)
|
||||||
|
|
||||||
@ -212,6 +223,9 @@ openjdk-extra-cflags = -fvisibility=hidden
|
|||||||
|
|
||||||
bootimage-cflags = -DTARGET_BYTES_PER_WORD=$(pointer-size)
|
bootimage-cflags = -DTARGET_BYTES_PER_WORD=$(pointer-size)
|
||||||
|
|
||||||
|
developer-dir := $(shell if test -d /Developer; then echo /Developer; \
|
||||||
|
else echo /Applications/Xcode.app/Contents/Developer; fi)
|
||||||
|
|
||||||
ifeq ($(build-arch),powerpc)
|
ifeq ($(build-arch),powerpc)
|
||||||
ifneq ($(arch),$(build-arch))
|
ifneq ($(arch),$(build-arch))
|
||||||
bootimage-cflags += -DTARGET_OPPOSITE_ENDIAN
|
bootimage-cflags += -DTARGET_OPPOSITE_ENDIAN
|
||||||
@ -221,6 +235,7 @@ endif
|
|||||||
ifeq ($(arch),i386)
|
ifeq ($(arch),i386)
|
||||||
pointer-size = 4
|
pointer-size = 4
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(arch),powerpc)
|
ifeq ($(arch),powerpc)
|
||||||
asm = powerpc
|
asm = powerpc
|
||||||
pointer-size = 4
|
pointer-size = 4
|
||||||
@ -231,7 +246,6 @@ ifeq ($(arch),powerpc)
|
|||||||
|
|
||||||
ifneq ($(platform),darwin)
|
ifneq ($(platform),darwin)
|
||||||
ifneq ($(arch),$(build-arch))
|
ifneq ($(arch),$(build-arch))
|
||||||
converter-cflags += -DOPPOSITE_ENDIAN
|
|
||||||
cxx = powerpc-linux-gnu-g++
|
cxx = powerpc-linux-gnu-g++
|
||||||
cc = powerpc-linux-gnu-gcc
|
cc = powerpc-linux-gnu-gcc
|
||||||
ar = powerpc-linux-gnu-ar
|
ar = powerpc-linux-gnu-ar
|
||||||
@ -240,9 +254,11 @@ ifeq ($(arch),powerpc)
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(arch),arm)
|
ifeq ($(arch),arm)
|
||||||
asm = arm
|
asm = arm
|
||||||
pointer-size = 4
|
pointer-size = 4
|
||||||
|
|
||||||
ifeq ($(build-platform),darwin)
|
ifeq ($(build-platform),darwin)
|
||||||
ios = true
|
ios = true
|
||||||
else
|
else
|
||||||
@ -252,7 +268,7 @@ ifeq ($(arch),arm)
|
|||||||
|
|
||||||
ifneq ($(arch),$(build-arch))
|
ifneq ($(arch),$(build-arch))
|
||||||
ifeq ($(platform),darwin)
|
ifeq ($(platform),darwin)
|
||||||
ios-bin = /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin
|
ios-bin = $(developer-dir)/Platforms/iPhoneOS.platform/Developer/usr/bin
|
||||||
cxx = $(ios-bin)/g++
|
cxx = $(ios-bin)/g++
|
||||||
cc = $(ios-bin)/gcc
|
cc = $(ios-bin)/gcc
|
||||||
ar = $(ios-bin)/ar
|
ar = $(ios-bin)/ar
|
||||||
@ -272,10 +288,6 @@ ifeq ($(ios),true)
|
|||||||
cflags += -DAVIAN_IOS
|
cflags += -DAVIAN_IOS
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(platform),linux)
|
|
||||||
bootimage-cflags += -DTARGET_PLATFORM_LINUX
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(build-platform),darwin)
|
ifeq ($(build-platform),darwin)
|
||||||
build-cflags = $(common-cflags) -fPIC -fvisibility=hidden -I$(src)
|
build-cflags = $(common-cflags) -fPIC -fvisibility=hidden -I$(src)
|
||||||
cflags += -I/System/Library/Frameworks/JavaVM.framework/Headers/
|
cflags += -I/System/Library/Frameworks/JavaVM.framework/Headers/
|
||||||
@ -283,8 +295,6 @@ ifeq ($(build-platform),darwin)
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(platform),darwin)
|
ifeq ($(platform),darwin)
|
||||||
bootimage-cflags += -DTARGET_PLATFORM_DARWIN
|
|
||||||
|
|
||||||
ifeq (${OSX_SDK_SYSROOT},)
|
ifeq (${OSX_SDK_SYSROOT},)
|
||||||
OSX_SDK_SYSROOT = 10.4u
|
OSX_SDK_SYSROOT = 10.4u
|
||||||
endif
|
endif
|
||||||
@ -303,9 +313,11 @@ ifeq ($(platform),darwin)
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
version-script-flag =
|
version-script-flag =
|
||||||
lflags = $(common-lflags) -ldl -framework CoreFoundation
|
lflags = $(common-lflags) -ldl -framework CoreFoundation \
|
||||||
|
-Wl,-compatibility_version,1.0.0
|
||||||
ifneq ($(arch),arm)
|
ifneq ($(arch),arm)
|
||||||
lflags += -framework CoreServices
|
lflags += -framework CoreServices -framework SystemConfiguration \
|
||||||
|
-framework Security
|
||||||
endif
|
endif
|
||||||
ifeq ($(bootimage),true)
|
ifeq ($(bootimage),true)
|
||||||
bootimage-lflags = -Wl,-segprot,__RWX,rwx,rwx
|
bootimage-lflags = -Wl,-segprot,__RWX,rwx,rwx
|
||||||
@ -315,12 +327,22 @@ ifeq ($(platform),darwin)
|
|||||||
so-suffix = .dylib
|
so-suffix = .dylib
|
||||||
shared = -dynamiclib
|
shared = -dynamiclib
|
||||||
|
|
||||||
|
sdk-dir = $(developer-dir)/Platforms/iPhoneOS.platform/Developer/SDKs
|
||||||
|
|
||||||
ifeq ($(arch),arm)
|
ifeq ($(arch),arm)
|
||||||
ifeq ($(build-arch),powerpc)
|
ios-version := \
|
||||||
converter-cflags += -DOPPOSITE_ENDIAN
|
$(shell if test -d $(sdk-dir)/iPhoneOS5.1.sdk; then echo 5.1; \
|
||||||
|
elif test -d $(sdk-dir)/iPhoneOS5.0.sdk; then echo 5.0; \
|
||||||
|
elif test -d $(sdk-dir)/iPhoneOS4.3.sdk; then echo 4.3; \
|
||||||
|
elif test -d $(sdk-dir)/iPhoneOS4.2.sdk; then echo 4.2; \
|
||||||
|
else echo; fi)
|
||||||
|
|
||||||
|
ifeq ($(ios-version),)
|
||||||
|
x := $(error "couldn't find SDK for iOS version")
|
||||||
endif
|
endif
|
||||||
flags = -arch armv6 -isysroot \
|
|
||||||
/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/
|
flags = -arch armv7 -isysroot \
|
||||||
|
$(sdk-dir)/iPhoneOS$(ios-version).sdk/
|
||||||
openjdk-extra-cflags += $(flags)
|
openjdk-extra-cflags += $(flags)
|
||||||
cflags += $(flags)
|
cflags += $(flags)
|
||||||
asmflags += $(flags)
|
asmflags += $(flags)
|
||||||
@ -328,9 +350,6 @@ ifeq ($(platform),darwin)
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(arch),powerpc)
|
ifeq ($(arch),powerpc)
|
||||||
ifneq (,$(filter i386 x86_64 arm,$(build-arch)))
|
|
||||||
converter-cflags += -DOPPOSITE_ENDIAN
|
|
||||||
endif
|
|
||||||
openjdk-extra-cflags += -arch ppc -mmacosx-version-min=${OSX_SDK_VERSION}
|
openjdk-extra-cflags += -arch ppc -mmacosx-version-min=${OSX_SDK_VERSION}
|
||||||
cflags += -arch ppc -mmacosx-version-min=${OSX_SDK_VERSION}
|
cflags += -arch ppc -mmacosx-version-min=${OSX_SDK_VERSION}
|
||||||
asmflags += -arch ppc -mmacosx-version-min=${OSX_SDK_VERSION}
|
asmflags += -arch ppc -mmacosx-version-min=${OSX_SDK_VERSION}
|
||||||
@ -338,9 +357,6 @@ ifeq ($(platform),darwin)
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(arch),i386)
|
ifeq ($(arch),i386)
|
||||||
ifeq ($(build-arch),powerpc)
|
|
||||||
converter-cflags += -DOPPOSITE_ENDIAN
|
|
||||||
endif
|
|
||||||
openjdk-extra-cflags += -arch i386 -mmacosx-version-min=${OSX_SDK_VERSION}
|
openjdk-extra-cflags += -arch i386 -mmacosx-version-min=${OSX_SDK_VERSION}
|
||||||
cflags += -arch i386 -mmacosx-version-min=${OSX_SDK_VERSION}
|
cflags += -arch i386 -mmacosx-version-min=${OSX_SDK_VERSION}
|
||||||
asmflags += -arch i386 -mmacosx-version-min=${OSX_SDK_VERSION}
|
asmflags += -arch i386 -mmacosx-version-min=${OSX_SDK_VERSION}
|
||||||
@ -348,9 +364,6 @@ ifeq ($(platform),darwin)
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(arch),x86_64)
|
ifeq ($(arch),x86_64)
|
||||||
ifeq ($(build-arch),powerpc)
|
|
||||||
converter-cflags += -DOPPOSITE_ENDIAN
|
|
||||||
endif
|
|
||||||
openjdk-extra-cflags += -arch x86_64
|
openjdk-extra-cflags += -arch x86_64
|
||||||
cflags += -arch x86_64
|
cflags += -arch x86_64
|
||||||
asmflags += -arch x86_64
|
asmflags += -arch x86_64
|
||||||
@ -359,10 +372,8 @@ ifeq ($(platform),darwin)
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(platform),windows)
|
ifeq ($(platform),windows)
|
||||||
bootimage-cflags += -DTARGET_PLATFORM_WINDOWS
|
inc = "$(win32)/include"
|
||||||
|
lib = "$(win32)/lib"
|
||||||
inc = "$(root)/win32/include"
|
|
||||||
lib = "$(root)/win32/lib"
|
|
||||||
|
|
||||||
embed-prefix = c:/avian-embedded
|
embed-prefix = c:/avian-embedded
|
||||||
|
|
||||||
@ -372,9 +383,8 @@ ifeq ($(platform),windows)
|
|||||||
so-suffix = .dll
|
so-suffix = .dll
|
||||||
exe-suffix = .exe
|
exe-suffix = .exe
|
||||||
|
|
||||||
lflags = -L$(lib) $(common-lflags) -lws2_32 -mwindows -mconsole
|
lflags = -L$(lib) $(common-lflags) -lws2_32 -liphlpapi -mwindows -mconsole
|
||||||
cflags = -I$(inc) $(common-cflags) -DWINVER=0x0500 -DTARGET_PLATFORM_WINDOWS
|
cflags = -I$(inc) $(common-cflags) -DWINVER=0x0500
|
||||||
|
|
||||||
|
|
||||||
ifeq (,$(filter mingw32 cygwin,$(build-platform)))
|
ifeq (,$(filter mingw32 cygwin,$(build-platform)))
|
||||||
openjdk-extra-cflags += -I$(src)/openjdk/caseSensitive
|
openjdk-extra-cflags += -I$(src)/openjdk/caseSensitive
|
||||||
@ -411,13 +421,16 @@ ifeq ($(platform),windows)
|
|||||||
ar = x86_64-w64-mingw32-ar
|
ar = x86_64-w64-mingw32-ar
|
||||||
ranlib = x86_64-w64-mingw32-ranlib
|
ranlib = x86_64-w64-mingw32-ranlib
|
||||||
strip = x86_64-w64-mingw32-strip
|
strip = x86_64-w64-mingw32-strip
|
||||||
inc = "$(root)/win64/include"
|
inc = "$(win64)/include"
|
||||||
lib = "$(root)/win64/lib"
|
lib = "$(win64)/lib"
|
||||||
|
else
|
||||||
|
shared += -Wl,--add-stdcall-alias
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(mode),debug)
|
ifeq ($(mode),debug)
|
||||||
optimization-cflags = -O0 -g3
|
optimization-cflags = -O0 -g3
|
||||||
|
converter-cflags += -O0 -g3
|
||||||
strip = :
|
strip = :
|
||||||
endif
|
endif
|
||||||
ifeq ($(mode),debug-fast)
|
ifeq ($(mode),debug-fast)
|
||||||
@ -459,6 +472,7 @@ ifneq ($(platform),darwin)
|
|||||||
ifeq ($(arch),i386)
|
ifeq ($(arch),i386)
|
||||||
# this is necessary to support __sync_bool_compare_and_swap:
|
# this is necessary to support __sync_bool_compare_and_swap:
|
||||||
cflags += -march=i586
|
cflags += -march=i586
|
||||||
|
lflags += -march=i586
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@ -469,7 +483,7 @@ build-ld := $(build-cc)
|
|||||||
|
|
||||||
ifdef msvc
|
ifdef msvc
|
||||||
windows-java-home := $(shell cygpath -m "$(JAVA_HOME)")
|
windows-java-home := $(shell cygpath -m "$(JAVA_HOME)")
|
||||||
zlib := $(shell cygpath -m "$(root)/win32/msvc")
|
zlib := $(shell cygpath -m "$(win32)/msvc")
|
||||||
cxx = "$(msvc)/BIN/cl.exe"
|
cxx = "$(msvc)/BIN/cl.exe"
|
||||||
cc = $(cxx)
|
cc = $(cxx)
|
||||||
ld = "$(msvc)/BIN/link.exe"
|
ld = "$(msvc)/BIN/link.exe"
|
||||||
@ -478,7 +492,8 @@ ifdef msvc
|
|||||||
-DUSE_ATOMIC_OPERATIONS -DAVIAN_JAVA_HOME=\"$(javahome)\" \
|
-DUSE_ATOMIC_OPERATIONS -DAVIAN_JAVA_HOME=\"$(javahome)\" \
|
||||||
-DAVIAN_EMBED_PREFIX=\"$(embed-prefix)\" \
|
-DAVIAN_EMBED_PREFIX=\"$(embed-prefix)\" \
|
||||||
-Fd$(build)/$(name).pdb -I"$(zlib)/include" -I$(src) -I"$(build)" \
|
-Fd$(build)/$(name).pdb -I"$(zlib)/include" -I$(src) -I"$(build)" \
|
||||||
-I"$(windows-java-home)/include" -I"$(windows-java-home)/include/win32"
|
-I"$(windows-java-home)/include" -I"$(windows-java-home)/include/win32" \
|
||||||
|
-DTARGET_BYTES_PER_WORD=$(pointer-size)
|
||||||
shared = -dll
|
shared = -dll
|
||||||
lflags = -nologo -LIBPATH:"$(zlib)/lib" -DEFAULTLIB:ws2_32 \
|
lflags = -nologo -LIBPATH:"$(zlib)/lib" -DEFAULTLIB:ws2_32 \
|
||||||
-DEFAULTLIB:zlib -MANIFEST -debug
|
-DEFAULTLIB:zlib -MANIFEST -debug
|
||||||
@ -569,10 +584,7 @@ bootimage-generator-objects = \
|
|||||||
$(call cpp-objects,$(bootimage-generator-sources),$(src),$(build))
|
$(call cpp-objects,$(bootimage-generator-sources),$(src),$(build))
|
||||||
bootimage-generator = $(build)/bootimage-generator
|
bootimage-generator = $(build)/bootimage-generator
|
||||||
|
|
||||||
bootimage-bin = $(build)/bootimage.bin
|
|
||||||
bootimage-object = $(build)/bootimage-bin.o
|
bootimage-object = $(build)/bootimage-bin.o
|
||||||
|
|
||||||
codeimage-bin = $(build)/codeimage.bin
|
|
||||||
codeimage-object = $(build)/codeimage-bin.o
|
codeimage-object = $(build)/codeimage-bin.o
|
||||||
|
|
||||||
ifeq ($(bootimage),true)
|
ifeq ($(bootimage),true)
|
||||||
@ -608,14 +620,23 @@ generator-objects = \
|
|||||||
$(call generator-cpp-objects,$(generator-sources),$(src),$(build))
|
$(call generator-cpp-objects,$(generator-sources),$(src),$(build))
|
||||||
generator = $(build)/generator
|
generator = $(build)/generator
|
||||||
|
|
||||||
converter-objects = \
|
converter-depends = \
|
||||||
$(build)/binaryToObject-main.o \
|
$(src)/binaryToObject/tools.h \
|
||||||
$(build)/binaryToObject-elf64.o \
|
$(src)/binaryToObject/endianness.h
|
||||||
$(build)/binaryToObject-elf32.o \
|
|
||||||
$(build)/binaryToObject-mach-o64.o \
|
|
||||||
$(build)/binaryToObject-mach-o32.o \
|
converter-sources = \
|
||||||
$(build)/binaryToObject-pe.o
|
$(src)/binaryToObject/tools.cpp \
|
||||||
converter = $(build)/binaryToObject
|
$(src)/binaryToObject/elf.cpp \
|
||||||
|
$(src)/binaryToObject/mach-o.cpp \
|
||||||
|
$(src)/binaryToObject/pe.cpp
|
||||||
|
|
||||||
|
converter-tool-sources = \
|
||||||
|
$(src)/binaryToObject/main.cpp
|
||||||
|
|
||||||
|
converter-objects = $(call cpp-objects,$(converter-sources),$(src),$(build))
|
||||||
|
converter-tool-objects = $(call cpp-objects,$(converter-tool-sources),$(src),$(build))
|
||||||
|
converter = $(build)/binaryToObject/binaryToObject
|
||||||
|
|
||||||
static-library = $(build)/lib$(name).a
|
static-library = $(build)/lib$(name).a
|
||||||
executable = $(build)/$(name)${exe-suffix}
|
executable = $(build)/$(name)${exe-suffix}
|
||||||
@ -685,6 +706,34 @@ ifeq ($(tails),true)
|
|||||||
extra.Tails
|
extra.Tails
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(target-arch),i386)
|
||||||
|
cflags += -DAVIAN_TARGET_ARCH=AVIAN_ARCH_X86
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(target-arch),x86_64)
|
||||||
|
cflags += -DAVIAN_TARGET_ARCH=AVIAN_ARCH_X86_64
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(target-arch),powerpc)
|
||||||
|
cflags += -DAVIAN_TARGET_ARCH=AVIAN_ARCH_POWERPC
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(target-arch),arm)
|
||||||
|
cflags += -DAVIAN_TARGET_ARCH=AVIAN_ARCH_ARM
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(target-platform),linux)
|
||||||
|
cflags += -DAVIAN_TARGET_PLATFORM=AVIAN_PLATFORM_LINUX
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(target-platform),windows)
|
||||||
|
cflags += -DAVIAN_TARGET_PLATFORM=AVIAN_PLATFORM_WINDOWS
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(target-platform),darwin)
|
||||||
|
cflags += -DAVIAN_TARGET_PLATFORM=AVIAN_PLATFORM_DARWIN
|
||||||
|
endif
|
||||||
|
|
||||||
class-name = $(patsubst $(1)/%.class,%,$(2))
|
class-name = $(patsubst $(1)/%.class,%,$(2))
|
||||||
class-names = $(foreach x,$(2),$(call class-name,$(1),$(x)))
|
class-names = $(foreach x,$(2),$(call class-name,$(1),$(x)))
|
||||||
|
|
||||||
@ -820,26 +869,12 @@ $(boot-object): $(boot-source)
|
|||||||
$(boot-javahome-object): $(src)/boot-javahome.cpp
|
$(boot-javahome-object): $(src)/boot-javahome.cpp
|
||||||
$(compile-object)
|
$(compile-object)
|
||||||
|
|
||||||
$(build)/binaryToObject-main.o: $(src)/binaryToObject/main.cpp
|
$(converter-objects) $(converter-tool-objects): $(build)/binaryToObject/%.o: $(src)/binaryToObject/%.cpp $(converter-depends)
|
||||||
$(build-cxx) $(converter-cflags) -c $(^) -o $(@)
|
@mkdir -p $(dir $(@))
|
||||||
|
$(build-cxx) $(converter-cflags) -c $(<) -o $(@)
|
||||||
|
|
||||||
$(build)/binaryToObject-elf64.o: $(src)/binaryToObject/elf.cpp
|
$(converter): $(converter-objects) $(converter-tool-objects)
|
||||||
$(build-cxx) $(converter-cflags) -DBITS_PER_WORD=64 -c $(^) -o $(@)
|
$(build-cc) $(^) -g -o $(@)
|
||||||
|
|
||||||
$(build)/binaryToObject-elf32.o: $(src)/binaryToObject/elf.cpp
|
|
||||||
$(build-cxx) $(converter-cflags) -DBITS_PER_WORD=32 -c $(^) -o $(@)
|
|
||||||
|
|
||||||
$(build)/binaryToObject-mach-o64.o: $(src)/binaryToObject/mach-o.cpp
|
|
||||||
$(build-cxx) $(converter-cflags) -DBITS_PER_WORD=64 -c $(^) -o $(@)
|
|
||||||
|
|
||||||
$(build)/binaryToObject-mach-o32.o: $(src)/binaryToObject/mach-o.cpp
|
|
||||||
$(build-cxx) $(converter-cflags) -DBITS_PER_WORD=32 -c $(^) -o $(@)
|
|
||||||
|
|
||||||
$(build)/binaryToObject-pe.o: $(src)/binaryToObject/pe.cpp
|
|
||||||
$(build-cxx) $(converter-cflags) -c $(^) -o $(@)
|
|
||||||
|
|
||||||
$(converter): $(converter-objects)
|
|
||||||
$(build-cc) $(^) -o $(@)
|
|
||||||
|
|
||||||
$(build)/classpath.jar: $(classpath-dep) $(classpath-jar-dep)
|
$(build)/classpath.jar: $(classpath-dep) $(classpath-jar-dep)
|
||||||
@echo "creating $(@)"
|
@echo "creating $(@)"
|
||||||
@ -880,20 +915,10 @@ $(static-library): $(vm-objects) $(classpath-objects) $(vm-heapwalk-objects) \
|
|||||||
$(ar) cru $(@) $(^)
|
$(ar) cru $(@) $(^)
|
||||||
$(ranlib) $(@)
|
$(ranlib) $(@)
|
||||||
|
|
||||||
$(bootimage-bin): $(bootimage-generator)
|
$(bootimage-object) $(codeimage-object): $(bootimage-generator)
|
||||||
$(<) $(classpath-build) $(@) $(codeimage-bin)
|
$(<) -cp $(classpath-build) -bootimage $(bootimage-object) -codeimage $(codeimage-object) \
|
||||||
|
-bootimage-symbols _binary_bootimage_bin_start:_binary_bootimage_bin_end \
|
||||||
$(bootimage-object): $(bootimage-bin) $(converter)
|
-codeimage-symbols _binary_codeimage_bin_start:_binary_codeimage_bin_end
|
||||||
@echo "creating $(@)"
|
|
||||||
$(converter) $(<) $(@) _binary_bootimage_bin_start \
|
|
||||||
_binary_bootimage_bin_end $(platform) $(arch) $(pointer-size) \
|
|
||||||
writable
|
|
||||||
|
|
||||||
$(codeimage-object): $(bootimage-bin) $(converter)
|
|
||||||
@echo "creating $(@)"
|
|
||||||
$(converter) $(codeimage-bin) $(@) _binary_codeimage_bin_start \
|
|
||||||
_binary_codeimage_bin_end $(platform) $(arch) $(pointer-size) \
|
|
||||||
executable
|
|
||||||
|
|
||||||
executable-objects = $(vm-objects) $(classpath-objects) $(driver-object) \
|
executable-objects = $(vm-objects) $(classpath-objects) $(driver-object) \
|
||||||
$(vm-heapwalk-objects) $(boot-object) $(vm-classpath-objects) \
|
$(vm-heapwalk-objects) $(boot-object) $(vm-classpath-objects) \
|
||||||
@ -916,10 +941,13 @@ else
|
|||||||
endif
|
endif
|
||||||
$(strip) $(strip-all) $(@)
|
$(strip) $(strip-all) $(@)
|
||||||
|
|
||||||
$(bootimage-generator):
|
$(bootimage-generator): $(bootimage-generator-objects)
|
||||||
|
echo arch=$(arch) platform=$(platform)
|
||||||
$(MAKE) mode=$(mode) \
|
$(MAKE) mode=$(mode) \
|
||||||
arch=$(build-arch) \
|
arch=$(build-arch) \
|
||||||
|
target-arch=$(arch) \
|
||||||
platform=$(bootimage-platform) \
|
platform=$(bootimage-platform) \
|
||||||
|
target-platform=$(platform) \
|
||||||
openjdk=$(openjdk) \
|
openjdk=$(openjdk) \
|
||||||
openjdk-src=$(openjdk-src) \
|
openjdk-src=$(openjdk-src) \
|
||||||
bootimage-generator= \
|
bootimage-generator= \
|
||||||
@ -930,7 +958,7 @@ $(bootimage-generator):
|
|||||||
|
|
||||||
$(build-bootimage-generator): \
|
$(build-bootimage-generator): \
|
||||||
$(vm-objects) $(classpath-object) $(classpath-objects) \
|
$(vm-objects) $(classpath-object) $(classpath-objects) \
|
||||||
$(heapwalk-objects) $(bootimage-generator-objects)
|
$(heapwalk-objects) $(bootimage-generator-objects) $(converter-objects)
|
||||||
@echo "linking $(@)"
|
@echo "linking $(@)"
|
||||||
ifeq ($(platform),windows)
|
ifeq ($(platform),windows)
|
||||||
ifdef msvc
|
ifdef msvc
|
||||||
@ -983,6 +1011,18 @@ $(openjdk-objects): $(build)/openjdk/%-openjdk.o: $(openjdk-src)/%.c \
|
|||||||
@echo "compiling $(@)"
|
@echo "compiling $(@)"
|
||||||
@mkdir -p $(dir $(@))
|
@mkdir -p $(dir $(@))
|
||||||
sed 's/^static jclass ia_class;//' < $(<) > $(build)/openjdk/$(notdir $(<))
|
sed 's/^static jclass ia_class;//' < $(<) > $(build)/openjdk/$(notdir $(<))
|
||||||
|
ifeq ($(ios),true)
|
||||||
|
sed \
|
||||||
|
-e 's/^#ifndef __APPLE__/#if 1/' \
|
||||||
|
-e 's/^#ifdef __APPLE__/#if 0/' \
|
||||||
|
< "$(openjdk-src)/solaris/native/java/lang/ProcessEnvironment_md.c" \
|
||||||
|
> $(build)/openjdk/ProcessEnvironment_md.c
|
||||||
|
sed \
|
||||||
|
-e 's/^#ifndef __APPLE__/#if 1/' \
|
||||||
|
-e 's/^#ifdef __APPLE__/#if 0/' \
|
||||||
|
< "$(openjdk-src)/solaris/native/java/lang/UNIXProcess_md.c" \
|
||||||
|
> $(build)/openjdk/UNIXProcess_md.c
|
||||||
|
endif
|
||||||
$(cc) -fPIC $(openjdk-extra-cflags) $(openjdk-cflags) \
|
$(cc) -fPIC $(openjdk-extra-cflags) $(openjdk-cflags) \
|
||||||
$(optimization-cflags) -w -c $(build)/openjdk/$(notdir $(<)) \
|
$(optimization-cflags) -w -c $(build)/openjdk/$(notdir $(<)) \
|
||||||
$(call output,$(@))
|
$(call output,$(@))
|
||||||
@ -1013,6 +1053,42 @@ ifeq ($(platform),windows)
|
|||||||
< "$(openjdk-src)/windows/native/java/net/NetworkInterface.h" \
|
< "$(openjdk-src)/windows/native/java/net/NetworkInterface.h" \
|
||||||
> $(build)/openjdk/NetworkInterface.h
|
> $(build)/openjdk/NetworkInterface.h
|
||||||
echo 'static int getAddrsFromAdapter(IP_ADAPTER_ADDRESSES *ptr, netaddr **netaddrPP);' >> $(build)/openjdk/NetworkInterface.h
|
echo 'static int getAddrsFromAdapter(IP_ADAPTER_ADDRESSES *ptr, netaddr **netaddrPP);' >> $(build)/openjdk/NetworkInterface.h
|
||||||
|
endif
|
||||||
|
ifeq ($(platform),darwin)
|
||||||
|
mkdir -p $(build)/openjdk/netinet
|
||||||
|
for file in \
|
||||||
|
/usr/include/netinet/ip.h \
|
||||||
|
/usr/include/netinet/in_systm.h \
|
||||||
|
/usr/include/netinet/ip_icmp.h \
|
||||||
|
/usr/include/netinet/in_var.h \
|
||||||
|
/usr/include/netinet/icmp6.h \
|
||||||
|
/usr/include/netinet/ip_var.h; do \
|
||||||
|
if [ ! -f "$(build)/openjdk/netinet/$$(basename $${file})" ]; then \
|
||||||
|
ln "$${file}" "$(build)/openjdk/netinet/$$(basename $${file})"; \
|
||||||
|
fi; \
|
||||||
|
done
|
||||||
|
mkdir -p $(build)/openjdk/netinet6
|
||||||
|
for file in \
|
||||||
|
/usr/include/netinet6/in6_var.h; do \
|
||||||
|
if [ ! -f "$(build)/openjdk/netinet6/$$(basename $${file})" ]; then \
|
||||||
|
ln "$${file}" "$(build)/openjdk/netinet6/$$(basename $${file})"; \
|
||||||
|
fi; \
|
||||||
|
done
|
||||||
|
mkdir -p $(build)/openjdk/net
|
||||||
|
for file in \
|
||||||
|
/usr/include/net/if_arp.h; do \
|
||||||
|
if [ ! -f "$(build)/openjdk/net/$$(basename $${file})" ]; then \
|
||||||
|
ln "$${file}" "$(build)/openjdk/net/$$(basename $${file})"; \
|
||||||
|
fi; \
|
||||||
|
done
|
||||||
|
mkdir -p $(build)/openjdk/sys
|
||||||
|
for file in \
|
||||||
|
/usr/include/sys/kern_event.h \
|
||||||
|
/usr/include/sys/sys_domain.h; do \
|
||||||
|
if [ ! -f "$(build)/openjdk/sys/$$(basename $${file})" ]; then \
|
||||||
|
ln "$${file}" "$(build)/openjdk/sys/$$(basename $${file})"; \
|
||||||
|
fi; \
|
||||||
|
done
|
||||||
endif
|
endif
|
||||||
@touch $(@)
|
@touch $(@)
|
||||||
|
|
||||||
@ -1024,6 +1100,7 @@ $(openjdk-jar-dep):
|
|||||||
$(jar) xf "$$($(native-path) "$(openjdk)/jre/lib/rt.jar")" && \
|
$(jar) xf "$$($(native-path) "$(openjdk)/jre/lib/rt.jar")" && \
|
||||||
$(jar) xf "$$($(native-path) "$(openjdk)/jre/lib/jsse.jar")" && \
|
$(jar) xf "$$($(native-path) "$(openjdk)/jre/lib/jsse.jar")" && \
|
||||||
$(jar) xf "$$($(native-path) "$(openjdk)/jre/lib/jce.jar")" && \
|
$(jar) xf "$$($(native-path) "$(openjdk)/jre/lib/jce.jar")" && \
|
||||||
|
$(jar) xf "$$($(native-path) "$(openjdk)/jre/lib/charsets.jar")" && \
|
||||||
$(jar) xf "$$($(native-path) "$(openjdk)/jre/lib/ext/sunjce_provider.jar")" && \
|
$(jar) xf "$$($(native-path) "$(openjdk)/jre/lib/ext/sunjce_provider.jar")" && \
|
||||||
$(jar) xf "$$($(native-path) "$(openjdk)/jre/lib/resources.jar")")
|
$(jar) xf "$$($(native-path) "$(openjdk)/jre/lib/resources.jar")")
|
||||||
@touch $(@)
|
@touch $(@)
|
||||||
|
@ -45,7 +45,6 @@ openjdk-sources = \
|
|||||||
$(openjdk-src)/share/native/java/util/zip/CRC32.c \
|
$(openjdk-src)/share/native/java/util/zip/CRC32.c \
|
||||||
$(openjdk-src)/share/native/java/util/zip/Deflater.c \
|
$(openjdk-src)/share/native/java/util/zip/Deflater.c \
|
||||||
$(openjdk-src)/share/native/java/util/zip/Inflater.c \
|
$(openjdk-src)/share/native/java/util/zip/Inflater.c \
|
||||||
$(openjdk-src)/share/native/java/util/zip/ZipEntry.c \
|
|
||||||
$(openjdk-src)/share/native/java/util/zip/ZipFile.c \
|
$(openjdk-src)/share/native/java/util/zip/ZipFile.c \
|
||||||
$(openjdk-src)/share/native/java/util/zip/zip_util.c \
|
$(openjdk-src)/share/native/java/util/zip/zip_util.c \
|
||||||
$(openjdk-src)/share/native/sun/management/VMManagementImpl.c \
|
$(openjdk-src)/share/native/sun/management/VMManagementImpl.c \
|
||||||
@ -76,6 +75,7 @@ openjdk-headers-classes = \
|
|||||||
java.lang.Double \
|
java.lang.Double \
|
||||||
java.lang.Float \
|
java.lang.Float \
|
||||||
java.lang.Integer \
|
java.lang.Integer \
|
||||||
|
java.lang.Long \
|
||||||
java.lang.Object \
|
java.lang.Object \
|
||||||
java.lang.Package \
|
java.lang.Package \
|
||||||
java.lang.Runtime \
|
java.lang.Runtime \
|
||||||
@ -124,7 +124,7 @@ openjdk-headers-classes = \
|
|||||||
sun.net.spi.DefaultProxySelector \
|
sun.net.spi.DefaultProxySelector \
|
||||||
sun.nio.ch.FileKey \
|
sun.nio.ch.FileKey \
|
||||||
sun.nio.ch.FileChannelImpl \
|
sun.nio.ch.FileChannelImpl \
|
||||||
sun.nio.ch.FileDispatcher \
|
sun.nio.ch.FileDispatcherImpl \
|
||||||
sun.nio.ch.DatagramChannelImpl \
|
sun.nio.ch.DatagramChannelImpl \
|
||||||
sun.nio.ch.DatagramDispatcher \
|
sun.nio.ch.DatagramDispatcher \
|
||||||
sun.nio.ch.IOStatus \
|
sun.nio.ch.IOStatus \
|
||||||
@ -173,6 +173,7 @@ endif
|
|||||||
|
|
||||||
ifeq ($(platform),windows)
|
ifeq ($(platform),windows)
|
||||||
openjdk-sources += \
|
openjdk-sources += \
|
||||||
|
$(openjdk-src)/windows/native/common/jni_util_md.c \
|
||||||
$(openjdk-src)/windows/native/java/io/canonicalize_md.c \
|
$(openjdk-src)/windows/native/java/io/canonicalize_md.c \
|
||||||
$(openjdk-src)/windows/native/java/io/Console_md.c \
|
$(openjdk-src)/windows/native/java/io/Console_md.c \
|
||||||
$(openjdk-src)/windows/native/java/io/FileDescriptor_md.c \
|
$(openjdk-src)/windows/native/java/io/FileDescriptor_md.c \
|
||||||
@ -193,7 +194,6 @@ ifeq ($(platform),windows)
|
|||||||
$(openjdk-src)/windows/native/java/net/Inet6AddressImpl.c \
|
$(openjdk-src)/windows/native/java/net/Inet6AddressImpl.c \
|
||||||
$(openjdk-src)/windows/native/java/net/NetworkInterface.c \
|
$(openjdk-src)/windows/native/java/net/NetworkInterface.c \
|
||||||
$(openjdk-src)/windows/native/java/net/NetworkInterface_winXP.c \
|
$(openjdk-src)/windows/native/java/net/NetworkInterface_winXP.c \
|
||||||
$(openjdk-src)/windows/native/java/net/NetworkInterface_win9x.c \
|
|
||||||
$(openjdk-src)/windows/native/java/net/SocketInputStream.c \
|
$(openjdk-src)/windows/native/java/net/SocketInputStream.c \
|
||||||
$(openjdk-src)/windows/native/java/net/SocketOutputStream.c \
|
$(openjdk-src)/windows/native/java/net/SocketOutputStream.c \
|
||||||
$(openjdk-src)/windows/native/java/util/WindowsPreferences.c \
|
$(openjdk-src)/windows/native/java/util/WindowsPreferences.c \
|
||||||
@ -203,7 +203,7 @@ ifeq ($(platform),windows)
|
|||||||
$(openjdk-src)/windows/native/sun/nio/ch/DatagramChannelImpl.c \
|
$(openjdk-src)/windows/native/sun/nio/ch/DatagramChannelImpl.c \
|
||||||
$(openjdk-src)/windows/native/sun/nio/ch/DatagramDispatcher.c \
|
$(openjdk-src)/windows/native/sun/nio/ch/DatagramDispatcher.c \
|
||||||
$(openjdk-src)/windows/native/sun/nio/ch/FileChannelImpl.c \
|
$(openjdk-src)/windows/native/sun/nio/ch/FileChannelImpl.c \
|
||||||
$(openjdk-src)/windows/native/sun/nio/ch/FileDispatcher.c \
|
$(openjdk-src)/windows/native/sun/nio/ch/FileDispatcherImpl.c \
|
||||||
$(openjdk-src)/windows/native/sun/nio/ch/FileKey.c \
|
$(openjdk-src)/windows/native/sun/nio/ch/FileKey.c \
|
||||||
$(openjdk-src)/windows/native/sun/nio/ch/IOUtil.c \
|
$(openjdk-src)/windows/native/sun/nio/ch/IOUtil.c \
|
||||||
$(openjdk-src)/windows/native/sun/nio/ch/Net.c \
|
$(openjdk-src)/windows/native/sun/nio/ch/Net.c \
|
||||||
@ -211,6 +211,7 @@ ifeq ($(platform),windows)
|
|||||||
$(openjdk-src)/windows/native/sun/nio/ch/SocketChannelImpl.c \
|
$(openjdk-src)/windows/native/sun/nio/ch/SocketChannelImpl.c \
|
||||||
$(openjdk-src)/windows/native/sun/nio/ch/SocketDispatcher.c \
|
$(openjdk-src)/windows/native/sun/nio/ch/SocketDispatcher.c \
|
||||||
$(openjdk-src)/windows/native/sun/nio/ch/WindowsSelectorImpl.c \
|
$(openjdk-src)/windows/native/sun/nio/ch/WindowsSelectorImpl.c \
|
||||||
|
$(openjdk-src)/windows/native/sun/nio/fs/WindowsNativeDispatcher.c \
|
||||||
$(openjdk-src)/windows/native/sun/security/provider/WinCAPISeedGenerator.c
|
$(openjdk-src)/windows/native/sun/security/provider/WinCAPISeedGenerator.c
|
||||||
|
|
||||||
openjdk-headers-classes += \
|
openjdk-headers-classes += \
|
||||||
@ -218,6 +219,7 @@ ifeq ($(platform),windows)
|
|||||||
java.lang.ProcessImpl \
|
java.lang.ProcessImpl \
|
||||||
sun.io.Win32ErrorMode \
|
sun.io.Win32ErrorMode \
|
||||||
sun.nio.ch.WindowsSelectorImpl \
|
sun.nio.ch.WindowsSelectorImpl \
|
||||||
|
sun.nio.fs.WindowsNativeDispatcher \
|
||||||
|
|
||||||
openjdk-cflags += \
|
openjdk-cflags += \
|
||||||
"-I$(openjdk-src)/windows/javavm/export" \
|
"-I$(openjdk-src)/windows/javavm/export" \
|
||||||
@ -228,6 +230,9 @@ ifeq ($(platform),windows)
|
|||||||
"-I$(openjdk-src)/windows/native/sun/nio/ch" \
|
"-I$(openjdk-src)/windows/native/sun/nio/ch" \
|
||||||
"-I$(openjdk-src)/windows/javavm/include" \
|
"-I$(openjdk-src)/windows/javavm/include" \
|
||||||
"-I$(root)/win32/include" \
|
"-I$(root)/win32/include" \
|
||||||
|
-DLOCALE_SNAME=0x0000005c \
|
||||||
|
-DLOCALE_SISO3166CTRYNAME2=0x00000068 \
|
||||||
|
-DLOCALE_SISO639LANGNAME2=0x00000067 \
|
||||||
-D_JNI_IMPLEMENTATION_ \
|
-D_JNI_IMPLEMENTATION_ \
|
||||||
-D_JAVASOFT_WIN32_TYPEDEF_MD_H_ \
|
-D_JAVASOFT_WIN32_TYPEDEF_MD_H_ \
|
||||||
-Ds6_words=_s6_words \
|
-Ds6_words=_s6_words \
|
||||||
@ -235,6 +240,7 @@ ifeq ($(platform),windows)
|
|||||||
else
|
else
|
||||||
openjdk-sources += \
|
openjdk-sources += \
|
||||||
$(openjdk-src)/solaris/native/common/jdk_util_md.c \
|
$(openjdk-src)/solaris/native/common/jdk_util_md.c \
|
||||||
|
$(openjdk-src)/solaris/native/common/jni_util_md.c \
|
||||||
$(openjdk-src)/solaris/native/java/io/canonicalize_md.c \
|
$(openjdk-src)/solaris/native/java/io/canonicalize_md.c \
|
||||||
$(openjdk-src)/solaris/native/java/io/Console_md.c \
|
$(openjdk-src)/solaris/native/java/io/Console_md.c \
|
||||||
$(openjdk-src)/solaris/native/java/io/FileDescriptor_md.c \
|
$(openjdk-src)/solaris/native/java/io/FileDescriptor_md.c \
|
||||||
@ -265,30 +271,26 @@ else
|
|||||||
$(openjdk-src)/solaris/native/sun/nio/ch/DatagramChannelImpl.c \
|
$(openjdk-src)/solaris/native/sun/nio/ch/DatagramChannelImpl.c \
|
||||||
$(openjdk-src)/solaris/native/sun/nio/ch/DatagramDispatcher.c \
|
$(openjdk-src)/solaris/native/sun/nio/ch/DatagramDispatcher.c \
|
||||||
$(openjdk-src)/solaris/native/sun/nio/ch/FileChannelImpl.c \
|
$(openjdk-src)/solaris/native/sun/nio/ch/FileChannelImpl.c \
|
||||||
$(openjdk-src)/solaris/native/sun/nio/ch/FileDispatcher.c \
|
$(openjdk-src)/solaris/native/sun/nio/ch/FileDispatcherImpl.c \
|
||||||
$(openjdk-src)/solaris/native/sun/nio/ch/FileKey.c \
|
$(openjdk-src)/solaris/native/sun/nio/ch/FileKey.c \
|
||||||
$(openjdk-src)/solaris/native/sun/nio/ch/IOUtil.c \
|
$(openjdk-src)/solaris/native/sun/nio/ch/IOUtil.c \
|
||||||
$(openjdk-src)/solaris/native/sun/nio/ch/Net.c \
|
$(openjdk-src)/solaris/native/sun/nio/ch/Net.c \
|
||||||
$(openjdk-src)/solaris/native/sun/nio/ch/ServerSocketChannelImpl.c \
|
$(openjdk-src)/solaris/native/sun/nio/ch/ServerSocketChannelImpl.c \
|
||||||
$(openjdk-src)/solaris/native/sun/nio/ch/SocketChannelImpl.c \
|
$(openjdk-src)/solaris/native/sun/nio/ch/SocketChannelImpl.c \
|
||||||
$(openjdk-src)/solaris/native/sun/nio/ch/SocketDispatcher.c \
|
$(openjdk-src)/solaris/native/sun/nio/ch/SocketDispatcher.c \
|
||||||
$(openjdk-src)/solaris/native/sun/nio/ch/EPollArrayWrapper.c \
|
|
||||||
$(openjdk-src)/solaris/native/sun/nio/ch/PollArrayWrapper.c \
|
$(openjdk-src)/solaris/native/sun/nio/ch/PollArrayWrapper.c \
|
||||||
$(openjdk-src)/solaris/native/sun/nio/ch/InheritedChannel.c \
|
$(openjdk-src)/solaris/native/sun/nio/ch/InheritedChannel.c \
|
||||||
$(openjdk-src)/solaris/native/sun/nio/ch/NativeThread.c \
|
$(openjdk-src)/solaris/native/sun/nio/ch/NativeThread.c \
|
||||||
|
$(openjdk-src)/solaris/native/sun/nio/fs/UnixNativeDispatcher.c \
|
||||||
ifeq ($(platform),linux)
|
|
||||||
openjdk-sources += \
|
|
||||||
$(openjdk-src)/solaris/native/java/net/linux_close.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
openjdk-headers-classes += \
|
openjdk-headers-classes += \
|
||||||
java.net.PlainDatagramSocketImpl \
|
java.net.PlainDatagramSocketImpl \
|
||||||
java.io.UnixFileSystem \
|
java.io.UnixFileSystem \
|
||||||
sun.nio.ch.InheritedChannel \
|
sun.nio.ch.InheritedChannel \
|
||||||
sun.nio.ch.EPollArrayWrapper \
|
sun.nio.fs.UnixNativeDispatcher \
|
||||||
|
|
||||||
openjdk-cflags += "-I$(openjdk-src)/solaris/javavm/export" \
|
openjdk-cflags += \
|
||||||
|
"-I$(openjdk-src)/solaris/javavm/export" \
|
||||||
"-I$(openjdk-src)/solaris/native/common" \
|
"-I$(openjdk-src)/solaris/native/common" \
|
||||||
"-I$(openjdk-src)/solaris/native/java/io" \
|
"-I$(openjdk-src)/solaris/native/java/io" \
|
||||||
"-I$(openjdk-src)/solaris/native/java/lang" \
|
"-I$(openjdk-src)/solaris/native/java/lang" \
|
||||||
@ -297,10 +299,45 @@ else
|
|||||||
"-I$(openjdk-src)/solaris/native/sun/management" \
|
"-I$(openjdk-src)/solaris/native/sun/management" \
|
||||||
"-I$(openjdk-src)/solaris/native/sun/nio/ch" \
|
"-I$(openjdk-src)/solaris/native/sun/nio/ch" \
|
||||||
"-I$(openjdk-src)/solaris/javavm/include" \
|
"-I$(openjdk-src)/solaris/javavm/include" \
|
||||||
"-I$(openjdk-src)/solaris/hpi/include"
|
"-I$(openjdk-src)/solaris/hpi/include" \
|
||||||
|
"-I$(openjdk-src)/solaris/native/common/deps"
|
||||||
|
|
||||||
|
ifeq ($(platform),linux)
|
||||||
|
openjdk-sources += \
|
||||||
|
$(openjdk-src)/solaris/native/java/net/linux_close.c \
|
||||||
|
$(openjdk-src)/solaris/native/common/deps/syscalls_fp.c \
|
||||||
|
$(openjdk-src)/solaris/native/common/deps/gconf2/gconf_fp.c \
|
||||||
|
$(openjdk-src)/solaris/native/common/deps/glib2/gio_fp.c \
|
||||||
|
$(openjdk-src)/solaris/native/sun/nio/ch/EPollArrayWrapper.c
|
||||||
|
|
||||||
|
openjdk-headers-classes += \
|
||||||
|
sun.nio.ch.EPollArrayWrapper
|
||||||
|
|
||||||
|
openjdk-cflags += \
|
||||||
|
"-I$(openjdk-src)/solaris/native/common/deps/glib2" \
|
||||||
|
"-I$(openjdk-src)/solaris/native/common/deps/gconf2" \
|
||||||
|
$(shell pkg-config --cflags glib-2.0) \
|
||||||
|
$(shell pkg-config --cflags gconf-2.0)
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(platform),darwin)
|
||||||
|
openjdk-sources += \
|
||||||
|
$(openjdk-src)/solaris/native/java/net/bsd_close.c
|
||||||
|
|
||||||
|
ifeq ($(ios),true)
|
||||||
|
openjdk-local-sources += \
|
||||||
|
$(src)/openjdk/my_java_props_macosx.c
|
||||||
|
else
|
||||||
|
openjdk-sources += \
|
||||||
|
$(openjdk-src)/solaris/native/java/lang/java_props_macosx.c
|
||||||
|
endif
|
||||||
|
|
||||||
|
openjdk-cflags += \
|
||||||
|
-DMACOSX
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
openjdk-local-sources = \
|
openjdk-local-sources += \
|
||||||
$(src)/openjdk/my_net_util.c \
|
$(src)/openjdk/my_net_util.c \
|
||||||
$(src)/openjdk/my_management.c
|
$(src)/openjdk/my_management.c
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
-keep class java.lang.System {
|
-keep class java.lang.System {
|
||||||
private static void initializeSystemClass();
|
private static void initializeSystemClass();
|
||||||
|
public static void setProperties(java.util.Properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
-keep class java.lang.ClassLoader {
|
-keep class java.lang.ClassLoader {
|
||||||
@ -33,6 +34,11 @@
|
|||||||
|
|
||||||
-keep class java.util.Properties {
|
-keep class java.util.Properties {
|
||||||
public java.lang.Object setProperty(java.lang.String, java.lang.String);
|
public java.lang.Object setProperty(java.lang.String, java.lang.String);
|
||||||
|
public java.lang.String getProperty(java.lang.String);
|
||||||
|
}
|
||||||
|
|
||||||
|
-keep class java.util.Hashtable {
|
||||||
|
public java.lang.Object remove(java.lang.Object);
|
||||||
}
|
}
|
||||||
|
|
||||||
-keep class avian.OpenJDK {
|
-keep class avian.OpenJDK {
|
||||||
|
130
readme.txt
130
readme.txt
@ -54,7 +54,7 @@ Avian can currently target the following platforms:
|
|||||||
Linux (i386, x86_64, ARM, and 32-bit PowerPC)
|
Linux (i386, x86_64, ARM, and 32-bit PowerPC)
|
||||||
Windows (i386 and x86_64)
|
Windows (i386 and x86_64)
|
||||||
Mac OS X (i386, x86_64 and 32-bit PowerPC)
|
Mac OS X (i386, x86_64 and 32-bit PowerPC)
|
||||||
|
Apple iOS (i386 and ARM)
|
||||||
|
|
||||||
Building
|
Building
|
||||||
--------
|
--------
|
||||||
@ -78,6 +78,7 @@ certain flags described below, all of which are optional.
|
|||||||
arch={i386,x86_64,powerpc,arm} \
|
arch={i386,x86_64,powerpc,arm} \
|
||||||
process={compile,interpret} \
|
process={compile,interpret} \
|
||||||
mode={debug,debug-fast,fast,small} \
|
mode={debug,debug-fast,fast,small} \
|
||||||
|
ios={true,false} \
|
||||||
bootimage={true,false} \
|
bootimage={true,false} \
|
||||||
heapdump={true,false} \
|
heapdump={true,false} \
|
||||||
tails={true,false} \
|
tails={true,false} \
|
||||||
@ -93,13 +94,20 @@ certain flags described below, all of which are optional.
|
|||||||
default: output of $(uname -m), normalized in some cases
|
default: output of $(uname -m), normalized in some cases
|
||||||
(e.g. i686 -> i386)
|
(e.g. i686 -> i386)
|
||||||
|
|
||||||
|
* process - choice between pure interpreter or JIT compiler
|
||||||
|
default: compile
|
||||||
|
|
||||||
* mode - which set of compilation flags to use to determine
|
* mode - which set of compilation flags to use to determine
|
||||||
optimization level, debug symbols, and whether to enable
|
optimization level, debug symbols, and whether to enable
|
||||||
assertions
|
assertions
|
||||||
default: fast
|
default: fast
|
||||||
|
|
||||||
* process - choice between pure interpreter or JIT compiler
|
* ios - if true, cross-compile for iOS on OS X. Note that
|
||||||
default: compile
|
non-jailbroken iOS devices do not allow JIT compilation, so only
|
||||||
|
process=interpret or bootimage=true builds will run on such
|
||||||
|
devices. See git://oss.readytalk.com/hello-ios.git for an example
|
||||||
|
of an Xcode project for iOS which uses Avian.
|
||||||
|
default: false
|
||||||
|
|
||||||
* bootimage - if true, create a boot image containing the pre-parsed
|
* bootimage - if true, create a boot image containing the pre-parsed
|
||||||
class library and ahead-of-time compiled methods. This option is
|
class library and ahead-of-time compiled methods. This option is
|
||||||
@ -220,11 +228,11 @@ features beyond that subset, you may want to tell Avian to use
|
|||||||
OpenJDK's class library instead. To do so, specify the directory
|
OpenJDK's class library instead. To do so, specify the directory
|
||||||
where OpenJDK is installed, e.g.:
|
where OpenJDK is installed, e.g.:
|
||||||
|
|
||||||
$ make openjdk=/usr/lib/jvm/java-6-openjdk
|
$ make openjdk=/usr/lib/jvm/java-7-openjdk
|
||||||
|
|
||||||
This will build Avian as a conventional JVM (e.g. libjvm.so) which
|
This will build Avian as a conventional JVM (e.g. libjvm.so) which
|
||||||
loads its boot class library and native libraries (e.g. libjava.so)
|
loads its boot class library and native libraries (e.g. libjava.so)
|
||||||
from /usr/lib/jvm/java-6-openjdk/jre at runtime. To run an
|
from /usr/lib/jvm/java-7-openjdk/jre at runtime. To run an
|
||||||
application in this configuration, you'll need to make sure the VM is
|
application in this configuration, you'll need to make sure the VM is
|
||||||
in your library search path. For example:
|
in your library search path. For example:
|
||||||
|
|
||||||
@ -235,8 +243,8 @@ in your library search path. For example:
|
|||||||
Alternatively, you can enable a stand-alone build using OpenJDK by
|
Alternatively, you can enable a stand-alone build using OpenJDK by
|
||||||
specifying the location of the OpenJDK source code, e.g.:
|
specifying the location of the OpenJDK source code, e.g.:
|
||||||
|
|
||||||
$ make openjdk=$(pwd)/../jdk6/build/linux-amd64/j2sdk-image \
|
$ make openjdk=$(pwd)/../jdk7/build/linux-amd64/j2sdk-image \
|
||||||
openjdk-src=$(pwd)/../jdk6/jdk/src
|
openjdk-src=$(pwd)/../jdk7/jdk/src
|
||||||
|
|
||||||
You must ensure that the path specified for openjdk-src does not have
|
You must ensure that the path specified for openjdk-src does not have
|
||||||
any spaces in it; make gets confused when dependency paths include
|
any spaces in it; make gets confused when dependency paths include
|
||||||
@ -260,7 +268,9 @@ an LZMA-enabled version:
|
|||||||
|
|
||||||
You can reduce the size futher for embedded builds by using ProGuard
|
You can reduce the size futher for embedded builds by using ProGuard
|
||||||
and the supplied openjdk.pro configuration file (see "Embedding with
|
and the supplied openjdk.pro configuration file (see "Embedding with
|
||||||
ProGuard and a Boot Image" below). Also see app.mk in
|
ProGuard and a Boot Image" below). Note that you'll still need to use
|
||||||
|
vm.pro in that case -- openjdk.pro just adds additional constraints
|
||||||
|
specific to the OpenJDK port. Also see app.mk in
|
||||||
git://oss.readytalk.com/avian-swt-examples.git for an example of using
|
git://oss.readytalk.com/avian-swt-examples.git for an example of using
|
||||||
Avian, OpenJDK, ProGuard, and UPX in concert.
|
Avian, OpenJDK, ProGuard, and UPX in concert.
|
||||||
|
|
||||||
@ -269,49 +279,42 @@ it on various OSes:
|
|||||||
|
|
||||||
Debian-based Linux:
|
Debian-based Linux:
|
||||||
# conventional build:
|
# conventional build:
|
||||||
apt-get install openjdk-6-jdk
|
apt-get install openjdk-7-jdk
|
||||||
make openjdk=/usr/lib/jvm/java-6-openjdk test
|
make openjdk=/usr/lib/jvm/java-7-openjdk test
|
||||||
|
|
||||||
# stand-alone build:
|
# stand-alone build:
|
||||||
apt-get install openjdk-6-jdk
|
apt-get install openjdk-7-jdk
|
||||||
apt-get source openjdk-6-jdk
|
apt-get source openjdk-7-jdk
|
||||||
apt-get build-dep openjdk-6-jdk
|
apt-get build-dep openjdk-7-jdk
|
||||||
(cd openjdk-6-6b18-1.8.3 && ./debian/rules patch)
|
(cd openjdk-7-7~b147-2.0 && dpkg-buildpackage)
|
||||||
make openjdk=/usr/lib/jvm/java-6-openjdk \
|
make openjdk=/usr/lib/jvm/java-7-openjdk \
|
||||||
openjdk-src=$(pwd)/openjdk-6-6b18-1.8.3/build/openjdk/jdk/src \
|
openjdk-src=$(pwd)/openjdk-7-7~b147-2.0/build/openjdk/jdk/src \
|
||||||
test
|
test
|
||||||
|
|
||||||
Mac OS X:
|
Mac OS X:
|
||||||
# Prerequisite: install MacPorts (http://www.macports.org/)
|
# Prerequisite: build OpenJDK 7 according to
|
||||||
sudo port selfupdate
|
# https://wikis.oracle.com/display/OpenJDK/Mac+OS+X+Port
|
||||||
|
|
||||||
# conventional build:
|
# conventional build:
|
||||||
sudo port install openjdk6
|
make openjdk=$(pwd)/../jdk7u-dev/build/macosx-amd64/j2sdk-image test
|
||||||
make openjdk=/opt/local/share/java/openjdk6 test
|
|
||||||
|
|
||||||
# stand-alone build:
|
# stand-alone build:
|
||||||
sudo port fetch openjdk6
|
make openjdk=$(pwd)/../jdk7u-dev/build/macosx-amd64/j2sdk-image \
|
||||||
sudo port patch openjdk6
|
openjdk-src=$(pwd)/../p/jdk7u-dev/jdk/src test
|
||||||
make openjdk=/opt/local/share/java/openjdk6 \
|
|
||||||
openjdk-src=/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_ports_java_openjdk6/work/jdk/src \
|
|
||||||
test
|
|
||||||
|
|
||||||
Windows (Cygwin):
|
Windows (Cygwin):
|
||||||
|
# Prerequisite: build OpenJDK 7 according to
|
||||||
|
# http://weblogs.java.net/blog/simonis/archive/2011/10/28/yaojowbi-yet-another-openjdk-windows-build-instruction
|
||||||
|
|
||||||
# conventional build:
|
# conventional build:
|
||||||
# Prerequisite: download and install the latest Windows OpenJDK
|
make openjdk=$(pwd)/../jdk7u-dev/build/windows-i586/j2sdk-image test
|
||||||
# build from http://www.openscg.com/se/openjdk/
|
|
||||||
make openjdk=/cygdrive/c/OpenSCG/openjdk-6.21 test
|
|
||||||
|
|
||||||
# stand-alone build:
|
# stand-alone build:
|
||||||
# Prerequisite: install OpenSCG build as above, plus the
|
make openjdk=$(pwd)/../jdk7u-dev/build/windows-i586/j2sdk-image \
|
||||||
# corresponding source bundle from
|
openjdk-src=$(pwd)/../p/jdk7u-dev/jdk/src test
|
||||||
# http://download.java.net/openjdk/jdk6/promoted/, e.g.:
|
|
||||||
wget http://download.java.net/openjdk/jdk6/promoted/b21/openjdk-6-src-b21-20_jan_2011.tar.gz
|
Currently, only OpenJDK 7 is supported. Later versions might work,
|
||||||
mkdir openjdk
|
but have not yet been tested.
|
||||||
(cd openjdk && tar xzf ../openjdk-6-src-b21-20_jan_2011.tar.gz)
|
|
||||||
make openjdk=/cygdrive/c/OpenSCG/openjdk-6.21 \
|
|
||||||
openjdk-src=$(pwd)/openjdk/jdk/src \
|
|
||||||
test
|
|
||||||
|
|
||||||
|
|
||||||
Installing
|
Installing
|
||||||
@ -356,7 +359,7 @@ EOF
|
|||||||
|
|
||||||
Step 3: Make an object file out of the jar.
|
Step 3: Make an object file out of the jar.
|
||||||
|
|
||||||
$ ../build/${platform}-${arch}/binaryToObject boot.jar boot-jar.o \
|
$ ../build/${platform}-${arch}/binaryToObject/binaryToObject boot.jar boot-jar.o \
|
||||||
_binary_boot_jar_start _binary_boot_jar_end ${platform} ${arch}
|
_binary_boot_jar_start _binary_boot_jar_end ${platform} ${arch}
|
||||||
|
|
||||||
Step 4: Write a driver which starts the VM and runs the desired main
|
Step 4: Write a driver which starts the VM and runs the desired main
|
||||||
@ -364,7 +367,7 @@ method. Note the bootJar function, which will be called by the VM to
|
|||||||
get a handle to the embedded jar. We tell the VM about this jar by
|
get a handle to the embedded jar. We tell the VM about this jar by
|
||||||
setting the boot classpath to "[bootJar]".
|
setting the boot classpath to "[bootJar]".
|
||||||
|
|
||||||
$ cat >main.cpp <<EOF
|
$ cat >embedded-jar-main.cpp <<EOF
|
||||||
#include "stdint.h"
|
#include "stdint.h"
|
||||||
#include "jni.h"
|
#include "jni.h"
|
||||||
|
|
||||||
@ -445,14 +448,15 @@ EOF
|
|||||||
|
|
||||||
on Linux:
|
on Linux:
|
||||||
$ g++ -I$JAVA_HOME/include -I$JAVA_HOME/include/linux \
|
$ g++ -I$JAVA_HOME/include -I$JAVA_HOME/include/linux \
|
||||||
-D_JNI_IMPLEMENTATION_ -c main.cpp -o main.o
|
-D_JNI_IMPLEMENTATION_ -c embedded-jar-main.cpp -o main.o
|
||||||
|
|
||||||
on Mac OS X:
|
on Mac OS X:
|
||||||
$ g++ -I$JAVA_HOME/include -D_JNI_IMPLEMENTATION_ -c main.cpp -o main.o
|
$ g++ -I$JAVA_HOME/include -D_JNI_IMPLEMENTATION_ -c embedded-jar-main.cpp \
|
||||||
|
-o main.o
|
||||||
|
|
||||||
on Windows:
|
on Windows:
|
||||||
$ g++ -I$JAVA_HOME/include -I$JAVA_HOME/include/win32 \
|
$ g++ -I$JAVA_HOME/include -I$JAVA_HOME/include/win32 \
|
||||||
-D_JNI_IMPLEMENTATION_ -c main.cpp -o main.o
|
-D_JNI_IMPLEMENTATION_ -c embedded-jar-main.cpp -o main.o
|
||||||
|
|
||||||
Step 5: Link the objects produced above to produce the final
|
Step 5: Link the objects produced above to produce the final
|
||||||
executable, and optionally strip its symbols.
|
executable, and optionally strip its symbols.
|
||||||
@ -547,29 +551,33 @@ EOF
|
|||||||
Step 5: Run ProGuard with stage1 as input and stage2 as output.
|
Step 5: Run ProGuard with stage1 as input and stage2 as output.
|
||||||
|
|
||||||
$ java -jar ../../proguard4.6/lib/proguard.jar \
|
$ java -jar ../../proguard4.6/lib/proguard.jar \
|
||||||
-injars stage1 -outjars stage2 @../vm.pro @hello.pro
|
-dontusemixedcaseclassnames -injars stage1 -outjars stage2 \
|
||||||
|
@../vm.pro @hello.pro
|
||||||
|
|
||||||
(note: pass -dontusemixedcaseclassnames to ProGuard when building on
|
(note: The -dontusemixedcaseclassnames option is only needed when
|
||||||
systems with case-insensitive filesystems such as Windows and OS X)
|
building on systems with case-insensitive filesystems such as Windows
|
||||||
|
and OS X. Also, you'll need to add -ignorewarnings if you use the
|
||||||
|
OpenJDK class library since the openjdk-src build does not include all
|
||||||
|
the JARs from OpenJDK, and thus ProGuard will not be able to resolve
|
||||||
|
all referenced classes. If you actually plan to use such classes at
|
||||||
|
runtime, you'll need to add them to stage1 before running ProGuard.
|
||||||
|
Finally, you'll need to add @../openjdk.pro to the above command when
|
||||||
|
using the OpenJDK library.)
|
||||||
|
|
||||||
Step 6: Build the boot and code images.
|
Step 6: Build the boot and code images.
|
||||||
|
|
||||||
$ ../build/linux-i386-bootimage/bootimage-generator stage2 \
|
$ ../build/linux-i386-bootimage/bootimage-generator
|
||||||
bootimage.bin codeimage.bin
|
-cp stage2 \
|
||||||
|
-bootimage bootimage-bin.o \
|
||||||
|
-codeimage codeimage-bin.o
|
||||||
|
|
||||||
Step 7: Make an object file out of the boot and code images.
|
Note that you can override the default names for the start and end
|
||||||
|
symbols in the boot/code image by also passing:
|
||||||
|
|
||||||
$ ../build/linux-i386-bootimage/binaryToObject \
|
-bootimage-symbols my_bootimage_start:my_bootimage_end \
|
||||||
bootimage.bin bootimage-bin.o \
|
-codeimage-symbols my_codeimage_start:my_codeimage_end
|
||||||
_binary_bootimage_bin_start _binary_bootimage_bin_end \
|
|
||||||
linux i386 8 writable
|
|
||||||
|
|
||||||
$ ../build/linux-i386-bootimage/binaryToObject \
|
Step 7: Write a driver which starts the VM and runs the desired main
|
||||||
codeimage.bin codeimage-bin.o \
|
|
||||||
_binary_codeimage_bin_start _binary_codeimage_bin_end \
|
|
||||||
linux i386 8 executable
|
|
||||||
|
|
||||||
Step 8: Write a driver which starts the VM and runs the desired main
|
|
||||||
method. Note the bootimageBin function, which will be called by the
|
method. Note the bootimageBin function, which will be called by the
|
||||||
VM to get a handle to the embedded boot image. We tell the VM about
|
VM to get a handle to the embedded boot image. We tell the VM about
|
||||||
this function via the "avian.bootimage" property.
|
this function via the "avian.bootimage" property.
|
||||||
@ -579,7 +587,7 @@ If our application loaded resources such as images and properties
|
|||||||
files via the classloader, we would also need to embed the jar file
|
files via the classloader, we would also need to embed the jar file
|
||||||
containing them. See the previous example for instructions.
|
containing them. See the previous example for instructions.
|
||||||
|
|
||||||
$ cat >main.cpp <<EOF
|
$ cat >bootimage-main.cpp <<EOF
|
||||||
#include "stdint.h"
|
#include "stdint.h"
|
||||||
#include "jni.h"
|
#include "jni.h"
|
||||||
|
|
||||||
@ -674,9 +682,9 @@ main(int ac, const char** av)
|
|||||||
EOF
|
EOF
|
||||||
|
|
||||||
$ g++ -I$JAVA_HOME/include -I$JAVA_HOME/include/linux \
|
$ g++ -I$JAVA_HOME/include -I$JAVA_HOME/include/linux \
|
||||||
-D_JNI_IMPLEMENTATION_ -c main.cpp -o main.o
|
-D_JNI_IMPLEMENTATION_ -c bootimage-main.cpp -o main.o
|
||||||
|
|
||||||
Step 9: Link the objects produced above to produce the final
|
Step 8: Link the objects produced above to produce the final
|
||||||
executable, and optionally strip its symbols.
|
executable, and optionally strip its symbols.
|
||||||
|
|
||||||
$ g++ -rdynamic *.o -ldl -lpthread -lz -o hello
|
$ g++ -rdynamic *.o -ldl -lpthread -lz -o hello
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2011, Avian Contributors
|
/* Copyright (c) 2008-2012, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
@ -57,4 +57,8 @@ copy(Allocator* allocator, const char* a)
|
|||||||
|
|
||||||
} // namespace vm
|
} // namespace vm
|
||||||
|
|
||||||
|
inline void* operator new (size_t size, vm::Allocator* allocator) {
|
||||||
|
return allocator->allocate(size);
|
||||||
|
}
|
||||||
|
|
||||||
#endif//ALLOCATOR_H
|
#endif//ALLOCATOR_H
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
.globl GLOBAL(vmNativeCall)
|
.globl GLOBAL(vmNativeCall)
|
||||||
|
.align 2
|
||||||
GLOBAL(vmNativeCall):
|
GLOBAL(vmNativeCall):
|
||||||
/*
|
/*
|
||||||
arguments:
|
arguments:
|
||||||
@ -57,6 +58,7 @@ LOCAL(loop):
|
|||||||
ldmfd sp!, {r4-r6, pc} // restore non-volatile regs and return
|
ldmfd sp!, {r4-r6, pc} // restore non-volatile regs and return
|
||||||
|
|
||||||
.globl GLOBAL(vmJump)
|
.globl GLOBAL(vmJump)
|
||||||
|
.align 2
|
||||||
GLOBAL(vmJump):
|
GLOBAL(vmJump):
|
||||||
mov lr, r0
|
mov lr, r0
|
||||||
ldr r0, [sp]
|
ldr r0, [sp]
|
||||||
@ -69,6 +71,7 @@ GLOBAL(vmJump):
|
|||||||
#define CHECKPOINT_STACK 24
|
#define CHECKPOINT_STACK 24
|
||||||
|
|
||||||
.globl GLOBAL(vmRun)
|
.globl GLOBAL(vmRun)
|
||||||
|
.align 2
|
||||||
GLOBAL(vmRun):
|
GLOBAL(vmRun):
|
||||||
// r0: function
|
// r0: function
|
||||||
// r1: arguments
|
// r1: arguments
|
||||||
@ -85,6 +88,7 @@ GLOBAL(vmRun):
|
|||||||
blx r12
|
blx r12
|
||||||
|
|
||||||
.globl GLOBAL(vmRun_returnAddress)
|
.globl GLOBAL(vmRun_returnAddress)
|
||||||
|
.align 2
|
||||||
GLOBAL(vmRun_returnAddress):
|
GLOBAL(vmRun_returnAddress):
|
||||||
add sp, sp, #12
|
add sp, sp, #12
|
||||||
ldmfd sp!, {r4-r11, lr}
|
ldmfd sp!, {r4-r11, lr}
|
||||||
|
49
src/arm.cpp
49
src/arm.cpp
@ -127,6 +127,8 @@ inline int ldmfd(int Rn, int rlist) { return BLOCKXFER(AL, 0, 1, 0, 1, 1, Rn, rl
|
|||||||
inline int stmfd(int Rn, int rlist) { return BLOCKXFER(AL, 1, 0, 0, 1, 0, Rn, rlist); }
|
inline int stmfd(int Rn, int rlist) { return BLOCKXFER(AL, 1, 0, 0, 1, 0, Rn, rlist); }
|
||||||
inline int swp(int Rd, int Rm, int Rn) { return SWAP(AL, 0, Rn, Rd, Rm); }
|
inline int swp(int Rd, int Rm, int Rn) { return SWAP(AL, 0, Rn, Rd, Rm); }
|
||||||
inline int swpb(int Rd, int Rm, int Rn) { return SWAP(AL, 1, Rn, Rd, Rm); }
|
inline int swpb(int Rd, int Rm, int Rn) { return SWAP(AL, 1, Rn, Rd, Rm); }
|
||||||
|
// breakpoint instruction, this really has its own instruction format
|
||||||
|
inline int bkpt(int16_t immed) { return 0xe1200070 | (((unsigned)immed & 0xffff) >> 4 << 8) | (immed & 0xf); }
|
||||||
// COPROCESSOR INSTRUCTIONS
|
// COPROCESSOR INSTRUCTIONS
|
||||||
inline int cdp(int coproc, int opcode_1, int CRd, int CRn, int CRm, int opcode_2) { return COOP(AL, opcode_1, CRn, CRd, coproc, opcode_2, CRm); }
|
inline int cdp(int coproc, int opcode_1, int CRd, int CRn, int CRm, int opcode_2) { return COOP(AL, opcode_1, CRn, CRd, coproc, opcode_2, CRm); }
|
||||||
inline int mcr(int coproc, int opcode_1, int Rd, int CRn, int CRm, int opcode_2=0) { return COREG(AL, opcode_1, 0, CRn, Rd, coproc, opcode_2, CRm); }
|
inline int mcr(int coproc, int opcode_1, int Rd, int CRn, int CRm, int opcode_2=0) { return COREG(AL, opcode_1, 0, CRn, Rd, coproc, opcode_2, CRm); }
|
||||||
@ -236,7 +238,6 @@ inline int fmstat() { return fmrx(15, FPSCR); }
|
|||||||
bool vfpSupported() {
|
bool vfpSupported() {
|
||||||
return true; // TODO
|
return true; // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint64_t MASK_LO32 = 0xffffffff;
|
const uint64_t MASK_LO32 = 0xffffffff;
|
||||||
@ -341,7 +342,7 @@ class Context {
|
|||||||
public:
|
public:
|
||||||
Context(System* s, Allocator* a, Zone* zone):
|
Context(System* s, Allocator* a, Zone* zone):
|
||||||
s(s), zone(zone), client(0), code(s, a, 1024), tasks(0), result(0),
|
s(s), zone(zone), client(0), code(s, a, 1024), tasks(0), result(0),
|
||||||
firstBlock(new (zone->allocate(sizeof(MyBlock))) MyBlock(this, 0)),
|
firstBlock(new(zone) MyBlock(this, 0)),
|
||||||
lastBlock(firstBlock), poolOffsetHead(0), poolOffsetTail(0),
|
lastBlock(firstBlock), poolOffsetHead(0), poolOffsetTail(0),
|
||||||
constantPool(0), constantPoolCount(0)
|
constantPool(0), constantPoolCount(0)
|
||||||
{ }
|
{ }
|
||||||
@ -459,8 +460,7 @@ class Offset: public Promise {
|
|||||||
Promise*
|
Promise*
|
||||||
offset(Context* c, bool forTrace = false)
|
offset(Context* c, bool forTrace = false)
|
||||||
{
|
{
|
||||||
return new (c->zone->allocate(sizeof(Offset)))
|
return new(c->zone) Offset(c, c->lastBlock, c->code.length(), forTrace);
|
||||||
Offset(c, c->lastBlock, c->code.length(), forTrace);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -527,8 +527,7 @@ class OffsetTask: public Task {
|
|||||||
void
|
void
|
||||||
appendOffsetTask(Context* c, Promise* promise, Promise* instructionOffset)
|
appendOffsetTask(Context* c, Promise* promise, Promise* instructionOffset)
|
||||||
{
|
{
|
||||||
c->tasks = new (c->zone->allocate(sizeof(OffsetTask))) OffsetTask
|
c->tasks = new(c->zone) OffsetTask(c->tasks, promise, instructionOffset);
|
||||||
(c->tasks, promise, instructionOffset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline unsigned
|
inline unsigned
|
||||||
@ -769,17 +768,14 @@ appendConstantPoolEntry(Context* c, Promise* constant, Promise* callOffset)
|
|||||||
if (constant->resolved()) {
|
if (constant->resolved()) {
|
||||||
// make a copy, since the original might be allocated on the
|
// make a copy, since the original might be allocated on the
|
||||||
// stack, and we need our copy to live until assembly is complete
|
// stack, and we need our copy to live until assembly is complete
|
||||||
constant = new (c->zone->allocate(sizeof(ResolvedPromise)))
|
constant = new(c->zone) ResolvedPromise(constant->value());
|
||||||
ResolvedPromise(constant->value());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
c->constantPool = new (c->zone->allocate(sizeof(ConstantPoolEntry)))
|
c->constantPool = new(c->zone) ConstantPoolEntry(c, constant, c->constantPool, callOffset);
|
||||||
ConstantPoolEntry(c, constant, c->constantPool, callOffset);
|
|
||||||
|
|
||||||
++ c->constantPoolCount;
|
++ c->constantPoolCount;
|
||||||
|
|
||||||
PoolOffset* o = new (c->zone->allocate(sizeof(PoolOffset))) PoolOffset
|
PoolOffset* o = new(c->zone) PoolOffset(c->lastBlock, c->constantPool, c->code.length() - c->lastBlock->offset);
|
||||||
(c->lastBlock, c->constantPool, c->code.length() - c->lastBlock->offset);
|
|
||||||
|
|
||||||
if (DebugPool) {
|
if (DebugPool) {
|
||||||
fprintf(stderr, "add pool offset %p %d to block %p\n",
|
fprintf(stderr, "add pool offset %p %d to block %p\n",
|
||||||
@ -798,8 +794,7 @@ void
|
|||||||
appendPoolEvent(Context* c, MyBlock* b, unsigned offset, PoolOffset* head,
|
appendPoolEvent(Context* c, MyBlock* b, unsigned offset, PoolOffset* head,
|
||||||
PoolOffset* tail)
|
PoolOffset* tail)
|
||||||
{
|
{
|
||||||
PoolEvent* e = new (c->zone->allocate(sizeof(PoolEvent))) PoolEvent
|
PoolEvent* e = new(c->zone) PoolEvent(head, tail, offset);
|
||||||
(head, tail, offset);
|
|
||||||
|
|
||||||
if (b->poolEventTail) {
|
if (b->poolEventTail) {
|
||||||
b->poolEventTail->next = e;
|
b->poolEventTail->next = e;
|
||||||
@ -1839,8 +1834,7 @@ branchCM(Context* con, TernaryOperation op, unsigned size,
|
|||||||
ShiftMaskPromise*
|
ShiftMaskPromise*
|
||||||
shiftMaskPromise(Context* c, Promise* base, unsigned shift, int64_t mask)
|
shiftMaskPromise(Context* c, Promise* base, unsigned shift, int64_t mask)
|
||||||
{
|
{
|
||||||
return new (c->zone->allocate(sizeof(ShiftMaskPromise)))
|
return new(c->zone) ShiftMaskPromise(base, shift, mask);
|
||||||
ShiftMaskPromise(base, shift, mask);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1934,6 +1928,12 @@ return_(Context* c)
|
|||||||
emit(c, bx(LinkRegister));
|
emit(c, bx(LinkRegister));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
trap(Context* c)
|
||||||
|
{
|
||||||
|
emit(c, bkpt());
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
memoryBarrier(Context*) {}
|
memoryBarrier(Context*) {}
|
||||||
|
|
||||||
@ -1947,7 +1947,7 @@ argumentFootprint(unsigned footprint)
|
|||||||
|
|
||||||
void
|
void
|
||||||
nextFrame(ArchitectureContext* c, uint32_t* start, unsigned size UNUSED,
|
nextFrame(ArchitectureContext* c, uint32_t* start, unsigned size UNUSED,
|
||||||
unsigned footprint, void* link, void*,
|
unsigned footprint, void* link, bool,
|
||||||
unsigned targetParameterFootprint UNUSED, void** ip, void** stack)
|
unsigned targetParameterFootprint UNUSED, void** ip, void** stack)
|
||||||
{
|
{
|
||||||
assert(c, *ip >= start);
|
assert(c, *ip >= start);
|
||||||
@ -2021,6 +2021,7 @@ populateTables(ArchitectureContext* c)
|
|||||||
zo[LoadBarrier] = memoryBarrier;
|
zo[LoadBarrier] = memoryBarrier;
|
||||||
zo[StoreStoreBarrier] = memoryBarrier;
|
zo[StoreStoreBarrier] = memoryBarrier;
|
||||||
zo[StoreLoadBarrier] = memoryBarrier;
|
zo[StoreLoadBarrier] = memoryBarrier;
|
||||||
|
zo[Trap] = trap;
|
||||||
|
|
||||||
uo[index(c, LongCall, C)] = CAST1(longCallC);
|
uo[index(c, LongCall, C)] = CAST1(longCallC);
|
||||||
|
|
||||||
@ -2252,12 +2253,12 @@ class MyArchitecture: public Assembler::Architecture {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void nextFrame(void* start, unsigned size, unsigned footprint,
|
virtual void nextFrame(void* start, unsigned size, unsigned footprint,
|
||||||
void* link, void* stackLimit,
|
void* link, bool mostRecent,
|
||||||
unsigned targetParameterFootprint, void** ip,
|
unsigned targetParameterFootprint, void** ip,
|
||||||
void** stack)
|
void** stack)
|
||||||
{
|
{
|
||||||
::nextFrame(&c, static_cast<uint32_t*>(start), size, footprint, link,
|
::nextFrame(&c, static_cast<uint32_t*>(start), size, footprint, link,
|
||||||
stackLimit, targetParameterFootprint, ip, stack);
|
mostRecent, targetParameterFootprint, ip, stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void* frameIp(void* stack) {
|
virtual void* frameIp(void* stack) {
|
||||||
@ -2508,9 +2509,7 @@ class MyAssembler: public Assembler {
|
|||||||
{
|
{
|
||||||
Register stack(StackRegister);
|
Register stack(StackRegister);
|
||||||
Memory stackLimit(ThreadRegister, stackLimitOffsetFromThread);
|
Memory stackLimit(ThreadRegister, stackLimitOffsetFromThread);
|
||||||
Constant handlerConstant
|
Constant handlerConstant(new(c.zone) ResolvedPromise(handler));
|
||||||
(new (c.zone->allocate(sizeof(ResolvedPromise)))
|
|
||||||
ResolvedPromise(handler));
|
|
||||||
branchRM(&c, JumpIfGreaterOrEqual, TargetBytesPerWord, &stack, &stackLimit,
|
branchRM(&c, JumpIfGreaterOrEqual, TargetBytesPerWord, &stack, &stackLimit,
|
||||||
&handlerConstant);
|
&handlerConstant);
|
||||||
}
|
}
|
||||||
@ -2815,8 +2814,7 @@ class MyAssembler: public Assembler {
|
|||||||
MyBlock* b = c.lastBlock;
|
MyBlock* b = c.lastBlock;
|
||||||
b->size = c.code.length() - b->offset;
|
b->size = c.code.length() - b->offset;
|
||||||
if (startNew) {
|
if (startNew) {
|
||||||
c.lastBlock = new (c.zone->allocate(sizeof(MyBlock)))
|
c.lastBlock = new (c.zone) MyBlock(&c, c.code.length());
|
||||||
MyBlock(&c, c.code.length());
|
|
||||||
} else {
|
} else {
|
||||||
c.lastBlock = 0;
|
c.lastBlock = 0;
|
||||||
}
|
}
|
||||||
@ -2887,8 +2885,7 @@ Assembler*
|
|||||||
makeAssembler(System* system, Allocator* allocator, Zone* zone,
|
makeAssembler(System* system, Allocator* allocator, Zone* zone,
|
||||||
Assembler::Architecture* architecture)
|
Assembler::Architecture* architecture)
|
||||||
{
|
{
|
||||||
return new (zone->allocate(sizeof(MyAssembler)))
|
return new(zone) MyAssembler(system, allocator, zone,
|
||||||
MyAssembler(system, allocator, zone,
|
|
||||||
static_cast<MyArchitecture*>(architecture));
|
static_cast<MyArchitecture*>(architecture));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2011, Avian Contributors
|
/* Copyright (c) 2008-2012, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
@ -32,10 +32,11 @@ enum Operation {
|
|||||||
Return,
|
Return,
|
||||||
LoadBarrier,
|
LoadBarrier,
|
||||||
StoreStoreBarrier,
|
StoreStoreBarrier,
|
||||||
StoreLoadBarrier
|
StoreLoadBarrier,
|
||||||
|
Trap
|
||||||
};
|
};
|
||||||
|
|
||||||
const unsigned OperationCount = StoreLoadBarrier + 1;
|
const unsigned OperationCount = Trap + 1;
|
||||||
|
|
||||||
enum UnaryOperation {
|
enum UnaryOperation {
|
||||||
Call,
|
Call,
|
||||||
@ -367,7 +368,7 @@ class Assembler {
|
|||||||
virtual unsigned alignFrameSize(unsigned sizeInWords) = 0;
|
virtual unsigned alignFrameSize(unsigned sizeInWords) = 0;
|
||||||
|
|
||||||
virtual void nextFrame(void* start, unsigned size, unsigned footprint,
|
virtual void nextFrame(void* start, unsigned size, unsigned footprint,
|
||||||
void* link, void* stackLimit,
|
void* link, bool mostRecent,
|
||||||
unsigned targetParameterFootprint, void** ip,
|
unsigned targetParameterFootprint, void** ip,
|
||||||
void** stack) = 0;
|
void** stack) = 0;
|
||||||
virtual void* frameIp(void* stack) = 0;
|
virtual void* frameIp(void* stack) = 0;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2009-2011, Avian Contributors
|
/* Copyright (c) 2009-2012, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
@ -8,12 +8,15 @@
|
|||||||
There is NO WARRANTY for this software. See license.txt for
|
There is NO WARRANTY for this software. See license.txt for
|
||||||
details. */
|
details. */
|
||||||
|
|
||||||
#include "stdint.h"
|
#include <stdint.h>
|
||||||
#include "stdio.h"
|
#include <stdio.h>
|
||||||
#include "string.h"
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "endianness.h"
|
#include "endianness.h"
|
||||||
|
|
||||||
|
#include "tools.h"
|
||||||
|
|
||||||
#define EI_NIDENT 16
|
#define EI_NIDENT 16
|
||||||
|
|
||||||
#define EI_MAG0 0
|
#define EI_MAG0 0
|
||||||
@ -62,344 +65,316 @@
|
|||||||
|
|
||||||
#define STV_DEFAULT 0
|
#define STV_DEFAULT 0
|
||||||
|
|
||||||
#define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
|
#define SYMBOL_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
|
||||||
#define ELF32_ST_INFO(bind, type) ELF64_ST_INFO((bind), (type))
|
|
||||||
|
|
||||||
#if (BITS_PER_WORD == 64)
|
|
||||||
# define FileHeader Elf64_Ehdr
|
|
||||||
# define SectionHeader Elf64_Shdr
|
|
||||||
# define Symbol Elf64_Sym
|
|
||||||
# define Class ELFCLASS64
|
|
||||||
# define SYMBOL_INFO ELF64_ST_INFO
|
|
||||||
#elif (BITS_PER_WORD == 32)
|
|
||||||
# define FileHeader Elf32_Ehdr
|
|
||||||
# define SectionHeader Elf32_Shdr
|
|
||||||
# define Symbol Elf32_Sym
|
|
||||||
# define Class ELFCLASS32
|
|
||||||
# define SYMBOL_INFO ELF32_ST_INFO
|
|
||||||
#else
|
|
||||||
# error
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define OSABI ELFOSABI_SYSV
|
#define OSABI ELFOSABI_SYSV
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
typedef uint16_t Elf64_Half;
|
using namespace avian::tools;
|
||||||
typedef uint32_t Elf64_Word;
|
|
||||||
typedef uint64_t Elf64_Addr;
|
|
||||||
typedef uint64_t Elf64_Xword;
|
|
||||||
typedef uint16_t Elf64_Section;
|
|
||||||
typedef uint64_t Elf64_Off;
|
|
||||||
|
|
||||||
struct Elf64_Ehdr {
|
template<class AddrTy>
|
||||||
unsigned char e_ident[EI_NIDENT];
|
struct ElfTypes {
|
||||||
Elf64_Half e_type;
|
typedef uint16_t Half;
|
||||||
Elf64_Half e_machine;
|
typedef uint32_t Word;
|
||||||
Elf64_Word e_version;
|
typedef AddrTy Addr;
|
||||||
Elf64_Addr e_entry;
|
typedef uint64_t Xword;
|
||||||
Elf64_Off e_phoff;
|
typedef uint16_t Section;
|
||||||
Elf64_Off e_shoff;
|
typedef AddrTy Off;
|
||||||
Elf64_Word e_flags;
|
typedef AddrTy XFlags;
|
||||||
Elf64_Half e_ehsize;
|
static const unsigned BytesPerWord = sizeof(AddrTy);
|
||||||
Elf64_Half e_phentsize;
|
|
||||||
Elf64_Half e_phnum;
|
|
||||||
Elf64_Half e_shentsize;
|
|
||||||
Elf64_Half e_shnum;
|
|
||||||
Elf64_Half e_shstrndx;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Elf64_Shdr {
|
template<class AddrTy>
|
||||||
Elf64_Word sh_name;
|
struct Symbol_Ty;
|
||||||
Elf64_Word sh_type;
|
|
||||||
Elf64_Xword sh_flags;
|
|
||||||
Elf64_Addr sh_addr;
|
|
||||||
Elf64_Off sh_offset;
|
|
||||||
Elf64_Xword sh_size;
|
|
||||||
Elf64_Word sh_link;
|
|
||||||
Elf64_Word sh_info;
|
|
||||||
Elf64_Xword sh_addralign;
|
|
||||||
Elf64_Xword sh_entsize;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Elf64_Sym {
|
template<>
|
||||||
Elf64_Word st_name;
|
struct Symbol_Ty<uint64_t> {
|
||||||
|
typedef ElfTypes<uint64_t> Elf;
|
||||||
|
|
||||||
|
Elf::Word st_name;
|
||||||
unsigned char st_info;
|
unsigned char st_info;
|
||||||
unsigned char st_other;
|
unsigned char st_other;
|
||||||
Elf64_Section st_shndx;
|
Elf::Section st_shndx;
|
||||||
Elf64_Addr st_value;
|
Elf::Addr st_value;
|
||||||
Elf64_Xword st_size;
|
Elf::Xword st_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef uint16_t Elf32_Half;
|
template<>
|
||||||
typedef uint32_t Elf32_Word;
|
struct Symbol_Ty<uint32_t> {
|
||||||
typedef uint32_t Elf32_Addr;
|
typedef ElfTypes<uint32_t> Elf;
|
||||||
typedef uint64_t Elf32_Xword;
|
|
||||||
typedef uint16_t Elf32_Section;
|
|
||||||
typedef uint32_t Elf32_Off;
|
|
||||||
|
|
||||||
struct Elf32_Ehdr {
|
Elf::Word st_name;
|
||||||
unsigned char e_ident[EI_NIDENT];
|
Elf::Addr st_value;
|
||||||
Elf32_Half e_type;
|
Elf::Word st_size;
|
||||||
Elf32_Half e_machine;
|
|
||||||
Elf32_Word e_version;
|
|
||||||
Elf32_Addr e_entry;
|
|
||||||
Elf32_Off e_phoff;
|
|
||||||
Elf32_Off e_shoff;
|
|
||||||
Elf32_Word e_flags;
|
|
||||||
Elf32_Half e_ehsize;
|
|
||||||
Elf32_Half e_phentsize;
|
|
||||||
Elf32_Half e_phnum;
|
|
||||||
Elf32_Half e_shentsize;
|
|
||||||
Elf32_Half e_shnum;
|
|
||||||
Elf32_Half e_shstrndx;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Elf32_Shdr {
|
|
||||||
Elf32_Word sh_name;
|
|
||||||
Elf32_Word sh_type;
|
|
||||||
Elf32_Word sh_flags;
|
|
||||||
Elf32_Addr sh_addr;
|
|
||||||
Elf32_Off sh_offset;
|
|
||||||
Elf32_Word sh_size;
|
|
||||||
Elf32_Word sh_link;
|
|
||||||
Elf32_Word sh_info;
|
|
||||||
Elf32_Word sh_addralign;
|
|
||||||
Elf32_Word sh_entsize;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Elf32_Sym {
|
|
||||||
Elf32_Word st_name;
|
|
||||||
Elf32_Addr st_value;
|
|
||||||
Elf32_Word st_size;
|
|
||||||
unsigned char st_info;
|
unsigned char st_info;
|
||||||
unsigned char st_other;
|
unsigned char st_other;
|
||||||
Elf32_Section st_shndx;
|
Elf::Section st_shndx;
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
using avian::endian::Endianness;
|
||||||
writeObject(const uint8_t* data, unsigned size, FILE* out,
|
|
||||||
const char* startName, const char* endName,
|
|
||||||
const char* sectionName, unsigned sectionFlags,
|
|
||||||
unsigned alignment, int machine, int encoding)
|
|
||||||
{
|
|
||||||
const unsigned sectionCount = 5;
|
|
||||||
const unsigned symbolCount = 2;
|
|
||||||
|
|
||||||
const unsigned sectionNameLength = strlen(sectionName) + 1;
|
#define V1 Endianness<TargetLittleEndian>::v1
|
||||||
const unsigned startNameLength = strlen(startName) + 1;
|
#define V2 Endianness<TargetLittleEndian>::v2
|
||||||
const unsigned endNameLength = strlen(endName) + 1;
|
#define V3 Endianness<TargetLittleEndian>::v3
|
||||||
|
#define V4 Endianness<TargetLittleEndian>::v4
|
||||||
|
#define VANY Endianness<TargetLittleEndian>::vAny
|
||||||
|
|
||||||
const char* const sectionStringTableName = ".shstrtab";
|
|
||||||
const char* const stringTableName = ".strtab";
|
|
||||||
const char* const symbolTableName = ".symtab";
|
|
||||||
|
|
||||||
const unsigned sectionStringTableNameLength
|
unsigned getElfPlatform(PlatformInfo::Architecture arch) {
|
||||||
= strlen(sectionStringTableName) + 1;
|
switch(arch) {
|
||||||
const unsigned stringTableNameLength = strlen(stringTableName) + 1;
|
case PlatformInfo::x86_64:
|
||||||
const unsigned symbolTableNameLength = strlen(symbolTableName) + 1;
|
return EM_X86_64;
|
||||||
|
case PlatformInfo::x86:
|
||||||
const unsigned nullStringOffset = 0;
|
return EM_386;
|
||||||
|
case PlatformInfo::Arm:
|
||||||
const unsigned sectionStringTableNameOffset = nullStringOffset + 1;
|
return EM_ARM;
|
||||||
const unsigned stringTableNameOffset
|
case PlatformInfo::PowerPC:
|
||||||
= sectionStringTableNameOffset + sectionStringTableNameLength;
|
return EM_PPC;
|
||||||
const unsigned symbolTableNameOffset
|
}
|
||||||
= stringTableNameOffset + stringTableNameLength;
|
return ~0;
|
||||||
const unsigned sectionNameOffset
|
|
||||||
= symbolTableNameOffset + symbolTableNameLength;
|
|
||||||
const unsigned sectionStringTableLength
|
|
||||||
= sectionNameOffset + sectionNameLength;
|
|
||||||
|
|
||||||
const unsigned startNameOffset = nullStringOffset + 1;
|
|
||||||
const unsigned endNameOffset = startNameOffset + startNameLength;
|
|
||||||
const unsigned stringTableLength = endNameOffset + endNameLength;
|
|
||||||
|
|
||||||
const unsigned bodySectionNumber = 1;
|
|
||||||
const unsigned sectionStringTableSectionNumber = 2;
|
|
||||||
const unsigned stringTableSectionNumber = 3;
|
|
||||||
|
|
||||||
FileHeader fileHeader;
|
|
||||||
memset(&fileHeader, 0, sizeof(FileHeader));
|
|
||||||
fileHeader.e_ident[EI_MAG0] = V1(ELFMAG0);
|
|
||||||
fileHeader.e_ident[EI_MAG1] = V1(ELFMAG1);
|
|
||||||
fileHeader.e_ident[EI_MAG2] = V1(ELFMAG2);
|
|
||||||
fileHeader.e_ident[EI_MAG3] = V1(ELFMAG3);
|
|
||||||
fileHeader.e_ident[EI_CLASS] = V1(Class);
|
|
||||||
fileHeader.e_ident[EI_DATA] = V1(encoding);
|
|
||||||
fileHeader.e_ident[EI_VERSION] = V1(EV_CURRENT);
|
|
||||||
fileHeader.e_ident[EI_OSABI] = V1(OSABI);
|
|
||||||
fileHeader.e_ident[EI_ABIVERSION] = V1(0);
|
|
||||||
fileHeader.e_type = V2(ET_REL);
|
|
||||||
fileHeader.e_machine = V2(machine);
|
|
||||||
fileHeader.e_version = V4(EV_CURRENT);
|
|
||||||
fileHeader.e_entry = VW(0);
|
|
||||||
fileHeader.e_phoff = VW(0);
|
|
||||||
fileHeader.e_shoff = VW(sizeof(FileHeader));
|
|
||||||
fileHeader.e_flags = V4(machine == EM_ARM ? 0x04000000 : 0);
|
|
||||||
fileHeader.e_ehsize = V2(sizeof(FileHeader));
|
|
||||||
fileHeader.e_phentsize = V2(0);
|
|
||||||
fileHeader.e_phnum = V2(0);
|
|
||||||
fileHeader.e_shentsize = V2(sizeof(SectionHeader));
|
|
||||||
fileHeader.e_shnum = V2(sectionCount);
|
|
||||||
fileHeader.e_shstrndx = V2(sectionStringTableSectionNumber);
|
|
||||||
|
|
||||||
SectionHeader nullSection;
|
|
||||||
memset(&nullSection, 0, sizeof(SectionHeader));
|
|
||||||
|
|
||||||
SectionHeader bodySection;
|
|
||||||
bodySection.sh_name = V4(sectionNameOffset);
|
|
||||||
bodySection.sh_type = V4(SHT_PROGBITS);
|
|
||||||
bodySection.sh_flags = VW(sectionFlags);
|
|
||||||
bodySection.sh_addr = VW(0);
|
|
||||||
unsigned bodySectionOffset
|
|
||||||
= sizeof(FileHeader) + (sizeof(SectionHeader) * sectionCount);
|
|
||||||
bodySection.sh_offset = VW(bodySectionOffset);
|
|
||||||
unsigned bodySectionSize = size;
|
|
||||||
bodySection.sh_size = VW(bodySectionSize);
|
|
||||||
bodySection.sh_link = V4(0);
|
|
||||||
bodySection.sh_info = V4(0);
|
|
||||||
bodySection.sh_addralign = VW(alignment);
|
|
||||||
bodySection.sh_entsize = VW(0);
|
|
||||||
|
|
||||||
SectionHeader sectionStringTableSection;
|
|
||||||
sectionStringTableSection.sh_name = V4(sectionStringTableNameOffset);
|
|
||||||
sectionStringTableSection.sh_type = V4(SHT_STRTAB);
|
|
||||||
sectionStringTableSection.sh_flags = VW(0);
|
|
||||||
sectionStringTableSection.sh_addr = VW(0);
|
|
||||||
unsigned sectionStringTableSectionOffset
|
|
||||||
= bodySectionOffset + bodySectionSize;
|
|
||||||
sectionStringTableSection.sh_offset = VW(sectionStringTableSectionOffset);
|
|
||||||
unsigned sectionStringTableSectionSize = sectionStringTableLength;
|
|
||||||
sectionStringTableSection.sh_size = VW(sectionStringTableSectionSize);
|
|
||||||
sectionStringTableSection.sh_link = V4(0);
|
|
||||||
sectionStringTableSection.sh_info = V4(0);
|
|
||||||
sectionStringTableSection.sh_addralign = VW(1);
|
|
||||||
sectionStringTableSection.sh_entsize = VW(0);
|
|
||||||
|
|
||||||
SectionHeader stringTableSection;
|
|
||||||
stringTableSection.sh_name = V4(stringTableNameOffset);
|
|
||||||
stringTableSection.sh_type = V4(SHT_STRTAB);
|
|
||||||
stringTableSection.sh_flags = VW(0);
|
|
||||||
stringTableSection.sh_addr = VW(0);
|
|
||||||
unsigned stringTableSectionOffset
|
|
||||||
= sectionStringTableSectionOffset + sectionStringTableSectionSize;
|
|
||||||
stringTableSection.sh_offset = VW(stringTableSectionOffset);
|
|
||||||
unsigned stringTableSectionSize = stringTableLength;
|
|
||||||
stringTableSection.sh_size = VW(stringTableSectionSize);
|
|
||||||
stringTableSection.sh_link = V4(0);
|
|
||||||
stringTableSection.sh_info = V4(0);
|
|
||||||
stringTableSection.sh_addralign = VW(1);
|
|
||||||
stringTableSection.sh_entsize = VW(0);
|
|
||||||
|
|
||||||
SectionHeader symbolTableSection;
|
|
||||||
symbolTableSection.sh_name = V4(symbolTableNameOffset);
|
|
||||||
symbolTableSection.sh_type = V4(SHT_SYMTAB);
|
|
||||||
symbolTableSection.sh_flags = VW(0);
|
|
||||||
symbolTableSection.sh_addr = VW(0);
|
|
||||||
unsigned symbolTableSectionOffset
|
|
||||||
= stringTableSectionOffset + stringTableSectionSize;
|
|
||||||
symbolTableSection.sh_offset = VW(symbolTableSectionOffset);
|
|
||||||
unsigned symbolTableSectionSize = sizeof(Symbol) * symbolCount;
|
|
||||||
symbolTableSection.sh_size = VW(symbolTableSectionSize);
|
|
||||||
symbolTableSection.sh_link = V4(stringTableSectionNumber);
|
|
||||||
symbolTableSection.sh_info = V4(0);
|
|
||||||
symbolTableSection.sh_addralign = VW(BITS_PER_WORD / 8);
|
|
||||||
symbolTableSection.sh_entsize = VW(sizeof(Symbol));
|
|
||||||
|
|
||||||
Symbol startSymbol;
|
|
||||||
startSymbol.st_name = V4(startNameOffset);
|
|
||||||
startSymbol.st_value = VW(0);
|
|
||||||
startSymbol.st_size = VW(0);
|
|
||||||
startSymbol.st_info = V1(SYMBOL_INFO(STB_GLOBAL, STT_NOTYPE));
|
|
||||||
startSymbol.st_other = V1(STV_DEFAULT);
|
|
||||||
startSymbol.st_shndx = V2(bodySectionNumber);
|
|
||||||
|
|
||||||
Symbol endSymbol;
|
|
||||||
endSymbol.st_name = V4(endNameOffset);
|
|
||||||
endSymbol.st_value = VW(size);
|
|
||||||
endSymbol.st_size = VW(0);
|
|
||||||
endSymbol.st_info = V1(SYMBOL_INFO(STB_GLOBAL, STT_NOTYPE));
|
|
||||||
endSymbol.st_other = V1(STV_DEFAULT);
|
|
||||||
endSymbol.st_shndx = V2(bodySectionNumber);
|
|
||||||
|
|
||||||
fwrite(&fileHeader, 1, sizeof(fileHeader), out);
|
|
||||||
fwrite(&nullSection, 1, sizeof(nullSection), out);
|
|
||||||
fwrite(&bodySection, 1, sizeof(bodySection), out);
|
|
||||||
fwrite(§ionStringTableSection, 1, sizeof(sectionStringTableSection),
|
|
||||||
out);
|
|
||||||
fwrite(&stringTableSection, 1, sizeof(stringTableSection), out);
|
|
||||||
fwrite(&symbolTableSection, 1, sizeof(symbolTableSection), out);
|
|
||||||
|
|
||||||
fwrite(data, 1, size, out);
|
|
||||||
|
|
||||||
fputc(0, out);
|
|
||||||
fwrite(sectionStringTableName, 1, sectionStringTableNameLength, out);
|
|
||||||
fwrite(stringTableName, 1, stringTableNameLength, out);
|
|
||||||
fwrite(symbolTableName, 1, symbolTableNameLength, out);
|
|
||||||
fwrite(sectionName, 1, sectionNameLength, out);
|
|
||||||
|
|
||||||
fputc(0, out);
|
|
||||||
fwrite(startName, 1, startNameLength, out);
|
|
||||||
fwrite(endName, 1, endNameLength, out);
|
|
||||||
|
|
||||||
fwrite(&startSymbol, 1, sizeof(startSymbol), out);
|
|
||||||
fwrite(&endSymbol, 1, sizeof(endSymbol), out);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* getSectionName(unsigned accessFlags, unsigned& sectionFlags) {
|
||||||
|
sectionFlags = SHF_ALLOC;
|
||||||
|
if (accessFlags & Platform::Writable) {
|
||||||
|
if (accessFlags & Platform::Executable) {
|
||||||
|
sectionFlags |= SHF_WRITE | SHF_EXECINSTR;
|
||||||
|
return ".rwx";
|
||||||
|
} else {
|
||||||
|
sectionFlags |= SHF_WRITE;
|
||||||
|
return ".data";
|
||||||
|
}
|
||||||
|
} else if (accessFlags & Platform::Executable) {
|
||||||
|
sectionFlags |= SHF_EXECINSTR;
|
||||||
|
return ".text";
|
||||||
|
} else {
|
||||||
|
return ".rodata";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class AddrTy, bool TargetLittleEndian = true>
|
||||||
|
class ElfPlatform : public Platform {
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef ElfTypes<AddrTy> Elf;
|
||||||
|
static const unsigned Class = Elf::BytesPerWord / 4;
|
||||||
|
|
||||||
|
struct FileHeader {
|
||||||
|
unsigned char e_ident[EI_NIDENT];
|
||||||
|
typename Elf::Half e_type;
|
||||||
|
typename Elf::Half e_machine;
|
||||||
|
typename Elf::Word e_version;
|
||||||
|
typename Elf::Addr e_entry;
|
||||||
|
typename Elf::Off e_phoff;
|
||||||
|
typename Elf::Off e_shoff;
|
||||||
|
typename Elf::Word e_flags;
|
||||||
|
typename Elf::Half e_ehsize;
|
||||||
|
typename Elf::Half e_phentsize;
|
||||||
|
typename Elf::Half e_phnum;
|
||||||
|
typename Elf::Half e_shentsize;
|
||||||
|
typename Elf::Half e_shnum;
|
||||||
|
typename Elf::Half e_shstrndx;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SectionHeader {
|
||||||
|
typename Elf::Word sh_name;
|
||||||
|
typename Elf::Word sh_type;
|
||||||
|
typename Elf::XFlags sh_flags;
|
||||||
|
typename Elf::Addr sh_addr;
|
||||||
|
typename Elf::Off sh_offset;
|
||||||
|
typename Elf::Off sh_size;
|
||||||
|
typename Elf::Word sh_link;
|
||||||
|
typename Elf::Word sh_info;
|
||||||
|
typename Elf::Addr sh_addralign;
|
||||||
|
typename Elf::Off sh_entsize;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef Symbol_Ty<AddrTy> Symbol;
|
||||||
|
|
||||||
|
static const unsigned Encoding = TargetLittleEndian ? ELFDATA2LSB : ELFDATA2MSB;
|
||||||
|
|
||||||
|
const unsigned machine;
|
||||||
|
|
||||||
|
ElfPlatform(PlatformInfo::Architecture arch):
|
||||||
|
Platform(PlatformInfo(PlatformInfo::Linux, arch)),
|
||||||
|
machine(getElfPlatform(arch)) {}
|
||||||
|
|
||||||
|
class FileWriter {
|
||||||
|
public:
|
||||||
|
unsigned sectionCount;
|
||||||
|
unsigned sectionStringTableSectionNumber;
|
||||||
|
|
||||||
|
AddrTy dataOffset;
|
||||||
|
|
||||||
|
FileHeader header;
|
||||||
|
StringTable strings;
|
||||||
|
|
||||||
|
FileWriter(unsigned machine):
|
||||||
|
sectionCount(0),
|
||||||
|
dataOffset(sizeof(FileHeader))
|
||||||
|
{
|
||||||
|
memset(&header, 0, sizeof(FileHeader));
|
||||||
|
header.e_ident[EI_MAG0] = V1(ELFMAG0);
|
||||||
|
header.e_ident[EI_MAG1] = V1(ELFMAG1);
|
||||||
|
header.e_ident[EI_MAG2] = V1(ELFMAG2);
|
||||||
|
header.e_ident[EI_MAG3] = V1(ELFMAG3);
|
||||||
|
header.e_ident[EI_CLASS] = V1(Class);
|
||||||
|
header.e_ident[EI_DATA] = V1(Encoding);
|
||||||
|
header.e_ident[EI_VERSION] = V1(EV_CURRENT);
|
||||||
|
header.e_ident[EI_OSABI] = V1(OSABI);
|
||||||
|
header.e_ident[EI_ABIVERSION] = V1(0);
|
||||||
|
header.e_type = V2(ET_REL);
|
||||||
|
header.e_machine = V2(machine);
|
||||||
|
header.e_version = V4(EV_CURRENT);
|
||||||
|
header.e_entry = VANY(static_cast<AddrTy>(0));
|
||||||
|
header.e_phoff = VANY(static_cast<AddrTy>(0));
|
||||||
|
header.e_shoff = VANY(static_cast<AddrTy>(sizeof(FileHeader)));
|
||||||
|
header.e_flags = V4(machine == EM_ARM ? 0x04000000 : 0);
|
||||||
|
header.e_ehsize = V2(sizeof(FileHeader));
|
||||||
|
header.e_phentsize = V2(0);
|
||||||
|
header.e_phnum = V2(0);
|
||||||
|
header.e_shentsize = V2(sizeof(SectionHeader));
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeHeader(OutputStream* out) {
|
||||||
|
header.e_shnum = V2(sectionCount);
|
||||||
|
header.e_shstrndx = V2(sectionStringTableSectionNumber);
|
||||||
|
out->writeChunk(&header, sizeof(FileHeader));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SectionWriter {
|
||||||
|
public:
|
||||||
|
FileWriter& file;
|
||||||
|
String name;
|
||||||
|
SectionHeader header;
|
||||||
|
const size_t* dataSize;
|
||||||
|
const uint8_t* const* data;
|
||||||
|
|
||||||
|
SectionWriter(FileWriter& file):
|
||||||
|
file(file),
|
||||||
|
name(""),
|
||||||
|
data(0),
|
||||||
|
dataSize(0)
|
||||||
|
{
|
||||||
|
memset(&header, 0, sizeof(SectionHeader));
|
||||||
|
file.sectionCount++;
|
||||||
|
file.dataOffset += sizeof(SectionHeader);
|
||||||
|
size_t nameOffset = file.strings.add(name);
|
||||||
|
header.sh_name = V4(nameOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
SectionWriter(
|
||||||
|
FileWriter& file,
|
||||||
|
const char* chname,
|
||||||
|
unsigned type,
|
||||||
|
AddrTy flags,
|
||||||
|
unsigned alignment,
|
||||||
|
AddrTy addr,
|
||||||
|
const uint8_t* const* data,
|
||||||
|
size_t* dataSize,
|
||||||
|
size_t entsize = 0,
|
||||||
|
unsigned link = 0):
|
||||||
|
|
||||||
|
file(file),
|
||||||
|
name(chname),
|
||||||
|
data(data),
|
||||||
|
dataSize(dataSize)
|
||||||
|
{
|
||||||
|
if(strcmp(chname, ".shstrtab") == 0) {
|
||||||
|
file.sectionStringTableSectionNumber = file.sectionCount;
|
||||||
|
}
|
||||||
|
file.sectionCount++;
|
||||||
|
file.dataOffset += sizeof(SectionHeader);
|
||||||
|
size_t nameOffset = file.strings.add(name);
|
||||||
|
|
||||||
|
header.sh_name = V4(nameOffset);
|
||||||
|
header.sh_type = V4(type);
|
||||||
|
header.sh_flags = VANY(flags);
|
||||||
|
header.sh_addr = VANY(addr);
|
||||||
|
// header.sh_offset = VANY(static_cast<AddrTy>(bodySectionOffset));
|
||||||
|
// header.sh_size = VANY(static_cast<AddrTy>(*dataSize));
|
||||||
|
header.sh_link = V4(link);
|
||||||
|
header.sh_info = V4(0);
|
||||||
|
header.sh_addralign = VANY(static_cast<AddrTy>(alignment));
|
||||||
|
header.sh_entsize = VANY(static_cast<AddrTy>(entsize));
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeHeader(OutputStream* out) {
|
||||||
|
if(dataSize) {
|
||||||
|
header.sh_offset = VANY(file.dataOffset);
|
||||||
|
header.sh_size = VANY(static_cast<AddrTy>(*dataSize));
|
||||||
|
file.dataOffset += *dataSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
out->writeChunk(&header, sizeof(SectionHeader));
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeData(OutputStream* out) {
|
||||||
|
if(data) {
|
||||||
|
out->writeChunk(*data, *dataSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual bool writeObject(OutputStream* out, Slice<SymbolInfo> symbols, Slice<const uint8_t> data, unsigned accessFlags, unsigned alignment) {
|
||||||
|
|
||||||
|
unsigned sectionFlags;
|
||||||
|
const char* sectionName = getSectionName(accessFlags, sectionFlags);
|
||||||
|
|
||||||
|
StringTable symbolStringTable;
|
||||||
|
Buffer symbolTable;
|
||||||
|
|
||||||
|
FileWriter file(machine);
|
||||||
|
|
||||||
|
const int bodySectionNumber = 1;
|
||||||
|
const int stringTableSectionNumber = 3;
|
||||||
|
|
||||||
|
SectionWriter sections[] = {
|
||||||
|
SectionWriter(file), // null section
|
||||||
|
SectionWriter(file, sectionName, SHT_PROGBITS, sectionFlags, alignment, 0, &data.items, &data.count), // body section
|
||||||
|
SectionWriter(file, ".shstrtab", SHT_STRTAB, 0, 1, 0, &file.strings.data, &file.strings.length),
|
||||||
|
SectionWriter(file, ".strtab", SHT_STRTAB, 0, 1, 0, &symbolStringTable.data, &symbolStringTable.length),
|
||||||
|
SectionWriter(file, ".symtab", SHT_SYMTAB, 0, 8, 0, &symbolTable.data, &symbolTable.length, sizeof(Symbol), stringTableSectionNumber)
|
||||||
|
};
|
||||||
|
|
||||||
|
// for some reason, string tables require a null first element...
|
||||||
|
symbolStringTable.add("");
|
||||||
|
|
||||||
|
for(SymbolInfo* sym = symbols.begin(); sym != symbols.end(); sym++) {
|
||||||
|
size_t nameOffset = symbolStringTable.add(sym->name);
|
||||||
|
|
||||||
|
Symbol symbolStruct;
|
||||||
|
symbolStruct.st_name = V4(nameOffset);
|
||||||
|
symbolStruct.st_value = VANY(static_cast<AddrTy>(sym->addr));
|
||||||
|
symbolStruct.st_size = VANY(static_cast<AddrTy>(0));
|
||||||
|
symbolStruct.st_info = V1(SYMBOL_INFO(STB_GLOBAL, STT_NOTYPE));
|
||||||
|
symbolStruct.st_other = V1(STV_DEFAULT);
|
||||||
|
symbolStruct.st_shndx = V2(bodySectionNumber);
|
||||||
|
symbolTable.write(&symbolStruct, sizeof(Symbol));
|
||||||
|
}
|
||||||
|
|
||||||
|
file.writeHeader(out);
|
||||||
|
|
||||||
|
for(int i = 0; i < file.sectionCount; i++) {
|
||||||
|
sections[i].writeHeader(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < file.sectionCount; i++) {
|
||||||
|
sections[i].writeData(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ElfPlatform<uint32_t> elfx86Platform(PlatformInfo::x86);
|
||||||
|
ElfPlatform<uint32_t> elfArmPlatform(PlatformInfo::Arm);
|
||||||
|
ElfPlatform<uint32_t, false> elfPowerPCPlatform(PlatformInfo::PowerPC);
|
||||||
|
ElfPlatform<uint64_t> elfx86_64Platform(PlatformInfo::x86_64);
|
||||||
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
#define MACRO_MAKE_NAME(a, b, c) a##b##c
|
|
||||||
#define MAKE_NAME(a, b, c) MACRO_MAKE_NAME(a, b, c)
|
|
||||||
|
|
||||||
namespace binaryToObject {
|
|
||||||
|
|
||||||
bool
|
|
||||||
MAKE_NAME(writeElf, BITS_PER_WORD, Object)
|
|
||||||
(uint8_t* data, unsigned size, FILE* out, const char* startName,
|
|
||||||
const char* endName, const char* architecture, unsigned alignment,
|
|
||||||
bool writable, bool executable)
|
|
||||||
{
|
|
||||||
int machine;
|
|
||||||
int encoding;
|
|
||||||
if (strcmp(architecture, "x86_64") == 0) {
|
|
||||||
machine = EM_X86_64;
|
|
||||||
encoding = ELFDATA2LSB;
|
|
||||||
} else if (strcmp(architecture, "i386") == 0) {
|
|
||||||
machine = EM_386;
|
|
||||||
encoding = ELFDATA2LSB;
|
|
||||||
} else if (strcmp(architecture, "arm") == 0) {
|
|
||||||
machine = EM_ARM;
|
|
||||||
encoding = ELFDATA2LSB;
|
|
||||||
} else if (strcmp(architecture, "powerpc") == 0) {
|
|
||||||
machine = EM_PPC;
|
|
||||||
encoding = ELFDATA2MSB;
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "unsupported architecture: %s\n", architecture);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* sectionName;
|
|
||||||
unsigned sectionFlags = SHF_ALLOC;
|
|
||||||
if (writable) {
|
|
||||||
if (executable) {
|
|
||||||
sectionName = ".rwx";
|
|
||||||
sectionFlags |= SHF_WRITE | SHF_EXECINSTR;
|
|
||||||
} else {
|
|
||||||
sectionName = ".data";
|
|
||||||
sectionFlags |= SHF_WRITE;
|
|
||||||
}
|
|
||||||
} else if (executable) {
|
|
||||||
sectionName = ".text";
|
|
||||||
sectionFlags |= SHF_EXECINSTR;
|
|
||||||
} else {
|
|
||||||
sectionName = ".rodata";
|
|
||||||
}
|
|
||||||
|
|
||||||
writeObject(data, size, out, startName, endName, sectionName, sectionFlags,
|
|
||||||
alignment, machine, encoding);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace binaryToObject
|
|
||||||
|
@ -1,38 +1,81 @@
|
|||||||
#ifndef ENDIANNESS_H
|
/* Copyright (c) 2008-2012, Avian Contributors
|
||||||
#define ENDIANNESS_H
|
|
||||||
|
|
||||||
#define V1(v) (v)
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
that the above copyright notice and this permission notice appear
|
||||||
|
in all copies.
|
||||||
|
|
||||||
#ifdef OPPOSITE_ENDIAN
|
There is NO WARRANTY for this software. See license.txt for
|
||||||
# define V2(v) \
|
details. */
|
||||||
((((v) >> 8) & 0xFF) | \
|
|
||||||
(((v) << 8)))
|
|
||||||
# define V4(v) \
|
|
||||||
((((v) >> 24) & 0x000000FF) | \
|
|
||||||
(((v) >> 8) & 0x0000FF00) | \
|
|
||||||
(((v) << 8) & 0x00FF0000) | \
|
|
||||||
(((v) << 24)))
|
|
||||||
# define V8(v) \
|
|
||||||
(((static_cast<uint64_t>(v) >> 56) & UINT64_C(0x00000000000000FF)) | \
|
|
||||||
((static_cast<uint64_t>(v) >> 40) & UINT64_C(0x000000000000FF00)) | \
|
|
||||||
((static_cast<uint64_t>(v) >> 24) & UINT64_C(0x0000000000FF0000)) | \
|
|
||||||
((static_cast<uint64_t>(v) >> 8) & UINT64_C(0x00000000FF000000)) | \
|
|
||||||
((static_cast<uint64_t>(v) << 8) & UINT64_C(0x000000FF00000000)) | \
|
|
||||||
((static_cast<uint64_t>(v) << 24) & UINT64_C(0x0000FF0000000000)) | \
|
|
||||||
((static_cast<uint64_t>(v) << 40) & UINT64_C(0x00FF000000000000)) | \
|
|
||||||
((static_cast<uint64_t>(v) << 56)))
|
|
||||||
#else
|
|
||||||
# define V2(v) (v)
|
|
||||||
# define V4(v) (v)
|
|
||||||
# define V8(v) (v)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (BITS_PER_WORD == 64)
|
#ifndef AVIAN_ENDIANNESS_H
|
||||||
# define VW(v) V8(v)
|
#define AVIAN_ENDIANNESS_H
|
||||||
#elif (BITS_PER_WORD == 32)
|
|
||||||
# define VW(v) V4(v)
|
|
||||||
#else
|
|
||||||
# error
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif//ENDIANNESS_H
|
namespace avian {
|
||||||
|
|
||||||
|
namespace endian {
|
||||||
|
|
||||||
|
static union {
|
||||||
|
uint32_t i;
|
||||||
|
char c[4];
|
||||||
|
} _DetectEndianness = {1};
|
||||||
|
|
||||||
|
const bool LittleEndian = _DetectEndianness.c[0] == 1;
|
||||||
|
|
||||||
|
template<bool TargetLittleEndian>
|
||||||
|
class Endianness {
|
||||||
|
public:
|
||||||
|
static inline uint8_t v1(uint8_t v) {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint16_t v2(uint16_t v) {
|
||||||
|
if(LittleEndian == TargetLittleEndian) {
|
||||||
|
return v;
|
||||||
|
} else {
|
||||||
|
return ((v >> 8) & 0xFF) | (v << 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t v4(uint32_t v) {
|
||||||
|
if(LittleEndian == TargetLittleEndian) {
|
||||||
|
return v;
|
||||||
|
} else {
|
||||||
|
return
|
||||||
|
((v >> 24) & 0x000000FF) |
|
||||||
|
((v >> 8) & 0x0000FF00) |
|
||||||
|
((v << 8) & 0x00FF0000) |
|
||||||
|
((v << 24));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t vAny(uint32_t v) {
|
||||||
|
return v4(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint64_t v8(uint64_t v) {
|
||||||
|
if(LittleEndian == TargetLittleEndian) {
|
||||||
|
return v;
|
||||||
|
} else {
|
||||||
|
return
|
||||||
|
((static_cast<uint64_t>(v) >> 56) & (static_cast<uint64_t>(0xff) << 0)) |
|
||||||
|
((static_cast<uint64_t>(v) >> 40) & (static_cast<uint64_t>(0xff) << 8)) |
|
||||||
|
((static_cast<uint64_t>(v) >> 24) & (static_cast<uint64_t>(0xff) << 16)) |
|
||||||
|
((static_cast<uint64_t>(v) >> 8) & (static_cast<uint64_t>(0xff) << 24)) |
|
||||||
|
((static_cast<uint64_t>(v) << 8) & (static_cast<uint64_t>(0xff) << 32)) |
|
||||||
|
((static_cast<uint64_t>(v) << 24) & (static_cast<uint64_t>(0xff) << 40)) |
|
||||||
|
((static_cast<uint64_t>(v) << 40) & (static_cast<uint64_t>(0xff) << 48)) |
|
||||||
|
((static_cast<uint64_t>(v) << 56));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint64_t vAny(uint64_t v) {
|
||||||
|
return v8(v);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace endian
|
||||||
|
|
||||||
|
} // namespace avian
|
||||||
|
|
||||||
|
#endif // AVIAN_ENDIANNESS_H
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2011, Avian Contributors
|
/* Copyright (c) 2008-2012, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
@ -8,19 +8,19 @@
|
|||||||
There is NO WARRANTY for this software. See license.txt for
|
There is NO WARRANTY for this software. See license.txt for
|
||||||
details. */
|
details. */
|
||||||
|
|
||||||
#include "stdint.h"
|
#include <stdint.h>
|
||||||
#include "stdio.h"
|
#include <stdio.h>
|
||||||
#include "string.h"
|
#include <string.h>
|
||||||
|
|
||||||
#include "endianness.h"
|
#include "endianness.h"
|
||||||
|
|
||||||
|
#include "tools.h"
|
||||||
|
|
||||||
#define MH_MAGIC_64 0xfeedfacf
|
#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_SYMTAB 2
|
#define LC_SYMTAB 2
|
||||||
|
|
||||||
#define S_REGULAR 0
|
#define S_REGULAR 0
|
||||||
@ -38,144 +38,23 @@
|
|||||||
#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
|
#define CPU_SUBTYPE_ARM_V7 9
|
||||||
|
|
||||||
#if (BITS_PER_WORD == 64)
|
|
||||||
# define Magic MH_MAGIC_64
|
|
||||||
# define Segment LC_SEGMENT_64
|
|
||||||
# define FileHeader mach_header_64
|
|
||||||
# define SegmentCommand segment_command_64
|
|
||||||
# define Section section_64
|
|
||||||
# define NList struct nlist_64
|
|
||||||
#elif (BITS_PER_WORD == 32)
|
|
||||||
# define Magic MH_MAGIC
|
|
||||||
# define Segment LC_SEGMENT
|
|
||||||
# define FileHeader mach_header
|
|
||||||
# define SegmentCommand segment_command
|
|
||||||
# define Section section
|
|
||||||
# define NList struct nlist
|
|
||||||
#else
|
|
||||||
# error
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
using namespace avian::tools;
|
||||||
|
|
||||||
typedef int cpu_type_t;
|
typedef int cpu_type_t;
|
||||||
typedef int cpu_subtype_t;
|
typedef int cpu_subtype_t;
|
||||||
typedef int vm_prot_t;
|
typedef int vm_prot_t;
|
||||||
|
|
||||||
struct mach_header_64 {
|
using avian::endian::Endianness;
|
||||||
uint32_t magic;
|
|
||||||
cpu_type_t cputype;
|
|
||||||
cpu_subtype_t cpusubtype;
|
|
||||||
uint32_t filetype;
|
|
||||||
uint32_t ncmds;
|
|
||||||
uint32_t sizeofcmds;
|
|
||||||
uint32_t flags;
|
|
||||||
uint32_t reserved;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct segment_command_64 {
|
#define V1 Endianness<TargetLittleEndian>::v1
|
||||||
uint32_t cmd;
|
#define V2 Endianness<TargetLittleEndian>::v2
|
||||||
uint32_t cmdsize;
|
#define V3 Endianness<TargetLittleEndian>::v3
|
||||||
char segname[16];
|
#define V4 Endianness<TargetLittleEndian>::v4
|
||||||
uint64_t vmaddr;
|
#define VANY Endianness<TargetLittleEndian>::vAny
|
||||||
uint64_t vmsize;
|
|
||||||
uint64_t fileoff;
|
|
||||||
uint64_t filesize;
|
|
||||||
vm_prot_t maxprot;
|
|
||||||
vm_prot_t initprot;
|
|
||||||
uint32_t nsects;
|
|
||||||
uint32_t flags;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct section_64 {
|
|
||||||
char sectname[16];
|
|
||||||
char segname[16];
|
|
||||||
uint64_t addr;
|
|
||||||
uint64_t size;
|
|
||||||
uint32_t offset;
|
|
||||||
uint32_t align;
|
|
||||||
uint32_t reloff;
|
|
||||||
uint32_t nreloc;
|
|
||||||
uint32_t flags;
|
|
||||||
uint32_t reserved1;
|
|
||||||
uint32_t reserved2;
|
|
||||||
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 {
|
|
||||||
uint32_t magic;
|
|
||||||
cpu_type_t cputype;
|
|
||||||
cpu_subtype_t cpusubtype;
|
|
||||||
uint32_t filetype;
|
|
||||||
uint32_t ncmds;
|
|
||||||
uint32_t sizeofcmds;
|
|
||||||
uint32_t flags;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct segment_command {
|
|
||||||
uint32_t cmd;
|
|
||||||
uint32_t cmdsize;
|
|
||||||
char segname[16];
|
|
||||||
uint32_t vmaddr;
|
|
||||||
uint32_t vmsize;
|
|
||||||
uint32_t fileoff;
|
|
||||||
uint32_t filesize;
|
|
||||||
vm_prot_t maxprot;
|
|
||||||
vm_prot_t initprot;
|
|
||||||
uint32_t nsects;
|
|
||||||
uint32_t flags;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct section {
|
|
||||||
char sectname[16];
|
|
||||||
char segname[16];
|
|
||||||
uint32_t addr;
|
|
||||||
uint32_t size;
|
|
||||||
uint32_t offset;
|
|
||||||
uint32_t align;
|
|
||||||
uint32_t reloff;
|
|
||||||
uint32_t nreloc;
|
|
||||||
uint32_t flags;
|
|
||||||
uint32_t reserved1;
|
|
||||||
uint32_t reserved2;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct symtab_command {
|
|
||||||
uint32_t cmd;
|
|
||||||
uint32_t cmdsize;
|
|
||||||
uint32_t symoff;
|
|
||||||
uint32_t nsyms;
|
|
||||||
uint32_t stroff;
|
|
||||||
uint32_t strsize;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct nlist {
|
|
||||||
union {
|
|
||||||
int32_t n_strx;
|
|
||||||
} n_un;
|
|
||||||
uint8_t n_type;
|
|
||||||
uint8_t n_sect;
|
|
||||||
int16_t n_desc;
|
|
||||||
uint32_t n_value;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline unsigned
|
|
||||||
pad(unsigned n)
|
|
||||||
{
|
|
||||||
return (n + ((BITS_PER_WORD / 8) - 1)) & ~((BITS_PER_WORD / 8) - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline unsigned
|
inline unsigned
|
||||||
log(unsigned n)
|
log(unsigned n)
|
||||||
@ -185,177 +64,233 @@ log(unsigned n)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
template<class AddrTy, bool TargetLittleEndian = true>
|
||||||
writeObject(const uint8_t* data, unsigned size, FILE* out,
|
class MachOPlatform : public Platform {
|
||||||
const char* startName, const char* endName,
|
public:
|
||||||
const char* segmentName, const char* sectionName,
|
|
||||||
unsigned alignment, cpu_type_t cpuType, cpu_subtype_t cpuSubType)
|
|
||||||
{
|
|
||||||
unsigned startNameLength = strlen(startName) + 1;
|
|
||||||
unsigned endNameLength = strlen(endName) + 1;
|
|
||||||
|
|
||||||
FileHeader header = {
|
struct FileHeader {
|
||||||
V4(Magic), // magic
|
uint32_t magic;
|
||||||
V4(cpuType),
|
cpu_type_t cputype;
|
||||||
V4(cpuSubType),
|
cpu_subtype_t cpusubtype;
|
||||||
V4(MH_OBJECT), // filetype,
|
uint32_t filetype;
|
||||||
V4(2), // ncmds
|
uint32_t ncmds;
|
||||||
V4(sizeof(SegmentCommand)
|
uint32_t sizeofcmds;
|
||||||
+ sizeof(Section)
|
|
||||||
+ sizeof(symtab_command)), // sizeofcmds
|
union {
|
||||||
V4(0) // flags
|
uint32_t flags;
|
||||||
|
AddrTy flagsAndMaybeReserved;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
SegmentCommand segment = {
|
|
||||||
V4(Segment), // cmd
|
struct SegmentCommand {
|
||||||
V4(sizeof(SegmentCommand) + sizeof(Section)), // cmdsize
|
uint32_t cmd;
|
||||||
"", // segname
|
uint32_t cmdsize;
|
||||||
VW(0), // vmaddr
|
char segname[16];
|
||||||
VW(pad(size)), // vmsize
|
AddrTy vmaddr;
|
||||||
VW(sizeof(FileHeader)
|
AddrTy vmsize;
|
||||||
+ sizeof(SegmentCommand)
|
AddrTy fileoff;
|
||||||
+ sizeof(Section)
|
AddrTy filesize;
|
||||||
+ sizeof(symtab_command)), // fileoff
|
vm_prot_t maxprot;
|
||||||
VW(pad(size)), // filesize
|
vm_prot_t initprot;
|
||||||
V4(7), // maxprot
|
uint32_t nsects;
|
||||||
V4(7), // initprot
|
uint32_t flags;
|
||||||
V4(1), // nsects
|
|
||||||
V4(0) // flags
|
|
||||||
};
|
};
|
||||||
|
|
||||||
strncpy(segment.segname, segmentName, sizeof(segment.segname));
|
struct Section {
|
||||||
|
char sectname[16];
|
||||||
Section sect = {
|
char segname[16];
|
||||||
"", // sectname
|
AddrTy addr;
|
||||||
"", // segname
|
AddrTy size;
|
||||||
VW(0), // addr
|
uint32_t offset;
|
||||||
VW(pad(size)), // size
|
uint32_t align;
|
||||||
V4(sizeof(FileHeader)
|
uint32_t reloff;
|
||||||
+ sizeof(SegmentCommand)
|
uint32_t nreloc;
|
||||||
+ sizeof(Section)
|
uint32_t flags;
|
||||||
+ sizeof(symtab_command)), // offset
|
uint32_t reserved1;
|
||||||
V4(log(alignment)), // align
|
AddrTy reserved2AndMaybe3;
|
||||||
V4(0), // reloff
|
|
||||||
V4(0), // nreloc
|
|
||||||
V4(S_REGULAR), // flags
|
|
||||||
V4(0), // reserved1
|
|
||||||
V4(0), // reserved2
|
|
||||||
};
|
};
|
||||||
|
|
||||||
strncpy(sect.segname, segmentName, sizeof(sect.segname));
|
struct NList {
|
||||||
strncpy(sect.sectname, sectionName, sizeof(sect.sectname));
|
union {
|
||||||
|
uint32_t n_strx;
|
||||||
symtab_command symbolTable = {
|
} n_un;
|
||||||
V4(LC_SYMTAB), // cmd
|
uint8_t n_type;
|
||||||
V4(sizeof(symtab_command)), // cmdsize
|
uint8_t n_sect;
|
||||||
V4(sizeof(FileHeader)
|
uint16_t n_desc;
|
||||||
+ sizeof(SegmentCommand)
|
AddrTy n_value;
|
||||||
+ sizeof(Section)
|
|
||||||
+ sizeof(symtab_command)
|
|
||||||
+ pad(size)), // symoff
|
|
||||||
V4(2), // nsyms
|
|
||||||
V4(sizeof(FileHeader)
|
|
||||||
+ sizeof(SegmentCommand)
|
|
||||||
+ sizeof(Section)
|
|
||||||
+ sizeof(symtab_command)
|
|
||||||
+ pad(size)
|
|
||||||
+ (sizeof(NList) * 2)), // stroff
|
|
||||||
V4(1 + startNameLength + endNameLength), // strsize
|
|
||||||
};
|
};
|
||||||
|
|
||||||
NList symbolList[] = {
|
struct SymtabCommand {
|
||||||
{
|
uint32_t cmd;
|
||||||
V4(1), // n_un
|
uint32_t cmdsize;
|
||||||
V1(N_SECT | N_EXT), // n_type
|
uint32_t symoff;
|
||||||
V1(1), // n_sect
|
uint32_t nsyms;
|
||||||
V2(0), // n_desc
|
uint32_t stroff;
|
||||||
VW(0) // n_value
|
uint32_t strsize;
|
||||||
},
|
};
|
||||||
{
|
|
||||||
V4(1 + startNameLength), // n_un
|
static const unsigned BytesPerWord = sizeof(AddrTy);
|
||||||
V1(N_SECT | N_EXT), // n_type
|
static const unsigned Segment = BytesPerWord == 8 ? 0x19 : 1;
|
||||||
V1(1), // n_sect
|
static const unsigned Magic = BytesPerWord == 8 ? 0xfeedfacf : 0xfeedface;
|
||||||
V2(0), // n_desc
|
|
||||||
VW(size) // n_value
|
static inline unsigned
|
||||||
|
pad(unsigned n)
|
||||||
|
{
|
||||||
|
return (n + (BytesPerWord - 1)) & ~(BytesPerWord - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool writeObject(OutputStream* out, Slice<SymbolInfo> symbols, Slice<const uint8_t> data, unsigned accessFlags, unsigned alignment) {
|
||||||
|
cpu_type_t cpuType;
|
||||||
|
cpu_subtype_t cpuSubType;
|
||||||
|
switch(info.arch) {
|
||||||
|
case PlatformInfo::x86_64:
|
||||||
|
cpuType = CPU_TYPE_X86_64;
|
||||||
|
cpuSubType = CPU_SUBTYPE_X86_64_ALL;
|
||||||
|
break;
|
||||||
|
case PlatformInfo::x86:
|
||||||
|
cpuType = CPU_TYPE_I386;
|
||||||
|
cpuSubType = CPU_SUBTYPE_I386_ALL;
|
||||||
|
break;
|
||||||
|
case PlatformInfo::PowerPC:
|
||||||
|
cpuType = CPU_TYPE_POWERPC;
|
||||||
|
cpuSubType = CPU_SUBTYPE_POWERPC_ALL;
|
||||||
|
break;
|
||||||
|
case PlatformInfo::Arm:
|
||||||
|
cpuType = CPU_TYPE_ARM;
|
||||||
|
cpuSubType = CPU_SUBTYPE_ARM_V7;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// should never happen (see MachOPlatform declarations at bottom)
|
||||||
|
fprintf(stderr, "unsupported architecture: %d\n", info.arch);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
fwrite(&header, 1, sizeof(header), out);
|
const char* segmentName;
|
||||||
fwrite(&segment, 1, sizeof(segment), out);
|
const char* sectionName;
|
||||||
fwrite(§, 1, sizeof(sect), out);
|
if (accessFlags & Writable) {
|
||||||
fwrite(&symbolTable, 1, sizeof(symbolTable), out);
|
if (accessFlags & Executable) {
|
||||||
|
segmentName = "__RWX";
|
||||||
|
sectionName = "__rwx";
|
||||||
|
} else {
|
||||||
|
segmentName = "__DATA";
|
||||||
|
sectionName = "__data";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
segmentName = "__TEXT";
|
||||||
|
sectionName = "__text";
|
||||||
|
}
|
||||||
|
|
||||||
fwrite(data, 1, size, out);
|
FileHeader header = {
|
||||||
for (unsigned i = 0; i < pad(size) - size; ++i) fputc(0, out);
|
V4(Magic), // magic
|
||||||
|
V4(cpuType),
|
||||||
|
V4(cpuSubType),
|
||||||
|
V4(MH_OBJECT), // filetype,
|
||||||
|
V4(2), // ncmds
|
||||||
|
V4(sizeof(SegmentCommand)
|
||||||
|
+ sizeof(Section)
|
||||||
|
+ sizeof(SymtabCommand)), // sizeofcmds
|
||||||
|
V4(0) // flags
|
||||||
|
};
|
||||||
|
|
||||||
fwrite(&symbolList, 1, sizeof(symbolList), out);
|
AddrTy finalSize = pad(data.count);
|
||||||
|
|
||||||
fputc(0, out);
|
SegmentCommand segment = {
|
||||||
fwrite(startName, 1, startNameLength, out);
|
V4(Segment), // cmd
|
||||||
fwrite(endName, 1, endNameLength, out);
|
V4(sizeof(SegmentCommand) + sizeof(Section)), // cmdsize
|
||||||
}
|
"", // segname
|
||||||
|
VANY(static_cast<AddrTy>(0)), // vmaddr
|
||||||
|
VANY(static_cast<AddrTy>(finalSize)), // vmsize
|
||||||
|
VANY(static_cast<AddrTy>(sizeof(FileHeader)
|
||||||
|
+ sizeof(SegmentCommand)
|
||||||
|
+ sizeof(Section)
|
||||||
|
+ sizeof(SymtabCommand))), // fileoff
|
||||||
|
VANY(static_cast<AddrTy>(finalSize)), // filesize
|
||||||
|
V4(7), // maxprot
|
||||||
|
V4(7), // initprot
|
||||||
|
V4(1), // nsects
|
||||||
|
V4(0) // flags
|
||||||
|
};
|
||||||
|
|
||||||
|
strncpy(segment.segname, segmentName, sizeof(segment.segname));
|
||||||
|
|
||||||
|
Section sect = {
|
||||||
|
"", // sectname
|
||||||
|
"", // segname
|
||||||
|
VANY(static_cast<AddrTy>(0)), // addr
|
||||||
|
VANY(static_cast<AddrTy>(finalSize)), // size
|
||||||
|
V4(sizeof(FileHeader)
|
||||||
|
+ sizeof(SegmentCommand)
|
||||||
|
+ sizeof(Section)
|
||||||
|
+ sizeof(SymtabCommand)), // offset
|
||||||
|
V4(log(alignment)), // align
|
||||||
|
V4(0), // reloff
|
||||||
|
V4(0), // nreloc
|
||||||
|
V4(S_REGULAR), // flags
|
||||||
|
V4(0), // reserved1
|
||||||
|
V4(0), // reserved2
|
||||||
|
};
|
||||||
|
|
||||||
|
strncpy(sect.segname, segmentName, sizeof(sect.segname));
|
||||||
|
strncpy(sect.sectname, sectionName, sizeof(sect.sectname));
|
||||||
|
|
||||||
|
StringTable strings;
|
||||||
|
strings.add("");
|
||||||
|
Buffer symbolList;
|
||||||
|
|
||||||
|
for(SymbolInfo* sym = symbols.begin(); sym != symbols.end(); sym++) {
|
||||||
|
unsigned offset = strings.length;
|
||||||
|
strings.write("_", 1);
|
||||||
|
strings.add(sym->name);
|
||||||
|
NList symbol = {
|
||||||
|
V4(offset), // n_un
|
||||||
|
V1(N_SECT | N_EXT), // n_type
|
||||||
|
V1(1), // n_sect
|
||||||
|
V2(0), // n_desc
|
||||||
|
VANY(static_cast<AddrTy>(sym->addr)) // n_value
|
||||||
|
};
|
||||||
|
symbolList.write(&symbol, sizeof(NList));
|
||||||
|
}
|
||||||
|
|
||||||
|
SymtabCommand symbolTable = {
|
||||||
|
V4(LC_SYMTAB), // cmd
|
||||||
|
V4(sizeof(SymtabCommand)), // cmdsize
|
||||||
|
V4(sizeof(FileHeader)
|
||||||
|
+ sizeof(SegmentCommand)
|
||||||
|
+ sizeof(Section)
|
||||||
|
+ sizeof(SymtabCommand)
|
||||||
|
+ finalSize), // symoff
|
||||||
|
V4(symbols.count), // nsyms
|
||||||
|
V4(sizeof(FileHeader)
|
||||||
|
+ sizeof(SegmentCommand)
|
||||||
|
+ sizeof(Section)
|
||||||
|
+ sizeof(SymtabCommand)
|
||||||
|
+ finalSize
|
||||||
|
+ (sizeof(NList) * symbols.count)), // stroff
|
||||||
|
V4(strings.length), // strsize
|
||||||
|
};
|
||||||
|
|
||||||
|
out->writeChunk(&header, sizeof(header));
|
||||||
|
out->writeChunk(&segment, sizeof(segment));
|
||||||
|
out->writeChunk(§, sizeof(sect));
|
||||||
|
out->writeChunk(&symbolTable, sizeof(symbolTable));
|
||||||
|
|
||||||
|
out->writeChunk(data.items, data.count);
|
||||||
|
out->writeRepeat(0, finalSize - data.count);
|
||||||
|
|
||||||
|
out->writeChunk(symbolList.data, symbolList.length);
|
||||||
|
|
||||||
|
out->writeChunk(strings.data, strings.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
MachOPlatform(PlatformInfo::Architecture arch):
|
||||||
|
Platform(PlatformInfo(PlatformInfo::Darwin, arch)) {}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
MachOPlatform<uint32_t> darwinx86Platform(PlatformInfo::x86);
|
||||||
|
MachOPlatform<uint32_t> darwinArmPlatform(PlatformInfo::Arm);
|
||||||
|
MachOPlatform<uint32_t, false> darwinPowerPCPlatform(PlatformInfo::PowerPC);
|
||||||
|
MachOPlatform<uint64_t> darwinx86_64Platform(PlatformInfo::x86_64);
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
#define MACRO_MAKE_NAME(a, b, c) a##b##c
|
|
||||||
#define MAKE_NAME(a, b, c) MACRO_MAKE_NAME(a, b, c)
|
|
||||||
|
|
||||||
namespace binaryToObject {
|
|
||||||
|
|
||||||
bool
|
|
||||||
MAKE_NAME(writeMachO, BITS_PER_WORD, Object)
|
|
||||||
(uint8_t* data, unsigned size, FILE* out, const char* startName,
|
|
||||||
const char* endName, const char* architecture, unsigned alignment,
|
|
||||||
bool writable, bool executable)
|
|
||||||
{
|
|
||||||
cpu_type_t cpuType;
|
|
||||||
cpu_subtype_t cpuSubType;
|
|
||||||
if (strcmp(architecture, "x86_64") == 0) {
|
|
||||||
cpuType = CPU_TYPE_X86_64;
|
|
||||||
cpuSubType = CPU_SUBTYPE_X86_64_ALL;
|
|
||||||
} else if (strcmp(architecture, "i386") == 0) {
|
|
||||||
cpuType = CPU_TYPE_I386;
|
|
||||||
cpuSubType = CPU_SUBTYPE_I386_ALL;
|
|
||||||
} 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* segmentName;
|
|
||||||
const char* sectionName;
|
|
||||||
if (writable) {
|
|
||||||
if (executable) {
|
|
||||||
segmentName = "__RWX";
|
|
||||||
sectionName = "__rwx";
|
|
||||||
} else {
|
|
||||||
segmentName = "__DATA";
|
|
||||||
sectionName = "__data";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
segmentName = "__TEXT";
|
|
||||||
sectionName = "__text";
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned startNameLength = strlen(startName);
|
|
||||||
char myStartName[startNameLength + 2];
|
|
||||||
myStartName[0] = '_';
|
|
||||||
memcpy(myStartName + 1, startName, startNameLength + 1);
|
|
||||||
|
|
||||||
unsigned endNameLength = strlen(endName);
|
|
||||||
char myEndName[endNameLength + 2];
|
|
||||||
myEndName[0] = '_';
|
|
||||||
memcpy(myEndName + 1, endName, endNameLength + 1);
|
|
||||||
|
|
||||||
writeObject(data, size, out, myStartName, myEndName, segmentName,
|
|
||||||
sectionName, alignment, cpuType, cpuSubType);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace binaryToObject
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2011, Avian Contributors
|
/* Copyright (c) 2008-2012, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
@ -8,111 +8,59 @@
|
|||||||
There is NO WARRANTY for this software. See license.txt for
|
There is NO WARRANTY for this software. See license.txt for
|
||||||
details. */
|
details. */
|
||||||
|
|
||||||
#include "stdint.h"
|
#include <stdint.h>
|
||||||
#include "stdio.h"
|
#include <stdio.h>
|
||||||
#include "stdlib.h"
|
#include <stdlib.h>
|
||||||
#include "string.h"
|
#include <string.h>
|
||||||
|
|
||||||
#include "sys/stat.h"
|
#include <sys/stat.h>
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#else
|
#else
|
||||||
#include "sys/mman.h"
|
#include <sys/mman.h>
|
||||||
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
#include "fcntl.h"
|
#include <fcntl.h>
|
||||||
#include "unistd.h"
|
|
||||||
|
|
||||||
namespace binaryToObject {
|
#include "tools.h"
|
||||||
|
|
||||||
bool
|
extern "C"
|
||||||
writeElf64Object(uint8_t* data, unsigned size, FILE* out,
|
void __cxa_pure_virtual() {
|
||||||
const char* startName, const char* endName,
|
abort();
|
||||||
const char* architecture, unsigned alignment, bool writable,
|
}
|
||||||
bool executable);
|
|
||||||
|
|
||||||
bool
|
void* operator new(size_t size) {
|
||||||
writeElf32Object(uint8_t* data, unsigned size, FILE* out,
|
return malloc(size);
|
||||||
const char* startName, const char* endName,
|
}
|
||||||
const char* architecture, unsigned alignment, bool writable,
|
|
||||||
bool executable);
|
|
||||||
|
|
||||||
bool
|
void operator delete(void* mem) { abort(); }
|
||||||
writeMachO64Object(uint8_t* data, unsigned size, FILE* out,
|
|
||||||
const char* startName, const char* endName,
|
|
||||||
const char* architecture, unsigned alignment, bool writable,
|
|
||||||
bool executable);
|
|
||||||
|
|
||||||
bool
|
|
||||||
writeMachO32Object(uint8_t* data, unsigned size, FILE* out,
|
|
||||||
const char* startName, const char* endName,
|
|
||||||
const char* architecture, unsigned alignment, bool writable,
|
|
||||||
bool executable);
|
|
||||||
|
|
||||||
bool
|
|
||||||
writePEObject(uint8_t* data, unsigned size, FILE* out, const char* startName,
|
|
||||||
const char* endName, const char* architecture,
|
|
||||||
unsigned alignment, bool writable, bool executable);
|
|
||||||
|
|
||||||
} // namespace binaryToObject
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
using namespace avian::tools;
|
||||||
|
|
||||||
bool
|
bool
|
||||||
writeObject(uint8_t* data, unsigned size, FILE* out, const char* startName,
|
writeObject(uint8_t* data, size_t size, OutputStream* out, const char* startName,
|
||||||
const char* endName, const char* platform,
|
const char* endName, const char* os,
|
||||||
const char* architecture, unsigned alignment, bool writable,
|
const char* architecture, unsigned alignment, bool writable,
|
||||||
bool executable)
|
bool executable)
|
||||||
{
|
{
|
||||||
using namespace binaryToObject;
|
Platform* platform = Platform::getPlatform(PlatformInfo(PlatformInfo::osFromString(os), PlatformInfo::archFromString(architecture)));
|
||||||
|
|
||||||
bool found = false;
|
if(!platform) {
|
||||||
bool success = false;
|
fprintf(stderr, "unsupported platform: %s/%s\n", os, architecture);
|
||||||
if (strcmp("linux", platform) == 0) {
|
|
||||||
if (strcmp("x86_64", architecture) == 0) {
|
|
||||||
found = true;
|
|
||||||
success = writeElf64Object
|
|
||||||
(data, size, out, startName, endName, architecture, alignment,
|
|
||||||
writable, executable);
|
|
||||||
} else if (strcmp("i386", architecture) == 0
|
|
||||||
or strcmp("arm", architecture) == 0
|
|
||||||
or strcmp("powerpc", architecture) == 0)
|
|
||||||
{
|
|
||||||
found = true;
|
|
||||||
success = writeElf32Object
|
|
||||||
(data, size, out, startName, endName, architecture, alignment,
|
|
||||||
writable, executable);
|
|
||||||
}
|
|
||||||
} else if (strcmp("darwin", platform) == 0) {
|
|
||||||
if (strcmp("x86_64", architecture) == 0) {
|
|
||||||
found = true;
|
|
||||||
success = writeMachO64Object
|
|
||||||
(data, size, out, startName, endName, architecture, alignment,
|
|
||||||
writable, executable);
|
|
||||||
} else if (strcmp("i386", architecture) == 0
|
|
||||||
or strcmp("powerpc", architecture) == 0
|
|
||||||
or strcmp("arm", architecture) == 0)
|
|
||||||
{
|
|
||||||
found = true;
|
|
||||||
success = writeMachO32Object
|
|
||||||
(data, size, out, startName, endName, architecture, alignment,
|
|
||||||
writable, executable);
|
|
||||||
}
|
|
||||||
} else if (strcmp("windows", platform) == 0
|
|
||||||
and ((strcmp("x86_64", architecture) == 0
|
|
||||||
or strcmp("i386", architecture) == 0)))
|
|
||||||
{
|
|
||||||
found = true;
|
|
||||||
success = writePEObject
|
|
||||||
(data, size, out, startName, endName, architecture, alignment, writable,
|
|
||||||
executable);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (not found) {
|
|
||||||
fprintf(stderr, "unsupported platform: %s/%s\n", platform, architecture);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
SymbolInfo symbols[] = {
|
||||||
|
SymbolInfo(0, startName),
|
||||||
|
SymbolInfo(size, endName)
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned accessFlags = (writable ? Platform::Writable : 0) | (executable ? Platform::Executable : 0);
|
||||||
|
|
||||||
|
return platform->writeObject(out, Slice<SymbolInfo>(symbols, 2), Slice<const uint8_t>(data, size), accessFlags, alignment);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -191,13 +139,11 @@ main(int argc, const char** argv)
|
|||||||
bool success = false;
|
bool success = false;
|
||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
FILE* out = fopen(argv[2], "wb");
|
FileOutputStream out(argv[2]);
|
||||||
if (out) {
|
if (out.isValid()) {
|
||||||
success = writeObject
|
success = writeObject
|
||||||
(data, size, out, argv[3], argv[4], argv[5], argv[6], alignment,
|
(data, size, &out, argv[3], argv[4], argv[5], argv[6], alignment,
|
||||||
writable, executable);
|
writable, executable);
|
||||||
|
|
||||||
fclose(out);
|
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "unable to open %s\n", argv[2]);
|
fprintf(stderr, "unable to open %s\n", argv[2]);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2009, Avian Contributors
|
/* Copyright (c) 2009-2012, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
@ -8,16 +8,21 @@
|
|||||||
There is NO WARRANTY for this software. See license.txt for
|
There is NO WARRANTY for this software. See license.txt for
|
||||||
details. */
|
details. */
|
||||||
|
|
||||||
#include "stdint.h"
|
#include <stdint.h>
|
||||||
#include "stdio.h"
|
#include <stdio.h>
|
||||||
#include "string.h"
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "tools.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
#define IMAGE_SIZEOF_SHORT_NAME 8
|
#define IMAGE_SIZEOF_SHORT_NAME 8
|
||||||
|
|
||||||
#define IMAGE_FILE_RELOCS_STRIPPED 1
|
#define IMAGE_FILE_RELOCS_STRIPPED 1
|
||||||
#define IMAGE_FILE_LINE_NUMS_STRIPPED 4
|
#define IMAGE_FILE_LINE_NUMS_STRIPPED 4
|
||||||
#define IMAGE_FILE_MACHINE_AMD64 0x8664
|
#define IMAGE_FILE_MACHINE_AMD64 0x8664
|
||||||
#define IMAGE_FILE_MACHINE_I386 0x014c
|
#define IMAGE_FILE_MACHINE_I386 0x014c
|
||||||
#define IMAGE_FILE_32BIT_MACHINE 256
|
#define IMAGE_FILE_32BIT_MACHINE 256
|
||||||
|
|
||||||
#define IMAGE_SCN_ALIGN_1BYTES 0x100000
|
#define IMAGE_SCN_ALIGN_1BYTES 0x100000
|
||||||
@ -29,8 +34,6 @@
|
|||||||
#define IMAGE_SCN_MEM_WRITE 0x80000000
|
#define IMAGE_SCN_MEM_WRITE 0x80000000
|
||||||
#define IMAGE_SCN_CNT_CODE 32
|
#define IMAGE_SCN_CNT_CODE 32
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
struct IMAGE_FILE_HEADER {
|
struct IMAGE_FILE_HEADER {
|
||||||
uint16_t Machine;
|
uint16_t Machine;
|
||||||
uint16_t NumberOfSections;
|
uint16_t NumberOfSections;
|
||||||
@ -77,155 +80,199 @@ pad(unsigned n)
|
|||||||
return (n + (4 - 1)) & ~(4 - 1);
|
return (n + (4 - 1)) & ~(4 - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
using namespace avian::tools;
|
||||||
writeObject(const uint8_t* data, unsigned size, FILE* out,
|
|
||||||
const char* startName, const char* endName,
|
|
||||||
const char* sectionName, int machine, int machineMask,
|
|
||||||
int sectionMask)
|
|
||||||
{
|
|
||||||
const unsigned sectionCount = 1;
|
|
||||||
const unsigned symbolCount = 2;
|
|
||||||
|
|
||||||
const unsigned sectionNumber = 1;
|
template<unsigned BytesPerWord>
|
||||||
|
class WindowsPlatform : public Platform {
|
||||||
|
public:
|
||||||
|
|
||||||
const unsigned startNameLength = strlen(startName) + 1;
|
|
||||||
const unsigned endNameLength = strlen(endName) + 1;
|
|
||||||
|
|
||||||
const unsigned startNameOffset = 4;
|
class FileWriter {
|
||||||
const unsigned endNameOffset = startNameOffset + startNameLength;
|
public:
|
||||||
|
unsigned sectionCount;
|
||||||
|
unsigned symbolCount;
|
||||||
|
unsigned dataStart;
|
||||||
|
unsigned dataOffset;
|
||||||
|
|
||||||
IMAGE_FILE_HEADER fileHeader = {
|
IMAGE_FILE_HEADER header;
|
||||||
machine, // Machine
|
|
||||||
sectionCount, // NumberOfSections
|
StringTable strings;
|
||||||
0, // TimeDateStamp
|
Buffer symbols;
|
||||||
sizeof(IMAGE_FILE_HEADER)
|
|
||||||
+ sizeof(IMAGE_SECTION_HEADER)
|
FileWriter(unsigned machine, unsigned machineMask, unsigned symbolCount):
|
||||||
+ pad(size), // PointerToSymbolTable
|
sectionCount(0),
|
||||||
symbolCount, // NumberOfSymbols
|
symbolCount(symbolCount),
|
||||||
0, // SizeOfOptionalHeader
|
dataStart(sizeof(IMAGE_FILE_HEADER)),
|
||||||
IMAGE_FILE_RELOCS_STRIPPED
|
dataOffset(0)
|
||||||
| IMAGE_FILE_LINE_NUMS_STRIPPED
|
{
|
||||||
| machineMask // Characteristics
|
header.Machine = machine;
|
||||||
|
// header.NumberOfSections = sectionCount;
|
||||||
|
header.TimeDateStamp = 0;
|
||||||
|
// header.PointerToSymbolTable = sizeof(IMAGE_FILE_HEADER)
|
||||||
|
// + sizeof(IMAGE_SECTION_HEADER)
|
||||||
|
// + pad(size);
|
||||||
|
// header.NumberOfSymbols = symbolCount;
|
||||||
|
header.SizeOfOptionalHeader = 0;
|
||||||
|
header.Characteristics = IMAGE_FILE_RELOCS_STRIPPED
|
||||||
|
| IMAGE_FILE_LINE_NUMS_STRIPPED
|
||||||
|
| machineMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeHeader(OutputStream* out) {
|
||||||
|
header.NumberOfSections = sectionCount;
|
||||||
|
header.PointerToSymbolTable = dataStart + dataOffset;
|
||||||
|
dataOffset = pad(dataOffset + symbolCount * sizeof(IMAGE_SYMBOL));
|
||||||
|
header.NumberOfSymbols = symbolCount;
|
||||||
|
out->writeChunk(&header, sizeof(IMAGE_FILE_HEADER));
|
||||||
|
}
|
||||||
|
|
||||||
|
void addSymbol(String name, unsigned addr, unsigned sectionNumber, unsigned type, unsigned storageClass) {
|
||||||
|
unsigned nameOffset = strings.add(name);
|
||||||
|
IMAGE_SYMBOL symbol = {
|
||||||
|
{ 0 }, // Name
|
||||||
|
addr, // Value
|
||||||
|
sectionNumber, // SectionNumber
|
||||||
|
type, // Type
|
||||||
|
storageClass, // StorageClass
|
||||||
|
0, // NumberOfAuxSymbols
|
||||||
|
};
|
||||||
|
symbol.N.Name.Long = nameOffset+4;
|
||||||
|
symbols.write(&symbol, sizeof(IMAGE_SYMBOL));
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeData(OutputStream* out) {
|
||||||
|
out->writeChunk(symbols.data, symbols.length);
|
||||||
|
uint32_t size = strings.length + 4;
|
||||||
|
out->writeChunk(&size, 4);
|
||||||
|
out->writeChunk(strings.data, strings.length);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
IMAGE_SECTION_HEADER sectionHeader = {
|
class SectionWriter {
|
||||||
"", // Name
|
public:
|
||||||
0, // PhysicalAddress
|
FileWriter& file;
|
||||||
0, // VirtualAddress
|
IMAGE_SECTION_HEADER header;
|
||||||
pad(size), // SizeOfRawData
|
size_t dataSize;
|
||||||
sizeof(IMAGE_FILE_HEADER)
|
size_t finalSize;
|
||||||
+ sizeof(IMAGE_SECTION_HEADER), // PointerToRawData
|
const uint8_t* data;
|
||||||
0, // PointerToRelocations
|
unsigned dataOffset;
|
||||||
0, // PointerToLinenumbers
|
|
||||||
0, // NumberOfRelocations
|
SectionWriter(
|
||||||
0, // NumberOfLinenumbers
|
FileWriter& file,
|
||||||
sectionMask // Characteristics
|
const char* name,
|
||||||
|
unsigned sectionMask,
|
||||||
|
const uint8_t* data,
|
||||||
|
size_t dataSize):
|
||||||
|
|
||||||
|
file(file),
|
||||||
|
data(data),
|
||||||
|
dataSize(dataSize),
|
||||||
|
finalSize(pad(dataSize))
|
||||||
|
{
|
||||||
|
file.sectionCount++;
|
||||||
|
file.dataStart += sizeof(IMAGE_SECTION_HEADER);
|
||||||
|
strcpy(reinterpret_cast<char*>(header.Name), name);
|
||||||
|
header.Misc.VirtualSize = 0;
|
||||||
|
header.SizeOfRawData = finalSize;
|
||||||
|
// header.PointerToRawData = file.dataOffset;
|
||||||
|
dataOffset = file.dataOffset;
|
||||||
|
file.dataOffset += finalSize;
|
||||||
|
header.PointerToRelocations = 0;
|
||||||
|
header.PointerToLinenumbers = 0;
|
||||||
|
header.NumberOfRelocations = 0;
|
||||||
|
header.NumberOfLinenumbers = 0;
|
||||||
|
header.Characteristics = sectionMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeHeader(OutputStream* out) {
|
||||||
|
header.PointerToRawData = dataOffset + file.dataStart;
|
||||||
|
out->writeChunk(&header, sizeof(IMAGE_SECTION_HEADER));
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeData(OutputStream* out) {
|
||||||
|
out->writeChunk(data, dataSize);
|
||||||
|
out->writeRepeat(0, finalSize - dataSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
strncpy(reinterpret_cast<char*>(sectionHeader.Name), sectionName,
|
virtual bool writeObject(OutputStream* out, Slice<SymbolInfo> symbols, Slice<const uint8_t> data, unsigned accessFlags, unsigned alignment) {
|
||||||
sizeof(sectionHeader.Name));
|
|
||||||
|
|
||||||
IMAGE_SYMBOL startSymbol = {
|
int machine;
|
||||||
{ 0 }, // Name
|
int machineMask;
|
||||||
0, // Value
|
|
||||||
sectionNumber, // SectionNumber
|
|
||||||
0, // Type
|
|
||||||
2, // StorageClass
|
|
||||||
0, // NumberOfAuxSymbols
|
|
||||||
};
|
|
||||||
startSymbol.N.Name.Long = startNameOffset;
|
|
||||||
|
|
||||||
IMAGE_SYMBOL endSymbol = {
|
if (BytesPerWord == 8) {
|
||||||
{ 0 }, // Name
|
machine = IMAGE_FILE_MACHINE_AMD64;
|
||||||
size, // Value
|
machineMask = 0;
|
||||||
sectionNumber, // SectionNumber
|
} else { // if (BytesPerWord == 8)
|
||||||
0, // Type
|
machine = IMAGE_FILE_MACHINE_I386;
|
||||||
2, // StorageClass
|
machineMask = IMAGE_FILE_32BIT_MACHINE;
|
||||||
0, // NumberOfAuxSymbols
|
}
|
||||||
};
|
|
||||||
endSymbol.N.Name.Long = endNameOffset;
|
|
||||||
|
|
||||||
fwrite(&fileHeader, 1, sizeof(fileHeader), out);
|
int sectionMask;
|
||||||
fwrite(§ionHeader, 1, sizeof(sectionHeader), out);
|
switch (alignment) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
sectionMask = IMAGE_SCN_ALIGN_1BYTES;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
sectionMask = IMAGE_SCN_ALIGN_2BYTES;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
sectionMask = IMAGE_SCN_ALIGN_4BYTES;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
sectionMask = IMAGE_SCN_ALIGN_8BYTES;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "unsupported alignment: %d\n", alignment);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
fwrite(data, 1, size, out);
|
sectionMask |= IMAGE_SCN_MEM_READ;
|
||||||
for (unsigned i = 0; i < pad(size) - size; ++i) fputc(0, out);
|
|
||||||
|
|
||||||
fwrite(&startSymbol, 1, sizeof(startSymbol), out);
|
const char* sectionName;
|
||||||
fwrite(&endSymbol, 1, sizeof(endSymbol), out);
|
if (accessFlags & Platform::Writable) {
|
||||||
|
if (accessFlags & Platform::Executable) {
|
||||||
|
sectionName = ".rwx";
|
||||||
|
sectionMask |= IMAGE_SCN_MEM_WRITE
|
||||||
|
| IMAGE_SCN_MEM_EXECUTE
|
||||||
|
| IMAGE_SCN_CNT_CODE;
|
||||||
|
} else {
|
||||||
|
sectionName = ".data";
|
||||||
|
sectionMask |= IMAGE_SCN_MEM_WRITE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sectionName = ".text";
|
||||||
|
sectionMask |= IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_CNT_CODE;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t symbolTableSize = endNameOffset + endNameLength;
|
FileWriter file(machine, machineMask, symbols.count);
|
||||||
fwrite(&symbolTableSize, 1, 4, out);
|
|
||||||
|
|
||||||
fwrite(startName, 1, startNameLength, out);
|
SectionWriter section(file, sectionName, sectionMask, data.items, data.count);
|
||||||
fwrite(endName, 1, endNameLength, out);
|
|
||||||
}
|
file.writeHeader(out);
|
||||||
|
|
||||||
|
for(SymbolInfo* sym = symbols.begin(); sym != symbols.end(); sym++) {
|
||||||
|
file.addSymbol(sym->name, sym->addr, 1, 0, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
section.writeHeader(out);
|
||||||
|
|
||||||
|
section.writeData(out);
|
||||||
|
|
||||||
|
file.writeData(out);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
WindowsPlatform():
|
||||||
|
Platform(PlatformInfo(PlatformInfo::Windows, BytesPerWord == 4 ? PlatformInfo::x86 : PlatformInfo::x86_64)) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
WindowsPlatform<4> windows32Platform;
|
||||||
|
WindowsPlatform<8> windows64Platform;
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace binaryToObject {
|
|
||||||
|
|
||||||
bool
|
|
||||||
writePEObject
|
|
||||||
(uint8_t* data, unsigned size, FILE* out, const char* startName,
|
|
||||||
const char* endName, const char* architecture, unsigned alignment,
|
|
||||||
bool writable, bool executable)
|
|
||||||
{
|
|
||||||
int machine;
|
|
||||||
int machineMask;
|
|
||||||
if (strcmp(architecture, "x86_64") == 0) {
|
|
||||||
machine = IMAGE_FILE_MACHINE_AMD64;
|
|
||||||
machineMask = 0;
|
|
||||||
} else if (strcmp(architecture, "i386") == 0) {
|
|
||||||
machine = IMAGE_FILE_MACHINE_I386;
|
|
||||||
machineMask = IMAGE_FILE_32BIT_MACHINE;
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "unsupported architecture: %s\n", architecture);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sectionMask;
|
|
||||||
switch (alignment) {
|
|
||||||
case 0:
|
|
||||||
case 1:
|
|
||||||
sectionMask = IMAGE_SCN_ALIGN_1BYTES;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
sectionMask = IMAGE_SCN_ALIGN_2BYTES;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
sectionMask = IMAGE_SCN_ALIGN_4BYTES;
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
sectionMask = IMAGE_SCN_ALIGN_8BYTES;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "unsupported alignment: %d\n", alignment);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
sectionMask |= IMAGE_SCN_MEM_READ;
|
|
||||||
|
|
||||||
const char* sectionName;
|
|
||||||
if (writable) {
|
|
||||||
if (executable) {
|
|
||||||
sectionName = ".rwx";
|
|
||||||
sectionMask |= IMAGE_SCN_MEM_WRITE
|
|
||||||
| IMAGE_SCN_MEM_EXECUTE
|
|
||||||
| IMAGE_SCN_CNT_CODE;
|
|
||||||
} else {
|
|
||||||
sectionName = ".data";
|
|
||||||
sectionMask |= IMAGE_SCN_MEM_WRITE;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
sectionName = ".text";
|
|
||||||
sectionMask |= IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_CNT_CODE;
|
|
||||||
}
|
|
||||||
|
|
||||||
writeObject(data, size, out, startName, endName, sectionName, machine,
|
|
||||||
machineMask, sectionMask);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace binaryToObject
|
|
||||||
|
125
src/binaryToObject/tools.cpp
Normal file
125
src/binaryToObject/tools.cpp
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
/* Copyright (c) 2009-2012, Avian Contributors
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
that the above copyright notice and this permission notice appear
|
||||||
|
in all copies.
|
||||||
|
|
||||||
|
There is NO WARRANTY for this software. See license.txt for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "tools.h"
|
||||||
|
|
||||||
|
namespace avian {
|
||||||
|
|
||||||
|
namespace tools {
|
||||||
|
|
||||||
|
String::String(const char* text):
|
||||||
|
text(text),
|
||||||
|
length(strlen(text)) {}
|
||||||
|
|
||||||
|
Buffer::Buffer():
|
||||||
|
capacity(100),
|
||||||
|
length(0),
|
||||||
|
data((uint8_t*)malloc(capacity)) {}
|
||||||
|
|
||||||
|
Buffer::~Buffer() {
|
||||||
|
free(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Buffer::ensure(size_t more) {
|
||||||
|
if(length + more > capacity) {
|
||||||
|
capacity = capacity * 2 + more;
|
||||||
|
data = (uint8_t*)realloc(data, capacity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Buffer::write(const void* d, size_t size) {
|
||||||
|
ensure(size);
|
||||||
|
memcpy(data + length, d, size);
|
||||||
|
length += size;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned StringTable::add(String str) {
|
||||||
|
unsigned offset = Buffer::length;
|
||||||
|
Buffer::write(str.text, str.length + 1);
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OutputStream::write(uint8_t byte) {
|
||||||
|
writeChunk(&byte, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OutputStream::writeRepeat(uint8_t byte, size_t size) {
|
||||||
|
for(size_t i = 0; i < size; i++) {
|
||||||
|
write(byte);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FileOutputStream::FileOutputStream(const char* name):
|
||||||
|
file(fopen(name, "wb")) {}
|
||||||
|
|
||||||
|
FileOutputStream::~FileOutputStream() {
|
||||||
|
if(file) {
|
||||||
|
fclose(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FileOutputStream::isValid() {
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileOutputStream::writeChunk(const void* data, size_t size) {
|
||||||
|
fwrite(data, size, 1, file);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileOutputStream::write(uint8_t byte) {
|
||||||
|
fputc(byte, file);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Platform* Platform::first = 0;
|
||||||
|
|
||||||
|
PlatformInfo::OperatingSystem PlatformInfo::osFromString(const char* os) {
|
||||||
|
if(strcmp(os, "linux") == 0) {
|
||||||
|
return Linux;
|
||||||
|
} else if(strcmp(os, "windows") == 0) {
|
||||||
|
return Windows;
|
||||||
|
} else if(strcmp(os, "darwin") == 0) {
|
||||||
|
return Darwin;
|
||||||
|
} else {
|
||||||
|
return UnknownOS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PlatformInfo::Architecture PlatformInfo::archFromString(const char* arch) {
|
||||||
|
if(strcmp(arch, "i386") == 0) {
|
||||||
|
return x86;
|
||||||
|
} else if(strcmp(arch, "x86_64") == 0) {
|
||||||
|
return x86_64;
|
||||||
|
} else if(strcmp(arch, "powerpc") == 0) {
|
||||||
|
return PowerPC;
|
||||||
|
} else if(strcmp(arch, "arm") == 0) {
|
||||||
|
return Arm;
|
||||||
|
} else {
|
||||||
|
return UnknownArch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Platform* Platform::getPlatform(PlatformInfo info) {
|
||||||
|
for(Platform* p = first; p; p = p->next) {
|
||||||
|
if(p->info == info) {
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace tools
|
||||||
|
|
||||||
|
} // namespace avian
|
196
src/binaryToObject/tools.h
Normal file
196
src/binaryToObject/tools.h
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
/* Copyright (c) 2009-2012, Avian Contributors
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
that the above copyright notice and this permission notice appear
|
||||||
|
in all copies.
|
||||||
|
|
||||||
|
There is NO WARRANTY for this software. See license.txt for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#ifndef AVIAN_TOOLS_H_
|
||||||
|
#define AVIAN_TOOLS_H_
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "environment.h"
|
||||||
|
|
||||||
|
namespace avian {
|
||||||
|
|
||||||
|
namespace tools {
|
||||||
|
|
||||||
|
class OutputStream {
|
||||||
|
public:
|
||||||
|
virtual void writeChunk(const void* data, size_t size) = 0;
|
||||||
|
virtual void write(uint8_t byte);
|
||||||
|
virtual void writeRepeat(uint8_t byte, size_t size);
|
||||||
|
};
|
||||||
|
|
||||||
|
class FileOutputStream : public OutputStream {
|
||||||
|
private:
|
||||||
|
FILE* file;
|
||||||
|
public:
|
||||||
|
FileOutputStream(const char* name);
|
||||||
|
~FileOutputStream();
|
||||||
|
|
||||||
|
bool isValid();
|
||||||
|
|
||||||
|
virtual void writeChunk(const void* data, size_t size);
|
||||||
|
virtual void write(uint8_t byte);
|
||||||
|
};
|
||||||
|
|
||||||
|
class String {
|
||||||
|
public:
|
||||||
|
const char* text;
|
||||||
|
size_t length;
|
||||||
|
|
||||||
|
String(const char* text);
|
||||||
|
|
||||||
|
inline String(const char* text, size_t length):
|
||||||
|
text(text),
|
||||||
|
length(length) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SymbolInfo {
|
||||||
|
public:
|
||||||
|
unsigned addr;
|
||||||
|
String name;
|
||||||
|
|
||||||
|
inline SymbolInfo(uint64_t addr, const String& name):
|
||||||
|
addr(addr),
|
||||||
|
name(name) {}
|
||||||
|
|
||||||
|
inline SymbolInfo():
|
||||||
|
name("") {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class Buffer {
|
||||||
|
public:
|
||||||
|
size_t capacity;
|
||||||
|
size_t length;
|
||||||
|
uint8_t* data;
|
||||||
|
|
||||||
|
Buffer();
|
||||||
|
~Buffer();
|
||||||
|
|
||||||
|
void ensure(size_t more);
|
||||||
|
void write(const void* d, size_t size);
|
||||||
|
};
|
||||||
|
|
||||||
|
class StringTable : public Buffer {
|
||||||
|
public:
|
||||||
|
unsigned add(String str);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class Slice {
|
||||||
|
public:
|
||||||
|
T* items;
|
||||||
|
size_t count;
|
||||||
|
|
||||||
|
inline Slice(T* items, size_t count):
|
||||||
|
items(items),
|
||||||
|
count(count) {}
|
||||||
|
|
||||||
|
inline Slice(const Slice<T>& copy):
|
||||||
|
items(copy.items),
|
||||||
|
count(copy.count) {}
|
||||||
|
|
||||||
|
inline T* begin() {
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline T* end() {
|
||||||
|
return items + count;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class DynamicArray : public Slice<T> {
|
||||||
|
public:
|
||||||
|
size_t capacity;
|
||||||
|
|
||||||
|
DynamicArray():
|
||||||
|
Slice<T>((T*)malloc(10 * sizeof(T)), 0),
|
||||||
|
capacity(10) {}
|
||||||
|
~DynamicArray() {
|
||||||
|
free(Slice<T>::items);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ensure(size_t more) {
|
||||||
|
if(Slice<T>::count + more > capacity) {
|
||||||
|
capacity = capacity * 2 + more;
|
||||||
|
Slice<T>::items = (T*)realloc(Slice<T>::items, capacity * sizeof(T));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void add(const T& item) {
|
||||||
|
ensure(1);
|
||||||
|
Slice<T>::items[Slice<T>::count++] = item;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class PlatformInfo {
|
||||||
|
public:
|
||||||
|
enum OperatingSystem {
|
||||||
|
Linux = AVIAN_PLATFORM_LINUX,
|
||||||
|
Windows = AVIAN_PLATFORM_WINDOWS,
|
||||||
|
Darwin = AVIAN_PLATFORM_DARWIN,
|
||||||
|
UnknownOS = AVIAN_PLATFORM_UNKNOWN
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Architecture {
|
||||||
|
x86 = AVIAN_ARCH_X86,
|
||||||
|
x86_64 = AVIAN_ARCH_X86_64,
|
||||||
|
PowerPC = AVIAN_ARCH_POWERPC,
|
||||||
|
Arm = AVIAN_ARCH_ARM,
|
||||||
|
UnknownArch = AVIAN_ARCH_UNKNOWN
|
||||||
|
};
|
||||||
|
|
||||||
|
const OperatingSystem os;
|
||||||
|
const Architecture arch;
|
||||||
|
|
||||||
|
static OperatingSystem osFromString(const char* os);
|
||||||
|
static Architecture archFromString(const char* arch);
|
||||||
|
|
||||||
|
inline PlatformInfo(OperatingSystem os, Architecture arch):
|
||||||
|
os(os),
|
||||||
|
arch(arch) {}
|
||||||
|
|
||||||
|
inline bool operator == (const PlatformInfo& other) {
|
||||||
|
return os == other.os && arch == other.arch;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool isLittleEndian() {
|
||||||
|
return arch != PowerPC;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class Platform {
|
||||||
|
private:
|
||||||
|
Platform* next;
|
||||||
|
static Platform* first;
|
||||||
|
public:
|
||||||
|
PlatformInfo info;
|
||||||
|
|
||||||
|
inline Platform(PlatformInfo info):
|
||||||
|
next(first),
|
||||||
|
info(info)
|
||||||
|
{
|
||||||
|
first = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum AccessFlags {
|
||||||
|
Writable = 1 << 0,
|
||||||
|
Executable = 1 << 1
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual bool writeObject(OutputStream* out, Slice<SymbolInfo> symbols, Slice<const uint8_t> data, unsigned accessFlags, unsigned alignment) = 0;
|
||||||
|
|
||||||
|
static Platform* getPlatform(PlatformInfo info);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace tools
|
||||||
|
|
||||||
|
} // namespace avian
|
||||||
|
|
||||||
|
#endif
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2010, Avian Contributors
|
/* Copyright (c) 2010-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2010, Avian Contributors
|
/* Copyright (c) 2008-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2011, Avian Contributors
|
/* Copyright (c) 2008-2012, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
@ -16,16 +16,18 @@
|
|||||||
#include "stream.h"
|
#include "stream.h"
|
||||||
#include "assembler.h"
|
#include "assembler.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
|
#include "binaryToObject/tools.h"
|
||||||
|
|
||||||
// since we aren't linking against libstdc++, we must implement this
|
// since we aren't linking against libstdc++, we must implement this
|
||||||
// ourselves:
|
// ourselves:
|
||||||
extern "C" void __cxa_pure_virtual(void) { abort(); }
|
extern "C" void __cxa_pure_virtual(void) { abort(); }
|
||||||
|
|
||||||
using namespace vm;
|
using namespace vm;
|
||||||
|
using namespace avian::tools;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
const unsigned HeapCapacity = 256 * 1024 * 1024;
|
const unsigned HeapCapacity = 512 * 1024 * 1024;
|
||||||
|
|
||||||
const unsigned TargetFixieSizeInBytes = 8 + (TargetBytesPerWord * 2);
|
const unsigned TargetFixieSizeInBytes = 8 + (TargetBytesPerWord * 2);
|
||||||
const unsigned TargetFixieSizeInWords = ceiling
|
const unsigned TargetFixieSizeInWords = ceiling
|
||||||
@ -435,6 +437,10 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
|
|||||||
|
|
||||||
memberFields[memberIndex] = *f;
|
memberFields[memberIndex] = *f;
|
||||||
|
|
||||||
|
while (targetMemberOffset % f->targetSize) {
|
||||||
|
++ targetMemberOffset;
|
||||||
|
}
|
||||||
|
|
||||||
targetMemberOffset += f->targetSize;
|
targetMemberOffset += f->targetSize;
|
||||||
|
|
||||||
++ memberIndex;
|
++ memberIndex;
|
||||||
@ -498,10 +504,8 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (fieldFlags(t, field) & ACC_STATIC) {
|
if (fieldFlags(t, field) & ACC_STATIC) {
|
||||||
unsigned excess = (targetStaticOffset % targetSize)
|
while (targetStaticOffset % targetSize) {
|
||||||
% TargetBytesPerWord;
|
++ targetStaticOffset;
|
||||||
if (excess) {
|
|
||||||
targetStaticOffset += TargetBytesPerWord - excess;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
buildStaticOffset = fieldOffset(t, field);
|
buildStaticOffset = fieldOffset(t, field);
|
||||||
@ -680,10 +684,6 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (; methods; methods = pairSecond(t, methods)) {
|
for (; methods; methods = pairSecond(t, methods)) {
|
||||||
intptr_t address = codeCompiled(t, methodCode(t, pairFirst(t, methods)));
|
|
||||||
reinterpret_cast<target_uintptr_t*>(address)[-1]
|
|
||||||
= targetVW(reinterpret_cast<target_uintptr_t*>(address)[-1]);
|
|
||||||
|
|
||||||
codeCompiled(t, methodCode(t, pairFirst(t, methods)))
|
codeCompiled(t, methodCode(t, pairFirst(t, methods)))
|
||||||
-= reinterpret_cast<uintptr_t>(code);
|
-= reinterpret_cast<uintptr_t>(code);
|
||||||
}
|
}
|
||||||
@ -1281,12 +1281,48 @@ targetThunk(BootImage::Thunk t)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
writeBootImage2(Thread* t, FILE* bootimageOutput, FILE* codeOutput,
|
writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutput,
|
||||||
BootImage* image, uint8_t* code, const char* className,
|
BootImage* image, uint8_t* code, const char* className,
|
||||||
const char* methodName, const char* methodSpec)
|
const char* methodName, const char* methodSpec,
|
||||||
|
const char* bootimageStart, const char* bootimageEnd,
|
||||||
|
const char* codeimageStart, const char* codeimageEnd)
|
||||||
{
|
{
|
||||||
|
setRoot(t, Machine::OutOfMemoryError,
|
||||||
|
make(t, type(t, Machine::OutOfMemoryErrorType)));
|
||||||
|
|
||||||
Zone zone(t->m->system, t->m->heap, 64 * 1024);
|
Zone zone(t->m->system, t->m->heap, 64 * 1024);
|
||||||
|
|
||||||
|
class MyCompilationHandler : public Processor::CompilationHandler {
|
||||||
|
public:
|
||||||
|
|
||||||
|
String heapDup(const char* name) {
|
||||||
|
String ret(name);
|
||||||
|
char* n = (char*)heap->allocate(ret.length + 1);
|
||||||
|
memcpy(n, ret.text, ret.length + 1);
|
||||||
|
ret.text = n;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void compiled(const void* code, unsigned size UNUSED, unsigned frameSize UNUSED, const char* name) {
|
||||||
|
uint64_t offset = reinterpret_cast<uint64_t>(code) - codeOffset;
|
||||||
|
symbols.add(SymbolInfo(offset, heapDup(name)));
|
||||||
|
// printf("%ld %ld %s.%s%s\n", offset, offset + size, class_, name, spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void dispose() {}
|
||||||
|
|
||||||
|
DynamicArray<SymbolInfo> symbols;
|
||||||
|
uint64_t codeOffset;
|
||||||
|
Heap* heap;
|
||||||
|
|
||||||
|
MyCompilationHandler(uint64_t codeOffset, Heap* heap):
|
||||||
|
codeOffset(codeOffset),
|
||||||
|
heap(heap) {}
|
||||||
|
|
||||||
|
} compilationHandler(reinterpret_cast<uint64_t>(code), t->m->heap);
|
||||||
|
|
||||||
|
t->m->processor->addCompilationHandler(&compilationHandler);
|
||||||
|
|
||||||
object classPoolMap;
|
object classPoolMap;
|
||||||
object typeMaps;
|
object typeMaps;
|
||||||
object constants;
|
object constants;
|
||||||
@ -1573,6 +1609,8 @@ writeBootImage2(Thread* t, FILE* bootimageOutput, FILE* codeOutput,
|
|||||||
image->bootClassCount, image->stringCount, image->callCount,
|
image->bootClassCount, image->stringCount, image->callCount,
|
||||||
image->heapSize, image->codeSize);
|
image->heapSize, image->codeSize);
|
||||||
|
|
||||||
|
Buffer bootimageData;
|
||||||
|
|
||||||
if (true) {
|
if (true) {
|
||||||
{ BootImage targetImage;
|
{ BootImage targetImage;
|
||||||
|
|
||||||
@ -1589,19 +1627,15 @@ writeBootImage2(Thread* t, FILE* bootimageOutput, FILE* codeOutput,
|
|||||||
#include "bootimage-fields.cpp"
|
#include "bootimage-fields.cpp"
|
||||||
#undef THUNK_FIELD
|
#undef THUNK_FIELD
|
||||||
|
|
||||||
fwrite(&targetImage, sizeof(BootImage), 1, bootimageOutput);
|
bootimageData.write(&targetImage, sizeof(BootImage));
|
||||||
}
|
}
|
||||||
|
|
||||||
fwrite(bootClassTable, image->bootClassCount * sizeof(unsigned), 1,
|
bootimageData.write(bootClassTable, image->bootClassCount * sizeof(unsigned));
|
||||||
bootimageOutput);
|
bootimageData.write(appClassTable, image->appClassCount * sizeof(unsigned));
|
||||||
fwrite(appClassTable, image->appClassCount * sizeof(unsigned), 1,
|
bootimageData.write(stringTable, image->stringCount * sizeof(unsigned));
|
||||||
bootimageOutput);
|
bootimageData.write(callTable, image->callCount * sizeof(unsigned) * 2);
|
||||||
fwrite(stringTable, image->stringCount * sizeof(unsigned), 1,
|
|
||||||
bootimageOutput);
|
|
||||||
fwrite(callTable, image->callCount * sizeof(unsigned) * 2, 1,
|
|
||||||
bootimageOutput);
|
|
||||||
|
|
||||||
unsigned offset = sizeof(BootImage)
|
unsigned offset = sizeof(BootImage)
|
||||||
+ (image->bootClassCount * sizeof(unsigned))
|
+ (image->bootClassCount * sizeof(unsigned))
|
||||||
+ (image->appClassCount * sizeof(unsigned))
|
+ (image->appClassCount * sizeof(unsigned))
|
||||||
+ (image->stringCount * sizeof(unsigned))
|
+ (image->stringCount * sizeof(unsigned))
|
||||||
@ -1609,52 +1643,313 @@ writeBootImage2(Thread* t, FILE* bootimageOutput, FILE* codeOutput,
|
|||||||
|
|
||||||
while (offset % TargetBytesPerWord) {
|
while (offset % TargetBytesPerWord) {
|
||||||
uint8_t c = 0;
|
uint8_t c = 0;
|
||||||
fwrite(&c, 1, 1, bootimageOutput);
|
bootimageData.write(&c, 1);
|
||||||
++ offset;
|
++ offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
fwrite(heapMap, pad(heapMapSize(image->heapSize), TargetBytesPerWord), 1,
|
bootimageData.write(heapMap, pad(heapMapSize(image->heapSize), TargetBytesPerWord));
|
||||||
bootimageOutput);
|
|
||||||
|
|
||||||
fwrite(heap, pad(image->heapSize, TargetBytesPerWord), 1, bootimageOutput);
|
bootimageData.write(heap, pad(image->heapSize, TargetBytesPerWord));
|
||||||
|
|
||||||
fwrite(code, pad(image->codeSize, TargetBytesPerWord), 1, codeOutput);
|
// fwrite(code, pad(image->codeSize, TargetBytesPerWord), 1, codeOutput);
|
||||||
|
|
||||||
|
Platform* platform = Platform::getPlatform(PlatformInfo((PlatformInfo::OperatingSystem)AVIAN_TARGET_PLATFORM, (PlatformInfo::Architecture)AVIAN_TARGET_ARCH));
|
||||||
|
|
||||||
|
// if(!platform) {
|
||||||
|
// fprintf(stderr, "unsupported platform: %s/%s\n", os, architecture);
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
|
||||||
|
SymbolInfo bootimageSymbols[] = {
|
||||||
|
SymbolInfo(0, bootimageStart),
|
||||||
|
SymbolInfo(bootimageData.length, bootimageEnd)
|
||||||
|
};
|
||||||
|
|
||||||
|
platform->writeObject(bootimageOutput, Slice<SymbolInfo>(bootimageSymbols, 2), Slice<const uint8_t>(bootimageData.data, bootimageData.length), Platform::Writable, TargetBytesPerWord);
|
||||||
|
|
||||||
|
compilationHandler.symbols.add(SymbolInfo(0, codeimageStart));
|
||||||
|
compilationHandler.symbols.add(SymbolInfo(image->codeSize, codeimageEnd));
|
||||||
|
|
||||||
|
platform->writeObject(codeOutput, Slice<SymbolInfo>(compilationHandler.symbols), Slice<const uint8_t>(code, image->codeSize), Platform::Executable, TargetBytesPerWord);
|
||||||
|
|
||||||
|
for(SymbolInfo* sym = compilationHandler.symbols.begin(); sym != compilationHandler.symbols.end() - 2; sym++) {
|
||||||
|
t->m->heap->free(const_cast<void*>((const void*)sym->name.text), sym->name.length + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t
|
uint64_t
|
||||||
writeBootImage(Thread* t, uintptr_t* arguments)
|
writeBootImage(Thread* t, uintptr_t* arguments)
|
||||||
{
|
{
|
||||||
FILE* bootimageOutput = reinterpret_cast<FILE*>(arguments[0]);
|
OutputStream* bootimageOutput = reinterpret_cast<OutputStream*>(arguments[0]);
|
||||||
FILE* codeOutput = reinterpret_cast<FILE*>(arguments[1]);
|
OutputStream* codeOutput = reinterpret_cast<OutputStream*>(arguments[1]);
|
||||||
BootImage* image = reinterpret_cast<BootImage*>(arguments[2]);
|
BootImage* image = reinterpret_cast<BootImage*>(arguments[2]);
|
||||||
uint8_t* code = reinterpret_cast<uint8_t*>(arguments[3]);
|
uint8_t* code = reinterpret_cast<uint8_t*>(arguments[3]);
|
||||||
const char* className = reinterpret_cast<const char*>(arguments[4]);
|
const char* className = reinterpret_cast<const char*>(arguments[4]);
|
||||||
const char* methodName = reinterpret_cast<const char*>(arguments[5]);
|
const char* methodName = reinterpret_cast<const char*>(arguments[5]);
|
||||||
const char* methodSpec = reinterpret_cast<const char*>(arguments[6]);
|
const char* methodSpec = reinterpret_cast<const char*>(arguments[6]);
|
||||||
|
|
||||||
|
const char* bootimageStart = reinterpret_cast<const char*>(arguments[7]);
|
||||||
|
const char* bootimageEnd = reinterpret_cast<const char*>(arguments[8]);
|
||||||
|
const char* codeimageStart = reinterpret_cast<const char*>(arguments[9]);
|
||||||
|
const char* codeimageEnd = reinterpret_cast<const char*>(arguments[10]);
|
||||||
|
|
||||||
writeBootImage2
|
writeBootImage2
|
||||||
(t, bootimageOutput, codeOutput, image, code, className, methodName,
|
(t, bootimageOutput, codeOutput, image, code, className, methodName,
|
||||||
methodSpec);
|
methodSpec, bootimageStart, bootimageEnd, codeimageStart, codeimageEnd);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Arg;
|
||||||
|
|
||||||
|
class ArgParser {
|
||||||
|
public:
|
||||||
|
Arg* first;
|
||||||
|
Arg** last;
|
||||||
|
|
||||||
|
ArgParser():
|
||||||
|
first(0),
|
||||||
|
last(&first) {}
|
||||||
|
|
||||||
|
bool parse(int ac, const char** av);
|
||||||
|
void printUsage(const char* exe);
|
||||||
|
};
|
||||||
|
|
||||||
|
class Arg {
|
||||||
|
public:
|
||||||
|
Arg* next;
|
||||||
|
bool required;
|
||||||
|
const char* name;
|
||||||
|
const char* desc;
|
||||||
|
|
||||||
|
const char* value;
|
||||||
|
|
||||||
|
Arg(ArgParser& parser, bool required, const char* name, const char* desc):
|
||||||
|
next(0),
|
||||||
|
required(required),
|
||||||
|
name(name),
|
||||||
|
desc(desc),
|
||||||
|
value(0)
|
||||||
|
{
|
||||||
|
*parser.last = this;
|
||||||
|
parser.last = &next;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
bool ArgParser::parse(int ac, const char** av) {
|
||||||
|
Arg* state = 0;
|
||||||
|
|
||||||
|
for(int i = 1; i < ac; i++) {
|
||||||
|
if(state) {
|
||||||
|
if(state->value) {
|
||||||
|
fprintf(stderr, "duplicate parameter %s: '%s' and '%s'\n", state->name, state->value, av[i]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
state->value = av[i];
|
||||||
|
state = 0;
|
||||||
|
} else {
|
||||||
|
if(av[i][0] != '-') {
|
||||||
|
fprintf(stderr, "expected -parameter\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for(Arg* arg = first; arg; arg = arg->next) {
|
||||||
|
if(strcmp(arg->name, &av[i][1]) == 0) {
|
||||||
|
state = arg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!state) {
|
||||||
|
fprintf(stderr, "unrecognized parameter %s\n", av[i]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(state) {
|
||||||
|
fprintf(stderr, "expected argument after -%s\n", state->name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(Arg* arg = first; arg; arg = arg->next) {
|
||||||
|
if(arg->required && !arg->value) {
|
||||||
|
fprintf(stderr, "expected value for %s\n", arg->name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ArgParser::printUsage(const char* exe) {
|
||||||
|
fprintf(stderr, "usage:\n%s \\\n", exe);
|
||||||
|
for(Arg* arg = first; arg; arg = arg->next) {
|
||||||
|
const char* lineEnd = arg->next ? " \\" : "";
|
||||||
|
if(arg->required) {
|
||||||
|
fprintf(stderr, " -%s\t%s%s\n", arg->name, arg->desc, lineEnd);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, " [-%s\t%s]%s\n", arg->name, arg->desc, lineEnd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Arguments {
|
||||||
|
public:
|
||||||
|
|
||||||
|
const char* classpath;
|
||||||
|
|
||||||
|
const char* bootimage;
|
||||||
|
const char* codeimage;
|
||||||
|
|
||||||
|
char* entryClass;
|
||||||
|
char* entryMethod;
|
||||||
|
char* entrySpec;
|
||||||
|
|
||||||
|
char* bootimageStart;
|
||||||
|
char* bootimageEnd;
|
||||||
|
|
||||||
|
char* codeimageStart;
|
||||||
|
char* codeimageEnd;
|
||||||
|
|
||||||
|
bool maybeSplit(const char* src, char*& destA, char*& destB) {
|
||||||
|
if(src) {
|
||||||
|
const char* split = strchr(src, ':');
|
||||||
|
if(!split) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
destA = strndup(src, split - src);
|
||||||
|
destB = strdup(split + 1);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Arguments(int ac, const char** av):
|
||||||
|
entryClass(0),
|
||||||
|
entryMethod(0),
|
||||||
|
entrySpec(0),
|
||||||
|
bootimageStart(0),
|
||||||
|
bootimageEnd(0),
|
||||||
|
codeimageStart(0),
|
||||||
|
codeimageEnd(0)
|
||||||
|
{
|
||||||
|
ArgParser parser;
|
||||||
|
Arg classpath(parser, true, "cp", "<classpath>");
|
||||||
|
Arg bootimage(parser, true, "bootimage", "<bootimage file>");
|
||||||
|
Arg codeimage(parser, true, "codeimage", "<codeimage file>");
|
||||||
|
Arg entry(parser, false, "entry", "<class name>[.<method name>[<method spec>]]");
|
||||||
|
Arg bootimageSymbols(parser, false, "bootimage-symbols", "<start symbol name>:<end symbol name>");
|
||||||
|
Arg codeimageSymbols(parser, false, "codeimage-symbols", "<start symbol name>:<end symbol name>");
|
||||||
|
|
||||||
|
if(!parser.parse(ac, av)) {
|
||||||
|
parser.printUsage(av[0]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->classpath = classpath.value;
|
||||||
|
this->bootimage = bootimage.value;
|
||||||
|
this->codeimage = codeimage.value;
|
||||||
|
|
||||||
|
if(entry.value) {
|
||||||
|
if(const char* entryClassEnd = strchr(entry.value, '.')) {
|
||||||
|
entryClass = strndup(entry.value, entryClassEnd - entry.value);
|
||||||
|
if(const char* entryMethodEnd = strchr(entryClassEnd, '(')) {
|
||||||
|
entryMethod = strndup(entryClassEnd + 1, entryMethodEnd - entryClassEnd - 1);
|
||||||
|
entrySpec = strdup(entryMethodEnd);
|
||||||
|
} else {
|
||||||
|
entryMethod = strdup(entryClassEnd + 1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
entryClass = strdup(entry.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!maybeSplit(bootimageSymbols.value, bootimageStart, bootimageEnd) ||
|
||||||
|
!maybeSplit(codeimageSymbols.value, codeimageStart, codeimageEnd))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "wrong format for symbols\n");
|
||||||
|
parser.printUsage(av[0]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!bootimageStart) {
|
||||||
|
bootimageStart = strdup("_binary_bootimage_bin_start");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!bootimageEnd) {
|
||||||
|
bootimageEnd = strdup("_binary_bootimage_bin_end");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!codeimageStart) {
|
||||||
|
codeimageStart = strdup("_binary_codeimage_bin_start");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!codeimageEnd) {
|
||||||
|
codeimageEnd = strdup("_binary_codeimage_bin_end");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
~Arguments() {
|
||||||
|
if(entryClass) {
|
||||||
|
free(entryClass);
|
||||||
|
}
|
||||||
|
if(entryMethod) {
|
||||||
|
free(entryMethod);
|
||||||
|
}
|
||||||
|
if(entrySpec) {
|
||||||
|
free(entrySpec);
|
||||||
|
}
|
||||||
|
if(bootimageStart) {
|
||||||
|
free(bootimageStart);
|
||||||
|
}
|
||||||
|
if(bootimageEnd) {
|
||||||
|
free(bootimageEnd);
|
||||||
|
}
|
||||||
|
if(codeimageStart) {
|
||||||
|
free(codeimageStart);
|
||||||
|
}
|
||||||
|
if(codeimageEnd) {
|
||||||
|
free(codeimageEnd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dump() {
|
||||||
|
printf(
|
||||||
|
"classpath = %s\n"
|
||||||
|
"bootimage = %s\n"
|
||||||
|
"codeimage = %s\n"
|
||||||
|
"entryClass = %s\n"
|
||||||
|
"entryMethod = %s\n"
|
||||||
|
"entrySpec = %s\n"
|
||||||
|
"bootimageStart = %s\n"
|
||||||
|
"bootimageEnd = %s\n"
|
||||||
|
"codeimageStart = %s\n"
|
||||||
|
"codeimageEnd = %s\n",
|
||||||
|
classpath,
|
||||||
|
bootimage,
|
||||||
|
codeimage,
|
||||||
|
entryClass,
|
||||||
|
entryMethod,
|
||||||
|
entrySpec,
|
||||||
|
bootimageStart,
|
||||||
|
bootimageEnd,
|
||||||
|
codeimageStart,
|
||||||
|
codeimageEnd);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int ac, const char** av)
|
main(int ac, const char** av)
|
||||||
{
|
{
|
||||||
if (ac < 4 or ac > 7) {
|
Arguments args(ac, av);
|
||||||
fprintf(stderr, "usage: %s <classpath> <bootimage file> <code file>"
|
// args.dump();
|
||||||
" [<class name> [<method name> [<method spec>]]]\n", av[0]);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
System* s = makeSystem(0);
|
System* s = makeSystem(0);
|
||||||
Heap* h = makeHeap(s, HeapCapacity * 2);
|
Heap* h = makeHeap(s, HeapCapacity * 2);
|
||||||
Classpath* c = makeClasspath(s, h, AVIAN_JAVA_HOME, AVIAN_EMBED_PREFIX);
|
Classpath* c = makeClasspath(s, h, AVIAN_JAVA_HOME, AVIAN_EMBED_PREFIX);
|
||||||
Finder* f = makeFinder(s, h, av[1], 0);
|
Finder* f = makeFinder(s, h, args.classpath, 0);
|
||||||
Processor* p = makeProcessor(s, h, false);
|
Processor* p = makeProcessor(s, h, false);
|
||||||
|
|
||||||
// todo: currently, the compiler cannot compile code with jumps or
|
// todo: currently, the compiler cannot compile code with jumps or
|
||||||
@ -1662,44 +1957,51 @@ main(int ac, const char** av)
|
|||||||
// in a branch instruction for the target architecture (~32MB on
|
// in a branch instruction for the target architecture (~32MB on
|
||||||
// PowerPC and ARM). When that limitation is removed, we'll be able
|
// PowerPC and ARM). When that limitation is removed, we'll be able
|
||||||
// to specify a capacity as large as we like here:
|
// to specify a capacity as large as we like here:
|
||||||
|
#if (defined ARCH_x86_64) || (defined ARCH_x86_32)
|
||||||
|
const unsigned CodeCapacity = 128 * 1024 * 1024;
|
||||||
|
#else
|
||||||
const unsigned CodeCapacity = 30 * 1024 * 1024;
|
const unsigned CodeCapacity = 30 * 1024 * 1024;
|
||||||
|
#endif
|
||||||
|
|
||||||
uint8_t* code = static_cast<uint8_t*>(h->allocate(CodeCapacity));
|
uint8_t* code = static_cast<uint8_t*>(h->allocate(CodeCapacity));
|
||||||
BootImage image;
|
BootImage image;
|
||||||
p->initialize(&image, code, CodeCapacity);
|
p->initialize(&image, code, CodeCapacity);
|
||||||
|
|
||||||
Machine* m = new (h->allocate(sizeof(Machine))) Machine
|
Machine* m = new (h->allocate(sizeof(Machine))) Machine
|
||||||
(s, h, f, 0, p, c, 0, 0, 0, 0);
|
(s, h, f, 0, p, c, 0, 0, 0, 0, 128 * 1024);
|
||||||
Thread* t = p->makeThread(m, 0, 0);
|
Thread* t = p->makeThread(m, 0, 0);
|
||||||
|
|
||||||
enter(t, Thread::ActiveState);
|
enter(t, Thread::ActiveState);
|
||||||
enter(t, Thread::IdleState);
|
enter(t, Thread::IdleState);
|
||||||
|
|
||||||
FILE* bootimageOutput = vm::fopen(av[2], "wb");
|
FileOutputStream bootimageOutput(args.bootimage);
|
||||||
if (bootimageOutput == 0) {
|
if (!bootimageOutput.isValid()) {
|
||||||
fprintf(stderr, "unable to open %s\n", av[2]);
|
fprintf(stderr, "unable to open %s\n", args.bootimage);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE* codeOutput = vm::fopen(av[3], "wb");
|
FileOutputStream codeOutput(args.codeimage);
|
||||||
if (codeOutput == 0) {
|
if (!codeOutput.isValid()) {
|
||||||
fprintf(stderr, "unable to open %s\n", av[3]);
|
fprintf(stderr, "unable to open %s\n", args.codeimage);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(bootimageOutput),
|
uintptr_t arguments[] = {
|
||||||
reinterpret_cast<uintptr_t>(codeOutput),
|
reinterpret_cast<uintptr_t>(&bootimageOutput),
|
||||||
reinterpret_cast<uintptr_t>(&image),
|
reinterpret_cast<uintptr_t>(&codeOutput),
|
||||||
reinterpret_cast<uintptr_t>(code),
|
reinterpret_cast<uintptr_t>(&image),
|
||||||
reinterpret_cast<uintptr_t>(ac > 4 ? av[4] : 0),
|
reinterpret_cast<uintptr_t>(code),
|
||||||
reinterpret_cast<uintptr_t>(ac > 5 ? av[5] : 0),
|
reinterpret_cast<uintptr_t>(args.entryClass),
|
||||||
reinterpret_cast<uintptr_t>(ac > 6 ? av[6] : 0) };
|
reinterpret_cast<uintptr_t>(args.entryMethod),
|
||||||
|
reinterpret_cast<uintptr_t>(args.entrySpec),
|
||||||
|
reinterpret_cast<uintptr_t>(args.bootimageStart),
|
||||||
|
reinterpret_cast<uintptr_t>(args.bootimageEnd),
|
||||||
|
reinterpret_cast<uintptr_t>(args.codeimageStart),
|
||||||
|
reinterpret_cast<uintptr_t>(args.codeimageEnd)
|
||||||
|
};
|
||||||
|
|
||||||
run(t, writeBootImage, arguments);
|
run(t, writeBootImage, arguments);
|
||||||
|
|
||||||
fclose(codeOutput);
|
|
||||||
fclose(bootimageOutput);
|
|
||||||
|
|
||||||
if (t->exception) {
|
if (t->exception) {
|
||||||
printTrace(t, t->exception);
|
printTrace(t, t->exception);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2010, Avian Contributors
|
/* Copyright (c) 2008-2011, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
186
src/builtin.cpp
186
src/builtin.cpp
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2011, Avian Contributors
|
/* Copyright (c) 2008-2012, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
@ -327,3 +327,187 @@ Avian_avian_Singleton_getLong
|
|||||||
(t, reinterpret_cast<object>(arguments[0]), arguments[1]), 8);
|
(t, reinterpret_cast<object>(arguments[0]), arguments[1]), 8);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT int64_t JNICALL
|
||||||
|
Avian_sun_misc_Unsafe_allocateMemory
|
||||||
|
(Thread* t, object, uintptr_t* arguments)
|
||||||
|
{
|
||||||
|
int64_t size; memcpy(&size, arguments + 1, 8);
|
||||||
|
void* p = malloc(size);
|
||||||
|
if (p) {
|
||||||
|
return reinterpret_cast<int64_t>(p);
|
||||||
|
} else {
|
||||||
|
throwNew(t, Machine::OutOfMemoryErrorType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT void JNICALL
|
||||||
|
Avian_sun_misc_Unsafe_freeMemory
|
||||||
|
(Thread*, object, uintptr_t* arguments)
|
||||||
|
{
|
||||||
|
int64_t p; memcpy(&p, arguments + 1, 8);
|
||||||
|
if (p) {
|
||||||
|
free(reinterpret_cast<void*>(p));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT void JNICALL
|
||||||
|
Avian_sun_misc_Unsafe_setMemory
|
||||||
|
(Thread* t, object, uintptr_t* arguments)
|
||||||
|
{
|
||||||
|
object base = reinterpret_cast<object>(arguments[1]);
|
||||||
|
int64_t offset; memcpy(&offset, arguments + 2, 8);
|
||||||
|
int64_t count; memcpy(&count, arguments + 4, 8);
|
||||||
|
int8_t value = arguments[6];
|
||||||
|
|
||||||
|
PROTECT(t, base);
|
||||||
|
|
||||||
|
ACQUIRE(t, t->m->referenceLock);
|
||||||
|
|
||||||
|
if (base) {
|
||||||
|
memset(&cast<int8_t>(base, offset), value, count);
|
||||||
|
} else {
|
||||||
|
memset(reinterpret_cast<int8_t*>(offset), value, count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NB: The following primitive get/put methods are only used by the
|
||||||
|
// interpreter. The JIT/AOT compiler implements them as intrinsics,
|
||||||
|
// so these versions will be ignored.
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT void JNICALL
|
||||||
|
Avian_sun_misc_Unsafe_putByte__JB
|
||||||
|
(Thread*, object, uintptr_t* arguments)
|
||||||
|
{
|
||||||
|
int64_t p; memcpy(&p, arguments + 1, 8);
|
||||||
|
int8_t v = arguments[3];
|
||||||
|
|
||||||
|
*reinterpret_cast<int8_t*>(p) = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT void JNICALL
|
||||||
|
Avian_sun_misc_Unsafe_putShort__JS
|
||||||
|
(Thread*, object, uintptr_t* arguments)
|
||||||
|
{
|
||||||
|
int64_t p; memcpy(&p, arguments + 1, 8);
|
||||||
|
int16_t v = arguments[3];
|
||||||
|
|
||||||
|
*reinterpret_cast<int16_t*>(p) = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT void JNICALL
|
||||||
|
Avian_sun_misc_Unsafe_putChar__JC
|
||||||
|
(Thread* t, object method, uintptr_t* arguments)
|
||||||
|
{
|
||||||
|
Avian_sun_misc_Unsafe_putShort__JS(t, method, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT void JNICALL
|
||||||
|
Avian_sun_misc_Unsafe_putInt__JI
|
||||||
|
(Thread*, object, uintptr_t* arguments)
|
||||||
|
{
|
||||||
|
int64_t p; memcpy(&p, arguments + 1, 8);
|
||||||
|
int32_t v = arguments[3];
|
||||||
|
|
||||||
|
*reinterpret_cast<int32_t*>(p) = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT void JNICALL
|
||||||
|
Avian_sun_misc_Unsafe_putFloat__JF
|
||||||
|
(Thread* t, object method, uintptr_t* arguments)
|
||||||
|
{
|
||||||
|
Avian_sun_misc_Unsafe_putInt__JI(t, method, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT void JNICALL
|
||||||
|
Avian_sun_misc_Unsafe_putLong__JJ
|
||||||
|
(Thread*, object, uintptr_t* arguments)
|
||||||
|
{
|
||||||
|
int64_t p; memcpy(&p, arguments + 1, 8);
|
||||||
|
int64_t v; memcpy(&v, arguments + 3, 8);
|
||||||
|
|
||||||
|
*reinterpret_cast<int64_t*>(p) = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT void JNICALL
|
||||||
|
Avian_sun_misc_Unsafe_putDouble__JD
|
||||||
|
(Thread* t, object method, uintptr_t* arguments)
|
||||||
|
{
|
||||||
|
Avian_sun_misc_Unsafe_putLong__JJ(t, method, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT void JNICALL
|
||||||
|
Avian_sun_misc_Unsafe_putAddress__JJ
|
||||||
|
(Thread*, object, uintptr_t* arguments)
|
||||||
|
{
|
||||||
|
int64_t p; memcpy(&p, arguments + 1, 8);
|
||||||
|
int64_t v; memcpy(&v, arguments + 3, 8);
|
||||||
|
|
||||||
|
*reinterpret_cast<intptr_t*>(p) = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT int64_t JNICALL
|
||||||
|
Avian_sun_misc_Unsafe_getByte__J
|
||||||
|
(Thread*, object, uintptr_t* arguments)
|
||||||
|
{
|
||||||
|
int64_t p; memcpy(&p, arguments + 1, 8);
|
||||||
|
|
||||||
|
return *reinterpret_cast<int8_t*>(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT int64_t JNICALL
|
||||||
|
Avian_sun_misc_Unsafe_getShort__J
|
||||||
|
(Thread*, object, uintptr_t* arguments)
|
||||||
|
{
|
||||||
|
int64_t p; memcpy(&p, arguments + 1, 8);
|
||||||
|
|
||||||
|
return *reinterpret_cast<int16_t*>(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT int64_t JNICALL
|
||||||
|
Avian_sun_misc_Unsafe_getChar__J
|
||||||
|
(Thread* t, object method, uintptr_t* arguments)
|
||||||
|
{
|
||||||
|
return Avian_sun_misc_Unsafe_getShort__J(t, method, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT int64_t JNICALL
|
||||||
|
Avian_sun_misc_Unsafe_getInt__J
|
||||||
|
(Thread*, object, uintptr_t* arguments)
|
||||||
|
{
|
||||||
|
int64_t p; memcpy(&p, arguments + 1, 8);
|
||||||
|
|
||||||
|
return *reinterpret_cast<int32_t*>(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT int64_t JNICALL
|
||||||
|
Avian_sun_misc_Unsafe_getFloat__J
|
||||||
|
(Thread* t, object method, uintptr_t* arguments)
|
||||||
|
{
|
||||||
|
return Avian_sun_misc_Unsafe_getInt__J(t, method, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT int64_t JNICALL
|
||||||
|
Avian_sun_misc_Unsafe_getLong__J
|
||||||
|
(Thread*, object, uintptr_t* arguments)
|
||||||
|
{
|
||||||
|
int64_t p; memcpy(&p, arguments + 1, 8);
|
||||||
|
|
||||||
|
return *reinterpret_cast<int64_t*>(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT int64_t JNICALL
|
||||||
|
Avian_sun_misc_Unsafe_getDouble__J
|
||||||
|
(Thread* t, object method, uintptr_t* arguments)
|
||||||
|
{
|
||||||
|
return Avian_sun_misc_Unsafe_getLong__J(t, method, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT int64_t JNICALL
|
||||||
|
Avian_sun_misc_Unsafe_getAddress__J
|
||||||
|
(Thread*, object, uintptr_t* arguments)
|
||||||
|
{
|
||||||
|
int64_t p; memcpy(&p, arguments + 1, 8);
|
||||||
|
|
||||||
|
return *reinterpret_cast<intptr_t*>(p);
|
||||||
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2010-2011, Avian Contributors
|
/* Copyright (c) 2010-2012, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
@ -54,6 +54,12 @@ class MyClasspath : public Classpath {
|
|||||||
root(t, Machine::BootLoader), 0, 0, group, 0);
|
root(t, Machine::BootLoader), 0, 0, group, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void
|
||||||
|
clearInterrupted(Thread*)
|
||||||
|
{
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
virtual void
|
virtual void
|
||||||
runThread(Thread* t)
|
runThread(Thread* t)
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2010-2011, Avian Contributors
|
/* Copyright (c) 2010-2012, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
@ -120,6 +120,16 @@ void
|
|||||||
runOnLoadIfFound(Thread* t, System::Library* library)
|
runOnLoadIfFound(Thread* t, System::Library* library)
|
||||||
{
|
{
|
||||||
void* p = library->resolve("JNI_OnLoad");
|
void* p = library->resolve("JNI_OnLoad");
|
||||||
|
|
||||||
|
#ifdef PLATFORM_WINDOWS
|
||||||
|
if (p == 0) {
|
||||||
|
p = library->resolve("_JNI_OnLoad@8");
|
||||||
|
if (p == 0) {
|
||||||
|
p = library->resolve("JNI_OnLoad@8");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (p) {
|
if (p) {
|
||||||
jint (JNICALL * JNI_OnLoad)(Machine*, void*);
|
jint (JNICALL * JNI_OnLoad)(Machine*, void*);
|
||||||
memcpy(&JNI_OnLoad, &p, sizeof(void*));
|
memcpy(&JNI_OnLoad, &p, sizeof(void*));
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2010-2011, Avian Contributors
|
/* Copyright (c) 2010-2012, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
@ -42,7 +42,6 @@
|
|||||||
# define S_IWUSR _S_IWRITE
|
# define S_IWUSR _S_IWRITE
|
||||||
# else
|
# else
|
||||||
# define OPEN _open
|
# define OPEN _open
|
||||||
# define CREAT _creat
|
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# define O_RDONLY _O_RDONLY
|
# define O_RDONLY _O_RDONLY
|
||||||
@ -82,6 +81,8 @@ typedef int socklen_t;
|
|||||||
|
|
||||||
#endif // not PLATFORM_WINDOWS
|
#endif // not PLATFORM_WINDOWS
|
||||||
|
|
||||||
|
#define JVM_EEXIST -100
|
||||||
|
|
||||||
using namespace vm;
|
using namespace vm;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -97,12 +98,6 @@ OPEN(string_t path, int mask, int mode)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int
|
|
||||||
CREAT(string_t path, int mode)
|
|
||||||
{
|
|
||||||
return OPEN(path, _O_CREAT, mode);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace local {
|
namespace local {
|
||||||
@ -349,6 +344,9 @@ makeClassNameString(Thread* t, object name)
|
|||||||
void
|
void
|
||||||
interceptFileOperations(Thread*);
|
interceptFileOperations(Thread*);
|
||||||
|
|
||||||
|
void
|
||||||
|
clearInterrupted(Thread*);
|
||||||
|
|
||||||
class MyClasspath : public Classpath {
|
class MyClasspath : public Classpath {
|
||||||
public:
|
public:
|
||||||
static const unsigned BufferSize = 1024;
|
static const unsigned BufferSize = 1024;
|
||||||
@ -415,6 +413,8 @@ class MyClasspath : public Classpath {
|
|||||||
sb.append(javaHome);
|
sb.append(javaHome);
|
||||||
#ifdef PLATFORM_WINDOWS
|
#ifdef PLATFORM_WINDOWS
|
||||||
sb.append("/bin");
|
sb.append("/bin");
|
||||||
|
#elif defined __APPLE__
|
||||||
|
sb.append("/lib");
|
||||||
#elif defined ARCH_x86_64
|
#elif defined ARCH_x86_64
|
||||||
sb.append("/lib/amd64");
|
sb.append("/lib/amd64");
|
||||||
#else
|
#else
|
||||||
@ -440,9 +440,14 @@ class MyClasspath : public Classpath {
|
|||||||
PROTECT(t, class_);
|
PROTECT(t, class_);
|
||||||
|
|
||||||
object name = makeClassNameString(t, getClassName(t, class_));
|
object name = makeClassNameString(t, getClassName(t, class_));
|
||||||
|
PROTECT(t, name);
|
||||||
|
|
||||||
return vm::makeJclass
|
object c = allocate(t, FixedSizeOfJclass, true);
|
||||||
(t, 0, 0, name, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, class_);
|
setObjectClass(t, c, type(t, Machine::JclassType));
|
||||||
|
set(t, c, JclassName, name);
|
||||||
|
set(t, c, JclassVmClass, class_);
|
||||||
|
|
||||||
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual object
|
virtual object
|
||||||
@ -504,6 +509,12 @@ class MyClasspath : public Classpath {
|
|||||||
return thread;
|
return thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void
|
||||||
|
clearInterrupted(Thread* t)
|
||||||
|
{
|
||||||
|
local::clearInterrupted(t);
|
||||||
|
}
|
||||||
|
|
||||||
virtual void
|
virtual void
|
||||||
runThread(Thread* t)
|
runThread(Thread* t)
|
||||||
{
|
{
|
||||||
@ -551,31 +562,61 @@ class MyClasspath : public Classpath {
|
|||||||
expect(t, loadLibrary(t, libraryPath, "java", true, true));
|
expect(t, loadLibrary(t, libraryPath, "java", true, true));
|
||||||
#endif // not AVIAN_OPENJDK_SRC
|
#endif // not AVIAN_OPENJDK_SRC
|
||||||
|
|
||||||
object constructor = resolveMethod
|
{ object class_ = resolveClass
|
||||||
|
(t, root(t, Machine::BootLoader), "java/util/Properties", true,
|
||||||
|
Machine::NoClassDefFoundErrorType);
|
||||||
|
|
||||||
|
PROTECT(t, class_);
|
||||||
|
|
||||||
|
object instance = makeNew(t, class_);
|
||||||
|
|
||||||
|
PROTECT(t, instance);
|
||||||
|
|
||||||
|
object constructor = resolveMethod(t, class_, "<init>", "()V");
|
||||||
|
|
||||||
|
t->m->processor->invoke(t, constructor, instance);
|
||||||
|
|
||||||
|
t->m->processor->invoke
|
||||||
|
(t, root(t, Machine::BootLoader), "java/lang/System",
|
||||||
|
"setProperties", "(Ljava/util/Properties;)V", 0, instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
{ object constructor = resolveMethod
|
||||||
(t, type(t, Machine::ClassLoaderType), "<init>",
|
(t, type(t, Machine::ClassLoaderType), "<init>",
|
||||||
"(Ljava/lang/ClassLoader;)V");
|
"(Ljava/lang/ClassLoader;)V");
|
||||||
|
|
||||||
PROTECT(t, constructor);
|
PROTECT(t, constructor);
|
||||||
|
|
||||||
t->m->processor->invoke(t, constructor, root(t, Machine::BootLoader), 0);
|
t->m->processor->invoke(t, constructor, root(t, Machine::BootLoader), 0);
|
||||||
|
|
||||||
t->m->processor->invoke
|
t->m->processor->invoke
|
||||||
(t, constructor, root(t, Machine::AppLoader),
|
(t, constructor, root(t, Machine::AppLoader),
|
||||||
root(t, Machine::BootLoader));
|
root(t, Machine::BootLoader));
|
||||||
|
}
|
||||||
|
|
||||||
object scl = resolveField
|
{ object assertionLock = resolveField
|
||||||
(t, type(t, Machine::ClassLoaderType), "scl", "Ljava/lang/ClassLoader;");
|
(t, type(t, Machine::ClassLoaderType), "assertionLock",
|
||||||
|
"Ljava/lang/Object;");
|
||||||
|
|
||||||
PROTECT(t, scl);
|
set(t, root(t, Machine::BootLoader), fieldOffset(t, assertionLock),
|
||||||
|
root(t, Machine::BootLoader));
|
||||||
|
}
|
||||||
|
|
||||||
object sclSet = resolveField
|
{ object scl = resolveField
|
||||||
(t, type(t, Machine::ClassLoaderType), "sclSet", "Z");
|
(t, type(t, Machine::ClassLoaderType), "scl",
|
||||||
|
"Ljava/lang/ClassLoader;");
|
||||||
|
|
||||||
set(t, classStaticTable(t, type(t, Machine::ClassLoaderType)),
|
PROTECT(t, scl);
|
||||||
fieldOffset(t, scl), root(t, Machine::AppLoader));
|
|
||||||
|
|
||||||
cast<uint8_t>(classStaticTable(t, type(t, Machine::ClassLoaderType)),
|
object sclSet = resolveField
|
||||||
fieldOffset(t, sclSet)) = true;
|
(t, type(t, Machine::ClassLoaderType), "sclSet", "Z");
|
||||||
|
|
||||||
|
set(t, classStaticTable(t, type(t, Machine::ClassLoaderType)),
|
||||||
|
fieldOffset(t, scl), root(t, Machine::AppLoader));
|
||||||
|
|
||||||
|
cast<uint8_t>(classStaticTable(t, type(t, Machine::ClassLoaderType)),
|
||||||
|
fieldOffset(t, sclSet)) = true;
|
||||||
|
}
|
||||||
|
|
||||||
t->m->processor->invoke
|
t->m->processor->invoke
|
||||||
(t, root(t, Machine::BootLoader), "java/lang/System",
|
(t, root(t, Machine::BootLoader), "java/lang/System",
|
||||||
@ -1318,15 +1359,17 @@ getZipFileEntry(Thread* t, object method, uintptr_t* arguments)
|
|||||||
|
|
||||||
ZipFile* file = reinterpret_cast<ZipFile*>(peer);
|
ZipFile* file = reinterpret_cast<ZipFile*>(peer);
|
||||||
if (file->region) {
|
if (file->region) {
|
||||||
THREAD_RUNTIME_ARRAY(t, char, p, stringLength(t, path) + 2);
|
THREAD_RUNTIME_ARRAY(t, char, p, byteArrayLength(t, path) + 2);
|
||||||
stringChars(t, path, RUNTIME_ARRAY_BODY(p));
|
memcpy(RUNTIME_ARRAY_BODY(p), &byteArrayBody(t, path, 0),
|
||||||
|
byteArrayLength(t, path));
|
||||||
|
RUNTIME_ARRAY_BODY(p)[byteArrayLength(t, path)] = 0;
|
||||||
replace('\\', '/', RUNTIME_ARRAY_BODY(p));
|
replace('\\', '/', RUNTIME_ARRAY_BODY(p));
|
||||||
if (addSlash) {
|
if (addSlash) {
|
||||||
RUNTIME_ARRAY_BODY(p)[stringLength(t, path)] = '/';
|
RUNTIME_ARRAY_BODY(p)[byteArrayLength(t, path)] = '/';
|
||||||
RUNTIME_ARRAY_BODY(p)[stringLength(t, path) + 1] = 0;
|
RUNTIME_ARRAY_BODY(p)[byteArrayLength(t, path) + 1] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return reinterpret_cast<int64_t>(find(file, p, stringLength(t, path)));
|
return reinterpret_cast<int64_t>(find(file, p, byteArrayLength(t, path)));
|
||||||
} else {
|
} else {
|
||||||
int64_t entry = longValue
|
int64_t entry = longValue
|
||||||
(t, t->m->processor->invoke
|
(t, t->m->processor->invoke
|
||||||
@ -1340,6 +1383,43 @@ getZipFileEntry(Thread* t, object method, uintptr_t* arguments)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int64_t JNICALL
|
||||||
|
getZipFileEntryBytes(Thread* t, object method, uintptr_t* arguments)
|
||||||
|
{
|
||||||
|
int64_t peer; memcpy(&peer, arguments, 8);
|
||||||
|
int type = arguments[2];
|
||||||
|
|
||||||
|
ZipFile::Entry* entry = reinterpret_cast<ZipFile::Entry*>(peer);
|
||||||
|
if (entry->start) {
|
||||||
|
switch (type) {
|
||||||
|
case 0: { // name
|
||||||
|
unsigned nameLength = fileNameLength(entry->start);
|
||||||
|
object array = makeByteArray(t, nameLength + 1);
|
||||||
|
memcpy(&byteArrayBody(t, array, 0), fileName(entry->start), nameLength);
|
||||||
|
byteArrayBody(t, array, nameLength) = 0;
|
||||||
|
return reinterpret_cast<int64_t>(array);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case 1: { // extra
|
||||||
|
return 0;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case 2: { // comment
|
||||||
|
return 0;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
default: abort(t);
|
||||||
|
}
|
||||||
|
return compressedSize(entry->start);
|
||||||
|
} else {
|
||||||
|
return reinterpret_cast<int64_t>
|
||||||
|
(t->m->processor->invoke
|
||||||
|
(t, nativeInterceptOriginal
|
||||||
|
(t, methodRuntimeDataNative(t, getMethodRuntimeData(t, method))),
|
||||||
|
0, entry->entry, type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int64_t JNICALL
|
int64_t JNICALL
|
||||||
getNextZipFileEntry(Thread* t, object method, uintptr_t* arguments)
|
getNextZipFileEntry(Thread* t, object method, uintptr_t* arguments)
|
||||||
{
|
{
|
||||||
@ -1467,6 +1547,8 @@ freeZipFileEntry(Thread* t, object method, uintptr_t* arguments)
|
|||||||
(t, methodRuntimeDataNative(t, getMethodRuntimeData(t, method))),
|
(t, methodRuntimeDataNative(t, getMethodRuntimeData(t, method))),
|
||||||
0, file->file, entry->entry);
|
0, file->file, entry->entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t->m->heap->free(entry, sizeof(ZipFile::Entry));
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t JNICALL
|
int64_t JNICALL
|
||||||
@ -1674,7 +1756,7 @@ loadLibrary(Thread* t, object, uintptr_t* arguments)
|
|||||||
|
|
||||||
loadLibrary
|
loadLibrary
|
||||||
(t, static_cast<local::MyClasspath*>(t->m->classpath)->libraryPath,
|
(t, static_cast<local::MyClasspath*>(t->m->classpath)->libraryPath,
|
||||||
RUNTIME_ARRAY_BODY(n), not absolute, false);
|
RUNTIME_ARRAY_BODY(n), not absolute, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// only safe to call during bootstrap when there's only one thread
|
// only safe to call during bootstrap when there's only one thread
|
||||||
@ -1703,6 +1785,15 @@ intercept(Thread* t, object c, const char* name, const char* spec,
|
|||||||
object runtimeData = getMethodRuntimeData(t, m);
|
object runtimeData = getMethodRuntimeData(t, m);
|
||||||
|
|
||||||
set(t, runtimeData, MethodRuntimeDataNative, native);
|
set(t, runtimeData, MethodRuntimeDataNative, native);
|
||||||
|
} else {
|
||||||
|
// If we can't find the method, just ignore it, since ProGuard may
|
||||||
|
// have stripped it out as unused. Otherwise, the code below can
|
||||||
|
// be uncommented for debugging purposes.
|
||||||
|
|
||||||
|
// fprintf(stderr, "unable to find %s%s in %s\n",
|
||||||
|
// name, spec, &byteArrayBody(t, className(t, c), 0));
|
||||||
|
|
||||||
|
// abort(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1770,60 +1861,6 @@ interceptFileOperations(Thread* t)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{ object zipEntryClass = resolveClass
|
|
||||||
(t, root(t, Machine::BootLoader), "java/util/zip/ZipEntry", false);
|
|
||||||
|
|
||||||
if (zipEntryClass) {
|
|
||||||
PROTECT(t, zipEntryClass);
|
|
||||||
|
|
||||||
object zipEntryNameField = findFieldInClass2
|
|
||||||
(t, zipEntryClass, "name", "Ljava/lang/String;");
|
|
||||||
|
|
||||||
if (zipEntryNameField) {
|
|
||||||
cp->zipEntryNameField = fieldOffset(t, zipEntryNameField);
|
|
||||||
|
|
||||||
object zipEntryTimeField = findFieldInClass2
|
|
||||||
(t, zipEntryClass, "time", "J");
|
|
||||||
|
|
||||||
if (zipEntryTimeField) {
|
|
||||||
cp->zipEntryTimeField = fieldOffset(t, zipEntryTimeField);
|
|
||||||
|
|
||||||
object zipEntryCrcField = findFieldInClass2
|
|
||||||
(t, zipEntryClass, "crc", "J");
|
|
||||||
|
|
||||||
if (zipEntryCrcField) {
|
|
||||||
cp->zipEntryCrcField = fieldOffset(t, zipEntryCrcField);
|
|
||||||
|
|
||||||
object zipEntrySizeField = findFieldInClass2
|
|
||||||
(t, zipEntryClass, "size", "J");
|
|
||||||
|
|
||||||
if (zipEntrySizeField) {
|
|
||||||
cp->zipEntrySizeField = fieldOffset(t, zipEntrySizeField);
|
|
||||||
|
|
||||||
object zipEntryCsizeField = findFieldInClass2
|
|
||||||
(t, zipEntryClass, "csize", "J");
|
|
||||||
|
|
||||||
if (zipEntryCsizeField) {
|
|
||||||
cp->zipEntryCsizeField = fieldOffset(t, zipEntryCsizeField);
|
|
||||||
|
|
||||||
object zipEntryMethodField = findFieldInClass2
|
|
||||||
(t, zipEntryClass, "method", "I");
|
|
||||||
|
|
||||||
if (zipEntryMethodField) {
|
|
||||||
cp->zipEntryMethodField = fieldOffset
|
|
||||||
(t, zipEntryMethodField);
|
|
||||||
|
|
||||||
intercept(t, zipEntryClass, "initFields", "(J)V",
|
|
||||||
voidPointer(initializeZipEntryFields));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{ object zipFileClass = resolveClass
|
{ object zipFileClass = resolveClass
|
||||||
(t, root(t, Machine::BootLoader), "java/util/zip/ZipFile", false);
|
(t, root(t, Machine::BootLoader), "java/util/zip/ZipFile", false);
|
||||||
|
|
||||||
@ -1836,19 +1873,22 @@ interceptFileOperations(Thread* t)
|
|||||||
if (zipFileJzfileField) {
|
if (zipFileJzfileField) {
|
||||||
cp->zipFileJzfileField = fieldOffset(t, zipFileJzfileField);
|
cp->zipFileJzfileField = fieldOffset(t, zipFileJzfileField);
|
||||||
|
|
||||||
intercept(t, zipFileClass, "open", "(Ljava/lang/String;IJ)J",
|
intercept(t, zipFileClass, "open", "(Ljava/lang/String;IJZ)J",
|
||||||
voidPointer(openZipFile));
|
voidPointer(openZipFile));
|
||||||
|
|
||||||
intercept(t, zipFileClass, "getTotal", "(J)I",
|
intercept(t, zipFileClass, "getTotal", "(J)I",
|
||||||
voidPointer(getZipFileEntryCount));
|
voidPointer(getZipFileEntryCount));
|
||||||
|
|
||||||
intercept(t, zipFileClass, "getEntry", "(JLjava/lang/String;Z)J",
|
intercept(t, zipFileClass, "getEntry", "(J[BZ)J",
|
||||||
voidPointer(getZipFileEntry));
|
voidPointer(getZipFileEntry));
|
||||||
|
|
||||||
|
intercept(t, zipFileClass, "getEntryBytes", "(JI)[B",
|
||||||
|
voidPointer(getZipFileEntryBytes));
|
||||||
|
|
||||||
intercept(t, zipFileClass, "getNextEntry", "(JI)J",
|
intercept(t, zipFileClass, "getNextEntry", "(JI)J",
|
||||||
voidPointer(getNextZipFileEntry));
|
voidPointer(getNextZipFileEntry));
|
||||||
|
|
||||||
intercept(t, zipFileClass, "getMethod", "(J)I",
|
intercept(t, zipFileClass, "getEntryMethod", "(J)I",
|
||||||
voidPointer(getZipFileEntryMethod));
|
voidPointer(getZipFileEntryMethod));
|
||||||
|
|
||||||
intercept(t, zipFileClass, "freeEntry", "(JJ)V",
|
intercept(t, zipFileClass, "freeEntry", "(JJ)V",
|
||||||
@ -1857,10 +1897,10 @@ interceptFileOperations(Thread* t)
|
|||||||
intercept(t, zipFileClass, "read", "(JJJ[BII)I",
|
intercept(t, zipFileClass, "read", "(JJJ[BII)I",
|
||||||
voidPointer(readZipFileEntry));
|
voidPointer(readZipFileEntry));
|
||||||
|
|
||||||
intercept(t, zipFileClass, "getCSize", "(J)J",
|
intercept(t, zipFileClass, "getEntryCSize", "(J)J",
|
||||||
voidPointer(getZipFileEntryCompressedSize));
|
voidPointer(getZipFileEntryCompressedSize));
|
||||||
|
|
||||||
intercept(t, zipFileClass, "getSize", "(J)J",
|
intercept(t, zipFileClass, "getEntrySize", "(J)J",
|
||||||
voidPointer(getZipFileEntryUncompressedSize));
|
voidPointer(getZipFileEntryUncompressedSize));
|
||||||
|
|
||||||
intercept(t, zipFileClass, "getZipMessage", "(J)Ljava/lang/String;",
|
intercept(t, zipFileClass, "getZipMessage", "(J)Ljava/lang/String;",
|
||||||
@ -2181,6 +2221,14 @@ interruptLock(Thread* t, object thread)
|
|||||||
return threadInterruptLock(t, thread);
|
return threadInterruptLock(t, thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
clearInterrupted(Thread* t)
|
||||||
|
{
|
||||||
|
monitorAcquire(t, local::interruptLock(t, t->javaThread));
|
||||||
|
threadInterrupted(t, t->javaThread) = false;
|
||||||
|
monitorRelease(t, local::interruptLock(t, t->javaThread));
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
pipeAvailable(int fd, int* available)
|
pipeAvailable(int fd, int* available)
|
||||||
{
|
{
|
||||||
@ -2207,19 +2255,40 @@ pipeAvailable(int fd, int* available)
|
|||||||
}
|
}
|
||||||
|
|
||||||
object
|
object
|
||||||
fieldForOffset(Thread* t, object o, unsigned offset)
|
fieldForOffsetInClass(Thread* t, object c, unsigned offset)
|
||||||
{
|
{
|
||||||
object table = classFieldTable(t, objectClass(t, o));
|
object super = classSuper(t, c);
|
||||||
for (unsigned i = 0; i < objectArrayLength(t, table); ++i) {
|
if (super) {
|
||||||
object field = objectArrayBody(t, table, i);
|
object field = fieldForOffsetInClass(t, super, offset);
|
||||||
if ((fieldFlags(t, field) & ACC_STATIC) == 0
|
if (field) {
|
||||||
and fieldOffset(t, field) == offset)
|
|
||||||
{
|
|
||||||
return field;
|
return field;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abort(t);
|
object table = classFieldTable(t, c);
|
||||||
|
if (table) {
|
||||||
|
for (unsigned i = 0; i < objectArrayLength(t, table); ++i) {
|
||||||
|
object field = objectArrayBody(t, table, i);
|
||||||
|
if ((fieldFlags(t, field) & ACC_STATIC) == 0
|
||||||
|
and fieldOffset(t, field) == offset)
|
||||||
|
{
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
object
|
||||||
|
fieldForOffset(Thread* t, object o, unsigned offset)
|
||||||
|
{
|
||||||
|
object field = fieldForOffsetInClass(t, objectClass(t, o), offset);
|
||||||
|
if (field) {
|
||||||
|
return field;
|
||||||
|
} else {
|
||||||
|
abort(t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace local
|
} // namespace local
|
||||||
@ -2255,6 +2324,24 @@ Avian_sun_misc_Unsafe_registerNatives
|
|||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT void
|
||||||
|
Avian_sun_misc_Perf_registerNatives
|
||||||
|
(Thread*, object, uintptr_t*)
|
||||||
|
{
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT int64_t
|
||||||
|
Avian_sun_misc_Perf_createLong
|
||||||
|
(Thread* t, object, uintptr_t*)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<int64_t>
|
||||||
|
(t->m->processor->invoke
|
||||||
|
(t, resolveMethod
|
||||||
|
(t, root(t, Machine::BootLoader), "java/nio/ByteBuffer", "allocate",
|
||||||
|
"(I)Ljava/nio/ByteBuffer;"), 0, 8));
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT int64_t
|
extern "C" JNIEXPORT int64_t
|
||||||
Avian_sun_misc_Unsafe_addressSize
|
Avian_sun_misc_Unsafe_addressSize
|
||||||
(Thread*, object, uintptr_t*)
|
(Thread*, object, uintptr_t*)
|
||||||
@ -2504,13 +2591,20 @@ Avian_sun_misc_Unsafe_putFloat__Ljava_lang_Object_2JF
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT int64_t JNICALL
|
extern "C" JNIEXPORT int64_t JNICALL
|
||||||
Avian_sun_misc_Unsafe_getBoolean
|
Avian_sun_misc_Unsafe_getByte
|
||||||
(Thread*, object, uintptr_t* arguments)
|
(Thread*, object, uintptr_t* arguments)
|
||||||
{
|
{
|
||||||
object o = reinterpret_cast<object>(arguments[1]);
|
object o = reinterpret_cast<object>(arguments[1]);
|
||||||
int64_t offset; memcpy(&offset, arguments + 2, 8);
|
int64_t offset; memcpy(&offset, arguments + 2, 8);
|
||||||
|
|
||||||
return cast<uint8_t>(o, offset);
|
return cast<int8_t>(o, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT int64_t JNICALL
|
||||||
|
Avian_sun_misc_Unsafe_getBoolean
|
||||||
|
(Thread* t, object method, uintptr_t* arguments)
|
||||||
|
{
|
||||||
|
return Avian_sun_misc_Unsafe_getByte(t, method, arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
extern "C" JNIEXPORT void JNICALL
|
||||||
@ -2560,6 +2654,13 @@ Avian_sun_misc_Unsafe_putObjectVolatile
|
|||||||
storeLoadMemoryBarrier();
|
storeLoadMemoryBarrier();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT void JNICALL
|
||||||
|
Avian_sun_misc_Unsafe_putOrderedObject
|
||||||
|
(Thread* t, object method, uintptr_t* arguments)
|
||||||
|
{
|
||||||
|
Avian_sun_misc_Unsafe_putObjectVolatile(t, method, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT int64_t JNICALL
|
extern "C" JNIEXPORT int64_t JNICALL
|
||||||
Avian_sun_misc_Unsafe_compareAndSwapInt
|
Avian_sun_misc_Unsafe_compareAndSwapInt
|
||||||
(Thread*, object, uintptr_t* arguments)
|
(Thread*, object, uintptr_t* arguments)
|
||||||
@ -2615,115 +2716,6 @@ Avian_sun_misc_Unsafe_compareAndSwapLong
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT int64_t JNICALL
|
|
||||||
Avian_sun_misc_Unsafe_allocateMemory
|
|
||||||
(Thread* t, object, uintptr_t* arguments)
|
|
||||||
{
|
|
||||||
void* p = malloc(arguments[1]);
|
|
||||||
if (p) {
|
|
||||||
return reinterpret_cast<int64_t>(p);
|
|
||||||
} else {
|
|
||||||
throwNew(t, Machine::OutOfMemoryErrorType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
|
||||||
Avian_sun_misc_Unsafe_freeMemory
|
|
||||||
(Thread*, object, uintptr_t* arguments)
|
|
||||||
{
|
|
||||||
void* p = reinterpret_cast<void*>(arguments[1]);
|
|
||||||
if (p) {
|
|
||||||
free(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
|
||||||
Avian_sun_misc_Unsafe_setMemory
|
|
||||||
(Thread*, object, uintptr_t* arguments)
|
|
||||||
{
|
|
||||||
int64_t p; memcpy(&p, arguments + 1, 8);
|
|
||||||
int64_t count; memcpy(&count, arguments + 3, 8);
|
|
||||||
int8_t v = arguments[5];
|
|
||||||
|
|
||||||
memset(reinterpret_cast<int8_t*>(p), v, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
|
||||||
Avian_sun_misc_Unsafe_putByte__JB
|
|
||||||
(Thread*, object, uintptr_t* arguments)
|
|
||||||
{
|
|
||||||
int64_t p; memcpy(&p, arguments + 1, 8);
|
|
||||||
int8_t v = arguments[3];
|
|
||||||
|
|
||||||
*reinterpret_cast<int8_t*>(p) = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
|
||||||
Avian_sun_misc_Unsafe_putShort__JS
|
|
||||||
(Thread*, object, uintptr_t* arguments)
|
|
||||||
{
|
|
||||||
int64_t p; memcpy(&p, arguments + 1, 8);
|
|
||||||
int16_t v = arguments[3];
|
|
||||||
|
|
||||||
*reinterpret_cast<int16_t*>(p) = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
|
||||||
Avian_sun_misc_Unsafe_putLong__JJ
|
|
||||||
(Thread*, object, uintptr_t* arguments)
|
|
||||||
{
|
|
||||||
int64_t p; memcpy(&p, arguments + 1, 8);
|
|
||||||
int64_t v; memcpy(&v, arguments + 3, 8);
|
|
||||||
|
|
||||||
*reinterpret_cast<int64_t*>(p) = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
|
||||||
Avian_sun_misc_Unsafe_putInt__JI
|
|
||||||
(Thread*, object, uintptr_t* arguments)
|
|
||||||
{
|
|
||||||
int64_t p; memcpy(&p, arguments + 1, 8);
|
|
||||||
int32_t v = arguments[3];
|
|
||||||
|
|
||||||
*reinterpret_cast<int32_t*>(p) = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT int64_t JNICALL
|
|
||||||
Avian_sun_misc_Unsafe_getByte__J
|
|
||||||
(Thread*, object, uintptr_t* arguments)
|
|
||||||
{
|
|
||||||
int64_t p; memcpy(&p, arguments + 1, 8);
|
|
||||||
|
|
||||||
return *reinterpret_cast<int8_t*>(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT int64_t JNICALL
|
|
||||||
Avian_sun_misc_Unsafe_getInt__J
|
|
||||||
(Thread*, object, uintptr_t* arguments)
|
|
||||||
{
|
|
||||||
int64_t p; memcpy(&p, arguments + 1, 8);
|
|
||||||
|
|
||||||
return *reinterpret_cast<int32_t*>(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT int64_t JNICALL
|
|
||||||
Avian_sun_misc_Unsafe_getLong__J
|
|
||||||
(Thread*, object, uintptr_t* arguments)
|
|
||||||
{
|
|
||||||
int64_t p; memcpy(&p, arguments + 1, 8);
|
|
||||||
|
|
||||||
return *reinterpret_cast<int64_t*>(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT int64_t JNICALL
|
|
||||||
Avian_sun_misc_Unsafe_getFloat__J
|
|
||||||
(Thread*, object, uintptr_t* arguments)
|
|
||||||
{
|
|
||||||
int64_t p; memcpy(&p, arguments + 1, 8);
|
|
||||||
|
|
||||||
return *reinterpret_cast<int32_t*>(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT int64_t JNICALL
|
extern "C" JNIEXPORT int64_t JNICALL
|
||||||
Avian_sun_misc_Unsafe_pageSize
|
Avian_sun_misc_Unsafe_pageSize
|
||||||
(Thread*, object, uintptr_t*)
|
(Thread*, object, uintptr_t*)
|
||||||
@ -2764,12 +2756,15 @@ Avian_sun_misc_Unsafe_park
|
|||||||
if (time <= 0) {
|
if (time <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else if (time) {
|
||||||
time /= 1000 * 1000;
|
// if not absolute, interpret time as nanoseconds, but make sure
|
||||||
|
// it doesn't become zero when we convert to milliseconds, since
|
||||||
|
// zero is interpreted as infinity below
|
||||||
|
time = (time / (1000 * 1000)) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
monitorAcquire(t, local::interruptLock(t, t->javaThread));
|
monitorAcquire(t, local::interruptLock(t, t->javaThread));
|
||||||
while (time > 0
|
while (time >= 0
|
||||||
and (not (threadUnparked(t, t->javaThread)
|
and (not (threadUnparked(t, t->javaThread)
|
||||||
or monitorWait
|
or monitorWait
|
||||||
(t, local::interruptLock(t, t->javaThread), time))))
|
(t, local::interruptLock(t, t->javaThread), time))))
|
||||||
@ -2777,11 +2772,55 @@ Avian_sun_misc_Unsafe_park
|
|||||||
int64_t now = t->m->system->now();
|
int64_t now = t->m->system->now();
|
||||||
time -= now - then;
|
time -= now - then;
|
||||||
then = now;
|
then = now;
|
||||||
|
|
||||||
|
if (time == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
threadUnparked(t, t->javaThread) = false;
|
threadUnparked(t, t->javaThread) = false;
|
||||||
monitorRelease(t, local::interruptLock(t, t->javaThread));
|
monitorRelease(t, local::interruptLock(t, t->javaThread));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT void JNICALL
|
||||||
|
Avian_sun_misc_Unsafe_copyMemory
|
||||||
|
(Thread* t, object, uintptr_t* arguments)
|
||||||
|
{
|
||||||
|
object srcBase = reinterpret_cast<object>(arguments[1]);
|
||||||
|
int64_t srcOffset; memcpy(&srcOffset, arguments + 2, 8);
|
||||||
|
object dstBase = reinterpret_cast<object>(arguments[4]);
|
||||||
|
int64_t dstOffset; memcpy(&dstOffset, arguments + 5, 8);
|
||||||
|
int64_t count; memcpy(&count, arguments + 7, 8);
|
||||||
|
|
||||||
|
PROTECT(t, srcBase);
|
||||||
|
PROTECT(t, dstBase);
|
||||||
|
|
||||||
|
ACQUIRE(t, t->m->referenceLock);
|
||||||
|
|
||||||
|
void* src = srcBase
|
||||||
|
? &cast<uint8_t>(srcBase, srcOffset)
|
||||||
|
: reinterpret_cast<uint8_t*>(srcOffset);
|
||||||
|
|
||||||
|
void* dst = dstBase
|
||||||
|
? &cast<uint8_t>(dstBase, dstOffset)
|
||||||
|
: reinterpret_cast<uint8_t*>(dstOffset);
|
||||||
|
|
||||||
|
memcpy(dst, src, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT void JNICALL
|
||||||
|
Avian_sun_misc_Unsafe_monitorEnter
|
||||||
|
(Thread* t, object, uintptr_t* arguments)
|
||||||
|
{
|
||||||
|
acquire(t, reinterpret_cast<object>(arguments[1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT void JNICALL
|
||||||
|
Avian_sun_misc_Unsafe_monitorExit
|
||||||
|
(Thread* t, object, uintptr_t* arguments)
|
||||||
|
{
|
||||||
|
release(t, reinterpret_cast<object>(arguments[1]));
|
||||||
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
namespace local {
|
namespace local {
|
||||||
@ -2956,22 +2995,22 @@ jvmInitProperties(Thread* t, uintptr_t* arguments)
|
|||||||
GetCurrentDirectory(MAX_PATH, buffer);
|
GetCurrentDirectory(MAX_PATH, buffer);
|
||||||
|
|
||||||
local::setProperty(t, method, *properties, "user.dir", buffer);
|
local::setProperty(t, method, *properties, "user.dir", buffer);
|
||||||
#else
|
#else // not PLATFORM_WINDOWS
|
||||||
local::setProperty(t, method, *properties, "line.separator", "\n");
|
local::setProperty(t, method, *properties, "line.separator", "\n");
|
||||||
local::setProperty(t, method, *properties, "file.separator", "/");
|
local::setProperty(t, method, *properties, "file.separator", "/");
|
||||||
local::setProperty(t, method, *properties, "path.separator", ":");
|
local::setProperty(t, method, *properties, "path.separator", ":");
|
||||||
# ifdef __APPLE__
|
# ifdef __APPLE__
|
||||||
local::setProperty(t, method, *properties, "os.name", "Mac OS X");
|
local::setProperty(t, method, *properties, "os.name", "Mac OS X");
|
||||||
# else
|
# else // not __APPLE__
|
||||||
local::setProperty(t, method, *properties, "os.name", "Linux");
|
local::setProperty(t, method, *properties, "os.name", "Linux");
|
||||||
# endif
|
# endif // not __APPLE__
|
||||||
local::setProperty(t, method, *properties, "java.io.tmpdir", "/tmp");
|
local::setProperty(t, method, *properties, "java.io.tmpdir", "/tmp");
|
||||||
local::setProperty(t, method, *properties, "user.home", getenv("HOME"));
|
local::setProperty(t, method, *properties, "user.home", getenv("HOME"));
|
||||||
|
|
||||||
char buffer[PATH_MAX];
|
char buffer[PATH_MAX];
|
||||||
local::setProperty(t, method, *properties, "user.dir",
|
local::setProperty(t, method, *properties, "user.dir",
|
||||||
getcwd(buffer, PATH_MAX));
|
getcwd(buffer, PATH_MAX));
|
||||||
#endif
|
#endif // not PLATFORM_WINDOWS
|
||||||
|
|
||||||
local::setProperty(t, method, *properties, "java.protocol.handler.pkgs",
|
local::setProperty(t, method, *properties, "java.protocol.handler.pkgs",
|
||||||
"avian");
|
"avian");
|
||||||
@ -2987,6 +3026,11 @@ jvmInitProperties(Thread* t, uintptr_t* arguments)
|
|||||||
(t, method, *properties, "sun.boot.library.path",
|
(t, method, *properties, "sun.boot.library.path",
|
||||||
static_cast<local::MyClasspath*>(t->m->classpath)->libraryPath);
|
static_cast<local::MyClasspath*>(t->m->classpath)->libraryPath);
|
||||||
|
|
||||||
|
local::setProperty
|
||||||
|
(t, method, *properties, "sun.boot.class.path",
|
||||||
|
static_cast<Finder*>
|
||||||
|
(systemClassLoaderFinder(t, root(t, Machine::BootLoader)))->path());
|
||||||
|
|
||||||
local::setProperty(t, method, *properties, "file.encoding", "ASCII");
|
local::setProperty(t, method, *properties, "file.encoding", "ASCII");
|
||||||
#ifdef ARCH_x86_32
|
#ifdef ARCH_x86_32
|
||||||
local::setProperty(t, method, *properties, "os.arch", "x86");
|
local::setProperty(t, method, *properties, "os.arch", "x86");
|
||||||
@ -3153,7 +3197,7 @@ jvmFillInStackTrace(Thread* t, uintptr_t* arguments)
|
|||||||
{
|
{
|
||||||
jobject throwable = reinterpret_cast<jobject>(arguments[0]);
|
jobject throwable = reinterpret_cast<jobject>(arguments[0]);
|
||||||
|
|
||||||
object trace = getTrace(t, 1);
|
object trace = getTrace(t, 2);
|
||||||
set(t, *throwable, ThrowableTrace, trace);
|
set(t, *throwable, ThrowableTrace, trace);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@ -3231,12 +3275,20 @@ EXPORT(JVM_DisableCompiler)(Thread*, jclass)
|
|||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t
|
||||||
|
jvmStartThread(Thread* t, uintptr_t* arguments)
|
||||||
|
{
|
||||||
|
jobject thread = reinterpret_cast<jobject>(arguments[0]);
|
||||||
|
|
||||||
|
return startThread(t, *thread) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
extern "C" JNIEXPORT void JNICALL
|
||||||
EXPORT(JVM_StartThread)(Thread* t, jobject thread)
|
EXPORT(JVM_StartThread)(Thread* t, jobject thread)
|
||||||
{
|
{
|
||||||
ENTER(t, Thread::ActiveState);
|
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(thread) };
|
||||||
|
|
||||||
startThread(t, *thread);
|
run(t, jvmStartThread, arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
extern "C" JNIEXPORT void JNICALL
|
||||||
@ -3315,9 +3367,8 @@ jvmInterrupt(Thread* t, uintptr_t* arguments)
|
|||||||
Thread* p = reinterpret_cast<Thread*>(threadPeer(t, *thread));
|
Thread* p = reinterpret_cast<Thread*>(threadPeer(t, *thread));
|
||||||
if (p) {
|
if (p) {
|
||||||
interrupt(t, p);
|
interrupt(t, p);
|
||||||
} else {
|
|
||||||
threadInterrupted(t, *thread) = true;
|
|
||||||
}
|
}
|
||||||
|
threadInterrupted(t, *thread) = true;
|
||||||
monitorRelease(t, local::interruptLock(t, *thread));
|
monitorRelease(t, local::interruptLock(t, *thread));
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@ -3355,8 +3406,21 @@ EXPORT(JVM_IsInterrupted)(Thread* t, jobject thread, jboolean clear)
|
|||||||
return run(t, jvmIsInterrupted, arguments);
|
return run(t, jvmIsInterrupted, arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t
|
||||||
|
jvmHoldsLock(Thread* t, uintptr_t* arguments)
|
||||||
|
{
|
||||||
|
object m = objectMonitor(t, *reinterpret_cast<jobject>(arguments[0]), false);
|
||||||
|
|
||||||
|
return m and monitorOwner(t, m) == t;
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT jboolean JNICALL
|
extern "C" JNIEXPORT jboolean JNICALL
|
||||||
EXPORT(JVM_HoldsLock)(Thread*, jclass, jobject) { abort(); }
|
EXPORT(JVM_HoldsLock)(Thread* t, jclass, jobject o)
|
||||||
|
{
|
||||||
|
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(o) };
|
||||||
|
|
||||||
|
return run(t, jvmHoldsLock, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
extern "C" JNIEXPORT void JNICALL
|
||||||
EXPORT(JVM_DumpAllStacks)(Thread*, jclass) { abort(); }
|
EXPORT(JVM_DumpAllStacks)(Thread*, jclass) { abort(); }
|
||||||
@ -3826,10 +3890,9 @@ EXPORT(JVM_FindClassFromClassLoader)(Thread* t, const char* name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT jclass JNICALL
|
extern "C" JNIEXPORT jclass JNICALL
|
||||||
EXPORT(JVM_FindClassFromBootLoader)(Thread* t, const char* name,
|
JVM_FindClassFromBootLoader(Thread* t, const char* name)
|
||||||
jboolean throwError)
|
|
||||||
{
|
{
|
||||||
return EXPORT(JVM_FindClassFromClassLoader)(t, name, false, 0, throwError);
|
return EXPORT(JVM_FindClassFromClassLoader)(t, name, false, 0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT jclass JNICALL
|
extern "C" JNIEXPORT jclass JNICALL
|
||||||
@ -4257,9 +4320,9 @@ jvmGetClassDeclaredMethods(Thread* t, uintptr_t* arguments)
|
|||||||
}
|
}
|
||||||
|
|
||||||
object method = makeJmethod
|
object method = makeJmethod
|
||||||
(t, true, *c, i, name, returnType, parameterTypes, exceptionTypes,
|
(t, true, 0, *c, i, name, returnType, parameterTypes, exceptionTypes,
|
||||||
methodFlags(t, vmMethod), signature, 0, annotationTable, 0,
|
methodFlags(t, vmMethod), signature, 0, annotationTable, 0,
|
||||||
annotationDefault, 0, 0, 0, 0, 0);
|
annotationDefault, 0, 0, 0);
|
||||||
|
|
||||||
assert(t, ai < objectArrayLength(t, array));
|
assert(t, ai < objectArrayLength(t, array));
|
||||||
|
|
||||||
@ -4346,8 +4409,8 @@ jvmGetClassDeclaredFields(Thread* t, uintptr_t* arguments)
|
|||||||
}
|
}
|
||||||
|
|
||||||
object field = makeJfield
|
object field = makeJfield
|
||||||
(t, true, *c, i, name, type, fieldFlags
|
(t, true, 0, *c, i, name, type, fieldFlags
|
||||||
(t, vmField), signature, 0, annotationTable, 0, 0, 0, 0, 0, 0);
|
(t, vmField), signature, 0, annotationTable, 0, 0, 0, 0);
|
||||||
|
|
||||||
assert(t, ai < objectArrayLength(t, array));
|
assert(t, ai < objectArrayLength(t, array));
|
||||||
|
|
||||||
@ -4437,8 +4500,8 @@ jvmGetClassDeclaredConstructors(Thread* t, uintptr_t* arguments)
|
|||||||
}
|
}
|
||||||
|
|
||||||
object method = makeJconstructor
|
object method = makeJconstructor
|
||||||
(t, true, *c, i, parameterTypes, exceptionTypes, methodFlags
|
(t, true, 0, *c, i, parameterTypes, exceptionTypes, methodFlags
|
||||||
(t, vmMethod), signature, 0, annotationTable, 0, 0, 0, 0, 0);
|
(t, vmMethod), signature, 0, annotationTable, 0, 0, 0, 0);
|
||||||
|
|
||||||
assert(t, ai < objectArrayLength(t, array));
|
assert(t, ai < objectArrayLength(t, array));
|
||||||
|
|
||||||
@ -4872,7 +4935,12 @@ EXPORT(JVM_NativePath)(char* path)
|
|||||||
extern "C" JNIEXPORT jint JNICALL
|
extern "C" JNIEXPORT jint JNICALL
|
||||||
EXPORT(JVM_Open)(const char* path, jint flags, jint mode)
|
EXPORT(JVM_Open)(const char* path, jint flags, jint mode)
|
||||||
{
|
{
|
||||||
return OPEN(path, flags, mode);
|
int r = OPEN(path, flags, mode);
|
||||||
|
if (r == -1) {
|
||||||
|
return errno == EEXIST ? JVM_EEXIST : -1;
|
||||||
|
} else {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT jint JNICALL
|
extern "C" JNIEXPORT jint JNICALL
|
||||||
@ -5205,9 +5273,11 @@ jboolean JNICALL
|
|||||||
GetBoolAttribute(Thread* t, jmmBoolAttribute attribute)
|
GetBoolAttribute(Thread* t, jmmBoolAttribute attribute)
|
||||||
{
|
{
|
||||||
const unsigned JMM_THREAD_CPU_TIME = 24;
|
const unsigned JMM_THREAD_CPU_TIME = 24;
|
||||||
|
const unsigned JMM_THREAD_ALLOCATED_MEMORY = 25;
|
||||||
|
|
||||||
switch (attribute) {
|
switch (attribute) {
|
||||||
case JMM_THREAD_CPU_TIME:
|
case JMM_THREAD_CPU_TIME:
|
||||||
|
case JMM_THREAD_ALLOCATED_MEMORY:
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -5290,13 +5360,19 @@ extern "C" JNIEXPORT jobjectArray JNICALL
|
|||||||
EXPORT(JVM_GetThreadStateNames)(JNIEnv*, jint, jintArray) { abort(); }
|
EXPORT(JVM_GetThreadStateNames)(JNIEnv*, jint, jintArray) { abort(); }
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
extern "C" JNIEXPORT void JNICALL
|
||||||
EXPORT(JVM_GetVersionInfo)(JNIEnv*, local::jvm_version_info*, size_t)
|
EXPORT(JVM_GetVersionInfo)(JNIEnv*, local::jvm_version_info* info, size_t size)
|
||||||
{ abort(); }
|
{
|
||||||
|
memset(info, 0, size);
|
||||||
|
info->jvm_version = 0x01070000;
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT jboolean JNICALL
|
extern "C" JNIEXPORT jboolean JNICALL
|
||||||
EXPORT(JVM_CX8Field)(JNIEnv*, jobject*, jfieldID*, jlong, jlong)
|
EXPORT(JVM_CX8Field)(JNIEnv*, jobject*, jfieldID*, jlong, jlong)
|
||||||
{ abort(); }
|
{ abort(); }
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT void JNICALL
|
||||||
|
EXPORT(JVM_SetNativeThreadName)(JNIEnv*, jobject, jstring) { abort(); }
|
||||||
|
|
||||||
} // namespace local
|
} // namespace local
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
@ -5316,7 +5392,17 @@ jio_vfprintf(FILE* stream, const char* format, va_list a)
|
|||||||
#ifdef PLATFORM_WINDOWS
|
#ifdef PLATFORM_WINDOWS
|
||||||
extern "C" JNIEXPORT void* JNICALL
|
extern "C" JNIEXPORT void* JNICALL
|
||||||
EXPORT(JVM_GetThreadInterruptEvent)()
|
EXPORT(JVM_GetThreadInterruptEvent)()
|
||||||
{ abort(); }
|
{
|
||||||
|
// hack: We don't want to expose thread interruption implementation
|
||||||
|
// details, so we give the class library a fake event to play with.
|
||||||
|
// This means that threads won't be interruptable when blocked in
|
||||||
|
// Process.waitFor.
|
||||||
|
static HANDLE fake = 0;
|
||||||
|
if (fake == 0) {
|
||||||
|
fake = CreateEvent(0, true, false, 0);
|
||||||
|
}
|
||||||
|
return fake;
|
||||||
|
}
|
||||||
|
|
||||||
namespace { HMODULE jvmHandle = 0; }
|
namespace { HMODULE jvmHandle = 0; }
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2011, Avian Contributors
|
/* Copyright (c) 2008-2012, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
@ -56,10 +56,12 @@ typedef unsigned __int64 uint64_t;
|
|||||||
# ifdef _M_IX86
|
# ifdef _M_IX86
|
||||||
typedef int32_t intptr_t;
|
typedef int32_t intptr_t;
|
||||||
typedef uint32_t uintptr_t;
|
typedef uint32_t uintptr_t;
|
||||||
|
# define UINT64_C(x) x##LL
|
||||||
# define ARCH_x86_32
|
# define ARCH_x86_32
|
||||||
# elif defined _M_X64
|
# elif defined _M_X64
|
||||||
typedef int64_t intptr_t;
|
typedef int64_t intptr_t;
|
||||||
typedef uint64_t uintptr_t;
|
typedef uint64_t uintptr_t;
|
||||||
|
# define UINT64_C(x) x##L
|
||||||
# define ARCH_x86_64
|
# define ARCH_x86_64
|
||||||
# else
|
# else
|
||||||
# error "unsupported architecture"
|
# error "unsupported architecture"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2010-2011, Avian Contributors
|
/* Copyright (c) 2010-2012, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
@ -38,6 +38,7 @@
|
|||||||
#define CONTINUATION_BODY 32
|
#define CONTINUATION_BODY 32
|
||||||
|
|
||||||
.globl GLOBAL(vmInvoke)
|
.globl GLOBAL(vmInvoke)
|
||||||
|
.align 2
|
||||||
GLOBAL(vmInvoke):
|
GLOBAL(vmInvoke):
|
||||||
/*
|
/*
|
||||||
arguments
|
arguments
|
||||||
@ -84,6 +85,7 @@ LOCAL(vmInvoke_argumentTest):
|
|||||||
blx r1
|
blx r1
|
||||||
|
|
||||||
.globl GLOBAL(vmInvoke_returnAddress)
|
.globl GLOBAL(vmInvoke_returnAddress)
|
||||||
|
.align 2
|
||||||
GLOBAL(vmInvoke_returnAddress):
|
GLOBAL(vmInvoke_returnAddress):
|
||||||
// restore stack pointer
|
// restore stack pointer
|
||||||
ldr sp, [r8, #THREAD_SCRATCH]
|
ldr sp, [r8, #THREAD_SCRATCH]
|
||||||
@ -97,6 +99,7 @@ GLOBAL(vmInvoke_returnAddress):
|
|||||||
str r5, [r8, #THREAD_STACK]
|
str r5, [r8, #THREAD_STACK]
|
||||||
|
|
||||||
.globl GLOBAL(vmInvoke_safeStack)
|
.globl GLOBAL(vmInvoke_safeStack)
|
||||||
|
.align 2
|
||||||
GLOBAL(vmInvoke_safeStack):
|
GLOBAL(vmInvoke_safeStack):
|
||||||
|
|
||||||
#ifdef AVIAN_CONTINUATIONS
|
#ifdef AVIAN_CONTINUATIONS
|
||||||
@ -174,6 +177,7 @@ LOCAL(vmInvoke_return):
|
|||||||
bx lr
|
bx lr
|
||||||
|
|
||||||
.globl GLOBAL(vmJumpAndInvoke)
|
.globl GLOBAL(vmJumpAndInvoke)
|
||||||
|
.align 2
|
||||||
GLOBAL(vmJumpAndInvoke):
|
GLOBAL(vmJumpAndInvoke):
|
||||||
#ifdef AVIAN_CONTINUATIONS
|
#ifdef AVIAN_CONTINUATIONS
|
||||||
// r0: thread
|
// r0: thread
|
||||||
|
497
src/compile.cpp
497
src/compile.cpp
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008-2011, Avian Contributors
|
/* Copyright (c) 2008-2012, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
@ -176,8 +176,8 @@ class MyThread: public Thread {
|
|||||||
Context(t, ip, stack, continuation, trace),
|
Context(t, ip, stack, continuation, trace),
|
||||||
t(t),
|
t(t),
|
||||||
link(0),
|
link(0),
|
||||||
javaStackLimit(0),
|
next(t->traceContext),
|
||||||
next(t->traceContext)
|
methodIsMostRecent(false)
|
||||||
{
|
{
|
||||||
t->traceContext = this;
|
t->traceContext = this;
|
||||||
}
|
}
|
||||||
@ -186,8 +186,8 @@ class MyThread: public Thread {
|
|||||||
Context(t, t->ip, t->stack, t->continuation, t->trace),
|
Context(t, t->ip, t->stack, t->continuation, t->trace),
|
||||||
t(t),
|
t(t),
|
||||||
link(link),
|
link(link),
|
||||||
javaStackLimit(0),
|
next(t->traceContext),
|
||||||
next(t->traceContext)
|
methodIsMostRecent(false)
|
||||||
{
|
{
|
||||||
t->traceContext = this;
|
t->traceContext = this;
|
||||||
}
|
}
|
||||||
@ -198,8 +198,8 @@ class MyThread: public Thread {
|
|||||||
|
|
||||||
MyThread* t;
|
MyThread* t;
|
||||||
void* link;
|
void* link;
|
||||||
void* javaStackLimit;
|
|
||||||
TraceContext* next;
|
TraceContext* next;
|
||||||
|
bool methodIsMostRecent;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void doTransition(MyThread* t, void* ip, void* stack,
|
static void doTransition(MyThread* t, void* ip, void* stack,
|
||||||
@ -353,18 +353,18 @@ root(Thread* t, Root root);
|
|||||||
void
|
void
|
||||||
setRoot(Thread* t, Root root, object value);
|
setRoot(Thread* t, Root root, object value);
|
||||||
|
|
||||||
unsigned
|
|
||||||
compiledSize(intptr_t address)
|
|
||||||
{
|
|
||||||
return reinterpret_cast<target_uintptr_t*>(address)[-1];
|
|
||||||
}
|
|
||||||
|
|
||||||
intptr_t
|
intptr_t
|
||||||
methodCompiled(Thread* t, object method)
|
methodCompiled(Thread* t, object method)
|
||||||
{
|
{
|
||||||
return codeCompiled(t, methodCode(t, method));
|
return codeCompiled(t, methodCode(t, method));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
methodCompiledSize(Thread* t, object method)
|
||||||
|
{
|
||||||
|
return codeCompiledSize(t, methodCode(t, method));
|
||||||
|
}
|
||||||
|
|
||||||
intptr_t
|
intptr_t
|
||||||
compareIpToMethodBounds(Thread* t, intptr_t ip, object method)
|
compareIpToMethodBounds(Thread* t, intptr_t ip, object method)
|
||||||
{
|
{
|
||||||
@ -374,13 +374,13 @@ compareIpToMethodBounds(Thread* t, intptr_t ip, object method)
|
|||||||
fprintf(stderr, "find %p in (%p,%p)\n",
|
fprintf(stderr, "find %p in (%p,%p)\n",
|
||||||
reinterpret_cast<void*>(ip),
|
reinterpret_cast<void*>(ip),
|
||||||
reinterpret_cast<void*>(start),
|
reinterpret_cast<void*>(start),
|
||||||
reinterpret_cast<void*>(start + compiledSize(start)));
|
reinterpret_cast<void*>(start + methodCompiledSize(t, method)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ip < start) {
|
if (ip < start) {
|
||||||
return -1;
|
return -1;
|
||||||
} else if (ip < start + static_cast<intptr_t>
|
} else if (ip < start + static_cast<intptr_t>
|
||||||
(compiledSize(start) + TargetBytesPerWord))
|
(methodCompiledSize(t, method)))
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
@ -427,19 +427,20 @@ alignedFrameSize(MyThread* t, object method)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nextFrame(MyThread* t, void** ip, void** sp, object method, object target)
|
nextFrame(MyThread* t, void** ip, void** sp, object method, object target,
|
||||||
|
bool mostRecent)
|
||||||
{
|
{
|
||||||
object code = methodCode(t, method);
|
object code = methodCode(t, method);
|
||||||
intptr_t start = codeCompiled(t, code);
|
intptr_t start = codeCompiled(t, code);
|
||||||
void* link;
|
void* link;
|
||||||
void* javaStackLimit;
|
bool methodIsMostRecent;
|
||||||
|
|
||||||
if (t->traceContext) {
|
if (t->traceContext) {
|
||||||
link = t->traceContext->link;
|
link = t->traceContext->link;
|
||||||
javaStackLimit = t->traceContext->javaStackLimit;
|
methodIsMostRecent = mostRecent and t->traceContext->methodIsMostRecent;
|
||||||
} else {
|
} else {
|
||||||
link = 0;
|
link = 0;
|
||||||
javaStackLimit = 0;
|
methodIsMostRecent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// fprintf(stderr, "nextFrame %s.%s%s target %s.%s%s ip %p sp %p\n",
|
// fprintf(stderr, "nextFrame %s.%s%s target %s.%s%s ip %p sp %p\n",
|
||||||
@ -458,8 +459,8 @@ nextFrame(MyThread* t, void** ip, void** sp, object method, object target)
|
|||||||
// *ip, *sp);
|
// *ip, *sp);
|
||||||
|
|
||||||
t->arch->nextFrame
|
t->arch->nextFrame
|
||||||
(reinterpret_cast<void*>(start), compiledSize(start),
|
(reinterpret_cast<void*>(start), codeCompiledSize(t, code),
|
||||||
alignedFrameSize(t, method), link, javaStackLimit,
|
alignedFrameSize(t, method), link, methodIsMostRecent,
|
||||||
target ? methodParameterFootprint(t, target) : -1, ip, sp);
|
target ? methodParameterFootprint(t, target) : -1, ip, sp);
|
||||||
|
|
||||||
// fprintf(stderr, "next frame ip %p sp %p\n", *ip, *sp);
|
// fprintf(stderr, "next frame ip %p sp %p\n", *ip, *sp);
|
||||||
@ -514,6 +515,7 @@ class MyStackWalker: public Processor::StackWalker {
|
|||||||
state(Start),
|
state(Start),
|
||||||
method_(0),
|
method_(0),
|
||||||
target(0),
|
target(0),
|
||||||
|
count_(0),
|
||||||
protector(this)
|
protector(this)
|
||||||
{
|
{
|
||||||
if (t->traceContext) {
|
if (t->traceContext) {
|
||||||
@ -538,6 +540,7 @@ class MyStackWalker: public Processor::StackWalker {
|
|||||||
method_(w->method_),
|
method_(w->method_),
|
||||||
target(w->target),
|
target(w->target),
|
||||||
continuation(w->continuation),
|
continuation(w->continuation),
|
||||||
|
count_(0),
|
||||||
protector(this)
|
protector(this)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
@ -609,13 +612,15 @@ class MyStackWalker: public Processor::StackWalker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void next() {
|
void next() {
|
||||||
|
expect(t, count_ <= stackSizeInWords(t));
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case Continuation:
|
case Continuation:
|
||||||
continuation = continuationNext(t, continuation);
|
continuation = continuationNext(t, continuation);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Method:
|
case Method:
|
||||||
nextFrame(t, &ip_, &stack, method_, target);
|
nextFrame(t, &ip_, &stack, method_, target, count_ == 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NativeMethod:
|
case NativeMethod:
|
||||||
@ -625,6 +630,8 @@ class MyStackWalker: public Processor::StackWalker {
|
|||||||
abort(t);
|
abort(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
++ count_;
|
||||||
|
|
||||||
state = Next;
|
state = Next;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -671,6 +678,7 @@ class MyStackWalker: public Processor::StackWalker {
|
|||||||
object method_;
|
object method_;
|
||||||
object target;
|
object target;
|
||||||
object continuation;
|
object continuation;
|
||||||
|
unsigned count_;
|
||||||
MyProtector protector;
|
MyProtector protector;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1381,8 +1389,7 @@ class Frame {
|
|||||||
Compiler::Operand* append(object o) {
|
Compiler::Operand* append(object o) {
|
||||||
BootContext* bc = context->bootContext;
|
BootContext* bc = context->bootContext;
|
||||||
if (bc) {
|
if (bc) {
|
||||||
Promise* p = new (bc->zone->allocate(sizeof(ListenPromise)))
|
Promise* p = new (bc->zone) ListenPromise(t->m->system, bc->zone);
|
||||||
ListenPromise(t->m->system, bc->zone);
|
|
||||||
|
|
||||||
PROTECT(t, o);
|
PROTECT(t, o);
|
||||||
object pointer = makePointer(t, p);
|
object pointer = makePointer(t, p);
|
||||||
@ -1400,9 +1407,7 @@ class Frame {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
context->objectPool = new
|
context->objectPool = new(&context->zone) PoolElement(t, o, context->objectPool);
|
||||||
(context->zone.allocate(sizeof(PoolElement)))
|
|
||||||
PoolElement(t, o, context->objectPool);
|
|
||||||
|
|
||||||
++ context->objectPoolCount;
|
++ context->objectPoolCount;
|
||||||
|
|
||||||
@ -1607,8 +1612,7 @@ class Frame {
|
|||||||
Promise* addressPromise(Promise* p) {
|
Promise* addressPromise(Promise* p) {
|
||||||
BootContext* bc = context->bootContext;
|
BootContext* bc = context->bootContext;
|
||||||
if (bc) {
|
if (bc) {
|
||||||
bc->addresses = new (bc->zone->allocate(sizeof(DelayedPromise)))
|
bc->addresses = new(bc->zone) DelayedPromise(t->m->system, bc->zone, p, bc->addresses);
|
||||||
DelayedPromise(t->m->system, bc->zone, p, bc->addresses);
|
|
||||||
return bc->addresses;
|
return bc->addresses;
|
||||||
} else {
|
} else {
|
||||||
return p;
|
return p;
|
||||||
@ -1625,7 +1629,7 @@ class Frame {
|
|||||||
(TargetBytesPerWord, c->memory
|
(TargetBytesPerWord, c->memory
|
||||||
(c->register_(t->arch->thread()), Compiler::AddressType,
|
(c->register_(t->arch->thread()), Compiler::AddressType,
|
||||||
TargetThreadCodeImage), c->promiseConstant
|
TargetThreadCodeImage), c->promiseConstant
|
||||||
(new (context->zone.allocate(sizeof(OffsetPromise)))
|
(new(&context->zone)
|
||||||
OffsetPromise
|
OffsetPromise
|
||||||
(p, - reinterpret_cast<intptr_t>(codeAllocator(t)->base)),
|
(p, - reinterpret_cast<intptr_t>(codeAllocator(t)->base)),
|
||||||
Compiler::AddressType))
|
Compiler::AddressType))
|
||||||
@ -2065,6 +2069,7 @@ findUnwindTarget(MyThread* t, void** targetIp, void** targetFrame,
|
|||||||
}
|
}
|
||||||
|
|
||||||
object target = t->trace->targetMethod;
|
object target = t->trace->targetMethod;
|
||||||
|
bool mostRecent = true;
|
||||||
|
|
||||||
*targetIp = 0;
|
*targetIp = 0;
|
||||||
while (*targetIp == 0) {
|
while (*targetIp == 0) {
|
||||||
@ -2075,7 +2080,7 @@ findUnwindTarget(MyThread* t, void** targetIp, void** targetFrame,
|
|||||||
if (handler) {
|
if (handler) {
|
||||||
*targetIp = handler;
|
*targetIp = handler;
|
||||||
|
|
||||||
nextFrame(t, &ip, &stack, method, target);
|
nextFrame(t, &ip, &stack, method, target, mostRecent);
|
||||||
|
|
||||||
void** sp = static_cast<void**>(stackForFrame(t, stack, method))
|
void** sp = static_cast<void**>(stackForFrame(t, stack, method))
|
||||||
+ t->arch->frameReturnAddressSize();
|
+ t->arch->frameReturnAddressSize();
|
||||||
@ -2089,7 +2094,7 @@ findUnwindTarget(MyThread* t, void** targetIp, void** targetFrame,
|
|||||||
|
|
||||||
t->exception = 0;
|
t->exception = 0;
|
||||||
} else {
|
} else {
|
||||||
nextFrame(t, &ip, &stack, method, target);
|
nextFrame(t, &ip, &stack, method, target, mostRecent);
|
||||||
|
|
||||||
if (t->exception) {
|
if (t->exception) {
|
||||||
releaseLock(t, method, stack);
|
releaseLock(t, method, stack);
|
||||||
@ -2137,6 +2142,8 @@ findUnwindTarget(MyThread* t, void** targetIp, void** targetFrame,
|
|||||||
*targetContinuation = continuationNext(t, c);
|
*targetContinuation = continuationNext(t, c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mostRecent = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2160,6 +2167,8 @@ makeCurrentContinuation(MyThread* t, void** targetIp, void** targetStack)
|
|||||||
object last = 0;
|
object last = 0;
|
||||||
PROTECT(t, last);
|
PROTECT(t, last);
|
||||||
|
|
||||||
|
bool mostRecent = true;
|
||||||
|
|
||||||
*targetIp = 0;
|
*targetIp = 0;
|
||||||
while (*targetIp == 0) {
|
while (*targetIp == 0) {
|
||||||
object method = methodForIp(t, ip);
|
object method = methodForIp(t, ip);
|
||||||
@ -2177,7 +2186,7 @@ makeCurrentContinuation(MyThread* t, void** targetIp, void** targetStack)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void* nextIp = ip;
|
void* nextIp = ip;
|
||||||
nextFrame(t, &nextIp, &stack, method, target);
|
nextFrame(t, &nextIp, &stack, method, target, mostRecent);
|
||||||
|
|
||||||
void** bottom = static_cast<void**>(stack)
|
void** bottom = static_cast<void**>(stack)
|
||||||
+ t->arch->frameReturnAddressSize();
|
+ t->arch->frameReturnAddressSize();
|
||||||
@ -2215,6 +2224,8 @@ makeCurrentContinuation(MyThread* t, void** targetIp, void** targetStack)
|
|||||||
*targetStack = static_cast<void**>(stack)
|
*targetStack = static_cast<void**>(stack)
|
||||||
+ t->arch->frameReturnAddressSize();
|
+ t->arch->frameReturnAddressSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mostRecent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(t, last);
|
expect(t, last);
|
||||||
@ -2357,6 +2368,31 @@ findInterfaceMethodFromInstanceAndReference
|
|||||||
return findInterfaceMethodFromInstance(t, method, instance);
|
return findInterfaceMethodFromInstance(t, method, instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
checkMethod(Thread* t, object method, bool shouldBeStatic)
|
||||||
|
{
|
||||||
|
if (((methodFlags(t, method) & ACC_STATIC) == 0) == shouldBeStatic) {
|
||||||
|
throwNew(t, Machine::IncompatibleClassChangeErrorType,
|
||||||
|
"expected %s.%s%s to be %s",
|
||||||
|
&byteArrayBody(t, className(t, methodClass(t, method)), 0),
|
||||||
|
&byteArrayBody(t, methodName(t, method), 0),
|
||||||
|
&byteArrayBody(t, methodSpec(t, method), 0),
|
||||||
|
shouldBeStatic ? "static" : "non-static");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
checkField(Thread* t, object field, bool shouldBeStatic)
|
||||||
|
{
|
||||||
|
if (((fieldFlags(t, field) & ACC_STATIC) == 0) == shouldBeStatic) {
|
||||||
|
throwNew(t, Machine::IncompatibleClassChangeErrorType,
|
||||||
|
"expected %s.%s to be %s",
|
||||||
|
&byteArrayBody(t, className(t, fieldClass(t, field)), 0),
|
||||||
|
&byteArrayBody(t, fieldName(t, field), 0),
|
||||||
|
shouldBeStatic ? "static" : "non-static");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int64_t
|
int64_t
|
||||||
findSpecialMethodFromReference(MyThread* t, object pair)
|
findSpecialMethodFromReference(MyThread* t, object pair)
|
||||||
{
|
{
|
||||||
@ -2369,7 +2405,7 @@ findSpecialMethodFromReference(MyThread* t, object pair)
|
|||||||
target = findVirtualMethod(t, target, classSuper(t, class_));
|
target = findVirtualMethod(t, target, classSuper(t, class_));
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(t, (methodFlags(t, target) & ACC_STATIC) == 0);
|
checkMethod(t, target, false);
|
||||||
|
|
||||||
return prepareMethodForCall(t, target);
|
return prepareMethodForCall(t, target);
|
||||||
}
|
}
|
||||||
@ -2379,7 +2415,7 @@ findStaticMethodFromReference(MyThread* t, object pair)
|
|||||||
{
|
{
|
||||||
object target = resolveMethod(t, pair);
|
object target = resolveMethod(t, pair);
|
||||||
|
|
||||||
assert(t, methodFlags(t, target) & ACC_STATIC);
|
checkMethod(t, target, true);
|
||||||
|
|
||||||
return prepareMethodForCall(t, target);
|
return prepareMethodForCall(t, target);
|
||||||
}
|
}
|
||||||
@ -2393,7 +2429,7 @@ findVirtualMethodFromReference(MyThread* t, object pair, object instance)
|
|||||||
|
|
||||||
target = findVirtualMethod(t, target, objectClass(t, instance));
|
target = findVirtualMethod(t, target, objectClass(t, instance));
|
||||||
|
|
||||||
assert(t, (methodFlags(t, target) & ACC_STATIC) == 0);
|
checkMethod(t, target, false);
|
||||||
|
|
||||||
return prepareMethodForCall(t, target);
|
return prepareMethodForCall(t, target);
|
||||||
}
|
}
|
||||||
@ -3402,8 +3438,7 @@ compileDirectInvoke(MyThread* t, Frame* frame, object target, bool tailCall)
|
|||||||
and (not (TailCalls and tailCall
|
and (not (TailCalls and tailCall
|
||||||
and (methodFlags(t, target) & ACC_NATIVE))))
|
and (methodFlags(t, target) & ACC_NATIVE))))
|
||||||
{
|
{
|
||||||
Promise* p = new (bc->zone->allocate(sizeof(ListenPromise)))
|
Promise* p = new(bc->zone) ListenPromise(t->m->system, bc->zone);
|
||||||
ListenPromise(t->m->system, bc->zone);
|
|
||||||
|
|
||||||
PROTECT(t, target);
|
PROTECT(t, target);
|
||||||
object pointer = makePointer(t, p);
|
object pointer = makePointer(t, p);
|
||||||
@ -3809,6 +3844,13 @@ floatBranch(MyThread* t, Frame* frame, object code, unsigned& ip,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Compiler::Operand*
|
||||||
|
popLongAddress(Frame* frame)
|
||||||
|
{
|
||||||
|
return TargetBytesPerWord == 8 ? frame->popLong() : frame->c->load
|
||||||
|
(8, 8, frame->popLong(), TargetBytesPerWord);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
intrinsic(MyThread* t, Frame* frame, object target)
|
intrinsic(MyThread* t, Frame* frame, object target)
|
||||||
{
|
{
|
||||||
@ -3837,6 +3879,127 @@ intrinsic(MyThread* t, Frame* frame, object target)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (UNLIKELY(MATCH(className, "sun/misc/Unsafe"))) {
|
||||||
|
Compiler* c = frame->c;
|
||||||
|
if (MATCH(methodName(t, target), "getByte")
|
||||||
|
and MATCH(methodSpec(t, target), "(J)B"))
|
||||||
|
{
|
||||||
|
Compiler::Operand* address = popLongAddress(frame);
|
||||||
|
frame->popObject();
|
||||||
|
frame->pushInt
|
||||||
|
(c->load
|
||||||
|
(1, 1, c->memory(address, Compiler::IntegerType, 0, 0, 1),
|
||||||
|
TargetBytesPerWord));
|
||||||
|
return true;
|
||||||
|
} else if (MATCH(methodName(t, target), "putByte")
|
||||||
|
and MATCH(methodSpec(t, target), "(JB)V"))
|
||||||
|
{
|
||||||
|
Compiler::Operand* value = frame->popInt();
|
||||||
|
Compiler::Operand* address = popLongAddress(frame);
|
||||||
|
frame->popObject();
|
||||||
|
c->store
|
||||||
|
(TargetBytesPerWord, value, 1, c->memory
|
||||||
|
(address, Compiler::IntegerType, 0, 0, 1));
|
||||||
|
return true;
|
||||||
|
} else if ((MATCH(methodName(t, target), "getShort")
|
||||||
|
and MATCH(methodSpec(t, target), "(J)S"))
|
||||||
|
or (MATCH(methodName(t, target), "getChar")
|
||||||
|
and MATCH(methodSpec(t, target), "(J)C")))
|
||||||
|
{
|
||||||
|
Compiler::Operand* address = popLongAddress(frame);
|
||||||
|
frame->popObject();
|
||||||
|
frame->pushInt
|
||||||
|
(c->load
|
||||||
|
(2, 2, c->memory(address, Compiler::IntegerType, 0, 0, 1),
|
||||||
|
TargetBytesPerWord));
|
||||||
|
return true;
|
||||||
|
} else if ((MATCH(methodName(t, target), "putShort")
|
||||||
|
and MATCH(methodSpec(t, target), "(JS)V"))
|
||||||
|
or (MATCH(methodName(t, target), "putChar")
|
||||||
|
and MATCH(methodSpec(t, target), "(JC)V")))
|
||||||
|
{
|
||||||
|
Compiler::Operand* value = frame->popInt();
|
||||||
|
Compiler::Operand* address = popLongAddress(frame);
|
||||||
|
frame->popObject();
|
||||||
|
c->store
|
||||||
|
(TargetBytesPerWord, value, 2, c->memory
|
||||||
|
(address, Compiler::IntegerType, 0, 0, 1));
|
||||||
|
return true;
|
||||||
|
} else if ((MATCH(methodName(t, target), "getInt")
|
||||||
|
and MATCH(methodSpec(t, target), "(J)I"))
|
||||||
|
or (MATCH(methodName(t, target), "getFloat")
|
||||||
|
and MATCH(methodSpec(t, target), "(J)F")))
|
||||||
|
{
|
||||||
|
Compiler::Operand* address = popLongAddress(frame);
|
||||||
|
frame->popObject();
|
||||||
|
frame->pushInt
|
||||||
|
(c->load
|
||||||
|
(4, 4, c->memory
|
||||||
|
(address, MATCH(methodName(t, target), "getInt")
|
||||||
|
? Compiler::IntegerType : Compiler::FloatType, 0, 0, 1),
|
||||||
|
TargetBytesPerWord));
|
||||||
|
return true;
|
||||||
|
} else if ((MATCH(methodName(t, target), "putInt")
|
||||||
|
and MATCH(methodSpec(t, target), "(JI)V"))
|
||||||
|
or (MATCH(methodName(t, target), "putFloat")
|
||||||
|
and MATCH(methodSpec(t, target), "(JF)V")))
|
||||||
|
{
|
||||||
|
Compiler::Operand* value = frame->popInt();
|
||||||
|
Compiler::Operand* address = popLongAddress(frame);
|
||||||
|
frame->popObject();
|
||||||
|
c->store
|
||||||
|
(TargetBytesPerWord, value, 4, c->memory
|
||||||
|
(address, MATCH(methodName(t, target), "putInt")
|
||||||
|
? Compiler::IntegerType : Compiler::FloatType, 0, 0, 1));
|
||||||
|
return true;
|
||||||
|
} else if ((MATCH(methodName(t, target), "getLong")
|
||||||
|
and MATCH(methodSpec(t, target), "(J)J"))
|
||||||
|
or (MATCH(methodName(t, target), "getDouble")
|
||||||
|
and MATCH(methodSpec(t, target), "(J)D")))
|
||||||
|
{
|
||||||
|
Compiler::Operand* address = popLongAddress(frame);
|
||||||
|
frame->popObject();
|
||||||
|
frame->pushLong
|
||||||
|
(c->load
|
||||||
|
(8, 8, c->memory
|
||||||
|
(address, MATCH(methodName(t, target), "getLong")
|
||||||
|
? Compiler::IntegerType : Compiler::FloatType, 0, 0, 1),
|
||||||
|
8));
|
||||||
|
return true;
|
||||||
|
} else if ((MATCH(methodName(t, target), "putLong")
|
||||||
|
and MATCH(methodSpec(t, target), "(JJ)V"))
|
||||||
|
or (MATCH(methodName(t, target), "putDouble")
|
||||||
|
and MATCH(methodSpec(t, target), "(JD)V")))
|
||||||
|
{
|
||||||
|
Compiler::Operand* value = frame->popLong();
|
||||||
|
Compiler::Operand* address = popLongAddress(frame);
|
||||||
|
frame->popObject();
|
||||||
|
c->store
|
||||||
|
(8, value, 8, c->memory
|
||||||
|
(address, MATCH(methodName(t, target), "putLong")
|
||||||
|
? Compiler::IntegerType : Compiler::FloatType, 0, 0, 1));
|
||||||
|
return true;
|
||||||
|
} else if (MATCH(methodName(t, target), "getAddress")
|
||||||
|
and MATCH(methodSpec(t, target), "(J)J"))
|
||||||
|
{
|
||||||
|
Compiler::Operand* address = popLongAddress(frame);
|
||||||
|
frame->popObject();
|
||||||
|
frame->pushLong
|
||||||
|
(c->load
|
||||||
|
(TargetBytesPerWord, TargetBytesPerWord,
|
||||||
|
c->memory(address, Compiler::AddressType, 0, 0, 1), 8));
|
||||||
|
return true;
|
||||||
|
} else if (MATCH(methodName(t, target), "putAddress")
|
||||||
|
and MATCH(methodSpec(t, target), "(JJ)V"))
|
||||||
|
{
|
||||||
|
Compiler::Operand* value = frame->popLong();
|
||||||
|
Compiler::Operand* address = popLongAddress(frame);
|
||||||
|
frame->popObject();
|
||||||
|
c->store
|
||||||
|
(8, value, TargetBytesPerWord, c->memory
|
||||||
|
(address, Compiler::AddressType, 0, 0, 1));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -4167,6 +4330,10 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
0,
|
0,
|
||||||
Compiler::VoidType,
|
Compiler::VoidType,
|
||||||
2, c->register_(t->arch->thread()), target);
|
2, c->register_(t->arch->thread()), target);
|
||||||
|
|
||||||
|
if (ip == codeLength(t, code)) {
|
||||||
|
c->trap();
|
||||||
|
}
|
||||||
} return;
|
} return;
|
||||||
|
|
||||||
case bipush:
|
case bipush:
|
||||||
@ -4441,7 +4608,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
Compiler::Operand* table;
|
Compiler::Operand* table;
|
||||||
|
|
||||||
if (instruction == getstatic) {
|
if (instruction == getstatic) {
|
||||||
assert(t, fieldFlags(t, field) & ACC_STATIC);
|
checkField(t, field, true);
|
||||||
|
|
||||||
PROTECT(t, field);
|
PROTECT(t, field);
|
||||||
|
|
||||||
@ -4461,7 +4628,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
|
|
||||||
table = frame->append(classStaticTable(t, fieldClass(t, field)));
|
table = frame->append(classStaticTable(t, fieldClass(t, field)));
|
||||||
} else {
|
} else {
|
||||||
assert(t, (fieldFlags(t, field) & ACC_STATIC) == 0);
|
checkField(t, field, false);
|
||||||
|
|
||||||
table = frame->popObject();
|
table = frame->popObject();
|
||||||
|
|
||||||
@ -4906,7 +5073,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
int returnCode;
|
int returnCode;
|
||||||
bool tailCall;
|
bool tailCall;
|
||||||
if (LIKELY(target)) {
|
if (LIKELY(target)) {
|
||||||
assert(t, (methodFlags(t, target) & ACC_STATIC) == 0);
|
checkMethod(t, target, false);
|
||||||
|
|
||||||
argument = target;
|
argument = target;
|
||||||
thunk = findInterfaceMethodFromInstanceThunk;
|
thunk = findInterfaceMethodFromInstanceThunk;
|
||||||
@ -4965,7 +5132,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
target = findVirtualMethod(t, target, classSuper(t, class_));
|
target = findVirtualMethod(t, target, classSuper(t, class_));
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(t, (methodFlags(t, target) & ACC_STATIC) == 0);
|
checkMethod(t, target, false);
|
||||||
|
|
||||||
bool tailCall = isTailCall(t, code, ip, context->method, target);
|
bool tailCall = isTailCall(t, code, ip, context->method, target);
|
||||||
|
|
||||||
@ -4995,7 +5162,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
object target = resolveMethod(t, context->method, index - 1, false);
|
object target = resolveMethod(t, context->method, index - 1, false);
|
||||||
|
|
||||||
if (LIKELY(target)) {
|
if (LIKELY(target)) {
|
||||||
assert(t, methodFlags(t, target) & ACC_STATIC);
|
checkMethod(t, target, true);
|
||||||
|
|
||||||
if (not intrinsic(t, frame, target)) {
|
if (not intrinsic(t, frame, target)) {
|
||||||
bool tailCall = isTailCall(t, code, ip, context->method, target);
|
bool tailCall = isTailCall(t, code, ip, context->method, target);
|
||||||
@ -5021,44 +5188,46 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
object target = resolveMethod(t, context->method, index - 1, false);
|
object target = resolveMethod(t, context->method, index - 1, false);
|
||||||
|
|
||||||
if (LIKELY(target)) {
|
if (LIKELY(target)) {
|
||||||
assert(t, (methodFlags(t, target) & ACC_STATIC) == 0);
|
checkMethod(t, target, false);
|
||||||
|
|
||||||
|
if (not intrinsic(t, frame, target)) {
|
||||||
|
bool tailCall = isTailCall(t, code, ip, context->method, target);
|
||||||
|
|
||||||
bool tailCall = isTailCall(t, code, ip, context->method, target);
|
if (LIKELY(methodVirtual(t, target))) {
|
||||||
|
unsigned parameterFootprint = methodParameterFootprint(t, target);
|
||||||
|
|
||||||
if (LIKELY(methodVirtual(t, target))) {
|
unsigned offset = TargetClassVtable
|
||||||
unsigned parameterFootprint = methodParameterFootprint(t, target);
|
+ (methodOffset(t, target) * TargetBytesPerWord);
|
||||||
|
|
||||||
unsigned offset = TargetClassVtable
|
Compiler::Operand* instance = c->peek(1, parameterFootprint - 1);
|
||||||
+ (methodOffset(t, target) * TargetBytesPerWord);
|
|
||||||
|
|
||||||
Compiler::Operand* instance = c->peek(1, parameterFootprint - 1);
|
unsigned rSize = resultSize(t, methodReturnCode(t, target));
|
||||||
|
|
||||||
unsigned rSize = resultSize(t, methodReturnCode(t, target));
|
Compiler::Operand* result = c->stackCall
|
||||||
|
(c->memory
|
||||||
|
(c->and_
|
||||||
|
(TargetBytesPerWord, c->constant
|
||||||
|
(TargetPointerMask, Compiler::IntegerType),
|
||||||
|
c->memory(instance, Compiler::ObjectType, 0, 0, 1)),
|
||||||
|
Compiler::ObjectType, offset, 0, 1),
|
||||||
|
tailCall ? Compiler::TailJump : 0,
|
||||||
|
frame->trace(0, 0),
|
||||||
|
rSize,
|
||||||
|
operandTypeForFieldCode(t, methodReturnCode(t, target)),
|
||||||
|
parameterFootprint);
|
||||||
|
|
||||||
Compiler::Operand* result = c->stackCall
|
frame->pop(parameterFootprint);
|
||||||
(c->memory
|
|
||||||
(c->and_
|
|
||||||
(TargetBytesPerWord, c->constant
|
|
||||||
(TargetPointerMask, Compiler::IntegerType),
|
|
||||||
c->memory(instance, Compiler::ObjectType, 0, 0, 1)),
|
|
||||||
Compiler::ObjectType, offset, 0, 1),
|
|
||||||
tailCall ? Compiler::TailJump : 0,
|
|
||||||
frame->trace(0, 0),
|
|
||||||
rSize,
|
|
||||||
operandTypeForFieldCode(t, methodReturnCode(t, target)),
|
|
||||||
parameterFootprint);
|
|
||||||
|
|
||||||
frame->pop(parameterFootprint);
|
if (rSize) {
|
||||||
|
pushReturnValue(t, frame, methodReturnCode(t, target), result);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// OpenJDK generates invokevirtual calls to private methods
|
||||||
|
// (e.g. readObject and writeObject for serialization), so
|
||||||
|
// we must handle such cases here.
|
||||||
|
|
||||||
if (rSize) {
|
compileDirectInvoke(t, frame, target, tailCall);
|
||||||
pushReturnValue(t, frame, methodReturnCode(t, target), result);
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// OpenJDK generates invokevirtual calls to private methods
|
|
||||||
// (e.g. readObject and writeObject for serialization), so
|
|
||||||
// we must handle such cases here.
|
|
||||||
|
|
||||||
compileDirectInvoke(t, frame, target, tailCall);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
PROTECT(t, reference);
|
PROTECT(t, reference);
|
||||||
@ -5633,7 +5802,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
object staticTable = 0;
|
object staticTable = 0;
|
||||||
|
|
||||||
if (instruction == putstatic) {
|
if (instruction == putstatic) {
|
||||||
assert(t, fieldFlags(t, field) & ACC_STATIC);
|
checkField(t, field, true);
|
||||||
|
|
||||||
if (fieldClass(t, field) != methodClass(t, context->method)
|
if (fieldClass(t, field) != methodClass(t, context->method)
|
||||||
and classNeedsInit(t, fieldClass(t, field)))
|
and classNeedsInit(t, fieldClass(t, field)))
|
||||||
@ -5653,7 +5822,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
|
|
||||||
staticTable = classStaticTable(t, fieldClass(t, field));
|
staticTable = classStaticTable(t, fieldClass(t, field));
|
||||||
} else {
|
} else {
|
||||||
assert(t, (fieldFlags(t, field) & ACC_STATIC) == 0);
|
checkField(t, field, false);
|
||||||
|
|
||||||
if (inTryBlock(t, code, ip - 3)) {
|
if (inTryBlock(t, code, ip - 3)) {
|
||||||
c->saveLocals();
|
c->saveLocals();
|
||||||
@ -6019,29 +6188,15 @@ FILE* compileLog = 0;
|
|||||||
|
|
||||||
void
|
void
|
||||||
logCompile(MyThread* t, const void* code, unsigned size, const char* class_,
|
logCompile(MyThread* t, const void* code, unsigned size, const char* class_,
|
||||||
const char* name, const char* spec)
|
const char* name, const char* spec);
|
||||||
{
|
|
||||||
static bool open = false;
|
|
||||||
if (not open) {
|
|
||||||
open = true;
|
|
||||||
const char* path = findProperty(t, "avian.jit.log");
|
|
||||||
if (path) {
|
|
||||||
compileLog = vm::fopen(path, "wb");
|
|
||||||
} else if (DebugCompile) {
|
|
||||||
compileLog = stderr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (compileLog) {
|
|
||||||
fprintf(compileLog, "%p %p %s.%s%s\n",
|
|
||||||
code, static_cast<const uint8_t*>(code) + size,
|
|
||||||
class_, name, spec);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
resolveIpForwards(Context* context, int start, int end)
|
resolveIpForwards(Context* context, int start, int end)
|
||||||
{
|
{
|
||||||
|
if (start < 0) {
|
||||||
|
start = 0;
|
||||||
|
}
|
||||||
|
|
||||||
while (start < end and context->visitTable[start] == 0) {
|
while (start < end and context->visitTable[start] == 0) {
|
||||||
++ start;
|
++ start;
|
||||||
}
|
}
|
||||||
@ -6056,6 +6211,13 @@ resolveIpForwards(Context* context, int start, int end)
|
|||||||
int
|
int
|
||||||
resolveIpBackwards(Context* context, int start, int end)
|
resolveIpBackwards(Context* context, int start, int end)
|
||||||
{
|
{
|
||||||
|
Thread* t = context->thread;
|
||||||
|
if (start >= static_cast<int>
|
||||||
|
(codeLength(t, methodCode(t, context->method))))
|
||||||
|
{
|
||||||
|
start = codeLength(t, methodCode(t, context->method)) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
while (start >= end and context->visitTable[start] == 0) {
|
while (start >= end and context->visitTable[start] == 0) {
|
||||||
-- start;
|
-- start;
|
||||||
}
|
}
|
||||||
@ -6075,8 +6237,10 @@ truncateIntArray(Thread* t, object array, unsigned length)
|
|||||||
PROTECT(t, array);
|
PROTECT(t, array);
|
||||||
|
|
||||||
object newArray = makeIntArray(t, length);
|
object newArray = makeIntArray(t, length);
|
||||||
memcpy(&intArrayBody(t, newArray, 0), &intArrayBody(t, array, 0),
|
if (length) {
|
||||||
length * 4);
|
memcpy(&intArrayBody(t, newArray, 0), &intArrayBody(t, array, 0),
|
||||||
|
length * 4);
|
||||||
|
}
|
||||||
|
|
||||||
return newArray;
|
return newArray;
|
||||||
}
|
}
|
||||||
@ -6089,8 +6253,10 @@ truncateArray(Thread* t, object array, unsigned length)
|
|||||||
PROTECT(t, array);
|
PROTECT(t, array);
|
||||||
|
|
||||||
object newArray = makeArray(t, length);
|
object newArray = makeArray(t, length);
|
||||||
memcpy(&arrayBody(t, newArray, 0), &arrayBody(t, array, 0),
|
if (length) {
|
||||||
length * BytesPerWord);
|
memcpy(&arrayBody(t, newArray, 0), &arrayBody(t, array, 0),
|
||||||
|
length * BytesPerWord);
|
||||||
|
}
|
||||||
|
|
||||||
return newArray;
|
return newArray;
|
||||||
}
|
}
|
||||||
@ -6103,9 +6269,11 @@ truncateLineNumberTable(Thread* t, object table, unsigned length)
|
|||||||
PROTECT(t, table);
|
PROTECT(t, table);
|
||||||
|
|
||||||
object newTable = makeLineNumberTable(t, length);
|
object newTable = makeLineNumberTable(t, length);
|
||||||
memcpy(&lineNumberTableBody(t, newTable, 0),
|
if (length) {
|
||||||
&lineNumberTableBody(t, table, 0),
|
memcpy(&lineNumberTableBody(t, newTable, 0),
|
||||||
length * sizeof(uint64_t));
|
&lineNumberTableBody(t, table, 0),
|
||||||
|
length * sizeof(uint64_t));
|
||||||
|
}
|
||||||
|
|
||||||
return newTable;
|
return newTable;
|
||||||
}
|
}
|
||||||
@ -6139,11 +6307,16 @@ translateExceptionHandlerTable(MyThread* t, Context* context, intptr_t start)
|
|||||||
exceptionHandlerEnd(oldHandler));
|
exceptionHandlerEnd(oldHandler));
|
||||||
|
|
||||||
if (LIKELY(handlerStart >= 0)) {
|
if (LIKELY(handlerStart >= 0)) {
|
||||||
|
assert(t, handlerStart < static_cast<int>
|
||||||
|
(codeLength(t, methodCode(t, context->method))));
|
||||||
|
|
||||||
int handlerEnd = resolveIpBackwards
|
int handlerEnd = resolveIpBackwards
|
||||||
(context, exceptionHandlerEnd(oldHandler),
|
(context, exceptionHandlerEnd(oldHandler),
|
||||||
exceptionHandlerStart(oldHandler));
|
exceptionHandlerStart(oldHandler));
|
||||||
|
|
||||||
assert(t, handlerEnd >= 0);
|
assert(t, handlerEnd >= 0);
|
||||||
|
assert(t, handlerEnd < static_cast<int>
|
||||||
|
(codeLength(t, methodCode(t, context->method))));
|
||||||
|
|
||||||
intArrayBody(t, newIndex, ni * 3)
|
intArrayBody(t, newIndex, ni * 3)
|
||||||
= c->machineIp(handlerStart)->value() - start;
|
= c->machineIp(handlerStart)->value() - start;
|
||||||
@ -6489,7 +6662,7 @@ calculateFrameMaps(MyThread* t, Context* context, uintptr_t* originalRoots,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (path == 0) {
|
if (path == 0) {
|
||||||
path = new (context->zone.allocate(sizeof(SubroutinePath)))
|
path = new(&context->zone)
|
||||||
SubroutinePath(call, subroutinePath,
|
SubroutinePath(call, subroutinePath,
|
||||||
makeRootTable(t, &(context->zone), context->method));
|
makeRootTable(t, &(context->zone), context->method));
|
||||||
}
|
}
|
||||||
@ -6871,15 +7044,14 @@ finish(MyThread* t, FixedAllocator* allocator, Context* context)
|
|||||||
// we must acquire the class lock here at the latest
|
// we must acquire the class lock here at the latest
|
||||||
|
|
||||||
unsigned codeSize = c->resolve
|
unsigned codeSize = c->resolve
|
||||||
(allocator->base + allocator->offset + TargetBytesPerWord);
|
(allocator->base + allocator->offset);
|
||||||
|
|
||||||
unsigned total = pad(codeSize, TargetBytesPerWord)
|
unsigned total = pad(codeSize, TargetBytesPerWord)
|
||||||
+ pad(c->poolSize(), TargetBytesPerWord) + TargetBytesPerWord;
|
+ pad(c->poolSize(), TargetBytesPerWord);
|
||||||
|
|
||||||
target_uintptr_t* code = static_cast<target_uintptr_t*>
|
target_uintptr_t* code = static_cast<target_uintptr_t*>
|
||||||
(allocator->allocate(total, TargetBytesPerWord));
|
(allocator->allocate(total, TargetBytesPerWord));
|
||||||
code[0] = codeSize;
|
uint8_t* start = reinterpret_cast<uint8_t*>(code);
|
||||||
uint8_t* start = reinterpret_cast<uint8_t*>(code + 1);
|
|
||||||
|
|
||||||
context->executableAllocator = allocator;
|
context->executableAllocator = allocator;
|
||||||
context->executableStart = code;
|
context->executableStart = code;
|
||||||
@ -6915,8 +7087,7 @@ finish(MyThread* t, FixedAllocator* allocator, Context* context)
|
|||||||
p != bc->addressSentinal;
|
p != bc->addressSentinal;
|
||||||
p = p->next)
|
p = p->next)
|
||||||
{
|
{
|
||||||
p->basis = new (bc->zone->allocate(sizeof(ResolvedPromise)))
|
p->basis = new(bc->zone) ResolvedPromise(p->basis->value());
|
||||||
ResolvedPromise(p->basis->value());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6932,7 +7103,7 @@ finish(MyThread* t, FixedAllocator* allocator, Context* context)
|
|||||||
|
|
||||||
code = makeCode
|
code = makeCode
|
||||||
(t, 0, newExceptionHandlerTable, newLineNumberTable,
|
(t, 0, newExceptionHandlerTable, newLineNumberTable,
|
||||||
reinterpret_cast<uintptr_t>(start), codeMaxStack(t, code),
|
reinterpret_cast<uintptr_t>(start), codeSize, codeMaxStack(t, code),
|
||||||
codeMaxLocals(t, code), 0);
|
codeMaxLocals(t, code), 0);
|
||||||
|
|
||||||
set(t, context->method, MethodCode, code);
|
set(t, context->method, MethodCode, code);
|
||||||
@ -7636,6 +7807,7 @@ visitStack(MyThread* t, Heap::Visitor* v)
|
|||||||
MyThread::CallTrace* trace = t->trace;
|
MyThread::CallTrace* trace = t->trace;
|
||||||
object targetMethod = (trace ? trace->targetMethod : 0);
|
object targetMethod = (trace ? trace->targetMethod : 0);
|
||||||
object target = targetMethod;
|
object target = targetMethod;
|
||||||
|
bool mostRecent = true;
|
||||||
|
|
||||||
while (stack) {
|
while (stack) {
|
||||||
if (targetMethod) {
|
if (targetMethod) {
|
||||||
@ -7648,7 +7820,7 @@ visitStack(MyThread* t, Heap::Visitor* v)
|
|||||||
PROTECT(t, method);
|
PROTECT(t, method);
|
||||||
|
|
||||||
void* nextIp = ip;
|
void* nextIp = ip;
|
||||||
nextFrame(t, &nextIp, &stack, method, target);
|
nextFrame(t, &nextIp, &stack, method, target, mostRecent);
|
||||||
|
|
||||||
visitStackAndLocals(t, v, stack, method, ip);
|
visitStackAndLocals(t, v, stack, method, ip);
|
||||||
|
|
||||||
@ -7669,6 +7841,8 @@ visitStack(MyThread* t, Heap::Visitor* v)
|
|||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mostRecent = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8037,10 +8211,17 @@ class ArgumentList {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'J':
|
case 'J':
|
||||||
case 'D':
|
|
||||||
addLong(va_arg(arguments, uint64_t));
|
addLong(va_arg(arguments, uint64_t));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'D':
|
||||||
|
addLong(doubleToBits(va_arg(arguments, double)));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'F':
|
||||||
|
addInt(floatToBits(va_arg(arguments, double)));
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
addInt(va_arg(arguments, uint32_t));
|
addInt(va_arg(arguments, uint32_t));
|
||||||
break;
|
break;
|
||||||
@ -8150,7 +8331,7 @@ invoke(Thread* thread, object method, ArgumentList* arguments)
|
|||||||
uintptr_t stackLimit = t->stackLimit;
|
uintptr_t stackLimit = t->stackLimit;
|
||||||
uintptr_t stackPosition = reinterpret_cast<uintptr_t>(&t);
|
uintptr_t stackPosition = reinterpret_cast<uintptr_t>(&t);
|
||||||
if (stackLimit == 0) {
|
if (stackLimit == 0) {
|
||||||
t->stackLimit = stackPosition - StackSizeInBytes;
|
t->stackLimit = stackPosition - t->m->stackSizeInBytes;
|
||||||
} else if (stackPosition < stackLimit) {
|
} else if (stackPosition < stackLimit) {
|
||||||
throwNew(t, Machine::StackOverflowErrorType);
|
throwNew(t, Machine::StackOverflowErrorType);
|
||||||
}
|
}
|
||||||
@ -8295,6 +8476,24 @@ processor(MyThread* t);
|
|||||||
void
|
void
|
||||||
compileThunks(MyThread* t, FixedAllocator* allocator);
|
compileThunks(MyThread* t, FixedAllocator* allocator);
|
||||||
|
|
||||||
|
class CompilationHandlerList {
|
||||||
|
public:
|
||||||
|
CompilationHandlerList(CompilationHandlerList* next, Processor::CompilationHandler* handler):
|
||||||
|
next(next),
|
||||||
|
handler(handler) {}
|
||||||
|
|
||||||
|
void dispose(Allocator* allocator) {
|
||||||
|
if(this) {
|
||||||
|
next->dispose(allocator);
|
||||||
|
handler->dispose();
|
||||||
|
allocator->free(this, sizeof(*this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CompilationHandlerList* next;
|
||||||
|
Processor::CompilationHandler* handler;
|
||||||
|
};
|
||||||
|
|
||||||
class MyProcessor: public Processor {
|
class MyProcessor: public Processor {
|
||||||
public:
|
public:
|
||||||
class Thunk {
|
class Thunk {
|
||||||
@ -8338,7 +8537,8 @@ class MyProcessor: public Processor {
|
|||||||
FixedSizeOfArithmeticException),
|
FixedSizeOfArithmeticException),
|
||||||
codeAllocator(s, 0, 0),
|
codeAllocator(s, 0, 0),
|
||||||
callTableSize(0),
|
callTableSize(0),
|
||||||
useNativeFeatures(useNativeFeatures)
|
useNativeFeatures(useNativeFeatures),
|
||||||
|
compilationHandlers(0)
|
||||||
{
|
{
|
||||||
thunkTable[compileMethodIndex] = voidPointer(local::compileMethod);
|
thunkTable[compileMethodIndex] = voidPointer(local::compileMethod);
|
||||||
thunkTable[compileVirtualMethodIndex] = voidPointer(compileVirtualMethod);
|
thunkTable[compileVirtualMethodIndex] = voidPointer(compileVirtualMethod);
|
||||||
@ -8525,7 +8725,7 @@ class MyProcessor: public Processor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Reference* r = new (t->m->heap->allocate(sizeof(Reference)))
|
Reference* r = new (t->m->heap->allocate(sizeof(Reference)))
|
||||||
Reference(o, &(t->reference));
|
Reference(o, &(t->reference), false);
|
||||||
|
|
||||||
acquire(t, r);
|
acquire(t, r);
|
||||||
|
|
||||||
@ -8644,6 +8844,7 @@ class MyProcessor: public Processor {
|
|||||||
t->arch->release();
|
t->arch->release();
|
||||||
|
|
||||||
t->m->heap->free(t, sizeof(*t));
|
t->m->heap->free(t, sizeof(*t));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void dispose() {
|
virtual void dispose() {
|
||||||
@ -8651,6 +8852,8 @@ class MyProcessor: public Processor {
|
|||||||
s->freeExecutable(codeAllocator.base, codeAllocator.capacity);
|
s->freeExecutable(codeAllocator.base, codeAllocator.capacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
compilationHandlers->dispose(allocator);
|
||||||
|
|
||||||
s->handleSegFault(0);
|
s->handleSegFault(0);
|
||||||
|
|
||||||
allocator->free(this, sizeof(*this));
|
allocator->free(this, sizeof(*this));
|
||||||
@ -8674,7 +8877,7 @@ class MyProcessor: public Processor {
|
|||||||
// we caught the thread in Java code - use the register values
|
// we caught the thread in Java code - use the register values
|
||||||
c.ip = ip;
|
c.ip = ip;
|
||||||
c.stack = stack;
|
c.stack = stack;
|
||||||
c.javaStackLimit = stack;
|
c.methodIsMostRecent = true;
|
||||||
} else if (target->transition) {
|
} else if (target->transition) {
|
||||||
// we caught the thread in native code while in the middle
|
// we caught the thread in native code while in the middle
|
||||||
// of updating the context fields (MyThread::stack, etc.)
|
// of updating the context fields (MyThread::stack, etc.)
|
||||||
@ -8747,6 +8950,10 @@ class MyProcessor: public Processor {
|
|||||||
codeAllocator.capacity = capacity;
|
codeAllocator.capacity = capacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void addCompilationHandler(CompilationHandler* handler) {
|
||||||
|
compilationHandlers = new(allocator->allocate(sizeof(CompilationHandlerList))) CompilationHandlerList(compilationHandlers, handler);
|
||||||
|
}
|
||||||
|
|
||||||
virtual void compileMethod(Thread* vmt, Zone* zone, object* constants,
|
virtual void compileMethod(Thread* vmt, Zone* zone, object* constants,
|
||||||
object* calls, DelayedPromise** addresses,
|
object* calls, DelayedPromise** addresses,
|
||||||
object method, OffsetResolver* resolver)
|
object method, OffsetResolver* resolver)
|
||||||
@ -8902,8 +9109,56 @@ class MyProcessor: public Processor {
|
|||||||
unsigned callTableSize;
|
unsigned callTableSize;
|
||||||
bool useNativeFeatures;
|
bool useNativeFeatures;
|
||||||
void* thunkTable[dummyIndex + 1];
|
void* thunkTable[dummyIndex + 1];
|
||||||
|
CompilationHandlerList* compilationHandlers;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const char*
|
||||||
|
stringOrNull(const char* str) {
|
||||||
|
if(str) {
|
||||||
|
return str;
|
||||||
|
} else {
|
||||||
|
return "(null)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
stringOrNullSize(const char* str) {
|
||||||
|
return strlen(stringOrNull(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
logCompile(MyThread* t, const void* code, unsigned size, const char* class_,
|
||||||
|
const char* name, const char* spec)
|
||||||
|
{
|
||||||
|
static bool open = false;
|
||||||
|
if (not open) {
|
||||||
|
open = true;
|
||||||
|
const char* path = findProperty(t, "avian.jit.log");
|
||||||
|
if (path) {
|
||||||
|
compileLog = vm::fopen(path, "wb");
|
||||||
|
} else if (DebugCompile) {
|
||||||
|
compileLog = stderr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (compileLog) {
|
||||||
|
fprintf(compileLog, "%p %p %s.%s%s\n",
|
||||||
|
code, static_cast<const uint8_t*>(code) + size,
|
||||||
|
class_, name, spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t nameLength = stringOrNullSize(class_) + stringOrNullSize(name) + stringOrNullSize(spec) + 2;
|
||||||
|
|
||||||
|
THREAD_RUNTIME_ARRAY(t, char, completeName, nameLength);
|
||||||
|
|
||||||
|
sprintf(RUNTIME_ARRAY_BODY(completeName), "%s.%s%s", stringOrNull(class_), stringOrNull(name), stringOrNull(spec));
|
||||||
|
|
||||||
|
MyProcessor* p = static_cast<MyProcessor*>(t->m->processor);
|
||||||
|
for(CompilationHandlerList* h = p->compilationHandlers; h; h = h->next) {
|
||||||
|
h->handler->compiled(code, 0, 0, RUNTIME_ARRAY_BODY(completeName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void*
|
void*
|
||||||
compileMethod2(MyThread* t, void* ip)
|
compileMethod2(MyThread* t, void* ip)
|
||||||
{
|
{
|
||||||
@ -9303,8 +9558,7 @@ fixupMethods(Thread* t, object map, BootImage* image UNUSED, uint8_t* code)
|
|||||||
logCompile
|
logCompile
|
||||||
(static_cast<MyThread*>(t),
|
(static_cast<MyThread*>(t),
|
||||||
reinterpret_cast<uint8_t*>(methodCompiled(t, method)),
|
reinterpret_cast<uint8_t*>(methodCompiled(t, method)),
|
||||||
reinterpret_cast<uintptr_t*>
|
methodCompiledSize(t, method),
|
||||||
(methodCompiled(t, method))[-1],
|
|
||||||
reinterpret_cast<char*>
|
reinterpret_cast<char*>
|
||||||
(&byteArrayBody(t, className(t, methodClass(t, method)), 0)),
|
(&byteArrayBody(t, className(t, methodClass(t, method)), 0)),
|
||||||
reinterpret_cast<char*>
|
reinterpret_cast<char*>
|
||||||
@ -9495,8 +9749,7 @@ compileCall(MyThread* t, Context* c, ThunkIndex index, bool call = true)
|
|||||||
(call ? Call : Jump, TargetBytesPerWord, RegisterOperand, &scratch);
|
(call ? Call : Jump, TargetBytesPerWord, RegisterOperand, &scratch);
|
||||||
} else {
|
} else {
|
||||||
Assembler::Constant proc
|
Assembler::Constant proc
|
||||||
(new (c->zone.allocate(sizeof(ResolvedPromise)))
|
(new(&c->zone) ResolvedPromise(reinterpret_cast<intptr_t>(t->thunkTable[index])));
|
||||||
ResolvedPromise(reinterpret_cast<intptr_t>(t->thunkTable[index])));
|
|
||||||
|
|
||||||
a->apply
|
a->apply
|
||||||
(call ? LongCall : LongJump, TargetBytesPerWord, ConstantOperand, &proc);
|
(call ? LongCall : LongJump, TargetBytesPerWord, ConstantOperand, &proc);
|
||||||
@ -9771,7 +10024,15 @@ compileVirtualThunk(MyThread* t, unsigned index, unsigned* size)
|
|||||||
a->setDestination(start);
|
a->setDestination(start);
|
||||||
a->write();
|
a->write();
|
||||||
|
|
||||||
logCompile(t, start, *size, 0, "virtualThunk", 0);
|
const char* const virtualThunkBaseName = "virtualThunk";
|
||||||
|
const size_t virtualThunkBaseNameLength = strlen(virtualThunkBaseName);
|
||||||
|
const size_t maxIntStringLength = 10;
|
||||||
|
|
||||||
|
THREAD_RUNTIME_ARRAY(t, char, virtualThunkName, virtualThunkBaseNameLength + maxIntStringLength);
|
||||||
|
|
||||||
|
sprintf(RUNTIME_ARRAY_BODY(virtualThunkName), "%s%d", virtualThunkBaseName, index);
|
||||||
|
|
||||||
|
logCompile(t, start, *size, 0, virtualThunkName, 0);
|
||||||
|
|
||||||
return reinterpret_cast<uintptr_t>(start);
|
return reinterpret_cast<uintptr_t>(start);
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user