Add support for atexit handlers to the JIT, fixing 2003-05-14-AtExit.c
authorChris Lattner <sabre@nondot.org>
Wed, 14 May 2003 13:53:40 +0000 (13:53 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 14 May 2003 13:53:40 +0000 (13:53 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@6193 91177308-0d34-0410-b5e6-96231b3b80d8

lib/ExecutionEngine/JIT/Intercept.cpp
lib/ExecutionEngine/JIT/JIT.cpp
lib/ExecutionEngine/JIT/JIT.h
lib/ExecutionEngine/JIT/VM.h

index 448ff2d3563c9c092155522e23a5ac09e894a5db..aa58186ad859c3737116dc17e8b2c0f86c5709e1 100644 (file)
 #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());
index 39f305e127007d92114e6845a20da7f817e1b42f..05aa934a85c38081a7e93754bbd3d3313b66f7b3 100644 (file)
@@ -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;
 }
index 17c4ddd3dce85ba18b4fbd7099f1ff5ab5ad7921..a720c960f3dd743de22efa906b507d6df17fce8d 100644 (file)
@@ -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();
index 17c4ddd3dce85ba18b4fbd7099f1ff5ab5ad7921..a720c960f3dd743de22efa906b507d6df17fce8d 100644 (file)
@@ -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();