Permalink
Browse files

Add OpenJDK8 package and libffi for zero build

  • Loading branch information...
myunghoj committed Aug 17, 2016
1 parent 54ec653 commit 09019f5b1ba5c2fd326c7c53fc2acf1cfa2a9c08
@@ -2,6 +2,7 @@
# Install additional build dependencies for packages
# mysql: makefs
sudo apt-get install makefs
sudo apt-get install openjdk-7-jdk

# Build and install rumprun toolchain from source
RUMPRUN_PLATFORM=${RUMPRUN_PLATFORM:-hw}
@@ -5,4 +5,9 @@ if [ -z "${PACKAGE}" ]; then
exit 1
fi
cd ${PACKAGE}
make -j2
# Openjdk make should not be used with option -j
if [ "${PACKAGE}" == "openjdk8" ]; then
make
else
make -j2
fi
@@ -43,6 +43,8 @@ env:
- PACKAGE=sqlite
- PACKAGE=tor
- PACKAGE=apache2
- PACKAGE=libffi
- PACKAGE=openjdk8

notifications:
irc:
@@ -0,0 +1,35 @@
include ../Makefile.inc
UPSTREAM=ftp://sourceware.org/pub/libffi/libffi-3.2.1.tar.gz
TARBALL=$(notdir $(UPSTREAM))

all: build/libffi

build/libffi: build/Makefile
$(MAKE) -C build
$(MAKE) install -C build

LIBFFI_CONF_OPTS += \
--host=$(RUMPRUN_TOOLCHAIN_TUPLE) \
--prefix=$(RUMPRUN_PKGS_DIR) \
--disable-shared \
--with-sysroot=$(RUMPRUN_PKGS_DIR)

build/Makefile: build/stamp_patch
(cd build; \
./configure --host=$(RUMPRUN_TOOLCHAIN_TUPLE) $(LIBFFI_CONF_OPTS);)

build/stamp_patch: build/configure
../scripts/apply-patches.sh build/ patches/*
touch $@

dl/$(TARBALL):
mkdir -p dl
../scripts/fetch.sh ${UPSTREAM} dl/$(TARBALL)

build/configure: | dl/$(TARBALL)
mkdir -p build
(cd build && tar -xz --strip-components 1 -f ../dl/$(TARBALL))

.PHONY: clean
clean:
rm -rf build
@@ -0,0 +1,22 @@
Overview
========

A Portable Foreign Function Interface Library for OpenJDK8
https://sourceware.org/libffi/


Maintainer
----------

* Myungho Jung, mhjungk@gmail.com
* Github: @myunghoj

Patches
=======

Libffi has a bug that memory may be corrupted in multithreading if memory is deallocated by moving stack pointer. This patch apllies to `unix64.S` assembly code which fixes page fault error. This bug is found while testing `jetty` web server on `OpenJDK8` package.

Instructions
============

Run `make`.
@@ -0,0 +1,21 @@
diff -ruN a/src/x86/unix64.S b/src/x86/unix64.S
--- a/src/x86/unix64.S 2016-08-16 16:19:54.652352911 -0600
+++ b/src/x86/unix64.S 2016-08-16 16:24:43.458234126 -0600
@@ -75,12 +75,14 @@
/* Call the user function. */
call *%r11

+ movq 0(%rbp), %rcx /* Reload flags. */
+ movq 8(%rbp), %rdi /* Reload raddr. */
+ movq 16(%rbp), %r12 /* Backup old frame pointer. */
+
/* Deallocate stack arg area; local stack frame in redzone. */
leaq 24(%rbp), %rsp

- movq 0(%rbp), %rcx /* Reload flags. */
- movq 8(%rbp), %rdi /* Reload raddr. */
- movq 16(%rbp), %rbp /* Reload old frame pointer. */
+ movq %r12, %rbp /* Restore old frame pointer. */
.LUW2:

/* The first byte of the flags contains the FFI_TYPE. */
@@ -0,0 +1,93 @@
include ../Makefile.inc
JRE_DIR=$(wildcard build/javadist/jvm/openjdk-1.8.0-internal*/jre)
JAVA_BIN=$(wildcard build/javadist/bin/java)
SUB_MODULES=build/corba build/jaxp build/jaxws build/langtools build/jdk build/hotspot build/nashorn

OPENJDK_HG=http://hg.openjdk.java.net/bsd-port/jdk8
JDK8_VER=5fef56ef47c7
CORBA_VER=56b133772ec1
HOTSPOT_VER=d208cc11392a
JAXP_VER=1f032000ff4b
JAXWS_VER=81f2d81a48d7
JDK_VER=18007ac912e3
LANGTOOLS_VER=357800aef413
NASHORN_VER=4195ebe2576e

export COMPILER_WARNINGS_FATAL=false

all: $(RUMPRUN_PKGS_DIR)/lib/libffi.a bin/java images/jre.iso images/jar.ffs

.NOTPARALLEL: $(RUMPRUN_PKGS_DIR)/lib/libffi.a
$(RUMPRUN_PKGS_DIR)/lib/libffi.a:
$(MAKE) -C ../libffi

bin/java: build/javadist/bin/java
mkdir -p bin
cp $(JAVA_BIN) $@

build/javadist/bin/java: build/Makefile
$(MAKE) -C build JOBS=2
$(MAKE) -C build install

OPENJDK_CONF_ENV += \
CC=$(RUMPRUN_CC) \
CXX=$(RUMPRUN_CXX) \
LIBFFI_CFLAGS="$(shell pkg-config $(RUMPRUN_PKGS_DIR)/lib/pkgconfig/libffi.pc --cflags)" \
LIBFFI_LIBS="$(shell pkg-config $(RUMPRUN_PKGS_DIR)/lib/pkgconfig/libffi.pc --libs)" \
ALT_OBJCOPY=$(RUMPRUN_TOOLCHAIN_TUPLE)-objcopy \

OPENJDK_CONF_OPTS += \
--prefix=$(shell pwd)/build/javadist \
--openjdk-target=$(RUMPRUN_TOOLCHAIN_TUPLE) \
--disable-headful \
--enable-static-build \
--enable-static-libjli \
--disable-debug-symbols \
--with-jvm-variants=zero \
--with-extra-cflags="-I${RUMPRUN_PKGS_DIR}/include -I${RUMPRUN_SYSROOT}/include \
-I$(shell pwd)/build/common/include" \
--with-extra-cxxflags="-Wno-literal-suffix -Wno-narrowing -I${RUMPRUN_SYSROOT}/include/c++" \
--without-freetype \
--without-x

build/Makefile: build/stamp_patch
(cd build; $(OPENJDK_CONF_ENV) $(SHELL) ./configure $(OPENJDK_CONF_OPTS))

build/stamp_patch: $(SUB_MODULES) patches/*
../scripts/apply-patches.sh build/ patches/*
touch $@

$(SUB_MODULES): build/get_source.sh
(cd build && $(SHELL) ./get_source.sh \
&& hg update $(JDK8_VER) \
&& cd corba && hg update $(CORBA_VER) && cd .. \
&& cd hotspot && hg update $(HOTSPOT_VER) && cd .. \
&& cd jaxp && hg update $(JAXP_VER) && cd .. \
&& cd jaxws && hg update $(JAXWS_VER) && cd .. \
&& cd jdk && hg update $(JDK_VER) && cd .. \
&& cd langtools && hg update $(LANGTOOLS_VER) && cd .. \
&& cd nashorn && hg update $(NASHORN_VER))

build/get_source.sh:
(mkdir -p build && hg clone $(OPENJDK_HG) build)

images/jre.iso: build/javadist
mkdir -p images
$(RUMPRUN_GENISOIMAGE) -o images/jre.iso $(JRE_DIR)/lib

images/jar.ffs:
mkdir -p images
../mysql/scripts/rumprun-makefs.sh -u 1 -g 1 images/jar.ffs jar

.PHONY: clean
clean:
-$(MAKE) -C build clean
rm -f bin/java
rm -f images/jre.iso
rm -f images/jar.ffs

.PHONY: distclean
distclean: clean
rm -rf build

include ../Makefile.deps
@@ -0,0 +1,96 @@
Overview
========

Packaging of the [OpenJDK8](http://openjdk.java.net/projects/bsd-port/) BSD Port for rumprun.

Maintainer
----------

* Myungho Jung, mhjungk@gmail.com
* Github: @myunghoj

Patches
=======

Lots of patches are required to build java binary. Most of the them are for changing shared libraries to static libraries. Also, problems in cross compiling on Linux and mmap flags are modified for Rump.

Instructions
============

`Makefile` will automatically clone repositories, update changeset, apply patches, and build them.

```
make
```

Basically, only java binary will be built. If you want to build other binaries, just remove comments in `build/jdk/make/CompileLaunchers.gmk`.

And bake the image like below:

```
rumprun-bake xen bin/java.bin bin/java
```

Replace the platfrom with yours.

Examples
========

`HelloWorld.jar` is included in this package for test. To run java application, `JAVA_HOME` and `CLASS_PATH` should be set.

````
rumprun qemu -i -M 512 \
-N java \
-b ../images/jre.iso,/jdk/jre/lib \
-b ../images/jar.ffs,/jar \
-e JAVA_HOME=/jdk \
-e CLASS_PATH=/jar:/jdk/jre/lib \
-- ../bin/java.bin -jar /jar/HelloWorld.jar
````

You will see `Hello World!` message on qemu window.

jetty
-----

One of the objectives of this project is to run `jetty` web server on Rump. `jetty` package is not included so you can download it from (http://repo1.maven.org/maven2/org/eclipse/jetty/jetty-distribution/9.3.11.v20160721/jetty-distribution-9.3.11.v20160721.tar.gz) and extract files to `/jar/jetty`. Most of java web applications are needed to extract and write files on image. So, you need to create writable image with `jetty`.

````
make images/jar
````

It makes a writeable file system image with files in `jar/*` to `images/jar.ffs`.

You can run `jetty` demo application by following command below.

````
rumprun xen -i -M 1024 \
-N java \
-I xen0,xenif,script=vif-openvswitch,bridge=xenbr0 \
-W xen0,inet,static,10.0.0.11/24 \
-b ../images/jre.iso,/jdk/jre/lib \
-b ../images/jar.ffs,/jar \
-e JAVA_HOME=/jdk \
-e CLASS_PATH=/jar/jetty:/jdk/jre/lib \
-- ../bin/java.bin \
-Djava.io.tmpdir=/jar -jar /jar/jetty/start.jar \
jetty.home=/jar/jetty jetty.base=/jar/jetty/demo-base
````

`java.io.tmpdir` should be set as writable path because `jetty` extracts war file to the path.


Known issues
============

For now, only main libraries to execute java applications are included, so some of them such as jdb and hprof cannot be used.

Java looks for libraries based on the location of java binary. But java binary is not included in the image so it will search from `JAVA_HOME/jre/lib`.

Jsig library is not used which makes directly send all signals to Rump instead of signal chaining.

X11, freetype, and alsa libraries are not necessary and it only works as headless. It may be a problem because some of the headless java server applications need packages for serving to clients.

Hotspot VM is only working properly as zero and it needs libffi. It can also be built as Server but there are bugs related to page fault errors. It may be caused by assembly code jumping to garbage address but it is hard to debug because of limited debugging environment.

`dlopen` and `dlsym` cannot be used because 'Rump' doesn't support shared libraries. So, those are changed to customized functions looking up symbols in binary. `dlopen` will return `0xdeadbeef` to avoid checking null. It may be a problem later. `dlsym` looks for symbol name defined in `nativeSymbolMap.h` which is manually added using `grep` and `sed`.
@@ -0,0 +1,9 @@
#!/bin/sh
set -x
rumprun qemu -i -M 1024 \
-N java \
-b ../images/jre.iso,/jdk/jre/lib \
-b ../images/jar.ffs,/jar \
-e JAVA_HOME=/jdk \
-e CLASS_PATH=/jar:/jdk/jre/lib \
-- ../bin/java.bin -jar /jar/HelloWorld.jar
Binary file not shown.
Oops, something went wrong.

2 comments on commit 09019f5

@myunghoj

This comment has been minimized.

Copy link
Contributor

myunghoj replied Aug 17, 2016

Hi all!

I just ported OpenJDK8 to rump. It only works as zero version for now. I tested jetty web server and demo application. It should be tested more but I hope you enjoy it :)

@anttikantee

This comment has been minimized.

Copy link
Member

anttikantee replied Aug 17, 2016

Please sign in to comment.