directly emit codeimage as a object (binaryToObject is statically linked in), as a stepping stone to including extra symbols in said codeimage

This commit is contained in:
Joshua Warner 2012-05-01 13:16:32 -06:00
parent 99bc9b1d55
commit b742c58055
6 changed files with 122 additions and 56 deletions

View File

@ -18,6 +18,7 @@ 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)
@ -185,8 +186,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)
@ -223,9 +226,22 @@ ifeq ($(build-arch),powerpc)
endif endif
endif endif
ifeq ($(arch),i386) ifeq ($(target-arch),i386)
pointer-size = 4 cflags += -DAVIAN_TARGET_ARCH=AVIAN_ARCH_X86
endif 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 ($(arch),powerpc) ifeq ($(arch),powerpc)
asm = powerpc asm = powerpc
pointer-size = 4 pointer-size = 4
@ -244,9 +260,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
@ -277,7 +295,7 @@ ifeq ($(ios),true)
endif endif
ifeq ($(platform),linux) ifeq ($(platform),linux)
bootimage-cflags += -DTARGET_PLATFORM_LINUX cflags += -DAVIAN_TARGET_PLATFORM=AVIAN_PLATFORM_LINUX
endif endif
ifeq ($(build-platform),darwin) ifeq ($(build-platform),darwin)
@ -287,7 +305,7 @@ ifeq ($(build-platform),darwin)
endif endif
ifeq ($(platform),darwin) ifeq ($(platform),darwin)
bootimage-cflags += -DTARGET_PLATFORM_DARWIN cflags += -DAVIAN_TARGET_PLATFORM=AVIAN_PLATFORM_DARWIN
ifeq (${OSX_SDK_SYSROOT},) ifeq (${OSX_SDK_SYSROOT},)
OSX_SDK_SYSROOT = 10.4u OSX_SDK_SYSROOT = 10.4u
@ -364,7 +382,7 @@ ifeq ($(platform),darwin)
endif endif
ifeq ($(platform),windows) ifeq ($(platform),windows)
bootimage-cflags += -DTARGET_PLATFORM_WINDOWS cflags += -DAVIAN_TARGET_PLATFORM=AVIAN_PLATFORM_WINDOWS
inc = "$(win32)/include" inc = "$(win32)/include"
lib = "$(win32)/lib" lib = "$(win32)/lib"
@ -378,7 +396,7 @@ ifeq ($(platform),windows)
exe-suffix = .exe exe-suffix = .exe
lflags = -L$(lib) $(common-lflags) -lws2_32 -mwindows -mconsole lflags = -L$(lib) $(common-lflags) -lws2_32 -mwindows -mconsole
cflags = -I$(inc) $(common-cflags) -DWINVER=0x0500 -DTARGET_PLATFORM_WINDOWS cflags = -I$(inc) $(common-cflags) -DWINVER=0x0500 -DAVIAN_TARGET_PLATFORM=AVIAN_PLATFORM_WINDOWS
ifeq (,$(filter mingw32 cygwin,$(build-platform))) ifeq (,$(filter mingw32 cygwin,$(build-platform)))
@ -486,7 +504,7 @@ ifdef msvc
-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) -DTARGET_PLATFORM_WINDOWS -DTARGET_BYTES_PER_WORD=$(pointer-size) -DAVIAN_TARGET_PLATFORM=AVIAN_PLATFORM_WINDOWS
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
@ -622,13 +640,16 @@ converter-depends = \
converter-sources = \ converter-sources = \
$(src)/binaryToObject/main.cpp \
$(src)/binaryToObject/tools.cpp \ $(src)/binaryToObject/tools.cpp \
$(src)/binaryToObject/elf.cpp \ $(src)/binaryToObject/elf.cpp \
$(src)/binaryToObject/mach-o.cpp \ $(src)/binaryToObject/mach-o.cpp \
$(src)/binaryToObject/pe.cpp $(src)/binaryToObject/pe.cpp
converter-tool-sources = \
$(src)/binaryToObject/main.cpp
converter-objects = $(call cpp-objects,$(converter-sources),$(src),$(build)) converter-objects = $(call cpp-objects,$(converter-sources),$(src),$(build))
converter-tool-objects = $(call cpp-objects,$(converter-tool-sources),$(src),$(build))
converter = $(build)/binaryToObject/binaryToObject converter = $(build)/binaryToObject/binaryToObject
static-library = $(build)/lib$(name).a static-library = $(build)/lib$(name).a
@ -834,11 +855,11 @@ $(boot-object): $(boot-source)
$(boot-javahome-object): $(src)/boot-javahome.cpp $(boot-javahome-object): $(src)/boot-javahome.cpp
$(compile-object) $(compile-object)
$(converter-objects): $(build)/binaryToObject/%.o: $(src)/binaryToObject/%.cpp $(converter-depends) $(converter-objects) $(converter-tool-objects): $(build)/binaryToObject/%.o: $(src)/binaryToObject/%.cpp $(converter-depends)
@mkdir -p $(dir $(@)) @mkdir -p $(dir $(@))
$(build-cxx) $(converter-cflags) -c $(<) -o $(@) $(build-cxx) $(converter-cflags) -c $(<) -o $(@)
$(converter): $(converter-objects) $(converter): $(converter-objects) $(converter-tool-objects)
$(build-cc) $(^) -g -o $(@) $(build-cc) $(^) -g -o $(@)
$(build)/classpath.jar: $(classpath-dep) $(classpath-jar-dep) $(build)/classpath.jar: $(classpath-dep) $(classpath-jar-dep)
@ -881,7 +902,7 @@ $(static-library): $(vm-objects) $(classpath-objects) $(vm-heapwalk-objects) \
$(ranlib) $(@) $(ranlib) $(@)
$(bootimage-bin): $(bootimage-generator) $(bootimage-bin): $(bootimage-generator)
$(<) $(classpath-build) $(@) $(codeimage-bin) $(<) $(classpath-build) $(@) $(codeimage-object)
$(bootimage-object): $(bootimage-bin) $(converter) $(bootimage-object): $(bootimage-bin) $(converter)
@echo "creating $(@)" @echo "creating $(@)"
@ -889,12 +910,6 @@ $(bootimage-object): $(bootimage-bin) $(converter)
_binary_bootimage_bin_end $(platform) $(arch) $(pointer-size) \ _binary_bootimage_bin_end $(platform) $(arch) $(pointer-size) \
writable 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) \
$(javahome-object) $(boot-javahome-object) $(javahome-object) $(boot-javahome-object)
@ -919,6 +934,7 @@ endif
$(bootimage-generator): $(bootimage-generator-objects) $(bootimage-generator): $(bootimage-generator-objects)
$(MAKE) mode=$(mode) \ $(MAKE) mode=$(mode) \
arch=$(build-arch) \ arch=$(build-arch) \
target-arch=$(arch) \
platform=$(bootimage-platform) \ platform=$(bootimage-platform) \
openjdk=$(openjdk) \ openjdk=$(openjdk) \
openjdk-src=$(openjdk-src) \ openjdk-src=$(openjdk-src) \
@ -930,7 +946,7 @@ $(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) $(heapwalk-objects) $(bootimage-generator-objects) $(converter-objects)
@echo "linking $(@)" @echo "linking $(@)"
ifeq ($(platform),windows) ifeq ($(platform),windows)
ifdef msvc ifdef msvc

View File

@ -45,7 +45,7 @@ writeObject(uint8_t* data, size_t size, OutputStream* out, const char* startName
const char* architecture, unsigned alignment, bool writable, const char* architecture, unsigned alignment, bool writable,
bool executable) bool executable)
{ {
Platform* platform = Platform::getPlatform(PlatformInfo(os, architecture)); Platform* platform = Platform::getPlatform(PlatformInfo(PlatformInfo::osFromString(os), PlatformInfo::archFromString(architecture)));
if(!platform) { if(!platform) {
fprintf(stderr, "unsupported platform: %s/%s\n", os, architecture); fprintf(stderr, "unsupported platform: %s/%s\n", os, architecture);

View File

@ -11,6 +11,8 @@
#ifndef AVIAN_TOOLS_H_ #ifndef AVIAN_TOOLS_H_
#define AVIAN_TOOLS_H_ #define AVIAN_TOOLS_H_
#include "environment.h"
namespace avian { namespace avian {
namespace tools { namespace tools {
@ -96,11 +98,18 @@ public:
class PlatformInfo { class PlatformInfo {
public: public:
enum OperatingSystem { enum OperatingSystem {
Linux, Windows, Darwin, UnknownOS Linux = AVIAN_PLATFORM_LINUX,
Windows = AVIAN_PLATFORM_WINDOWS,
Darwin = AVIAN_PLATFORM_DARWIN,
UnknownOS = AVIAN_PLATFORM_UNKNOWN
}; };
enum Architecture { enum Architecture {
x86, x86_64, PowerPC, Arm, UnknownArch 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 OperatingSystem os;
@ -113,10 +122,6 @@ public:
os(os), os(os),
arch(arch) {} arch(arch) {}
inline PlatformInfo(const char* os, const char* arch):
os(osFromString(os)),
arch(archFromString(arch)) {}
inline bool operator == (const PlatformInfo& other) { inline bool operator == (const PlatformInfo& other) {
return os == other.os && arch == other.arch; return os == other.os && arch == other.arch;
} }

View File

@ -16,12 +16,14 @@
#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 {
@ -1285,7 +1287,7 @@ 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)
{ {
@ -1593,17 +1595,13 @@ 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); bootimageOutput->writeChunk(&targetImage, sizeof(BootImage));
} }
fwrite(bootClassTable, image->bootClassCount * sizeof(unsigned), 1, bootimageOutput->writeChunk(bootClassTable, image->bootClassCount * sizeof(unsigned));
bootimageOutput); bootimageOutput->writeChunk(appClassTable, image->appClassCount * sizeof(unsigned));
fwrite(appClassTable, image->appClassCount * sizeof(unsigned), 1, bootimageOutput->writeChunk(stringTable, image->stringCount * sizeof(unsigned));
bootimageOutput); bootimageOutput->writeChunk(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))
@ -1613,24 +1611,40 @@ 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); bootimageOutput->write(c);
++ offset; ++ offset;
} }
fwrite(heapMap, pad(heapMapSize(image->heapSize), TargetBytesPerWord), 1, bootimageOutput->writeChunk(heapMap, pad(heapMapSize(image->heapSize), TargetBytesPerWord));
bootimageOutput);
fwrite(heap, pad(image->heapSize, TargetBytesPerWord), 1, bootimageOutput); bootimageOutput->writeChunk(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;
// }
const char* const startName = "_binary_codeimage_bin_start";
const char* const endName = "_binary_codeimage_bin_end";
SymbolInfo symbols[] = {
SymbolInfo(0, startName),
SymbolInfo(image->codeSize, endName)
};
platform->writeObject(codeOutput, Slice<SymbolInfo>(symbols, 2), Slice<const uint8_t>(code, image->codeSize), Platform::Executable, TargetBytesPerWord);
} }
} }
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]);
@ -1679,20 +1693,20 @@ main(int ac, const char** av)
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(av[2]);
if (bootimageOutput == 0) { if (!bootimageOutput.isValid()) {
fprintf(stderr, "unable to open %s\n", av[2]); fprintf(stderr, "unable to open %s\n", av[2]);
return -1; return -1;
} }
FILE* codeOutput = vm::fopen(av[3], "wb"); FileOutputStream codeOutput(av[3]);
if (codeOutput == 0) { if (!codeOutput.isValid()) {
fprintf(stderr, "unable to open %s\n", av[3]); fprintf(stderr, "unable to open %s\n", av[3]);
return -1; return -1;
} }
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(bootimageOutput), uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(&bootimageOutput),
reinterpret_cast<uintptr_t>(codeOutput), reinterpret_cast<uintptr_t>(&codeOutput),
reinterpret_cast<uintptr_t>(&image), reinterpret_cast<uintptr_t>(&image),
reinterpret_cast<uintptr_t>(code), reinterpret_cast<uintptr_t>(code),
reinterpret_cast<uintptr_t>(ac > 4 ? av[4] : 0), reinterpret_cast<uintptr_t>(ac > 4 ? av[4] : 0),
@ -1701,9 +1715,6 @@ main(int ac, const char** av)
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;

33
src/environment.h Normal file
View File

@ -0,0 +1,33 @@
/* Copyright (c) 2008-2011, 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_ENVIRONMENT_H
#define AVIAN_ENVIRONMENT_H
#ifndef AVIAN_TARGET_PLATFORM
#error build system should have defined AVIAN_TARGET_PLATFORM
#endif
#ifndef AVIAN_TARGET_ARCH
#error build system should have defined AVIAN_TARGET_ARCH
#endif
#define AVIAN_PLATFORM_UNKNOWN 0
#define AVIAN_PLATFORM_LINUX 1
#define AVIAN_PLATFORM_WINDOWS 2
#define AVIAN_PLATFORM_DARWIN 3
#define AVIAN_ARCH_UNKNOWN 0
#define AVIAN_ARCH_X86 (1 << 8)
#define AVIAN_ARCH_X86_64 (2 << 8)
#define AVIAN_ARCH_ARM (3 << 8)
#define AVIAN_ARCH_POWERPC (4 << 8)
#endif

View File

@ -8,6 +8,7 @@
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 "environment.h"
#include "assembler.h" #include "assembler.h"
#include "target.h" #include "target.h"
#include "vector.h" #include "vector.h"
@ -2816,7 +2817,7 @@ class MyArchitecture: public Assembler::Architecture {
} }
virtual unsigned frameFootprint(unsigned footprint) { virtual unsigned frameFootprint(unsigned footprint) {
#ifdef TARGET_PLATFORM_WINDOWS #if AVIAN_TARGET_PLATFORM == AVIAN_PLATFORM_WINDOWS
return max(footprint, StackAlignmentInWords); return max(footprint, StackAlignmentInWords);
#else #else
return max(footprint > argumentRegisterCount() ? return max(footprint > argumentRegisterCount() ?
@ -2838,7 +2839,7 @@ class MyArchitecture: public Assembler::Architecture {
} }
virtual unsigned argumentRegisterCount() { virtual unsigned argumentRegisterCount() {
#ifdef TARGET_PLATFORM_WINDOWS #if AVIAN_TARGET_PLATFORM == AVIAN_PLATFORM_WINDOWS
if (TargetBytesPerWord == 8) return 4; else if (TargetBytesPerWord == 8) return 4; else
#else #else
if (TargetBytesPerWord == 8) return 6; else if (TargetBytesPerWord == 8) return 6; else
@ -2849,7 +2850,7 @@ class MyArchitecture: public Assembler::Architecture {
virtual int argumentRegister(unsigned index) { virtual int argumentRegister(unsigned index) {
assert(&c, TargetBytesPerWord == 8); assert(&c, TargetBytesPerWord == 8);
switch (index) { switch (index) {
#ifdef TARGET_PLATFORM_WINDOWS #if AVIAN_TARGET_PLATFORM == AVIAN_PLATFORM_WINDOWS
case 0: case 0:
return rcx; return rcx;
case 1: case 1: