mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-28 22:43:29 +00:00
Add support for atexit handlers to the JIT, fixing 2003-05-14-AtExit.c
llvm-svn: 6193
This commit is contained in:
parent
6f80e1b3c7
commit
e7f979708b
@ -12,6 +12,17 @@
|
||||
#include <dlfcn.h> // dlsym access
|
||||
#include <iostream>
|
||||
|
||||
// AtExitList - List of functions registered with the at_exit function
|
||||
static std::vector<void (*)()> AtExitList;
|
||||
|
||||
void VM::runAtExitHandlers() {
|
||||
while (!AtExitList.empty()) {
|
||||
void (*Fn)() = AtExitList.back();
|
||||
AtExitList.pop_back();
|
||||
Fn();
|
||||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Function stubs that are invoked instead of raw system calls
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -21,12 +32,14 @@ static void NoopFn() {}
|
||||
|
||||
// jit_exit - Used to intercept the "exit" system call.
|
||||
static void jit_exit(int Status) {
|
||||
exit(Status); // Do nothing for now.
|
||||
VM::runAtExitHandlers(); // Run at_exit handlers...
|
||||
exit(Status);
|
||||
}
|
||||
|
||||
// jit_atexit - Used to intercept the "at_exit" system call.
|
||||
static int jit_atexit(void (*Fn)(void)) {
|
||||
return atexit(Fn); // Do nothing for now.
|
||||
AtExitList.push_back(Fn); // Take note of at_exit handler...
|
||||
return 0; // Always successful
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -38,7 +51,7 @@ static int jit_atexit(void (*Fn)(void)) {
|
||||
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 (void*)&jit_exit;
|
||||
if (Name == "at_exit") return (void*)&jit_atexit;
|
||||
if (Name == "atexit") return (void*)&jit_atexit;
|
||||
|
||||
// If it's an external function, look it up in the process image...
|
||||
void *Ptr = dlsym(0, Name.c_str());
|
||||
|
@ -50,5 +50,9 @@ int VM::run(const std::string &FnName, const std::vector<std::string> &Args) {
|
||||
char **Argv = (char**)CreateArgv(Args);
|
||||
|
||||
// Call the main function...
|
||||
return PF(Args.size(), Argv);
|
||||
int Result = PF(Args.size(), Argv);
|
||||
|
||||
// Run any atexit handlers now!
|
||||
runAtExitHandlers();
|
||||
return Result;
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ class VM : public ExecutionEngine {
|
||||
// handler to lazily patch up references...
|
||||
//
|
||||
std::map<void*, Function*> FunctionRefs;
|
||||
|
||||
public:
|
||||
VM(Module *M, TargetMachine *tm);
|
||||
~VM();
|
||||
@ -54,6 +55,12 @@ public:
|
||||
// which causes lazy compilation of the target function.
|
||||
//
|
||||
static void CompilationCallback();
|
||||
|
||||
/// runAtExitHandlers - Before exiting the program, at_exit functions must be
|
||||
/// called. This method calls them.
|
||||
///
|
||||
static void runAtExitHandlers();
|
||||
|
||||
private:
|
||||
static MachineCodeEmitter *createEmitter(VM &V);
|
||||
void setupPassManager();
|
||||
|
Loading…
Reference in New Issue
Block a user