diff --git a/lib/ExecutionEngine/JIT/Intercept.cpp b/lib/ExecutionEngine/JIT/Intercept.cpp new file mode 100644 index 00000000000..4314fb6b10b --- /dev/null +++ b/lib/ExecutionEngine/JIT/Intercept.cpp @@ -0,0 +1,52 @@ +//===-- Intercept.cpp - System function interception routines -------------===// +// +// If a function call occurs to an external function, the JIT is designed to use +// dlsym on the current process to find a function to call. This is useful for +// calling system calls and library functions that are not available in LLVM. +// Some system calls, however, need to be handled specially. For this reason, +// we intercept some of them here and use our own stubs to handle them. +// +//===----------------------------------------------------------------------===// + +#include "VM.h" +#include // dlsym access + +//===----------------------------------------------------------------------===// +// Function stubs that are invoked instead of raw system calls +//===----------------------------------------------------------------------===// + +// NoopFn - Used if we have nothing else to call... +static void NoopFn() {} + +// jit_exit - Used to intercept the "exit" system call. +static void jit_exit(int Status) { + exit(Status); // Do nothing for now. +} + +// jit_atexit - Used to intercept the "at_exit" system call. +static int jit_atexit(void (*Fn)(void)) { + atexit(Fn); // Do nothing for now. +} + +//===----------------------------------------------------------------------===// +// +/// getPointerToNamedFunction - This method returns the address of the specified +/// function by using the dlsym function call. As such it is only useful for +/// resolving library symbols, not code generated symbols. +/// +void *VM::getPointerToNamedFunction(const std::string &Name) { + // Check to see if this is one of the functions we want to intercept... + if (Name == "exit") return jit_exit; + if (Name == "at_exit") return jit_atexit; + + // If it's an external function, look it up in the process image... + void *Ptr = dlsym(0, Name.c_str()); + if (Ptr == 0) { + std::cerr << "WARNING: Cannot resolve fn '" << Name + << "' using a dummy noop function instead!\n"; + Ptr = (void*)NoopFn; + } + + return Ptr; +} + diff --git a/lib/ExecutionEngine/JIT/VM.cpp b/lib/ExecutionEngine/JIT/VM.cpp index 6fd366ede51..c6748fa1dc7 100644 --- a/lib/ExecutionEngine/JIT/VM.cpp +++ b/lib/ExecutionEngine/JIT/VM.cpp @@ -1,4 +1,4 @@ -//===-- jello.cpp - LLVM Just in Time Compiler ----------------------------===// +//===-- VM.cpp - LLVM Just in Time Compiler -------------------------------===// // // This tool implements a just-in-time compiler for LLVM, allowing direct // execution of LLVM bytecode in an efficient manner. @@ -9,8 +9,6 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/CodeGen/MachineCodeEmitter.h" #include "llvm/Function.h" -#include // dlsym access - VM::~VM() { delete MCE; @@ -50,27 +48,10 @@ void *VM::resolveFunctionReference(void *RefAddr) { } const std::string &VM::getFunctionReferencedName(void *RefAddr) { + assert(FunctionRefs[RefAddr] && "Function address unknown!"); return FunctionRefs[RefAddr]->getName(); } -static void NoopFn() {} - -/// getPointerToNamedFunction - This method returns the address of the specified -/// function by using the dlsym function call. As such it is only useful for -/// resolving library symbols, not code generated symbols. -/// -void *VM::getPointerToNamedFunction(const std::string &Name) { - // If it's an external function, look it up in the process image... - void *Ptr = dlsym(0, Name.c_str()); - if (Ptr == 0) { - std::cerr << "WARNING: Cannot resolve fn '" << Name - << "' using a dummy noop function instead!\n"; - Ptr = (void*)NoopFn; - } - - return Ptr; -} - /// getPointerToFunction - This method is used to get the address of the /// specified function, compiling it if neccesary. ///