blob: 75abf435e6a528c093e0867d2daafe964388f0f4 [file] [log] [blame]
Chris Lattnerbd199fb2002-12-24 00:01:05 +00001//===-- Callback.cpp - Trap handler for function resolution ---------------===//
2//
3// This file defines the SIGSEGV handler which is invoked when a reference to a
4// non-codegen'd function is found.
5//
6//===----------------------------------------------------------------------===//
7
8#include "VM.h"
9#include "Support/Statistic.h"
Chris Lattnerbd199fb2002-12-24 00:01:05 +000010#include <iostream>
11
12static VM *TheVM = 0;
13
Chris Lattnerc309a762003-05-08 21:34:11 +000014// CompilationCallback - Invoked the first time that a call site is found,
15// which causes lazy compilation of the target function.
16//
17void VM::CompilationCallback() {
18#if defined(i386) || defined(__i386__) || defined(__x86__)
19 unsigned *StackPtr = (unsigned*)__builtin_frame_address(0);
20 unsigned RetAddr = (unsigned)__builtin_return_address(0);
Chris Lattnerbd199fb2002-12-24 00:01:05 +000021
Chris Lattnerc309a762003-05-08 21:34:11 +000022 assert(StackPtr[1] == RetAddr &&
23 "Could not find return address on the stack!");
Chris Lattnerbd199fb2002-12-24 00:01:05 +000024
25 // The call instruction should have pushed the return value onto the stack...
Chris Lattnerc309a762003-05-08 21:34:11 +000026 RetAddr -= 4; // Backtrack to the reference itself...
Chris Lattnerbd199fb2002-12-24 00:01:05 +000027
Chris Lattnerc309a762003-05-08 21:34:11 +000028 DEBUG(std::cerr << "In callback! Addr=0x" << std::hex << RetAddr
29 << " ESP=0x" << (unsigned)StackPtr << std::dec
Chris Lattnerbd199fb2002-12-24 00:01:05 +000030 << ": Resolving call to function: "
Chris Lattnerc309a762003-05-08 21:34:11 +000031 << TheVM->getFunctionReferencedName((void*)RetAddr) << "\n");
Chris Lattnerbd199fb2002-12-24 00:01:05 +000032
33 // Sanity check to make sure this really is a call instruction...
Chris Lattnerc309a762003-05-08 21:34:11 +000034 assert(((unsigned char*)RetAddr)[-1] == 0xE8 && "Not a call instr!");
Chris Lattnerbd199fb2002-12-24 00:01:05 +000035
Chris Lattnerc309a762003-05-08 21:34:11 +000036 unsigned NewVal = (unsigned)TheVM->resolveFunctionReference((void*)RetAddr);
Chris Lattnerbd199fb2002-12-24 00:01:05 +000037
38 // Rewrite the call target... so that we don't fault every time we execute
39 // the call.
Chris Lattnerc309a762003-05-08 21:34:11 +000040 *(unsigned*)RetAddr = NewVal-RetAddr-4;
Chris Lattnerbd199fb2002-12-24 00:01:05 +000041
Chris Lattnerc309a762003-05-08 21:34:11 +000042 // Change the return address to reexecute the call instruction...
43 StackPtr[1] -= 5;
44#else
45 abort();
Chris Lattnerbd199fb2002-12-24 00:01:05 +000046#endif
47}
48
49
50void VM::registerCallback() {
51 TheVM = this;
Chris Lattnerbd199fb2002-12-24 00:01:05 +000052}
53
54