initial support for Windows OpenJDK build

All the tests are passing for openjdk-src builds, but the non-src
openjdk build is crashing and there's trouble loading time zone info
from the embedded java.home directory.
This commit is contained in:
Joel Dice 2010-11-06 22:21:19 -06:00
parent df299f3564
commit e1b808024a
6 changed files with 196 additions and 43 deletions

View File

@ -124,7 +124,7 @@ warnings = -Wall -Wextra -Werror -Wunused-parameter -Winit-self \
common-cflags = $(warnings) -fno-rtti -fno-exceptions -fno-omit-frame-pointer \
"-I$(JAVA_HOME)/include" -idirafter $(src) -I$(build) $(classpath-cflags) \
-D__STDC_LIMIT_MACROS -D_JNI_IMPLEMENTATION_ -DAVIAN_VERSION=\"$(version)\" \
-DUSE_ATOMIC_OPERATIONS -DAVIAN_JAVA_HOME=\"$(javahome)\" \
-DUSE_ATOMIC_OPERATIONS "-DAVIAN_JAVA_HOME=\"$(javahome)\"" \
-DAVIAN_EMBED_PREFIX=\"$(embed-prefix)\"
build-cflags = $(common-cflags) -fPIC -fvisibility=hidden \
@ -138,6 +138,8 @@ build-lflags = -lz -lpthread -ldl
lflags = $(common-lflags) -lpthread -ldl
build-system = posix
system = posix
asm = x86
@ -196,6 +198,8 @@ ifeq ($(platform),windows)
inc = "$(root)/win32/include"
lib = "$(root)/win32/lib"
embed-prefix = c:/avian-embedded
system = windows
so-prefix =
@ -213,6 +217,7 @@ ifeq ($(platform),windows)
ranlib = i586-mingw32msvc-ranlib
strip = i586-mingw32msvc-strip
else
build-platform = windows
common-cflags += "-I$(JAVA_HOME)/include/win32"
build-cflags = $(common-cflags) -I$(src) -mthreads
ifeq ($(build-platform),cygwin)
@ -402,7 +407,7 @@ boot-object = $(build)/boot.o
generator-depends := $(wildcard $(src)/*.h)
generator-sources = \
$(src)/type-generator.cpp \
$(src)/$(system).cpp \
$(src)/$(build-system).cpp \
$(src)/finder.cpp
generator-cpp-objects = \
$(foreach x,$(1),$(patsubst $(2)/%.cpp,$(3)/%-build.o,$(x)))

View File

@ -128,7 +128,35 @@ openjdk-cflags = \
-D_GNU_SOURCE
ifeq ($(platform),windows)
# todo
openjdk-sources += \
$(openjdk-src)/windows/native/java/io/canonicalize_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/FileInputStream_md.c \
$(openjdk-src)/windows/native/java/io/FileOutputStream_md.c \
$(openjdk-src)/windows/native/java/io/FileSystem_md.c \
$(openjdk-src)/windows/native/java/io/io_util_md.c \
$(openjdk-src)/windows/native/java/io/RandomAccessFile_md.c \
$(openjdk-src)/windows/native/java/io/Win32FileSystem_md.c \
$(openjdk-src)/windows/native/java/io/WinNTFileSystem_md.c \
$(openjdk-src)/windows/native/java/lang/java_props_md.c \
$(openjdk-src)/windows/native/java/lang/ProcessEnvironment_md.c \
$(openjdk-src)/windows/native/java/util/WindowsPreferences.c \
$(openjdk-src)/windows/native/java/util/logging.c \
$(openjdk-src)/windows/native/java/util/TimeZone_md.c \
$(openjdk-src)/windows/native/sun/io/Win32ErrorMode.c \
openjdk-headers-classes += \
sun.io.Win32ErrorMode
openjdk-cflags += "-I$(openjdk-src)/windows/javavm/export" \
"-I$(openjdk-src)/windows/native/common" \
"-I$(openjdk-src)/windows/native/java/io" \
"-I$(openjdk-src)/windows/native/java/util" \
"-I$(openjdk-src)/windows/javavm/include" \
"-I$(root)/win32/include" \
-D_JNI_IMPLEMENTATION_ \
-D_JAVASOFT_WIN32_TYPEDEF_MD_H_
else
openjdk-sources += \
$(openjdk-src)/solaris/native/common/jdk_util_md.c \

View File

@ -20,10 +20,21 @@
# include <io.h>
# include <direct.h>
# include <share.h>
# include <errno.h>
# include <fcntl.h>
# include <sys/stat.h>
# include <sys/types.h>
#undef interface
# define CLOSE _close
# define READ _read
# define WRITE _write
# define FSTAT _fstat
# define STAT _stat
# define LSEEK _lseek
# define S_ISSOCK(x) false
# ifdef _MSC_VER
# define S_ISREG(x) ((x) | _S_IFREG)
@ -31,13 +42,17 @@
# define S_IRUSR _S_IREAD
# define S_IWUSR _S_IWRITE
# else
# define OPEN _wopen
# define CREAT _wcreat
# define OPEN _open
# define CREAT _creat
# endif
#define O_RDONLY _O_RDONLY
# define LIBRARY_PREFIX ""
# define LIBRARY_SUFFIX ".dll"
typedef int socklen_t;
#else // not PLATFORM_WINDOWS
# include <unistd.h>
@ -355,11 +370,20 @@ class MyClasspath : public Classpath {
globalMachine = t->m;
#ifdef AVIAN_OPENJDK_SRC
{ object ufsClass = resolveClass
(t, root(t, Machine::BootLoader), "java/io/UnixFileSystem");
{
#ifdef PLATFORM_WINDOWS
const char* const fsClassName = "java/io/WinNTFileSystem";
const char* const gbaMethodName = "getBooleanAttributes";
#else
const char* const fsClassName = "java/io/UnixFileSystem";
const char* const gbaMethodName = "getBooleanAttributes0";
#endif
if (ufsClass) {
PROTECT(t, ufsClass);
object fsClass = resolveClass
(t, root(t, Machine::BootLoader), fsClassName, false);
if (fsClass) {
PROTECT(t, fsClass);
object fileClass = resolveClass
(t, root(t, Machine::BootLoader), "java/io/File");
@ -371,10 +395,10 @@ class MyClasspath : public Classpath {
if (pathField) {
this->pathField = fieldOffset(t, pathField);
intercept(t, ufsClass, "getBooleanAttributes0",
"(Ljava/io/File;)I", voidPointer(getFileAttributes));
intercept(t, fsClass, gbaMethodName, "(Ljava/io/File;)I",
voidPointer(getFileAttributes));
intercept(t, ufsClass, "getLength", "(Ljava/io/File;)J",
intercept(t, fsClass, "getLength", "(Ljava/io/File;)J",
voidPointer(getLength));
}
}
@ -511,10 +535,30 @@ getFinder(Thread* t, const char* name, unsigned nameLength)
return 0;
}
bool
pathEqual(const char* a, const char* b, unsigned length)
{
#ifdef PLATFORM_WINDOWS
return strncasecmp(a, b, length) == 0;
#else
return strncmp(a, b, length) == 0;
#endif
}
bool
pathEqual(const char* a, const char* b)
{
#ifdef PLATFORM_WINDOWS
return strcasecmp(a, b) == 0;
#else
return strcmp(a, b) == 0;
#endif
}
class EmbeddedFile {
public:
EmbeddedFile(MyClasspath* cp, const char* path, unsigned pathLength) {
if (strncmp(cp->embedPrefix, path, cp->embedPrefixLength) == 0) {
if (pathEqual(cp->embedPrefix, path, cp->embedPrefixLength)) {
const char* p = path + cp->embedPrefixLength;
while (*p == '/') ++ p;
@ -564,8 +608,9 @@ getFileAttributes
RUNTIME_ARRAY(char, p, stringLength(t, path) + 1);
stringChars(t, path, RUNTIME_ARRAY_BODY(p));
replace('\\', '/', RUNTIME_ARRAY_BODY(p));
if (strcmp(cp->zipLibrary, RUNTIME_ARRAY_BODY(p)) == 0) {
if (pathEqual(cp->zipLibrary, RUNTIME_ARRAY_BODY(p))) {
return Exists | Regular;
} else {
EmbeddedFile ef(cp, RUNTIME_ARRAY_BODY(p), stringLength(t, path));
@ -613,6 +658,7 @@ getLength
RUNTIME_ARRAY(char, p, stringLength(t, path) + 1);
stringChars(t, path, RUNTIME_ARRAY_BODY(p));
replace('\\', '/', RUNTIME_ARRAY_BODY(p));
EmbeddedFile ef(cp, RUNTIME_ARRAY_BODY(p), stringLength(t, path));
if (ef.jar) {
@ -894,6 +940,31 @@ interruptLock(Thread* t, object thread)
return threadInterruptLock(t, thread);
}
bool
pipeAvailable(int fd, int* available)
{
#ifdef PLATFORM_WINDOWS
HANDLE h = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
if (h == INVALID_HANDLE_VALUE) {
return false;
}
DWORD n;
if (PeekNamedPipe(h, 0,0, 0, &n, 0)) {
*available = n;
} else {
if (GetLastError() != ERROR_BROKEN_PIPE) {
return false;
}
*available = 0;
}
return true;
#else
return ioctl(fd, FIONREAD, available) >= 0;
#endif
}
} // namespace local
} // namespace
@ -1470,13 +1541,17 @@ extern "C" JNIEXPORT jint JNICALL
JVM_ActiveProcessorCount(void) { abort(); }
extern "C" JNIEXPORT void* JNICALL
JVM_LoadLibrary(const char* name)
JVM_LoadLibrary(const char* path)
{
Thread* t = static_cast<Thread*>(local::globalMachine->localThread->get());
RUNTIME_ARRAY(char, p, strlen(path) + 1);
replace('\\', '/', RUNTIME_ARRAY_BODY(p), path);
#ifdef AVIAN_OPENJDK_SRC
if (strcmp(static_cast<local::MyClasspath*>(t->m->classpath)->zipLibrary,
name) == 0)
if (local::pathEqual
(static_cast<local::MyClasspath*>(t->m->classpath)->zipLibrary,
RUNTIME_ARRAY_BODY(p)))
{
return t->m->libraries;
}
@ -1485,8 +1560,8 @@ JVM_LoadLibrary(const char* name)
ENTER(t, Thread::ActiveState);
return loadLibrary
(t, static_cast<local::MyClasspath*>(t->m->classpath)->libraryPath, name,
false, false);
(t, static_cast<local::MyClasspath*>(t->m->classpath)->libraryPath,
RUNTIME_ARRAY_BODY(p), false, false);
}
extern "C" JNIEXPORT void JNICALL
@ -1597,7 +1672,11 @@ JVM_SetThreadPriority(Thread*, jobject, jint)
extern "C" JNIEXPORT void JNICALL
JVM_Yield(Thread*, jclass)
{
#ifdef PLATFORM_WINDOWS
SwitchToThread();
#else
sched_yield();
#endif
}
extern "C" JNIEXPORT void JNICALL
@ -2655,7 +2734,12 @@ JVM_Open(const char* path, jint flags, jint mode)
Thread* t = static_cast<Thread*>(local::globalMachine->localThread->get());
local::MyClasspath* cp = static_cast<local::MyClasspath*>(t->m->classpath);
local::EmbeddedFile ef(cp, path, strlen(path));
unsigned length = strlen(path);
RUNTIME_ARRAY(char, p, length + 1);
replace('\\', '/', RUNTIME_ARRAY_BODY(p), path);
local::EmbeddedFile ef(cp, RUNTIME_ARRAY_BODY(p), length);
if (ef.jar) {
if (flags != O_RDONLY) {
errno = EACCES;
@ -2706,7 +2790,7 @@ JVM_Open(const char* path, jint flags, jint mode)
return index + local::VirtualFileBase;
} else {
int r = OPEN(path, flags, mode);
int r = OPEN(RUNTIME_ARRAY_BODY(p), flags, mode);
expect(t, r < local::VirtualFileBase);
return r;
}
@ -2797,13 +2881,13 @@ JVM_Available(jint fd, jlong* result)
return 0;
}
} else {
struct stat buffer;
struct STAT buffer;
int n;
if (FSTAT(fd, &buffer) >= 0
and (S_ISCHR(buffer.st_mode)
or S_ISFIFO(buffer.st_mode)
or S_ISSOCK(buffer.st_mode))
and ioctl(fd, FIONREAD, &n) >= 0)
and local::pipeAvailable(fd, &n))
{
*result = n;
return 1;
@ -2877,7 +2961,22 @@ JVM_SetLength(jint, jlong) { abort(); }
extern "C" JNIEXPORT jint JNICALL
JVM_Sync(jint fd)
{
#ifdef PLATFORM_WINDOWS
HANDLE h = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
if (h == INVALID_HANDLE_VALUE) {
errno = EBADF;
return -1;
}
if (FlushFileBuffers(h)) {
return 0;
} else {
errno = EIO;
return -1;
}
#else
return fsync(fd);
#endif
}
extern "C" JNIEXPORT jint JNICALL
@ -3091,3 +3190,18 @@ jio_vfprintf(FILE* stream, const char* format, va_list a)
// return r;
// }
#ifdef PLATFORM_WINDOWS
namespace { HMODULE jvmHandle = 0; }
extern "C" int JDK_InitJvmHandle()
{
jvmHandle = GetModuleHandle(0);
return jvmHandle != 0;
}
extern "C" void* JDK_FindJvmEntry(const char* name)
{
return voidPointer(GetProcAddress(jvmHandle, name));
}
#endif

3
src/openjdk/Wincon.h Normal file
View File

@ -0,0 +1,3 @@
// Console_md.c #includes "Wincon.h", which only matches "wincon.h" on
// a case insensive filesystem, so we redirect here.
#include "wincon.h"

View File

@ -15,12 +15,13 @@
#if (defined __MINGW32__) || (defined _MSC_VER)
# define JNIEXPORT __declspec(dllexport)
# define JNICALL __stdcall
#else // not (defined __MINGW32__) || (defined _MSC_VER)
# define JNIEXPORT __attribute__ ((visibility("default")))
# define JNICALL
#endif // not (defined __MINGW32__) || (defined _MSC_VER)
#define JNIIMPORT
#define JNICALL
typedef int32_t jint;
typedef int64_t jlong;

View File

@ -457,11 +457,10 @@ class MySystem: public System {
class Library: public System::Library {
public:
Library(System* s, HMODULE handle, const char* name, bool mapName):
Library(System* s, HMODULE handle, const char* name):
s(s),
handle(handle),
name_(name),
mapName_(mapName),
next_(0)
{ }
@ -476,10 +475,6 @@ class MySystem: public System {
return name_;
}
virtual bool mapName() {
return mapName_;
}
virtual System::Library* next() {
return next_;
}
@ -511,7 +506,6 @@ class MySystem: public System {
System* s;
HMODULE handle;
const char* name_;
bool mapName_;
System::Library* next_;
};
@ -701,35 +695,40 @@ class MySystem: public System {
return status;
}
virtual FileType identify(const char* name) {
virtual FileType stat(const char* name, unsigned* length) {
struct _stat s;
int r = _stat(name, &s);
if (r == 0) {
if (S_ISREG(s.st_mode)) {
*length = s.st_size;
return TypeFile;
} else if (S_ISDIR(s.st_mode)) {
*length = 0;
return TypeDirectory;
} else {
*length = 0;
return TypeUnknown;
}
} else {
*length = 0;
return TypeDoesNotExist;
}
}
virtual const char* libraryPrefix() {
return "";
}
virtual const char* librarySuffix() {
return SO_SUFFIX;
}
virtual Status load(System::Library** lib,
const char* name,
bool mapName)
const char* name)
{
HMODULE handle;
unsigned nameLength = (name ? strlen(name) : 0);
if (mapName and name) {
unsigned size = sizeof(SO_PREFIX) + nameLength + sizeof(SO_SUFFIX);
RUNTIME_ARRAY(char, buffer, size);;
vm::snprintf
(RUNTIME_ARRAY_BODY(buffer), size, SO_PREFIX "%s" SO_SUFFIX, name);
handle = LoadLibrary(RUNTIME_ARRAY_BODY(buffer));
} else if (name) {
if (name) {
handle = LoadLibrary(name);
} else {
handle = GetModuleHandle(0);
@ -748,8 +747,7 @@ class MySystem: public System {
n = 0;
}
*lib = new (allocate(this, sizeof(Library)))
Library(this, handle, n, mapName);
*lib = new (allocate(this, sizeof(Library))) Library(this, handle, n);
return 0;
} else {
@ -761,6 +759,10 @@ class MySystem: public System {
return ';';
}
virtual char fileSeparator() {
return '\\';
}
virtual int64_t now() {
static LARGE_INTEGER frequency;
static LARGE_INTEGER time;