mirror of
https://github.com/corda/corda.git
synced 2025-01-01 02:36:44 +00:00
update makefile to optionally build and use a boot image; various bugfixes
This commit is contained in:
parent
0ef2ee1d02
commit
0ec5ad3701
55
makefile
55
makefile
@ -59,7 +59,6 @@ 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$(native-build) \
|
||||
-D__STDC_LIMIT_MACROS -D_JNI_IMPLEMENTATION_ -DAVIAN_VERSION=\"$(version)\" \
|
||||
-DBOOT_CLASSPATH=\"[classpathJar]\"
|
||||
|
||||
build-cflags = $(common-cflags) -fPIC -fvisibility=hidden \
|
||||
"-I$(JAVA_HOME)/include/linux" -I$(src) -pthread
|
||||
@ -187,7 +186,9 @@ vm-depends = \
|
||||
$(src)/util.h \
|
||||
$(src)/zone.h \
|
||||
$(src)/assembler.h \
|
||||
$(src)/compiler.h
|
||||
$(src)/compiler.h \
|
||||
$(src)/heapwalk.h \
|
||||
$(src)/bootimage.h
|
||||
|
||||
vm-sources = \
|
||||
$(src)/$(system).cpp \
|
||||
@ -227,10 +228,21 @@ ifeq ($(heapdump),true)
|
||||
cflags += -DAVIAN_HEAPDUMP
|
||||
endif
|
||||
|
||||
bootimage-sources = $(src)/bootimage.cpp
|
||||
bootimage-objects = \
|
||||
$(call cpp-objects,$(bootimage-sources),$(src),$(native-build))
|
||||
bootimage = $(native-build)/bootimage
|
||||
bootimage-generator-sources = $(src)/bootimage.cpp
|
||||
bootimage-generator-objects = \
|
||||
$(call cpp-objects,$(bootimage-generator-sources),$(src),$(native-build))
|
||||
bootimage-generator = $(native-build)/bootimage-generator
|
||||
|
||||
bootimage-bin = $(native-build)/bootimage.bin
|
||||
bootimage-object = $(native-build)/bootimage-bin.o
|
||||
|
||||
ifeq ($(bootimage),true)
|
||||
vm-classpath-object = $(bootimage-object)
|
||||
cflags += -DBOOT_IMAGE=\"bootimageBin\"
|
||||
else
|
||||
vm-classpath-object = $(classpath-object)
|
||||
cflags += -DBOOT_CLASSPATH=\"[classpathJar]\"
|
||||
endif
|
||||
|
||||
driver-source = $(src)/main.cpp
|
||||
driver-object = $(native-build)/main.o
|
||||
@ -269,7 +281,7 @@ args = $(flags) $(input)
|
||||
|
||||
.PHONY: build
|
||||
build: $(static-library) $(executable) $(dynamic-library) \
|
||||
$(executable-dynamic) $(classpath-dep) $(test-dep) $(bootimage)
|
||||
$(executable-dynamic) $(classpath-dep) $(test-dep)
|
||||
|
||||
$(test-classes): $(classpath-dep)
|
||||
|
||||
@ -356,7 +368,7 @@ $(vm-cpp-objects): $(native-build)/%.o: $(src)/%.cpp $(vm-depends)
|
||||
$(vm-asm-objects): $(native-build)/%-asm.o: $(src)/%.S
|
||||
$(compile-asm-object)
|
||||
|
||||
$(bootimage-objects): $(native-build)/%.o: $(src)/%.cpp $(vm-depends)
|
||||
$(bootimage-generator-objects): $(native-build)/%.o: $(src)/%.cpp $(vm-depends)
|
||||
$(compile-object)
|
||||
|
||||
$(heapwalk-objects): $(native-build)/%.o: $(src)/%.cpp $(vm-depends)
|
||||
@ -409,9 +421,24 @@ $(static-library): $(vm-objects) $(jni-objects)
|
||||
$(ar) cru $(@) $(^)
|
||||
$(ranlib) $(@)
|
||||
|
||||
$(bootimage-bin): $(bootimage-generator)
|
||||
$(<) $(classpath-build) > $(@)
|
||||
|
||||
$(bootimage-object): $(bootimage-bin)
|
||||
@echo "creating $(@)"
|
||||
ifeq ($(platform),darwin)
|
||||
$(binaryToMacho) $(<) \
|
||||
__binary_bootimage_bin_start __binary_bootimage_bin_end > $(@)
|
||||
else
|
||||
(wd=$$(pwd); \
|
||||
cd $(native-build); \
|
||||
$(objcopy) -I binary bootimage.bin \
|
||||
-O $(object-format) -B $(object-arch) "$${wd}/$(@)")
|
||||
endif
|
||||
|
||||
$(executable): \
|
||||
$(vm-objects) $(classpath-object) $(jni-objects) $(driver-object) \
|
||||
$(vm-heapwalk-objects) $(boot-object)
|
||||
$(vm-objects) $(jni-objects) $(driver-object) $(vm-heapwalk-objects) \
|
||||
$(boot-object) $(vm-classpath-object)
|
||||
@echo "linking $(@)"
|
||||
ifeq ($(platform),windows)
|
||||
$(dlltool) -z $(@).def $(^)
|
||||
@ -422,9 +449,9 @@ else
|
||||
endif
|
||||
$(strip) $(strip-all) $(@)
|
||||
|
||||
$(bootimage): \
|
||||
$(bootimage-generator): \
|
||||
$(vm-objects) $(classpath-object) $(jni-objects) $(heapwalk-objects) \
|
||||
$(bootimage-objects)
|
||||
$(bootimage-generator-objects)
|
||||
@echo "linking $(@)"
|
||||
ifeq ($(platform),windows)
|
||||
$(dlltool) -z $(@).def $(^)
|
||||
@ -436,8 +463,8 @@ endif
|
||||
$(strip) $(strip-all) $(@)
|
||||
|
||||
$(dynamic-library): \
|
||||
$(vm-objects) $(classpath-object) $(dynamic-object) $(jni-objects) \
|
||||
$(vm-heapwalk-objects) $(boot-object)
|
||||
$(vm-objects) $(dynamic-object) $(jni-objects) $(vm-heapwalk-objects) \
|
||||
$(boot-object) $(vm-classpath-object)
|
||||
@echo "linking $(@)"
|
||||
$(cc) $(^) $(shared) $(lflags) -o $(@)
|
||||
$(strip) $(strip-all) $(@)
|
||||
|
@ -211,7 +211,8 @@ class Assembler {
|
||||
|
||||
virtual unsigned length() = 0;
|
||||
|
||||
virtual void updateCall(void* returnAddress, void* newTarget) = 0;
|
||||
virtual void updateCall(UnaryOperation op, bool assertAlignment,
|
||||
void* returnAddress, void* newTarget) = 0;
|
||||
|
||||
virtual void dispose() = 0;
|
||||
};
|
||||
|
30
src/boot.cpp
30
src/boot.cpp
@ -15,6 +15,34 @@
|
||||
// ourselves:
|
||||
extern "C" void __cxa_pure_virtual(void) { abort(); }
|
||||
|
||||
#ifdef BOOT_IMAGE
|
||||
|
||||
#ifdef __MINGW32__
|
||||
# define EXPORT __declspec(dllexport)
|
||||
# define SYMBOL(x) binary_bootimage_bin_##x
|
||||
#else
|
||||
# define EXPORT __attribute__ ((visibility("default")))
|
||||
# define SYMBOL(x) _binary_bootimage_bin_##x
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
|
||||
extern const uint8_t SYMBOL(start)[];
|
||||
extern const uint8_t SYMBOL(end)[];
|
||||
|
||||
EXPORT const uint8_t*
|
||||
bootimageBin(unsigned* size)
|
||||
{
|
||||
*size = SYMBOL(end) - SYMBOL(start);
|
||||
return SYMBOL(start);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif//BOOT_IMAGE
|
||||
|
||||
#ifdef BOOT_CLASSPATH
|
||||
|
||||
#ifdef __MINGW32__
|
||||
# define EXPORT __declspec(dllexport)
|
||||
# define SYMBOL(x) binary_classpath_jar_##x
|
||||
@ -36,3 +64,5 @@ extern "C" {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif//BOOT_CLASSPATH
|
||||
|
@ -106,22 +106,18 @@ makeHeapImage(Thread* t, BootImage* image, uintptr_t* heap, uintptr_t* map,
|
||||
class Visitor: public HeapVisitor {
|
||||
public:
|
||||
Visitor(Thread* t, uintptr_t* heap, uintptr_t* map, unsigned capacity):
|
||||
t(t), currentObject(0), currentOffset(0), heap(heap), map(map),
|
||||
position(0), capacity(capacity)
|
||||
t(t), current(0), heap(heap), map(map), position(0), capacity(capacity)
|
||||
{ }
|
||||
|
||||
void visit(unsigned number) {
|
||||
if (currentObject) {
|
||||
unsigned index = currentObject - 1 + currentOffset;
|
||||
markBit(map, index);
|
||||
heap[index] = number;
|
||||
if (current) {
|
||||
if (number) markBit(map, current - 1);
|
||||
heap[current - 1] = number;
|
||||
}
|
||||
|
||||
currentObject = number;
|
||||
}
|
||||
|
||||
virtual void root() {
|
||||
currentObject = 0;
|
||||
current = 0;
|
||||
}
|
||||
|
||||
virtual unsigned visitNew(object p) {
|
||||
@ -146,17 +142,16 @@ makeHeapImage(Thread* t, BootImage* image, uintptr_t* heap, uintptr_t* map,
|
||||
visit(number);
|
||||
}
|
||||
|
||||
virtual void push(unsigned offset) {
|
||||
currentOffset = offset;
|
||||
virtual void push(object, unsigned number, unsigned offset) {
|
||||
current = number + offset;
|
||||
}
|
||||
|
||||
virtual void pop() {
|
||||
currentObject = 0;
|
||||
current = 0;
|
||||
}
|
||||
|
||||
Thread* t;
|
||||
unsigned currentObject;
|
||||
unsigned currentOffset;
|
||||
unsigned current;
|
||||
uintptr_t* heap;
|
||||
uintptr_t* map;
|
||||
unsigned position;
|
||||
@ -176,8 +171,8 @@ updateConstants(Thread* t, object constants, uint8_t* code, uintptr_t* codeMap,
|
||||
HeapMap* heapTable)
|
||||
{
|
||||
for (; constants; constants = tripleThird(t, constants)) {
|
||||
intptr_t target = heapTable->find(tripleFirst(t, constants));
|
||||
assert(t, target >= 0);
|
||||
unsigned target = heapTable->find(tripleFirst(t, constants));
|
||||
assert(t, target > 0);
|
||||
|
||||
void* dst = static_cast<ListenPromise*>
|
||||
(pointerValue(t, tripleSecond(t, constants)))->listener->resolve(target);
|
||||
@ -226,7 +221,7 @@ writeBootImage(Thread* t, FILE* out)
|
||||
|
||||
image.magic = BootImage::Magic;
|
||||
|
||||
if (true) {
|
||||
if (false) {
|
||||
fprintf(stderr, "heap size %d code size %d\n",
|
||||
image.heapSize, image.codeSize);
|
||||
} else {
|
||||
|
@ -59,7 +59,17 @@ codeMapSize(unsigned codeSize)
|
||||
inline unsigned
|
||||
heapMapSize(unsigned heapSize)
|
||||
{
|
||||
return ceiling(heapSize, BitsPerWord * 8) * BytesPerWord;
|
||||
return ceiling(heapSize, BitsPerWord * BytesPerWord) * BytesPerWord;
|
||||
}
|
||||
|
||||
inline object
|
||||
bootObject(uintptr_t* heap, unsigned offset)
|
||||
{
|
||||
if (offset) {
|
||||
return reinterpret_cast<object>(heap + offset - 1);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace vm
|
||||
|
@ -4050,6 +4050,14 @@ compile(MyThread* t, Allocator* allocator, Context* context)
|
||||
return finish(t, allocator, context);
|
||||
}
|
||||
|
||||
void
|
||||
updateCall(MyThread* t, UnaryOperation op, bool assertAlignment,
|
||||
void* returnAddress, void* target)
|
||||
{
|
||||
Context context(t);
|
||||
context.assembler->updateCall(op, assertAlignment, returnAddress, target);
|
||||
}
|
||||
|
||||
void
|
||||
compile(MyThread* t, Allocator* allocator, BootContext* bootContext,
|
||||
object method);
|
||||
@ -4081,9 +4089,9 @@ compileMethod2(MyThread* t)
|
||||
(t, resolveThisPointer(t, t->stack, target)), methodOffset(t, target))
|
||||
= address;
|
||||
} else {
|
||||
Context context(t);
|
||||
context.assembler->updateCall
|
||||
(reinterpret_cast<void*>(callNodeAddress(t, node)), address);
|
||||
updateCall
|
||||
(t, LongCall, true, reinterpret_cast<void*>(callNodeAddress(t, node)),
|
||||
address);
|
||||
}
|
||||
return address;
|
||||
}
|
||||
@ -5117,37 +5125,38 @@ class MyProcessor: public Processor {
|
||||
image->methodTreeSentinal = w->visitRoot(methodTreeSentinal);
|
||||
}
|
||||
|
||||
virtual void boot(Thread* t, BootImage* image, uintptr_t* heap,
|
||||
virtual void boot(Thread* vmt, BootImage* image, uintptr_t* heap,
|
||||
uint8_t* code)
|
||||
{
|
||||
methodTree = reinterpret_cast<object>(heap + image->methodTree);
|
||||
methodTreeSentinal = reinterpret_cast<object>
|
||||
(heap + image->methodTreeSentinal);
|
||||
MyThread* t = static_cast<MyThread*>(vmt);
|
||||
methodTree = bootObject(heap, image->methodTree);
|
||||
methodTreeSentinal = bootObject(heap, image->methodTreeSentinal);
|
||||
|
||||
callTable = fixupCallTable
|
||||
(static_cast<MyThread*>(t),
|
||||
reinterpret_cast<object>(heap + image->callTable),
|
||||
image->codeBase,
|
||||
(t, bootObject(heap, image->callTable), image->codeBase,
|
||||
reinterpret_cast<uintptr_t>(code));
|
||||
|
||||
defaultThunk = code + image->defaultThunk;
|
||||
{ void* p = voidPointer(::compileMethod);
|
||||
memcpy(code + image->compileMethodCall, &p, BytesPerWord); }
|
||||
|
||||
updateCall(t, LongCall, false, code + image->compileMethodCall,
|
||||
voidPointer(::compileMethod));
|
||||
|
||||
nativeThunk = code + image->nativeThunk;
|
||||
{ void* p = voidPointer(invokeNative);
|
||||
memcpy(code + image->invokeNativeCall, &p, BytesPerWord); }
|
||||
|
||||
updateCall(t, LongCall, false, code + image->invokeNativeCall,
|
||||
voidPointer(invokeNative));
|
||||
|
||||
aioobThunk = code + image->aioobThunk;
|
||||
{ void* p = voidPointer(throwArrayIndexOutOfBounds);
|
||||
memcpy(code + image->throwArrayIndexOutOfBoundsCall, &p, BytesPerWord); }
|
||||
|
||||
updateCall(t, LongCall, false,
|
||||
code + image->throwArrayIndexOutOfBoundsCall,
|
||||
voidPointer(throwArrayIndexOutOfBounds));
|
||||
|
||||
thunkTable = code + image->thunkTable;
|
||||
thunkSize = image->thunkSize;
|
||||
|
||||
#define THUNK(s) \
|
||||
{ void* p = voidPointer(s); \
|
||||
memcpy(code + image->s##Call, &p, BytesPerWord); }
|
||||
updateCall(t, LongJump, false, code + image->s##Call, voidPointer(s));
|
||||
|
||||
#include "thunks.cpp"
|
||||
|
||||
@ -5261,36 +5270,42 @@ compileThunks(MyThread* t, Allocator* allocator, MyProcessor* p,
|
||||
p->defaultThunk = finish
|
||||
(t, allocator, defaultContext.context.assembler, "default");
|
||||
|
||||
{ void* call = defaultContext.promise.listener->resolve
|
||||
(reinterpret_cast<intptr_t>(voidPointer(compileMethod)));
|
||||
{ uint8_t* call = static_cast<uint8_t*>
|
||||
(defaultContext.promise.listener->resolve
|
||||
(reinterpret_cast<intptr_t>(voidPointer(compileMethod))))
|
||||
+ BytesPerWord;
|
||||
|
||||
if (image) {
|
||||
image->defaultThunk = p->defaultThunk - imageBase;
|
||||
image->compileMethodCall = static_cast<uint8_t*>(call) - imageBase;
|
||||
image->compileMethodCall = call - imageBase;
|
||||
}
|
||||
}
|
||||
|
||||
p->nativeThunk = finish
|
||||
(t, allocator, nativeContext.context.assembler, "native");
|
||||
|
||||
{ void* call = nativeContext.promise.listener->resolve
|
||||
(reinterpret_cast<intptr_t>(voidPointer(invokeNative)));
|
||||
{ uint8_t* call = static_cast<uint8_t*>
|
||||
(nativeContext.promise.listener->resolve
|
||||
(reinterpret_cast<intptr_t>(voidPointer(invokeNative))))
|
||||
+ BytesPerWord;
|
||||
|
||||
if (image) {
|
||||
image->nativeThunk = p->nativeThunk - imageBase;
|
||||
image->invokeNativeCall = static_cast<uint8_t*>(call) - imageBase;
|
||||
image->invokeNativeCall = call - imageBase;
|
||||
}
|
||||
}
|
||||
|
||||
p->aioobThunk = finish
|
||||
(t, allocator, aioobContext.context.assembler, "aioob");
|
||||
|
||||
{ void* call = aioobContext.promise.listener->resolve
|
||||
(reinterpret_cast<intptr_t>(voidPointer(throwArrayIndexOutOfBounds)));
|
||||
{ uint8_t* call = static_cast<uint8_t*>
|
||||
(aioobContext.promise.listener->resolve
|
||||
(reinterpret_cast<intptr_t>(voidPointer(throwArrayIndexOutOfBounds))))
|
||||
+ BytesPerWord;
|
||||
|
||||
if (image) {
|
||||
image->aioobThunk = p->aioobThunk - imageBase;
|
||||
image->throwArrayIndexOutOfBoundsCall
|
||||
= static_cast<uint8_t*>(call) - imageBase;
|
||||
image->throwArrayIndexOutOfBoundsCall = call - imageBase;
|
||||
}
|
||||
}
|
||||
|
||||
@ -5309,10 +5324,11 @@ compileThunks(MyThread* t, Allocator* allocator, MyProcessor* p,
|
||||
#define THUNK(s) \
|
||||
tableContext.context.assembler->writeTo(start); \
|
||||
start += p->thunkSize; \
|
||||
{ void* call = tableContext.promise.listener->resolve \
|
||||
(reinterpret_cast<intptr_t>(voidPointer(s))); \
|
||||
{ uint8_t* call = static_cast<uint8_t*> \
|
||||
(tableContext.promise.listener->resolve \
|
||||
(reinterpret_cast<intptr_t>(voidPointer(s)))) + BytesPerWord; \
|
||||
if (image) { \
|
||||
image->s##Call = static_cast<uint8_t*>(call) - imageBase; \
|
||||
image->s##Call = call - imageBase; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
@ -266,7 +266,7 @@ walk(Context* c, HeapVisitor* v, object p)
|
||||
goto pop;
|
||||
|
||||
children: {
|
||||
v->push(nextChildOffset);
|
||||
v->push(p, find(c, p)->number, nextChildOffset);
|
||||
push(c, p, nextChildOffset);
|
||||
p = get(p, nextChildOffset);
|
||||
goto visit;
|
||||
|
@ -28,7 +28,8 @@ class HeapVisitor {
|
||||
virtual void root() = 0;
|
||||
virtual unsigned visitNew(object value) = 0;
|
||||
virtual void visitOld(object value, unsigned number) = 0;
|
||||
virtual void push(unsigned offset) = 0;
|
||||
virtual void push(object parent, unsigned parentNumber,
|
||||
unsigned childOffset) = 0;
|
||||
virtual void pop() = 0;
|
||||
};
|
||||
|
||||
|
@ -1517,11 +1517,8 @@ boot(Thread* t, BootImage* image)
|
||||
if (w) {
|
||||
for (unsigned bit = 0; bit < BitsPerWord; ++bit) {
|
||||
if (w & (static_cast<uintptr_t>(1) << bit)) {
|
||||
unsigned index = ::indexOf(word, bit);
|
||||
uintptr_t* p = heap + index;
|
||||
if (*p) {
|
||||
*p = reinterpret_cast<uintptr_t>(heap + *p - 1);
|
||||
}
|
||||
uintptr_t* p = heap + indexOf(word, bit);
|
||||
*p = reinterpret_cast<uintptr_t>(heap + (*p - 1));
|
||||
}
|
||||
}
|
||||
heapMap[word] = 0;
|
||||
@ -1530,9 +1527,9 @@ boot(Thread* t, BootImage* image)
|
||||
|
||||
t->m->heap->setImmortalHeap(heap, image->heapSize, heapMap);
|
||||
|
||||
t->m->loader = reinterpret_cast<object>(heap + image->loader);
|
||||
t->m->stringMap = reinterpret_cast<object>(heap + image->stringMap);
|
||||
t->m->types = reinterpret_cast<object>(heap + image->types);
|
||||
t->m->loader = bootObject(heap, image->loader);
|
||||
t->m->stringMap = bootObject(heap, image->stringMap);
|
||||
t->m->types = bootObject(heap, image->types);
|
||||
|
||||
uintptr_t* codeMap = heap + ceiling(image->heapSize, BytesPerWord);
|
||||
unsigned codeMapSizeInWords = ceiling
|
||||
@ -1544,12 +1541,10 @@ boot(Thread* t, BootImage* image)
|
||||
if (w) {
|
||||
for (unsigned bit = 0; bit < BitsPerWord; ++bit) {
|
||||
if (w & (static_cast<uintptr_t>(1) << bit)) {
|
||||
unsigned index = ::indexOf(word, bit);
|
||||
unsigned index = indexOf(word, bit);
|
||||
uintptr_t v; memcpy(&v, code + index, BytesPerWord);
|
||||
if (v) {
|
||||
v = reinterpret_cast<uintptr_t>(heap + v - 1);
|
||||
memcpy(code + index, &v, BytesPerWord);
|
||||
}
|
||||
v = reinterpret_cast<uintptr_t>(heap + v - 1);
|
||||
memcpy(code + index, &v, BytesPerWord);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1580,6 +1575,8 @@ boot(Thread* t)
|
||||
{
|
||||
Machine* m = t->m;
|
||||
|
||||
m->unsafe = true;
|
||||
|
||||
m->loader = allocate(t, sizeof(void*) * 3, true);
|
||||
memset(m->loader, 0, sizeof(void*) * 2);
|
||||
|
||||
@ -1882,6 +1879,8 @@ Thread::init()
|
||||
}
|
||||
}
|
||||
|
||||
m->unsafe = false;
|
||||
|
||||
if (image) {
|
||||
boot(this, image);
|
||||
} else {
|
||||
|
@ -79,11 +79,20 @@ main(int ac, const char** av)
|
||||
++ vmArgs.nOptions;
|
||||
#endif
|
||||
|
||||
#ifdef BOOT_IMAGE
|
||||
++ vmArgs.nOptions;
|
||||
#endif
|
||||
|
||||
JavaVMOption options[vmArgs.nOptions];
|
||||
vmArgs.options = options;
|
||||
|
||||
unsigned optionIndex = 0;
|
||||
|
||||
#ifdef BOOT_IMAGE
|
||||
options[optionIndex++].optionString
|
||||
= const_cast<char*>("-Davian.bootimage=" BOOT_IMAGE);
|
||||
#endif
|
||||
|
||||
#ifdef BOOT_CLASSPATH
|
||||
options[optionIndex++].optionString
|
||||
= const_cast<char*>("-Xbootclasspath:" BOOT_CLASSPATH);
|
||||
|
17
src/x86.cpp
17
src/x86.cpp
@ -135,7 +135,7 @@ class Task {
|
||||
Task* next;
|
||||
};
|
||||
|
||||
void
|
||||
void*
|
||||
resolveOffset(System* s, uint8_t* instruction, unsigned instructionSize,
|
||||
int64_t value)
|
||||
{
|
||||
@ -146,6 +146,7 @@ resolveOffset(System* s, uint8_t* instruction, unsigned instructionSize,
|
||||
|
||||
int32_t v4 = v;
|
||||
memcpy(instruction + instructionSize - 4, &v4, 4);
|
||||
return instruction + instructionSize - 4;
|
||||
}
|
||||
|
||||
class OffsetListener: public Promise::Listener {
|
||||
@ -158,8 +159,7 @@ class OffsetListener: public Promise::Listener {
|
||||
{ }
|
||||
|
||||
virtual void* resolve(int64_t value) {
|
||||
resolveOffset(s, instruction, instructionSize, value);
|
||||
return 0;
|
||||
return resolveOffset(s, instruction, instructionSize, value);
|
||||
}
|
||||
|
||||
System* s;
|
||||
@ -2270,10 +2270,15 @@ class MyAssembler: public Assembler {
|
||||
return c.code.length();
|
||||
}
|
||||
|
||||
virtual void updateCall(void* returnAddress, void* newTarget) {
|
||||
virtual void updateCall(UnaryOperation op UNUSED,
|
||||
bool assertAlignment UNUSED, void* returnAddress,
|
||||
void* newTarget)
|
||||
{
|
||||
uint8_t* instruction = static_cast<uint8_t*>(returnAddress) - 5;
|
||||
assert(&c, *instruction == 0xE8);
|
||||
assert(&c, reinterpret_cast<uintptr_t>(instruction + 1) % 4 == 0);
|
||||
assert(&c, (op == LongCall and *instruction == 0xE8)
|
||||
or (op == LongJump and *instruction == 0xE9));
|
||||
assert(&c, (not assertAlignment)
|
||||
or reinterpret_cast<uintptr_t>(instruction + 1) % 4 == 0);
|
||||
|
||||
int32_t v = static_cast<uint8_t*>(newTarget)
|
||||
- static_cast<uint8_t*>(returnAddress);
|
||||
|
Loading…
Reference in New Issue
Block a user