mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-15 06:29:05 +00:00
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@6052 91177308-0d34-0410-b5e6-96231b3b80d8
54 lines
1.7 KiB
C++
54 lines
1.7 KiB
C++
//===-- Callback.cpp - Trap handler for function resolution ---------------===//
|
|
//
|
|
// This file defines the SIGSEGV handler which is invoked when a reference to a
|
|
// non-codegen'd function is found.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "VM.h"
|
|
#include "Support/Statistic.h"
|
|
#include <iostream>
|
|
|
|
static VM *TheVM = 0;
|
|
|
|
// CompilationCallback - Invoked the first time that a call site is found,
|
|
// which causes lazy compilation of the target function.
|
|
//
|
|
void VM::CompilationCallback() {
|
|
#if defined(i386) || defined(__i386__) || defined(__x86__)
|
|
unsigned *StackPtr = (unsigned*)__builtin_frame_address(0);
|
|
unsigned RetAddr = (unsigned)__builtin_return_address(0);
|
|
|
|
assert(StackPtr[1] == RetAddr &&
|
|
"Could not find return address on the stack!");
|
|
|
|
// The call instruction should have pushed the return value onto the stack...
|
|
RetAddr -= 4; // Backtrack to the reference itself...
|
|
|
|
DEBUG(std::cerr << "In callback! Addr=0x" << std::hex << RetAddr
|
|
<< " ESP=0x" << (unsigned)StackPtr << std::dec
|
|
<< ": Resolving call to function: "
|
|
<< TheVM->getFunctionReferencedName((void*)RetAddr) << "\n");
|
|
|
|
// Sanity check to make sure this really is a call instruction...
|
|
assert(((unsigned char*)RetAddr)[-1] == 0xE8 && "Not a call instr!");
|
|
|
|
unsigned NewVal = (unsigned)TheVM->resolveFunctionReference((void*)RetAddr);
|
|
|
|
// Rewrite the call target... so that we don't fault every time we execute
|
|
// the call.
|
|
*(unsigned*)RetAddr = NewVal-RetAddr-4;
|
|
|
|
// Change the return address to reexecute the call instruction...
|
|
StackPtr[1] -= 5;
|
|
#else
|
|
abort();
|
|
#endif
|
|
}
|
|
|
|
void VM::registerCallback() {
|
|
TheVM = this;
|
|
}
|
|
|
|
|