mirror of
https://github.com/corda/corda.git
synced 2025-01-04 04:04:27 +00:00
add optional LZMA support for compressing embedded JARs, boot images, and shared objects
This commit is contained in:
parent
bd7ef24734
commit
5d9f7b2bc3
94
makefile
94
makefile
@ -33,6 +33,9 @@ endif
|
|||||||
ifneq ($(mode),fast)
|
ifneq ($(mode),fast)
|
||||||
options := $(options)-$(mode)
|
options := $(options)-$(mode)
|
||||||
endif
|
endif
|
||||||
|
ifneq ($(lzma),)
|
||||||
|
options := $(options)-lzma
|
||||||
|
endif
|
||||||
ifeq ($(bootimage),true)
|
ifeq ($(bootimage),true)
|
||||||
options := $(options)-bootimage
|
options := $(options)-bootimage
|
||||||
endif
|
endif
|
||||||
@ -532,6 +535,7 @@ ifdef msvc
|
|||||||
strip = :
|
strip = :
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
c-objects = $(foreach x,$(1),$(patsubst $(2)/%.c,$(3)/%.o,$(x)))
|
||||||
cpp-objects = $(foreach x,$(1),$(patsubst $(2)/%.cpp,$(3)/%.o,$(x)))
|
cpp-objects = $(foreach x,$(1),$(patsubst $(2)/%.cpp,$(3)/%.o,$(x)))
|
||||||
asm-objects = $(foreach x,$(1),$(patsubst $(2)/%.S,$(3)/%-asm.o,$(x)))
|
asm-objects = $(foreach x,$(1),$(patsubst $(2)/%.S,$(3)/%-asm.o,$(x)))
|
||||||
java-classes = $(foreach x,$(1),$(patsubst $(2)/%.java,$(3)/%.class,$(x)))
|
java-classes = $(foreach x,$(1),$(patsubst $(2)/%.java,$(3)/%.class,$(x)))
|
||||||
@ -594,7 +598,10 @@ ifeq ($(continuations),true)
|
|||||||
asmflags += -DAVIAN_CONTINUATIONS
|
asmflags += -DAVIAN_CONTINUATIONS
|
||||||
endif
|
endif
|
||||||
|
|
||||||
bootimage-generator-sources = $(src)/bootimage.cpp
|
bootimage-generator-sources = $(src)/bootimage.cpp
|
||||||
|
ifneq ($(lzma),)
|
||||||
|
bootimage-generator-sources += $(src)/lzma-encode.cpp
|
||||||
|
endif
|
||||||
bootimage-generator-objects = \
|
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
|
||||||
@ -629,17 +636,62 @@ generator-sources = \
|
|||||||
$(src)/type-generator.cpp \
|
$(src)/type-generator.cpp \
|
||||||
$(src)/$(build-system).cpp \
|
$(src)/$(build-system).cpp \
|
||||||
$(src)/finder.cpp
|
$(src)/finder.cpp
|
||||||
|
|
||||||
|
ifneq ($(lzma),)
|
||||||
|
common-cflags += -I$(lzma)/C -DAVIAN_USE_LZMA -D_7ZIP_ST
|
||||||
|
|
||||||
|
vm-sources += \
|
||||||
|
$(src)/lzma-decode.cpp
|
||||||
|
|
||||||
|
generator-sources += \
|
||||||
|
$(src)/lzma-decode.cpp
|
||||||
|
|
||||||
|
lzma-decode-sources = \
|
||||||
|
$(lzma)/C/LzmaDec.c
|
||||||
|
|
||||||
|
lzma-decode-objects = \
|
||||||
|
$(call c-objects,$(lzma-decode-sources),$(lzma)/C,$(build))
|
||||||
|
|
||||||
|
lzma-encode-sources = \
|
||||||
|
$(lzma)/C/LzmaEnc.c \
|
||||||
|
$(lzma)/C/LzFind.c
|
||||||
|
|
||||||
|
lzma-encode-objects = \
|
||||||
|
$(call c-objects,$(lzma-encode-sources),$(lzma)/C,$(build))
|
||||||
|
|
||||||
|
lzma-encoder = $(build)/lzma/lzma
|
||||||
|
|
||||||
|
lzma-encoder-cflags = -D__STDC_CONSTANT_MACROS -fno-rtti -fno-exceptions \
|
||||||
|
-I$(lzma)/C
|
||||||
|
|
||||||
|
lzma-encoder-sources = \
|
||||||
|
$(src)/lzma/main.cpp
|
||||||
|
|
||||||
|
lzma-encoder-objects = \
|
||||||
|
$(call cpp-objects,$(lzma-encoder-sources),$(src),$(build))
|
||||||
|
|
||||||
|
lzma-encoder-lzma-sources = $(lzma-encode-sources) $(lzma-decode-sources)
|
||||||
|
|
||||||
|
lzma-encoder-lzma-objects = \
|
||||||
|
$(call c-objects,$(lzma-encoder-lzma-sources),$(lzma)/C,$(build))
|
||||||
|
|
||||||
|
lzma-loader = $(build)/lzma/load.o
|
||||||
|
endif
|
||||||
|
|
||||||
generator-cpp-objects = \
|
generator-cpp-objects = \
|
||||||
$(foreach x,$(1),$(patsubst $(2)/%.cpp,$(3)/%-build.o,$(x)))
|
$(foreach x,$(1),$(patsubst $(2)/%.cpp,$(3)/%-build.o,$(x)))
|
||||||
|
generator-c-objects = \
|
||||||
|
$(foreach x,$(1),$(patsubst $(2)/%.c,$(3)/%-build.o,$(x)))
|
||||||
generator-objects = \
|
generator-objects = \
|
||||||
$(call generator-cpp-objects,$(generator-sources),$(src),$(build))
|
$(call generator-cpp-objects,$(generator-sources),$(src),$(build))
|
||||||
|
generator-lzma-objects = \
|
||||||
|
$(call generator-c-objects,$(lzma-decode-sources),$(lzma)/C,$(build))
|
||||||
generator = $(build)/generator
|
generator = $(build)/generator
|
||||||
|
|
||||||
converter-depends = \
|
converter-depends = \
|
||||||
$(src)/binaryToObject/tools.h \
|
$(src)/binaryToObject/tools.h \
|
||||||
$(src)/binaryToObject/endianness.h
|
$(src)/binaryToObject/endianness.h
|
||||||
|
|
||||||
|
|
||||||
converter-sources = \
|
converter-sources = \
|
||||||
$(src)/binaryToObject/tools.cpp \
|
$(src)/binaryToObject/tools.cpp \
|
||||||
$(src)/binaryToObject/elf.cpp \
|
$(src)/binaryToObject/elf.cpp \
|
||||||
@ -760,7 +812,7 @@ test-flags = -cp $(build)/test
|
|||||||
test-args = $(test-flags) $(input)
|
test-args = $(test-flags) $(input)
|
||||||
|
|
||||||
.PHONY: build
|
.PHONY: build
|
||||||
build: $(static-library) $(executable) $(dynamic-library) \
|
build: $(static-library) $(executable) $(dynamic-library) $(lzma-loader) \
|
||||||
$(executable-dynamic) $(classpath-dep) $(test-dep) $(test-extra-dep)
|
$(executable-dynamic) $(classpath-dep) $(test-dep) $(test-extra-dep)
|
||||||
|
|
||||||
$(test-dep): $(classpath-dep)
|
$(test-dep): $(classpath-dep)
|
||||||
@ -863,6 +915,9 @@ endef
|
|||||||
$(vm-cpp-objects): $(build)/%.o: $(src)/%.cpp $(vm-depends)
|
$(vm-cpp-objects): $(build)/%.o: $(src)/%.cpp $(vm-depends)
|
||||||
$(compile-object)
|
$(compile-object)
|
||||||
|
|
||||||
|
$(build)/%.o: $(lzma)/C/%.c
|
||||||
|
$(compile-object)
|
||||||
|
|
||||||
$(vm-asm-objects): $(build)/%-asm.o: $(src)/%.S
|
$(vm-asm-objects): $(build)/%-asm.o: $(src)/%.S
|
||||||
$(compile-asm-object)
|
$(compile-asm-object)
|
||||||
|
|
||||||
@ -894,6 +949,16 @@ $(converter-objects) $(converter-tool-objects): $(build)/binaryToObject/%.o: $(s
|
|||||||
$(converter): $(converter-objects) $(converter-tool-objects)
|
$(converter): $(converter-objects) $(converter-tool-objects)
|
||||||
$(build-cc) $(^) -g -o $(@)
|
$(build-cc) $(^) -g -o $(@)
|
||||||
|
|
||||||
|
$(lzma-encoder-objects): $(build)/lzma/%.o: $(src)/lzma/%.cpp
|
||||||
|
@mkdir -p $(dir $(@))
|
||||||
|
$(build-cxx) $(lzma-encoder-cflags) -c $(<) -o $(@)
|
||||||
|
|
||||||
|
$(lzma-encoder): $(lzma-encoder-objects) $(lzma-encoder-lzma-objects)
|
||||||
|
$(build-cc) $(^) -g -o $(@)
|
||||||
|
|
||||||
|
$(lzma-loader): $(src)/lzma/load.cpp
|
||||||
|
$(compile-object)
|
||||||
|
|
||||||
$(build)/classpath.jar: $(classpath-dep) $(classpath-jar-dep)
|
$(build)/classpath.jar: $(classpath-dep) $(classpath-jar-dep)
|
||||||
@echo "creating $(@)"
|
@echo "creating $(@)"
|
||||||
(wd=$$(pwd) && \
|
(wd=$$(pwd) && \
|
||||||
@ -916,18 +981,25 @@ $(javahome-object): $(build)/javahome.jar $(converter)
|
|||||||
$(converter) $(<) $(@) _binary_javahome_jar_start \
|
$(converter) $(<) $(@) _binary_javahome_jar_start \
|
||||||
_binary_javahome_jar_end $(platform) $(arch)
|
_binary_javahome_jar_end $(platform) $(arch)
|
||||||
|
|
||||||
$(generator-objects): $(generator-depends)
|
define compile-generator-object
|
||||||
$(generator-objects): $(build)/%-build.o: $(src)/%.cpp
|
|
||||||
@echo "compiling $(@)"
|
@echo "compiling $(@)"
|
||||||
@mkdir -p $(dir $(@))
|
@mkdir -p $(dir $(@))
|
||||||
$(build-cxx) -DPOINTER_SIZE=$(pointer-size) -O0 -g3 $(build-cflags) \
|
$(build-cxx) -DPOINTER_SIZE=$(pointer-size) -O0 -g3 $(build-cflags) \
|
||||||
-c $(<) -o $(@)
|
-c $(<) -o $(@)
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(generator-objects): $(generator-depends)
|
||||||
|
$(generator-objects): $(build)/%-build.o: $(src)/%.cpp
|
||||||
|
$(compile-generator-object)
|
||||||
|
|
||||||
|
$(generator-lzma-objects): $(build)/%-build.o: $(lzma)/C/%.c
|
||||||
|
$(compile-generator-object)
|
||||||
|
|
||||||
$(jni-objects): $(build)/%.o: $(classpath-src)/%.cpp
|
$(jni-objects): $(build)/%.o: $(classpath-src)/%.cpp
|
||||||
$(compile-object)
|
$(compile-object)
|
||||||
|
|
||||||
$(static-library): $(vm-objects) $(classpath-objects) $(vm-heapwalk-objects) \
|
$(static-library): $(vm-objects) $(classpath-objects) $(vm-heapwalk-objects) \
|
||||||
$(javahome-object) $(boot-javahome-object)
|
$(javahome-object) $(boot-javahome-object) $(lzma-decode-objects)
|
||||||
@echo "creating $(@)"
|
@echo "creating $(@)"
|
||||||
rm -rf $(@)
|
rm -rf $(@)
|
||||||
$(ar) cru $(@) $(^)
|
$(ar) cru $(@) $(^)
|
||||||
@ -940,7 +1012,7 @@ $(bootimage-object) $(codeimage-object): $(bootimage-generator)
|
|||||||
|
|
||||||
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) \
|
||||||
$(javahome-object) $(boot-javahome-object)
|
$(javahome-object) $(boot-javahome-object) $(lzma-decode-objects)
|
||||||
|
|
||||||
$(executable): $(executable-objects)
|
$(executable): $(executable-objects)
|
||||||
@echo "linking $(@)"
|
@echo "linking $(@)"
|
||||||
@ -976,7 +1048,8 @@ $(bootimage-generator): $(bootimage-generator-objects)
|
|||||||
|
|
||||||
$(build-bootimage-generator): \
|
$(build-bootimage-generator): \
|
||||||
$(vm-objects) $(classpath-object) $(classpath-objects) \
|
$(vm-objects) $(classpath-object) $(classpath-objects) \
|
||||||
$(heapwalk-objects) $(bootimage-generator-objects) $(converter-objects)
|
$(heapwalk-objects) $(bootimage-generator-objects) $(converter-objects) \
|
||||||
|
$(lzma-decode-objects) $(lzma-encode-objects)
|
||||||
@echo "linking $(@)"
|
@echo "linking $(@)"
|
||||||
ifeq ($(platform),windows)
|
ifeq ($(platform),windows)
|
||||||
ifdef msvc
|
ifdef msvc
|
||||||
@ -994,7 +1067,8 @@ endif
|
|||||||
|
|
||||||
$(dynamic-library): $(vm-objects) $(dynamic-object) $(classpath-objects) \
|
$(dynamic-library): $(vm-objects) $(dynamic-object) $(classpath-objects) \
|
||||||
$(vm-heapwalk-objects) $(boot-object) $(vm-classpath-objects) \
|
$(vm-heapwalk-objects) $(boot-object) $(vm-classpath-objects) \
|
||||||
$(classpath-libraries) $(javahome-object) $(boot-javahome-object)
|
$(classpath-libraries) $(javahome-object) $(boot-javahome-object) \
|
||||||
|
$(lzma-decode-objects)
|
||||||
@echo "linking $(@)"
|
@echo "linking $(@)"
|
||||||
ifdef msvc
|
ifdef msvc
|
||||||
$(ld) $(shared) $(lflags) $(^) -out:$(@) -PDB:$(@).pdb \
|
$(ld) $(shared) $(lflags) $(^) -out:$(@) -PDB:$(@).pdb \
|
||||||
@ -1020,7 +1094,7 @@ else
|
|||||||
endif
|
endif
|
||||||
$(strip) $(strip-all) $(@)
|
$(strip) $(strip-all) $(@)
|
||||||
|
|
||||||
$(generator): $(generator-objects)
|
$(generator): $(generator-objects) $(generator-lzma-objects)
|
||||||
@echo "linking $(@)"
|
@echo "linking $(@)"
|
||||||
$(build-ld) $(^) $(build-lflags) -o $(@)
|
$(build-ld) $(^) $(build-lflags) -o $(@)
|
||||||
|
|
||||||
|
24
readme.txt
24
readme.txt
@ -79,6 +79,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} \
|
||||||
|
lzma=<lzma source directory> \
|
||||||
ios={true,false} \
|
ios={true,false} \
|
||||||
bootimage={true,false} \
|
bootimage={true,false} \
|
||||||
heapdump={true,false} \
|
heapdump={true,false} \
|
||||||
@ -104,6 +105,13 @@ certain flags described below, all of which are optional.
|
|||||||
assertions
|
assertions
|
||||||
default: fast
|
default: fast
|
||||||
|
|
||||||
|
* lzma - if set, support use of LZMA to compress embedded JARs and
|
||||||
|
boot images. The value of this option should be a directory
|
||||||
|
containing a recent LZMA SDK (available at
|
||||||
|
http://www.7-zip.org/sdk.html). Currently, only version 9.20 of
|
||||||
|
the SDK has been tested, but other versions might work.
|
||||||
|
default: not set
|
||||||
|
|
||||||
* ios - if true, cross-compile for iOS on OS X. Note that
|
* ios - if true, cross-compile for iOS on OS X. Note that
|
||||||
non-jailbroken iOS devices do not allow JIT compilation, so only
|
non-jailbroken iOS devices do not allow JIT compilation, so only
|
||||||
process=interpret or bootimage=true builds will run on such
|
process=interpret or bootimage=true builds will run on such
|
||||||
@ -366,8 +374,20 @@ 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/binaryToObject boot.jar boot-jar.o \
|
$ ../build/${platform}-${arch}/binaryToObject/binaryToObject boot.jar \
|
||||||
_binary_boot_jar_start _binary_boot_jar_end ${platform} ${arch}
|
boot-jar.o _binary_boot_jar_start _binary_boot_jar_end ${platform} ${arch}
|
||||||
|
|
||||||
|
If you've built Avian using the lzma option, you may optionally
|
||||||
|
compress the jar before generating the object:
|
||||||
|
|
||||||
|
$ ../build/$(platform}-${arch}-lzma/lzma/lzma encode boot.jar boot.jar.lzma
|
||||||
|
&& ../build/${platform}-${arch}-lzma/binaryToObject/binaryToObject \
|
||||||
|
boot.jar.lzma boot-jar.o _binary_boot_jar_start _binary_boot_jar_end \
|
||||||
|
${platform} ${arch}
|
||||||
|
|
||||||
|
Note that you'll need to specify "-Xbootclasspath:[lzma:bootJar]"
|
||||||
|
instead of "-Xbootclasspath:[bootJar]" in the next step if you've used
|
||||||
|
LZMA to compress the jar.
|
||||||
|
|
||||||
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
|
||||||
method. Note the bootJar function, which will be called by the VM to
|
method. Note the bootJar function, which will be called by the VM to
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
FIELD(magic)
|
FIELD(magic)
|
||||||
|
|
||||||
|
FIELD(initialized)
|
||||||
|
|
||||||
FIELD(heapSize)
|
FIELD(heapSize)
|
||||||
FIELD(codeSize)
|
FIELD(codeSize)
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "assembler.h"
|
#include "assembler.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
#include "binaryToObject/tools.h"
|
#include "binaryToObject/tools.h"
|
||||||
|
#include "lzma.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:
|
||||||
@ -1275,7 +1276,8 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
|
|||||||
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* bootimageStart, const char* bootimageEnd,
|
||||||
const char* codeimageStart, const char* codeimageEnd)
|
const char* codeimageStart, const char* codeimageEnd,
|
||||||
|
bool useLZMA)
|
||||||
{
|
{
|
||||||
setRoot(t, Machine::OutOfMemoryError,
|
setRoot(t, Machine::OutOfMemoryError,
|
||||||
make(t, type(t, Machine::OutOfMemoryErrorType)));
|
make(t, type(t, Machine::OutOfMemoryErrorType)));
|
||||||
@ -1594,6 +1596,7 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
|
|||||||
heapWalker->dispose();
|
heapWalker->dispose();
|
||||||
|
|
||||||
image->magic = BootImage::Magic;
|
image->magic = BootImage::Magic;
|
||||||
|
image->initialized = 0;
|
||||||
|
|
||||||
fprintf(stderr, "class count %d string count %d call count %d\n"
|
fprintf(stderr, "class count %d string count %d call count %d\n"
|
||||||
"heap size %d code size %d\n",
|
"heap size %d code size %d\n",
|
||||||
@ -1656,7 +1659,27 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
|
|||||||
SymbolInfo(bootimageData.length, bootimageEnd)
|
SymbolInfo(bootimageData.length, bootimageEnd)
|
||||||
};
|
};
|
||||||
|
|
||||||
platform->writeObject(bootimageOutput, Slice<SymbolInfo>(bootimageSymbols, 2), Slice<const uint8_t>(bootimageData.data, bootimageData.length), Platform::Writable, TargetBytesPerWord);
|
uint8_t* bootimage;
|
||||||
|
unsigned bootimageLength;
|
||||||
|
if (useLZMA) {
|
||||||
|
#ifdef AVIAN_USE_LZMA
|
||||||
|
bootimage = encodeLZMA(t->m->system, t->m->heap, bootimageData.data,
|
||||||
|
bootimageData.length, &bootimageLength);
|
||||||
|
|
||||||
|
fprintf(stderr, "compressed heap size %d\n", bootimageLength);
|
||||||
|
#else
|
||||||
|
abort(t);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
bootimage = bootimageData.data;
|
||||||
|
bootimageLength = bootimageData.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
platform->writeObject(bootimageOutput, Slice<SymbolInfo>(bootimageSymbols, 2), Slice<const uint8_t>(bootimage, bootimageLength), Platform::Writable, TargetBytesPerWord);
|
||||||
|
|
||||||
|
if (useLZMA) {
|
||||||
|
t->m->heap->free(bootimage, bootimageLength);
|
||||||
|
}
|
||||||
|
|
||||||
compilationHandler.symbols.add(SymbolInfo(0, codeimageStart));
|
compilationHandler.symbols.add(SymbolInfo(0, codeimageStart));
|
||||||
compilationHandler.symbols.add(SymbolInfo(image->codeSize, codeimageEnd));
|
compilationHandler.symbols.add(SymbolInfo(image->codeSize, codeimageEnd));
|
||||||
@ -1684,10 +1707,12 @@ writeBootImage(Thread* t, uintptr_t* arguments)
|
|||||||
const char* bootimageEnd = reinterpret_cast<const char*>(arguments[8]);
|
const char* bootimageEnd = reinterpret_cast<const char*>(arguments[8]);
|
||||||
const char* codeimageStart = reinterpret_cast<const char*>(arguments[9]);
|
const char* codeimageStart = reinterpret_cast<const char*>(arguments[9]);
|
||||||
const char* codeimageEnd = reinterpret_cast<const char*>(arguments[10]);
|
const char* codeimageEnd = reinterpret_cast<const char*>(arguments[10]);
|
||||||
|
bool useLZMA = arguments[11];
|
||||||
|
|
||||||
writeBootImage2
|
writeBootImage2
|
||||||
(t, bootimageOutput, codeOutput, image, code, className, methodName,
|
(t, bootimageOutput, codeOutput, image, code, className, methodName,
|
||||||
methodSpec, bootimageStart, bootimageEnd, codeimageStart, codeimageEnd);
|
methodSpec, bootimageStart, bootimageEnd, codeimageStart, codeimageEnd,
|
||||||
|
useLZMA);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -1746,7 +1771,11 @@ bool ArgParser::parse(int ac, const char** av) {
|
|||||||
}
|
}
|
||||||
for(Arg* arg = first; arg; arg = arg->next) {
|
for(Arg* arg = first; arg; arg = arg->next) {
|
||||||
if(strcmp(arg->name, &av[i][1]) == 0) {
|
if(strcmp(arg->name, &av[i][1]) == 0) {
|
||||||
state = arg;
|
if (arg->desc == 0) {
|
||||||
|
arg->value = "true";
|
||||||
|
} else {
|
||||||
|
state = arg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!state) {
|
if(!state) {
|
||||||
@ -1801,6 +1830,8 @@ public:
|
|||||||
char* codeimageStart;
|
char* codeimageStart;
|
||||||
char* codeimageEnd;
|
char* codeimageEnd;
|
||||||
|
|
||||||
|
bool useLZMA;
|
||||||
|
|
||||||
bool maybeSplit(const char* src, char*& destA, char*& destB) {
|
bool maybeSplit(const char* src, char*& destA, char*& destB) {
|
||||||
if(src) {
|
if(src) {
|
||||||
const char* split = strchr(src, ':');
|
const char* split = strchr(src, ':');
|
||||||
@ -1830,6 +1861,7 @@ public:
|
|||||||
Arg entry(parser, false, "entry", "<class name>[.<method name>[<method spec>]]");
|
Arg entry(parser, false, "entry", "<class name>[.<method name>[<method spec>]]");
|
||||||
Arg bootimageSymbols(parser, false, "bootimage-symbols", "<start symbol name>:<end symbol name>");
|
Arg bootimageSymbols(parser, false, "bootimage-symbols", "<start symbol name>:<end symbol name>");
|
||||||
Arg codeimageSymbols(parser, false, "codeimage-symbols", "<start symbol name>:<end symbol name>");
|
Arg codeimageSymbols(parser, false, "codeimage-symbols", "<start symbol name>:<end symbol name>");
|
||||||
|
Arg useLZMA(parser, false, "use-lzma", 0);
|
||||||
|
|
||||||
if(!parser.parse(ac, av)) {
|
if(!parser.parse(ac, av)) {
|
||||||
parser.printUsage(av[0]);
|
parser.printUsage(av[0]);
|
||||||
@ -1839,6 +1871,7 @@ public:
|
|||||||
this->classpath = classpath.value;
|
this->classpath = classpath.value;
|
||||||
this->bootimage = bootimage.value;
|
this->bootimage = bootimage.value;
|
||||||
this->codeimage = codeimage.value;
|
this->codeimage = codeimage.value;
|
||||||
|
this->useLZMA = useLZMA.value != 0;
|
||||||
|
|
||||||
if(entry.value) {
|
if(entry.value) {
|
||||||
if(const char* entryClassEnd = strchr(entry.value, '.')) {
|
if(const char* entryClassEnd = strchr(entry.value, '.')) {
|
||||||
@ -1988,7 +2021,8 @@ main(int ac, const char** av)
|
|||||||
reinterpret_cast<uintptr_t>(args.bootimageStart),
|
reinterpret_cast<uintptr_t>(args.bootimageStart),
|
||||||
reinterpret_cast<uintptr_t>(args.bootimageEnd),
|
reinterpret_cast<uintptr_t>(args.bootimageEnd),
|
||||||
reinterpret_cast<uintptr_t>(args.codeimageStart),
|
reinterpret_cast<uintptr_t>(args.codeimageStart),
|
||||||
reinterpret_cast<uintptr_t>(args.codeimageEnd)
|
reinterpret_cast<uintptr_t>(args.codeimageEnd),
|
||||||
|
reinterpret_cast<uintptr_t>(args.useLZMA)
|
||||||
};
|
};
|
||||||
|
|
||||||
run(t, writeBootImage, arguments);
|
run(t, writeBootImage, arguments);
|
||||||
|
@ -9631,9 +9631,7 @@ boot(MyThread* t, BootImage* image, uint8_t* code)
|
|||||||
// fprintf(stderr, "code from %p to %p\n",
|
// fprintf(stderr, "code from %p to %p\n",
|
||||||
// code, code + image->codeSize);
|
// code, code + image->codeSize);
|
||||||
|
|
||||||
static bool fixed = false;
|
if (not image->initialized) {
|
||||||
|
|
||||||
if (not fixed) {
|
|
||||||
fixupHeap(t, heapMap, heapMapSizeInWords, heap);
|
fixupHeap(t, heapMap, heapMapSizeInWords, heap);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9680,7 +9678,7 @@ boot(MyThread* t, BootImage* image, uint8_t* code)
|
|||||||
|
|
||||||
findThunks(t, image, code);
|
findThunks(t, image, code);
|
||||||
|
|
||||||
if (fixed) {
|
if (image->initialized) {
|
||||||
resetRuntimeState
|
resetRuntimeState
|
||||||
(t, classLoaderMap(t, root(t, Machine::BootLoader)), heap,
|
(t, classLoaderMap(t, root(t, Machine::BootLoader)), heap,
|
||||||
image->heapSize);
|
image->heapSize);
|
||||||
@ -9703,7 +9701,7 @@ boot(MyThread* t, BootImage* image, uint8_t* code)
|
|||||||
(t, classLoaderMap(t, root(t, Machine::AppLoader)), image, code);
|
(t, classLoaderMap(t, root(t, Machine::AppLoader)), image, code);
|
||||||
}
|
}
|
||||||
|
|
||||||
fixed = true;
|
image->initialized = true;
|
||||||
|
|
||||||
setRoot(t, Machine::BootstrapClassMap, makeHashMap(t, 0, 0));
|
setRoot(t, Machine::BootstrapClassMap, makeHashMap(t, 0, 0));
|
||||||
}
|
}
|
||||||
|
@ -971,6 +971,29 @@ valid(Read* r)
|
|||||||
return r and r->valid();
|
return r and r->valid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
|
||||||
|
bool
|
||||||
|
hasBuddy(Context* c, Value* a, Value* b)
|
||||||
|
{
|
||||||
|
if (a == b) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
for (Value* p = a->buddy; p != a; p = p->buddy) {
|
||||||
|
if (p == b) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (++i > 1000) {
|
||||||
|
abort(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // not NDEBUG
|
||||||
|
|
||||||
Read*
|
Read*
|
||||||
live(Context* c UNUSED, Value* v)
|
live(Context* c UNUSED, Value* v)
|
||||||
{
|
{
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "system.h"
|
#include "system.h"
|
||||||
#include "tokenizer.h"
|
#include "tokenizer.h"
|
||||||
#include "finder.h"
|
#include "finder.h"
|
||||||
|
#include "lzma.h"
|
||||||
|
|
||||||
using namespace vm;
|
using namespace vm;
|
||||||
|
|
||||||
@ -173,11 +174,12 @@ class DirectoryElement: public Element {
|
|||||||
class PointerRegion: public System::Region {
|
class PointerRegion: public System::Region {
|
||||||
public:
|
public:
|
||||||
PointerRegion(System* s, Allocator* allocator, const uint8_t* start,
|
PointerRegion(System* s, Allocator* allocator, const uint8_t* start,
|
||||||
size_t length):
|
size_t length, bool freePointer = false):
|
||||||
s(s),
|
s(s),
|
||||||
allocator(allocator),
|
allocator(allocator),
|
||||||
start_(start),
|
start_(start),
|
||||||
length_(length)
|
length_(length),
|
||||||
|
freePointer(freePointer)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual const uint8_t* start() {
|
virtual const uint8_t* start() {
|
||||||
@ -189,6 +191,9 @@ class PointerRegion: public System::Region {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void dispose() {
|
virtual void dispose() {
|
||||||
|
if (freePointer) {
|
||||||
|
allocator->free(start_, length_);
|
||||||
|
}
|
||||||
allocator->free(this, sizeof(*this));
|
allocator->free(this, sizeof(*this));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,6 +201,7 @@ class PointerRegion: public System::Region {
|
|||||||
Allocator* allocator;
|
Allocator* allocator;
|
||||||
const uint8_t* start_;
|
const uint8_t* start_;
|
||||||
size_t length_;
|
size_t length_;
|
||||||
|
bool freePointer;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DataRegion: public System::Region {
|
class DataRegion: public System::Region {
|
||||||
@ -556,7 +562,10 @@ class BuiltinElement: public JarElement {
|
|||||||
virtual void init() {
|
virtual void init() {
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
if (s->success(s->load(&library, libraryName))) {
|
if (s->success(s->load(&library, libraryName))) {
|
||||||
void* p = library->resolve(name);
|
bool lzma = strncmp("lzma:", name, 5) == 0;
|
||||||
|
const char* symbolName = lzma ? name + 5 : name;
|
||||||
|
|
||||||
|
void* p = library->resolve(symbolName);
|
||||||
if (p) {
|
if (p) {
|
||||||
uint8_t* (*function)(unsigned*);
|
uint8_t* (*function)(unsigned*);
|
||||||
memcpy(&function, &p, BytesPerWord);
|
memcpy(&function, &p, BytesPerWord);
|
||||||
@ -564,10 +573,29 @@ class BuiltinElement: public JarElement {
|
|||||||
unsigned size;
|
unsigned size;
|
||||||
uint8_t* data = function(&size);
|
uint8_t* data = function(&size);
|
||||||
if (data) {
|
if (data) {
|
||||||
|
bool freePointer;
|
||||||
|
if (lzma) {
|
||||||
|
#ifdef AVIAN_USE_LZMA
|
||||||
|
unsigned outSize;
|
||||||
|
data = decodeLZMA(s, allocator, data, size, &outSize);
|
||||||
|
size = outSize;
|
||||||
|
freePointer = true;
|
||||||
|
#else
|
||||||
|
abort(s);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
freePointer = false;
|
||||||
|
}
|
||||||
region = new (allocator->allocate(sizeof(PointerRegion)))
|
region = new (allocator->allocate(sizeof(PointerRegion)))
|
||||||
PointerRegion(s, allocator, data, size);
|
PointerRegion(s, allocator, data, size, freePointer);
|
||||||
index = JarIndex::open(s, allocator, region);
|
index = JarIndex::open(s, allocator, region);
|
||||||
|
} else if (DebugFind) {
|
||||||
|
fprintf(stderr, "%s in %s returned null\n", symbolName,
|
||||||
|
libraryName);
|
||||||
}
|
}
|
||||||
|
} else if (DebugFind) {
|
||||||
|
fprintf(stderr, "unable to find %s in %s\n", symbolName,
|
||||||
|
libraryName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
49
src/lzma-decode.cpp
Normal file
49
src/lzma-decode.cpp
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/* 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. */
|
||||||
|
|
||||||
|
#include "lzma-util.h"
|
||||||
|
#include "LzmaDec.h"
|
||||||
|
|
||||||
|
using namespace vm;
|
||||||
|
|
||||||
|
namespace vm {
|
||||||
|
|
||||||
|
uint8_t*
|
||||||
|
decodeLZMA(System* s, Allocator* a, uint8_t* in, unsigned inSize,
|
||||||
|
unsigned* outSize)
|
||||||
|
{
|
||||||
|
const unsigned PropHeaderSize = 5;
|
||||||
|
const unsigned HeaderSize = 13;
|
||||||
|
|
||||||
|
int32_t outSize32;
|
||||||
|
memcpy(&outSize32, in + PropHeaderSize, 4);
|
||||||
|
expect(s, outSize32 >= 0);
|
||||||
|
SizeT outSizeT = outSize32;
|
||||||
|
|
||||||
|
uint8_t* out = static_cast<uint8_t*>(a->allocate(outSize32));
|
||||||
|
|
||||||
|
SizeT inSizeT = inSize;
|
||||||
|
LzmaAllocator allocator(a);
|
||||||
|
|
||||||
|
ELzmaStatus status;
|
||||||
|
int result = LzmaDecode
|
||||||
|
(out, &outSizeT, in + HeaderSize, &inSizeT, in, PropHeaderSize,
|
||||||
|
LZMA_FINISH_END, &status, &(allocator.allocator));
|
||||||
|
|
||||||
|
expect(s, result == SZ_OK);
|
||||||
|
expect(s, status == LZMA_STATUS_FINISHED_WITH_MARK);
|
||||||
|
|
||||||
|
*outSize = outSize32;
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace vm
|
||||||
|
|
71
src/lzma-encode.cpp
Normal file
71
src/lzma-encode.cpp
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
/* 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. */
|
||||||
|
|
||||||
|
#include "lzma-util.h"
|
||||||
|
#include "LzmaEnc.h"
|
||||||
|
|
||||||
|
using namespace vm;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
SRes
|
||||||
|
myProgress(void*, UInt64, UInt64)
|
||||||
|
{
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace vm {
|
||||||
|
|
||||||
|
uint8_t*
|
||||||
|
encodeLZMA(System* s, Allocator* a, uint8_t* in, unsigned inSize,
|
||||||
|
unsigned* outSize)
|
||||||
|
{
|
||||||
|
const unsigned PropHeaderSize = 5;
|
||||||
|
const unsigned HeaderSize = 13;
|
||||||
|
|
||||||
|
unsigned bufferSize = inSize * 2;
|
||||||
|
|
||||||
|
uint8_t* buffer = static_cast<uint8_t*>(a->allocate(bufferSize));
|
||||||
|
|
||||||
|
LzmaAllocator allocator(a);
|
||||||
|
|
||||||
|
CLzmaEncProps props;
|
||||||
|
LzmaEncProps_Init(&props);
|
||||||
|
props.level = 9;
|
||||||
|
props.writeEndMark = 1;
|
||||||
|
|
||||||
|
ICompressProgress progress = { myProgress };
|
||||||
|
|
||||||
|
SizeT propsSize = PropHeaderSize;
|
||||||
|
|
||||||
|
int32_t inSize32 = inSize;
|
||||||
|
memcpy(buffer + PropHeaderSize, &inSize32, 4);
|
||||||
|
|
||||||
|
SizeT outSizeT = bufferSize;
|
||||||
|
int result = LzmaEncode
|
||||||
|
(buffer + HeaderSize, &outSizeT, in, inSize, &props, buffer,
|
||||||
|
&propsSize, 1, &progress, &(allocator.allocator), &(allocator.allocator));
|
||||||
|
|
||||||
|
expect(s, result == SZ_OK);
|
||||||
|
|
||||||
|
*outSize = outSizeT + HeaderSize;
|
||||||
|
|
||||||
|
uint8_t* out = static_cast<uint8_t*>(a->allocate(*outSize));
|
||||||
|
memcpy(out, buffer, *outSize);
|
||||||
|
|
||||||
|
a->free(buffer, bufferSize);
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace vm
|
||||||
|
|
53
src/lzma-util.h
Normal file
53
src/lzma-util.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/* 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. */
|
||||||
|
|
||||||
|
#ifndef LZMA_UTIL_H
|
||||||
|
#define LZMA_UTIL_H
|
||||||
|
|
||||||
|
#include "lzma.h"
|
||||||
|
#include "Types.h"
|
||||||
|
#include "system.h"
|
||||||
|
#include "allocator.h"
|
||||||
|
|
||||||
|
namespace vm {
|
||||||
|
|
||||||
|
const unsigned Padding = 16;
|
||||||
|
|
||||||
|
class LzmaAllocator {
|
||||||
|
public:
|
||||||
|
LzmaAllocator(Allocator* a): a(a) {
|
||||||
|
allocator.Alloc = allocate;
|
||||||
|
allocator.Free = free;
|
||||||
|
}
|
||||||
|
|
||||||
|
ISzAlloc allocator;
|
||||||
|
Allocator* a;
|
||||||
|
|
||||||
|
static void* allocate(void* allocator, size_t size) {
|
||||||
|
uint8_t* p = static_cast<uint8_t*>
|
||||||
|
(static_cast<LzmaAllocator*>(allocator)->a->allocate(size + Padding));
|
||||||
|
int32_t size32 = size;
|
||||||
|
memcpy(p, &size32, 4);
|
||||||
|
return p + Padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void free(void* allocator, void* address) {
|
||||||
|
if (address) {
|
||||||
|
void* p = static_cast<uint8_t*>(address) - Padding;
|
||||||
|
int32_t size32;
|
||||||
|
memcpy(&size32, p, 4);
|
||||||
|
static_cast<LzmaAllocator*>(allocator)->a->free(p, size32 + Padding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace vm
|
||||||
|
|
||||||
|
#endif // LZMA_UTIL_H
|
29
src/lzma.h
Normal file
29
src/lzma.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/* 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. */
|
||||||
|
|
||||||
|
#ifndef LZMA_H
|
||||||
|
#define LZMA_H
|
||||||
|
|
||||||
|
#include "system.h"
|
||||||
|
#include "allocator.h"
|
||||||
|
|
||||||
|
namespace vm {
|
||||||
|
|
||||||
|
uint8_t*
|
||||||
|
decodeLZMA(System* s, Allocator* a, uint8_t* in, unsigned inSize,
|
||||||
|
unsigned* outSize);
|
||||||
|
|
||||||
|
uint8_t*
|
||||||
|
encodeLZMA(System* s, Allocator* a, uint8_t* in, unsigned inSize,
|
||||||
|
unsigned* outSize);
|
||||||
|
|
||||||
|
} // namespace vm
|
||||||
|
|
||||||
|
#endif // LZMA_H
|
115
src/lzma/load.cpp
Normal file
115
src/lzma/load.cpp
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "LzmaDec.h"
|
||||||
|
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
# define EXPORT __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
# define EXPORT __attribute__ ((visibility("default")))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined __MINGW32__ && ! defined __x86_64__
|
||||||
|
# define SYMBOL(x) binary_exe_##x
|
||||||
|
#else
|
||||||
|
# define SYMBOL(x) _binary_exe_##x
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
extern const uint8_t SYMBOL(start)[];
|
||||||
|
extern const uint8_t SYMBOL(end)[];
|
||||||
|
|
||||||
|
} // extern "C"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
void*
|
||||||
|
myAllocate(void*, size_t size)
|
||||||
|
{
|
||||||
|
return malloc(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
myFree(void*, void* address)
|
||||||
|
{
|
||||||
|
free(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int ac, const char** av)
|
||||||
|
{
|
||||||
|
const unsigned PropHeaderSize = 5;
|
||||||
|
const unsigned HeaderSize = 13;
|
||||||
|
|
||||||
|
SizeT inSize = SYMBOL(end) - SYMBOL(start);
|
||||||
|
|
||||||
|
int32_t outSize32;
|
||||||
|
memcpy(&outSize32, SYMBOL(start) + PropHeaderSize, 4);
|
||||||
|
SizeT outSize = outSize32;
|
||||||
|
|
||||||
|
uint8_t* out = static_cast<uint8_t*>(malloc(outSize));
|
||||||
|
if (out) {
|
||||||
|
ISzAlloc allocator = { myAllocate, myFree };
|
||||||
|
ELzmaStatus status = LZMA_STATUS_NOT_SPECIFIED;
|
||||||
|
|
||||||
|
if (SZ_OK == LzmaDecode
|
||||||
|
(out, &outSize, SYMBOL(start) + HeaderSize, &inSize, SYMBOL(start),
|
||||||
|
PropHeaderSize, LZMA_FINISH_END, &status, &allocator))
|
||||||
|
{
|
||||||
|
char name[L_tmpnam];
|
||||||
|
if (tmpnam(name)) {
|
||||||
|
int file = open(name, O_CREAT | O_EXCL | O_WRONLY, S_IRWXU);
|
||||||
|
if (file != -1) {
|
||||||
|
SizeT result = write(file, out, outSize);
|
||||||
|
free(out);
|
||||||
|
|
||||||
|
if (close(file) == 0 and outSize == result) {
|
||||||
|
void* library = dlopen(name, RTLD_LAZY | RTLD_GLOBAL);
|
||||||
|
unlink(name);
|
||||||
|
|
||||||
|
if (library) {
|
||||||
|
void* main = dlsym(library, "main");
|
||||||
|
if (main) {
|
||||||
|
int (*mainFunction)(int, const char**);
|
||||||
|
memcpy(&mainFunction, &main, sizeof(void*));
|
||||||
|
return mainFunction(ac, av);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "unable to find main in %s", name);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "unable to dlopen %s: %s\n", name, dlerror());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
unlink(name);
|
||||||
|
|
||||||
|
fprintf(stderr, "close or write failed; tried %d, got %d; %s\n",
|
||||||
|
static_cast<int>(outSize), static_cast<int>(result),
|
||||||
|
strerror(errno));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "unable to open %s\n", name);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "unable to make temporary file name\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "unable to decode LZMA data\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "unable to allocate buffer of size %d\n",
|
||||||
|
static_cast<int>(outSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
182
src/lzma/main.cpp
Normal file
182
src/lzma/main.cpp
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#ifdef WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#else
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include "LzmaEnc.h"
|
||||||
|
#include "LzmaDec.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
void*
|
||||||
|
myAllocate(void*, size_t size)
|
||||||
|
{
|
||||||
|
return malloc(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
myFree(void*, void* address)
|
||||||
|
{
|
||||||
|
free(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes
|
||||||
|
myProgress(void*, UInt64, UInt64)
|
||||||
|
{
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
usageAndExit(const char* program)
|
||||||
|
{
|
||||||
|
fprintf(stderr,
|
||||||
|
"usage: %s {encode|decode} <input file> <output file> "
|
||||||
|
"[<uncompressed size>]", program);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, const char** argv)
|
||||||
|
{
|
||||||
|
if (argc < 4 or argc > 5) {
|
||||||
|
usageAndExit(argv[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool encode = strcmp(argv[1], "encode") == 0;
|
||||||
|
|
||||||
|
uint8_t* data = 0;
|
||||||
|
unsigned size;
|
||||||
|
int fd = open(argv[2], O_RDONLY);
|
||||||
|
if (fd != -1) {
|
||||||
|
struct stat s;
|
||||||
|
int r = fstat(fd, &s);
|
||||||
|
if (r != -1) {
|
||||||
|
#ifdef WIN32
|
||||||
|
HANDLE fm;
|
||||||
|
HANDLE h = (HANDLE) _get_osfhandle (fd);
|
||||||
|
|
||||||
|
fm = CreateFileMapping(
|
||||||
|
h,
|
||||||
|
NULL,
|
||||||
|
PAGE_READONLY,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
NULL);
|
||||||
|
data = static_cast<uint8_t*>(MapViewOfFile(
|
||||||
|
fm,
|
||||||
|
FILE_MAP_READ,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
s.st_size));
|
||||||
|
|
||||||
|
CloseHandle(fm);
|
||||||
|
#else
|
||||||
|
data = static_cast<uint8_t*>
|
||||||
|
(mmap(0, s.st_size, PROT_READ, MAP_PRIVATE, fd, 0));
|
||||||
|
#endif
|
||||||
|
size = s.st_size;
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool success = false;
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
const unsigned PropHeaderSize = 5;
|
||||||
|
const unsigned HeaderSize = 13;
|
||||||
|
|
||||||
|
SizeT outSize;
|
||||||
|
if (encode) {
|
||||||
|
outSize = size * 2;
|
||||||
|
} else {
|
||||||
|
int32_t outSize32;
|
||||||
|
memcpy(&outSize32, data + PropHeaderSize, 4);
|
||||||
|
if (outSize32 >= 0) {
|
||||||
|
outSize = outSize32;
|
||||||
|
} else if (argc == 5) {
|
||||||
|
outSize = atoi(argv[4]);
|
||||||
|
} else {
|
||||||
|
outSize = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (outSize >= 0) {
|
||||||
|
uint8_t* out = static_cast<uint8_t*>(malloc(outSize));
|
||||||
|
if (out) {
|
||||||
|
SizeT inSize = size;
|
||||||
|
ISzAlloc allocator = { myAllocate, myFree };
|
||||||
|
ELzmaStatus status = LZMA_STATUS_NOT_SPECIFIED;
|
||||||
|
int result;
|
||||||
|
if (encode) {
|
||||||
|
CLzmaEncProps props;
|
||||||
|
LzmaEncProps_Init(&props);
|
||||||
|
props.level = 9;
|
||||||
|
props.writeEndMark = 1;
|
||||||
|
|
||||||
|
ICompressProgress progress = { myProgress };
|
||||||
|
|
||||||
|
SizeT propsSize = PropHeaderSize;
|
||||||
|
|
||||||
|
int32_t inSize32 = inSize;
|
||||||
|
memcpy(out + PropHeaderSize, &inSize32, 4);
|
||||||
|
|
||||||
|
result = LzmaEncode
|
||||||
|
(out + HeaderSize, &outSize, data, inSize, &props, out,
|
||||||
|
&propsSize, 1, &progress, &allocator, &allocator);
|
||||||
|
|
||||||
|
outSize += HeaderSize;
|
||||||
|
} else {
|
||||||
|
result = LzmaDecode
|
||||||
|
(out, &outSize, data + HeaderSize, &inSize, data, PropHeaderSize,
|
||||||
|
LZMA_FINISH_END, &status, &allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result == SZ_OK) {
|
||||||
|
FILE* outFile = fopen(argv[3], "wb");
|
||||||
|
|
||||||
|
if (outFile) {
|
||||||
|
if (fwrite(out, outSize, 1, outFile) == 1) {
|
||||||
|
success = true;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "unable to write to %s\n", argv[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(outFile);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "unable to open %s\n", argv[3]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "unable to %s data: result %d status %d\n",
|
||||||
|
encode ? "encode" : "decode", result, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(out);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "unable to allocate output buffer\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "unable to determine uncompressed size\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
UnmapViewOfFile(data);
|
||||||
|
#else
|
||||||
|
munmap(data, size);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
perror(argv[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (success ? 0 : -1);
|
||||||
|
}
|
@ -15,6 +15,7 @@
|
|||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "processor.h"
|
#include "processor.h"
|
||||||
#include "arch.h"
|
#include "arch.h"
|
||||||
|
#include "lzma.h"
|
||||||
|
|
||||||
using namespace vm;
|
using namespace vm;
|
||||||
|
|
||||||
@ -48,6 +49,40 @@ join(Thread* t, Thread* o)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
|
||||||
|
bool
|
||||||
|
find(Thread* t, Thread* o)
|
||||||
|
{
|
||||||
|
return (t == o)
|
||||||
|
or (t->peer and find(t->peer, o))
|
||||||
|
or (t->child and find(t->child, o));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
count(Thread* t, Thread* o)
|
||||||
|
{
|
||||||
|
unsigned c = 0;
|
||||||
|
|
||||||
|
if (t != o) ++ c;
|
||||||
|
if (t->peer) c += count(t->peer, o);
|
||||||
|
if (t->child) c += count(t->child, o);
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread**
|
||||||
|
fill(Thread* t, Thread* o, Thread** array)
|
||||||
|
{
|
||||||
|
if (t != o) *(array++) = t;
|
||||||
|
if (t->peer) array = fill(t->peer, o, array);
|
||||||
|
if (t->child) array = fill(t->child, o, array);
|
||||||
|
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // not NDEBUG
|
||||||
|
|
||||||
void
|
void
|
||||||
dispose(Thread* t, Thread* o, bool remove)
|
dispose(Thread* t, Thread* o, bool remove)
|
||||||
{
|
{
|
||||||
@ -203,8 +238,8 @@ turnOffTheLights(Thread* t)
|
|||||||
Finder* af = m->appFinder;
|
Finder* af = m->appFinder;
|
||||||
|
|
||||||
c->dispose();
|
c->dispose();
|
||||||
m->dispose();
|
|
||||||
h->disposeFixies();
|
h->disposeFixies();
|
||||||
|
m->dispose();
|
||||||
p->dispose();
|
p->dispose();
|
||||||
bf->dispose();
|
bf->dispose();
|
||||||
af->dispose();
|
af->dispose();
|
||||||
@ -2945,6 +2980,10 @@ Machine::dispose()
|
|||||||
heap->free(heapPool[i], ThreadHeapSizeInBytes);
|
heap->free(heapPool[i], ThreadHeapSizeInBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bootimage) {
|
||||||
|
heap->free(bootimage, bootimageSize);
|
||||||
|
}
|
||||||
|
|
||||||
heap->free(arguments, sizeof(const char*) * argumentCount);
|
heap->free(arguments, sizeof(const char*) * argumentCount);
|
||||||
|
|
||||||
heap->free(properties, sizeof(const char*) * propertyCount);
|
heap->free(properties, sizeof(const char*) * propertyCount);
|
||||||
@ -3000,13 +3039,28 @@ Thread::init()
|
|||||||
uint8_t* code = 0;
|
uint8_t* code = 0;
|
||||||
const char* imageFunctionName = findProperty(m, "avian.bootimage");
|
const char* imageFunctionName = findProperty(m, "avian.bootimage");
|
||||||
if (imageFunctionName) {
|
if (imageFunctionName) {
|
||||||
void* imagep = m->libraries->resolve(imageFunctionName);
|
bool lzma = strncmp("lzma:", imageFunctionName, 5) == 0;
|
||||||
|
const char* symbolName
|
||||||
|
= lzma ? imageFunctionName + 5 : imageFunctionName;
|
||||||
|
|
||||||
|
void* imagep = m->libraries->resolve(symbolName);
|
||||||
if (imagep) {
|
if (imagep) {
|
||||||
BootImage* (*imageFunction)(unsigned*);
|
uint8_t* (*imageFunction)(unsigned*);
|
||||||
memcpy(&imageFunction, &imagep, BytesPerWord);
|
memcpy(&imageFunction, &imagep, BytesPerWord);
|
||||||
|
|
||||||
unsigned size;
|
unsigned size;
|
||||||
image = imageFunction(&size);
|
uint8_t* imageBytes = imageFunction(&size);
|
||||||
|
if (lzma) {
|
||||||
|
#ifdef AVIAN_USE_LZMA
|
||||||
|
m->bootimage = image = reinterpret_cast<BootImage*>
|
||||||
|
(decodeLZMA
|
||||||
|
(m->system, m->heap, imageBytes, size, &(m->bootimageSize)));
|
||||||
|
#else
|
||||||
|
abort(this);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
image = reinterpret_cast<BootImage*>(imageBytes);
|
||||||
|
}
|
||||||
|
|
||||||
const char* codeFunctionName = findProperty(m, "avian.codeimage");
|
const char* codeFunctionName = findProperty(m, "avian.codeimage");
|
||||||
if (codeFunctionName) {
|
if (codeFunctionName) {
|
||||||
|
@ -1316,6 +1316,7 @@ class Machine {
|
|||||||
System::Monitor* shutdownLock;
|
System::Monitor* shutdownLock;
|
||||||
System::Library* libraries;
|
System::Library* libraries;
|
||||||
FILE* errorLog;
|
FILE* errorLog;
|
||||||
|
BootImage* bootimage;
|
||||||
object types;
|
object types;
|
||||||
object roots;
|
object roots;
|
||||||
object finalizers;
|
object finalizers;
|
||||||
@ -1332,6 +1333,7 @@ class Machine {
|
|||||||
JNIEnvVTable jniEnvVTable;
|
JNIEnvVTable jniEnvVTable;
|
||||||
uintptr_t* heapPool[ThreadHeapPoolSize];
|
uintptr_t* heapPool[ThreadHeapPoolSize];
|
||||||
unsigned heapPoolIndex;
|
unsigned heapPoolIndex;
|
||||||
|
unsigned bootimageSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
|
Loading…
Reference in New Issue
Block a user