From b742c58055ad0e65498bcaacf84021704d3e7b00 Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Tue, 1 May 2012 13:16:32 -0600 Subject: [PATCH] directly emit codeimage as a object (binaryToObject is statically linked in), as a stepping stone to including extra symbols in said codeimage --- makefile | 56 +++++++++++++++++++++------------ src/binaryToObject/main.cpp | 2 +- src/binaryToObject/tools.h | 17 ++++++---- src/bootimage.cpp | 63 ++++++++++++++++++++++--------------- src/environment.h | 33 +++++++++++++++++++ src/x86.cpp | 7 +++-- 6 files changed, 122 insertions(+), 56 deletions(-) create mode 100644 src/environment.h diff --git a/makefile b/makefile index 686f9ec5ea..ff1a862afe 100755 --- a/makefile +++ b/makefile @@ -18,6 +18,7 @@ build-platform := \ | sed 's/^cygwin.*$$/cygwin/') arch = $(build-arch) +target-arch = $(arch) bootimage-platform = \ $(subst cygwin,windows,$(subst mingw32,windows,$(build-platform))) platform = $(bootimage-platform) @@ -185,8 +186,10 @@ endif build-cflags = $(common-cflags) -fPIC -fvisibility=hidden \ "-I$(JAVA_HOME)/include/linux" -I$(src) -pthread -converter-cflags = -D__STDC_CONSTANT_MACROS -Isrc/binaryToObject \ - -fno-rtti -fno-exceptions +converter-cflags = -D__STDC_CONSTANT_MACROS -Isrc/binaryToObject -Isrc/ \ + -fno-rtti -fno-exceptions \ + -DAVIAN_TARGET_ARCH=AVIAN_ARCH_UNKNOWN \ + -DAVIAN_TARGET_PLATFORM=AVIAN_PLATFORM_UNKNOWN cflags = $(build-cflags) @@ -223,9 +226,22 @@ ifeq ($(build-arch),powerpc) endif endif -ifeq ($(arch),i386) - pointer-size = 4 +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 ($(arch),powerpc) asm = powerpc pointer-size = 4 @@ -244,9 +260,11 @@ ifeq ($(arch),powerpc) endif endif endif + ifeq ($(arch),arm) asm = arm pointer-size = 4 + ifeq ($(build-platform),darwin) ios = true else @@ -277,7 +295,7 @@ ifeq ($(ios),true) endif ifeq ($(platform),linux) - bootimage-cflags += -DTARGET_PLATFORM_LINUX + cflags += -DAVIAN_TARGET_PLATFORM=AVIAN_PLATFORM_LINUX endif ifeq ($(build-platform),darwin) @@ -287,7 +305,7 @@ ifeq ($(build-platform),darwin) endif ifeq ($(platform),darwin) - bootimage-cflags += -DTARGET_PLATFORM_DARWIN + cflags += -DAVIAN_TARGET_PLATFORM=AVIAN_PLATFORM_DARWIN ifeq (${OSX_SDK_SYSROOT},) OSX_SDK_SYSROOT = 10.4u @@ -364,7 +382,7 @@ ifeq ($(platform),darwin) endif ifeq ($(platform),windows) - bootimage-cflags += -DTARGET_PLATFORM_WINDOWS + cflags += -DAVIAN_TARGET_PLATFORM=AVIAN_PLATFORM_WINDOWS inc = "$(win32)/include" lib = "$(win32)/lib" @@ -378,7 +396,7 @@ ifeq ($(platform),windows) exe-suffix = .exe 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))) @@ -486,7 +504,7 @@ ifdef msvc -DAVIAN_EMBED_PREFIX=\"$(embed-prefix)\" \ -Fd$(build)/$(name).pdb -I"$(zlib)/include" -I$(src) -I"$(build)" \ -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 lflags = -nologo -LIBPATH:"$(zlib)/lib" -DEFAULTLIB:ws2_32 \ -DEFAULTLIB:zlib -MANIFEST -debug @@ -622,13 +640,16 @@ converter-depends = \ converter-sources = \ - $(src)/binaryToObject/main.cpp \ $(src)/binaryToObject/tools.cpp \ $(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 @@ -834,11 +855,11 @@ $(boot-object): $(boot-source) $(boot-javahome-object): $(src)/boot-javahome.cpp $(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 $(@)) $(build-cxx) $(converter-cflags) -c $(<) -o $(@) -$(converter): $(converter-objects) +$(converter): $(converter-objects) $(converter-tool-objects) $(build-cc) $(^) -g -o $(@) $(build)/classpath.jar: $(classpath-dep) $(classpath-jar-dep) @@ -881,7 +902,7 @@ $(static-library): $(vm-objects) $(classpath-objects) $(vm-heapwalk-objects) \ $(ranlib) $(@) $(bootimage-bin): $(bootimage-generator) - $(<) $(classpath-build) $(@) $(codeimage-bin) + $(<) $(classpath-build) $(@) $(codeimage-object) $(bootimage-object): $(bootimage-bin) $(converter) @echo "creating $(@)" @@ -889,12 +910,6 @@ $(bootimage-object): $(bootimage-bin) $(converter) _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) \ $(vm-heapwalk-objects) $(boot-object) $(vm-classpath-objects) \ $(javahome-object) $(boot-javahome-object) @@ -919,6 +934,7 @@ endif $(bootimage-generator): $(bootimage-generator-objects) $(MAKE) mode=$(mode) \ arch=$(build-arch) \ + target-arch=$(arch) \ platform=$(bootimage-platform) \ openjdk=$(openjdk) \ openjdk-src=$(openjdk-src) \ @@ -930,7 +946,7 @@ $(bootimage-generator): $(bootimage-generator-objects) $(build-bootimage-generator): \ $(vm-objects) $(classpath-object) $(classpath-objects) \ - $(heapwalk-objects) $(bootimage-generator-objects) + $(heapwalk-objects) $(bootimage-generator-objects) $(converter-objects) @echo "linking $(@)" ifeq ($(platform),windows) ifdef msvc diff --git a/src/binaryToObject/main.cpp b/src/binaryToObject/main.cpp index c3f3eb493f..00515947e3 100644 --- a/src/binaryToObject/main.cpp +++ b/src/binaryToObject/main.cpp @@ -45,7 +45,7 @@ writeObject(uint8_t* data, size_t size, OutputStream* out, const char* startName const char* architecture, unsigned alignment, bool writable, bool executable) { - Platform* platform = Platform::getPlatform(PlatformInfo(os, architecture)); + Platform* platform = Platform::getPlatform(PlatformInfo(PlatformInfo::osFromString(os), PlatformInfo::archFromString(architecture))); if(!platform) { fprintf(stderr, "unsupported platform: %s/%s\n", os, architecture); diff --git a/src/binaryToObject/tools.h b/src/binaryToObject/tools.h index bc3d1f4f19..52ac647bb9 100644 --- a/src/binaryToObject/tools.h +++ b/src/binaryToObject/tools.h @@ -11,6 +11,8 @@ #ifndef AVIAN_TOOLS_H_ #define AVIAN_TOOLS_H_ +#include "environment.h" + namespace avian { namespace tools { @@ -96,11 +98,18 @@ public: class PlatformInfo { public: enum OperatingSystem { - Linux, Windows, Darwin, UnknownOS + Linux = AVIAN_PLATFORM_LINUX, + Windows = AVIAN_PLATFORM_WINDOWS, + Darwin = AVIAN_PLATFORM_DARWIN, + UnknownOS = AVIAN_PLATFORM_UNKNOWN }; 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; @@ -113,10 +122,6 @@ public: os(os), arch(arch) {} - inline PlatformInfo(const char* os, const char* arch): - os(osFromString(os)), - arch(archFromString(arch)) {} - inline bool operator == (const PlatformInfo& other) { return os == other.os && arch == other.arch; } diff --git a/src/bootimage.cpp b/src/bootimage.cpp index 3d75f4401c..1571f5f9ca 100644 --- a/src/bootimage.cpp +++ b/src/bootimage.cpp @@ -16,12 +16,14 @@ #include "stream.h" #include "assembler.h" #include "target.h" +#include "binaryToObject/tools.h" // since we aren't linking against libstdc++, we must implement this // ourselves: extern "C" void __cxa_pure_virtual(void) { abort(); } using namespace vm; +using namespace avian::tools; namespace { @@ -1285,7 +1287,7 @@ targetThunk(BootImage::Thunk t) } void -writeBootImage2(Thread* t, FILE* bootimageOutput, FILE* codeOutput, +writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutput, BootImage* image, uint8_t* code, const char* className, const char* methodName, const char* methodSpec) { @@ -1593,17 +1595,13 @@ writeBootImage2(Thread* t, FILE* bootimageOutput, FILE* codeOutput, #include "bootimage-fields.cpp" #undef THUNK_FIELD - fwrite(&targetImage, sizeof(BootImage), 1, bootimageOutput); + bootimageOutput->writeChunk(&targetImage, sizeof(BootImage)); } - fwrite(bootClassTable, image->bootClassCount * sizeof(unsigned), 1, - bootimageOutput); - fwrite(appClassTable, image->appClassCount * sizeof(unsigned), 1, - bootimageOutput); - fwrite(stringTable, image->stringCount * sizeof(unsigned), 1, - bootimageOutput); - fwrite(callTable, image->callCount * sizeof(unsigned) * 2, 1, - bootimageOutput); + bootimageOutput->writeChunk(bootClassTable, image->bootClassCount * sizeof(unsigned)); + bootimageOutput->writeChunk(appClassTable, image->appClassCount * sizeof(unsigned)); + bootimageOutput->writeChunk(stringTable, image->stringCount * sizeof(unsigned)); + bootimageOutput->writeChunk(callTable, image->callCount * sizeof(unsigned) * 2); unsigned offset = sizeof(BootImage) + (image->bootClassCount * sizeof(unsigned)) @@ -1613,24 +1611,40 @@ writeBootImage2(Thread* t, FILE* bootimageOutput, FILE* codeOutput, while (offset % TargetBytesPerWord) { uint8_t c = 0; - fwrite(&c, 1, 1, bootimageOutput); + bootimageOutput->write(c); ++ offset; } - fwrite(heapMap, pad(heapMapSize(image->heapSize), TargetBytesPerWord), 1, - bootimageOutput); + bootimageOutput->writeChunk(heapMap, pad(heapMapSize(image->heapSize), TargetBytesPerWord)); - 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(symbols, 2), Slice(code, image->codeSize), Platform::Executable, TargetBytesPerWord); } } uint64_t writeBootImage(Thread* t, uintptr_t* arguments) { - FILE* bootimageOutput = reinterpret_cast(arguments[0]); - FILE* codeOutput = reinterpret_cast(arguments[1]); + OutputStream* bootimageOutput = reinterpret_cast(arguments[0]); + OutputStream* codeOutput = reinterpret_cast(arguments[1]); BootImage* image = reinterpret_cast(arguments[2]); uint8_t* code = reinterpret_cast(arguments[3]); const char* className = reinterpret_cast(arguments[4]); @@ -1679,20 +1693,20 @@ main(int ac, const char** av) enter(t, Thread::ActiveState); enter(t, Thread::IdleState); - FILE* bootimageOutput = vm::fopen(av[2], "wb"); - if (bootimageOutput == 0) { + FileOutputStream bootimageOutput(av[2]); + if (!bootimageOutput.isValid()) { fprintf(stderr, "unable to open %s\n", av[2]); return -1; } - FILE* codeOutput = vm::fopen(av[3], "wb"); - if (codeOutput == 0) { + FileOutputStream codeOutput(av[3]); + if (!codeOutput.isValid()) { fprintf(stderr, "unable to open %s\n", av[3]); return -1; } - uintptr_t arguments[] = { reinterpret_cast(bootimageOutput), - reinterpret_cast(codeOutput), + uintptr_t arguments[] = { reinterpret_cast(&bootimageOutput), + reinterpret_cast(&codeOutput), reinterpret_cast(&image), reinterpret_cast(code), reinterpret_cast(ac > 4 ? av[4] : 0), @@ -1701,9 +1715,6 @@ main(int ac, const char** av) run(t, writeBootImage, arguments); - fclose(codeOutput); - fclose(bootimageOutput); - if (t->exception) { printTrace(t, t->exception); return -1; diff --git a/src/environment.h b/src/environment.h new file mode 100644 index 0000000000..53a309057e --- /dev/null +++ b/src/environment.h @@ -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 \ No newline at end of file diff --git a/src/x86.cpp b/src/x86.cpp index bd6c418417..89d6f5df25 100644 --- a/src/x86.cpp +++ b/src/x86.cpp @@ -8,6 +8,7 @@ There is NO WARRANTY for this software. See license.txt for details. */ +#include "environment.h" #include "assembler.h" #include "target.h" #include "vector.h" @@ -2816,7 +2817,7 @@ class MyArchitecture: public Assembler::Architecture { } virtual unsigned frameFootprint(unsigned footprint) { -#ifdef TARGET_PLATFORM_WINDOWS +#if AVIAN_TARGET_PLATFORM == AVIAN_PLATFORM_WINDOWS return max(footprint, StackAlignmentInWords); #else return max(footprint > argumentRegisterCount() ? @@ -2838,7 +2839,7 @@ class MyArchitecture: public Assembler::Architecture { } virtual unsigned argumentRegisterCount() { -#ifdef TARGET_PLATFORM_WINDOWS +#if AVIAN_TARGET_PLATFORM == AVIAN_PLATFORM_WINDOWS if (TargetBytesPerWord == 8) return 4; else #else if (TargetBytesPerWord == 8) return 6; else @@ -2849,7 +2850,7 @@ class MyArchitecture: public Assembler::Architecture { virtual int argumentRegister(unsigned index) { assert(&c, TargetBytesPerWord == 8); switch (index) { -#ifdef TARGET_PLATFORM_WINDOWS +#if AVIAN_TARGET_PLATFORM == AVIAN_PLATFORM_WINDOWS case 0: return rcx; case 1: