diff --git a/interpreter/cling/include/cling/Interpreter/Interpreter.h b/interpreter/cling/include/cling/Interpreter/Interpreter.h
index fb1f76a53ce3dabfe277ac592f821624755ce12f..79a3fae954d58e6bd8b945e5cad479927a7d203d 100644
--- a/interpreter/cling/include/cling/Interpreter/Interpreter.h
+++ b/interpreter/cling/include/cling/Interpreter/Interpreter.h
@@ -274,17 +274,16 @@ namespace cling {
                                                 llvm::StringRef code,
                                                 bool withAccessControl);
 
-    ///\brief Include C++ runtime headers and definitions.
+    ///\brief Initialize runtime and C/C++ level overrides
     ///
-    void IncludeCXXRuntime();
-
-    ///\brief Include C runtime headers and definitions.
+    ///\param[in] NoRuntime - Don't include the runtime headers / gCling
+    ///\param[in] SyntaxOnly - In SyntaxOnly mode
+    ///\param[out] Globals - Global symbols that need to be emitted
     ///
-    void IncludeCRuntime();
-
-    ///\brief Init atexit runtime delegation.
+    ///\returns The resulting Transation of initialization.
     ///
-    void InitAExit();
+    Transaction* Initialize(bool NoRuntime, bool SyntaxOnly,
+                            llvm::SmallVectorImpl<llvm::StringRef>& Globals);
 
     ///\brief The target constructor to be called from both the delegating
     /// constructors. parentInterp might be nullptr.
diff --git a/interpreter/cling/lib/Interpreter/IncrementalExecutor.cpp b/interpreter/cling/lib/Interpreter/IncrementalExecutor.cpp
index da1e59221a9741c9e459be3b3177ad27b47ca50b..71f3dde1cc12219917a205f492c5977b3f1156b2 100644
--- a/interpreter/cling/lib/Interpreter/IncrementalExecutor.cpp
+++ b/interpreter/cling/lib/Interpreter/IncrementalExecutor.cpp
@@ -38,8 +38,7 @@ namespace cling {
 
 IncrementalExecutor::IncrementalExecutor(clang::DiagnosticsEngine& diags,
                                          const clang::CompilerInstance& CI):
-  m_externalIncrementalExecutor(nullptr),
-  m_CurrentAtExitModule(0)
+  m_externalIncrementalExecutor(nullptr)
 #if 0
   : m_Diags(diags)
 #endif
@@ -123,10 +122,11 @@ void IncrementalExecutor::shuttingDown() {
   }
 }
 
-void IncrementalExecutor::AddAtExitFunc(void (*func) (void*), void* arg) {
+void IncrementalExecutor::AddAtExitFunc(void (*func) (void*), void* arg,
+                                        llvm::Module* M) {
   // Register a CXAAtExit function
   cling::internal::SpinLockGuard slg(m_AtExitFuncsSpinLock);
-  m_AtExitFuncs.push_back(CXAAtExitElement(func, arg, m_CurrentAtExitModule));
+  m_AtExitFuncs.push_back(CXAAtExitElement(func, arg, M));
 }
 
 void unresolvedSymbol()
@@ -206,14 +206,6 @@ IncrementalExecutor::runStaticInitializersOnce(const Transaction& T) {
   llvm::Module* m = T.getModule();
   assert(m && "Module must not be null");
 
-  // Set m_CurrentAtExitModule to the Module, unset to 0 once done.
-  struct AtExitModuleSetterRAII {
-    llvm::Module*& m_AEM;
-    AtExitModuleSetterRAII(llvm::Module* M, llvm::Module*& AEM): m_AEM(AEM)
-    { AEM = M; }
-    ~AtExitModuleSetterRAII() { m_AEM = 0; }
-  } DSOHandleSetter(m, m_CurrentAtExitModule);
-
   // We don't care whether something was unresolved before.
   m_unresolvedSymbols.clear();
 
@@ -333,14 +325,15 @@ IncrementalExecutor::installLazyFunctionCreator(LazyFunctionCreatorFunc_t fp)
 }
 
 bool
-IncrementalExecutor::addSymbol(const char* symbolName,  void* symbolAddress) {
-  return IncrementalJIT::searchLibraries(symbolName, symbolAddress).second;
+IncrementalExecutor::addSymbol(const char* Name,  void* Addr,
+                               bool Jit) {
+  return m_JIT->lookupSymbol(Name, Addr, Jit).second;
 }
 
 void* IncrementalExecutor::getAddressOfGlobal(llvm::StringRef symbolName,
                                               bool* fromJIT /*=0*/) {
   // Return a symbol's address, and whether it was jitted.
-  void* address = IncrementalJIT::searchLibraries(symbolName).first;
+  void* address = m_JIT->lookupSymbol(symbolName).first;
 
   // It's not from the JIT if it's in a dylib.
   if (fromJIT)
diff --git a/interpreter/cling/lib/Interpreter/IncrementalExecutor.h b/interpreter/cling/lib/Interpreter/IncrementalExecutor.h
index 1e717ff6b34f2abefabed4cad99c2d84899b33a5..25a56dd4ba53cd182e8482ed69dc69fe783b7a4d 100644
--- a/interpreter/cling/lib/Interpreter/IncrementalExecutor.h
+++ b/interpreter/cling/lib/Interpreter/IncrementalExecutor.h
@@ -114,10 +114,6 @@ namespace cling {
     ///
     AtExitFunctions m_AtExitFuncs;
 
-    ///\brief Module for which registration of static destructors currently
-    /// takes place.
-    llvm::Module* m_CurrentAtExitModule;
-
     ///\brief Modules to emit upon the next call to the JIT.
     ///
     std::vector<llvm::Module*> m_ModulesToJIT;
@@ -208,12 +204,13 @@ namespace cling {
     /// Allows runtime declaration of a function passing its pointer for being
     /// used by JIT generated code.
     ///
-    /// @param[in] symbolName - The name of the symbol as required by the
+    /// @param[in] Name - The name of the symbol as required by the
     ///                         linker (mangled if needed)
-    /// @param[in] symbolAddress - The function pointer to register
+    /// @param[in] Address - The function pointer to register
+    /// @param[in] JIT - Add to the JIT injected symbol table
     /// @returns true if the symbol is successfully registered, false otherwise.
     ///
-    bool addSymbol(const char* symbolName,  void* symbolAddress);
+    bool addSymbol(const char* Name, void* Address, bool JIT = false);
 
     ///\brief Add a llvm::Module to the JIT.
     ///
@@ -251,7 +248,7 @@ namespace cling {
 
     ///\brief Keep track of the entities whose dtor we need to call.
     ///
-    void AddAtExitFunc(void (*func) (void*), void* arg);
+    void AddAtExitFunc(void (*func) (void*), void* arg, llvm::Module* M);
 
     ///\brief Try to resolve a symbol through our LazyFunctionCreators;
     /// print an error message if that fails.
diff --git a/interpreter/cling/lib/Interpreter/IncrementalJIT.cpp b/interpreter/cling/lib/Interpreter/IncrementalJIT.cpp
index 686bad20363c698245b675112c643f21dfbc3fbf..961e9922af0832fb644bfb1d50b8772b217b4295 100644
--- a/interpreter/cling/lib/Interpreter/IncrementalJIT.cpp
+++ b/interpreter/cling/lib/Interpreter/IncrementalJIT.cpp
@@ -25,12 +25,6 @@
 using namespace llvm;
 
 namespace {
-// Forward cxa_atexit for global d'tors.
-static int local_cxa_atexit(void (*func) (void*), void* arg, void* dso) {
-  cling::IncrementalExecutor* exe = (cling::IncrementalExecutor*)dso;
-  exe->AddAtExitFunc(func, arg);
-  return 0;
-}
 
 ///\brief Memory manager providing the lop-level link to the
 /// IncrementalExecutor, handles missing or special / replaced symbols.
@@ -195,17 +189,6 @@ IncrementalJIT::IncrementalJIT(IncrementalExecutor& exe,
 llvm::orc::JITSymbol
 IncrementalJIT::getInjectedSymbols(const std::string& Name) const {
   using JITSymbol = llvm::orc::JITSymbol;
-  if (Name == MANGLE_PREFIX "__cxa_atexit") {
-    // Rewire __cxa_atexit to ~Interpreter(), thus also global destruction
-    // coming from the JIT.
-    return JITSymbol((uint64_t)&local_cxa_atexit,
-                     llvm::JITSymbolFlags::Exported);
-  } else if (Name == MANGLE_PREFIX "__dso_handle") {
-    // Provide IncrementalExecutor as the third argument to __cxa_atexit.
-    return JITSymbol((uint64_t)&m_Parent,
-                     llvm::JITSymbolFlags::Exported);
-  }
-
   auto SymMapI = m_SymbolMap.find(Name);
   if (SymMapI != m_SymbolMap.end())
     return JITSymbol(SymMapI->second, llvm::JITSymbolFlags::Exported);
@@ -214,7 +197,7 @@ IncrementalJIT::getInjectedSymbols(const std::string& Name) const {
 }
 
 std::pair<void*, bool>
-IncrementalJIT::searchLibraries(llvm::StringRef Name, void *InAddr) {
+IncrementalJIT::lookupSymbol(llvm::StringRef Name, void *InAddr, bool Jit) {
   // FIXME: See comments on DLSym below.
 #if !defined(LLVM_ON_WIN32)
   void* Addr = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(Name);
@@ -222,7 +205,12 @@ IncrementalJIT::searchLibraries(llvm::StringRef Name, void *InAddr) {
   void* Addr = const_cast<void*>(platform::DLSym(Name));
 #endif
 
-  if (InAddr && !Addr) {
+  if (InAddr && (!Addr || Jit)) {
+    if (Jit) {
+      std::string Key(Name);
+      Key.insert(0, MANGLE_PREFIX);
+      m_SymbolMap[Key] = llvm::orc::TargetAddress(InAddr);
+    }
     llvm::sys::DynamicLibrary::AddSymbol(Name, InAddr);
     return std::make_pair(InAddr, true);
   }
diff --git a/interpreter/cling/lib/Interpreter/IncrementalJIT.h b/interpreter/cling/lib/Interpreter/IncrementalJIT.h
index 185d26b9982cc967a7fbdd6ffb3246390efbf4d1..fcb4af150ac423af32785f8625920b12e4726328 100644
--- a/interpreter/cling/lib/Interpreter/IncrementalJIT.h
+++ b/interpreter/cling/lib/Interpreter/IncrementalJIT.h
@@ -215,9 +215,10 @@ public:
   ///\brief Get the address of a symbol from the process' loaded libraries.
   /// \param Name - symbol to look for
   /// \param Addr - known address of the symbol that can be cached later use
+  /// \param Jit - add to the injected symbols cache
   /// \returns The address of the symbol and whether it was cached
-  static std::pair<void*, bool>
-  searchLibraries(llvm::StringRef Name, void* Addr = nullptr);
+  std::pair<void*, bool>
+  lookupSymbol(llvm::StringRef Name, void* Addr = nullptr, bool Jit = false);
 };
 } // end cling
 #endif // CLING_INCREMENTAL_EXECUTOR_H
diff --git a/interpreter/cling/lib/Interpreter/Interpreter.cpp b/interpreter/cling/lib/Interpreter/Interpreter.cpp
index d57e467037df77b46f5186210a53bb0dad0e8cb1..2803b2ada4ef5ac5efae31147cb48d98ac7a94cf 100644
--- a/interpreter/cling/lib/Interpreter/Interpreter.cpp
+++ b/interpreter/cling/lib/Interpreter/Interpreter.cpp
@@ -57,6 +57,13 @@ using namespace clang;
 
 namespace {
 
+  // Forward cxa_atexit for global d'tors.
+  static int local_cxa_atexit(void (*func) (void*), void* arg,
+                              cling::Interpreter* Interp) {
+    Interp->AddAtExitFunc(func, arg);
+    return 0;
+  }
+
   static cling::Interpreter::ExecutionResult
   ConvertExecutionResult(cling::IncrementalExecutor::ExecutionResult ExeRes) {
     switch (ExeRes) {
@@ -188,16 +195,30 @@ namespace cling {
 
     handleFrontendOptions();
 
-    if (!noRuntime) {
-      if (getCI()->getLangOpts().CPlusPlus)
-        IncludeCXXRuntime();
-      else
-        IncludeCRuntime();
-    }
+    llvm::SmallVector<llvm::StringRef, 6> Syms;
+    Initialize(noRuntime, isInSyntaxOnlyMode(), Syms);
+
     // Commit the transactions, now that gCling is set up. It is needed for
     // static initialization in these transactions through local_cxa_atexit().
     for (auto&& I: IncrParserTransactions)
       m_IncrParser->commitTransaction(I);
+
+    // Now that the transactions have been commited, force symbol emission
+    // and overrides.
+    if (const Transaction* T = getLastTransaction()) {
+      if (llvm::Module* M = T->getModule()) {
+        for (const llvm::StringRef& Sym : Syms) {
+          if (const llvm::GlobalValue* GV = M->getNamedValue(Sym)) {
+            if (void* Addr = m_Executor->getPointerToGlobalFromJIT(*GV))
+              m_Executor->addSymbol(Sym.str().c_str(), Addr, true);
+            else
+              cling::errs() << Sym << " not defined\n";
+          } else
+            cling::errs() << Sym << " not in Module!\n";
+        }
+      }
+    }
+
     // Disable suggestions for ROOT
     bool showSuggestions = !llvm::StringRef(ClingStringify(CLING_VERSION)).startswith("ROOT");
 
@@ -216,8 +237,6 @@ namespace cling {
       // Prevents stripping the symbol due to dead-code optimization.
       internal::symbol_requester();
     }
-
-    InitAExit();
   }
 
   ///\brief Constructor for the child Interpreter.
@@ -278,63 +297,93 @@ namespace cling {
     }
   }
 
-  void Interpreter::InitAExit() {
-    if (isInSyntaxOnlyMode())
-      return;
-
-    const char* Linkage = getCI()->getLangOpts().CPlusPlus ? "extern \"C\"" : "";
-    llvm::SmallString<512> Buf;
+  Transaction* Interpreter::Initialize(bool NoRuntime, bool SyntaxOnly,
+                              llvm::SmallVectorImpl<llvm::StringRef>& Globals) {
+    llvm::SmallString<1024> Buf;
     llvm::raw_svector_ostream Strm(Buf);
-    Strm << Linkage << " int __cxa_atexit(void (*f) (void*), void*, void*);\n"
-         << Linkage << " int atexit(void(*f)()) {"
-            "return __cxa_atexit((void(*)(void*))f, nullptr, (void*)"
-         << m_Executor.get() << "); }\n";
-    Transaction *T = nullptr;
-    declare(Strm.str(), &T);
-    if (llvm::Module* M = T ? T->getModule() : nullptr) {
-      if (const llvm::GlobalValue* GV = M->getNamedValue("atexit"))
-        m_Executor->getPointerToGlobalFromJIT(*GV);
+    const clang::LangOptions& LangOpts = getCI()->getLangOpts();
+    const void* thisP = static_cast<void*>(this);
+
+    // FIXME: gCling should be const so assignemnt is a compile time error.
+    // Currently the name mangling is coming up wrong for the const version
+    // (on OS X at least, so probably Linux too) and the JIT thinks the symbol
+    // is undefined in a child Interpreter.  And speaking of children, should
+    // gCling actually be thisCling, so a child Interpreter can only access
+    // itself? One could use a macro (simillar to __dso_handle) to block
+    // assignemnt and get around the mangling issue.
+    const char* Linkage = LangOpts.CPlusPlus ? "extern \"C\"" : "";
+    if (!NoRuntime && !SyntaxOnly) {
+      if (LangOpts.CPlusPlus) {
+        Strm << "#include \"cling/Interpreter/RuntimeUniverse.h\"\n"
+                "namespace cling { class Interpreter; namespace runtime { "
+                "Interpreter* gCling=(Interpreter*)" << thisP << "; }}\n";
+      } else {
+        Strm << "#include \"cling/Interpreter/CValuePrinter.h\"\n"
+                "void* gCling=(void*)" << thisP << ";\n";
+      }
     }
-  }
 
-  void Interpreter::IncludeCXXRuntime() {
-    // Set up common declarations which are going to be available
-    // only at runtime
-    // Make sure that the universe won't be included to compile time by using
-    // -D __CLING__ as CompilerInstance's arguments
+    // Intercept all atexit calls, as the Interpreter and functions will be long
+    // gone when the -native- versions invoke them.
+    if (!SyntaxOnly) {
+      // While __dso_handle is still overriden in the JIT below,
+      // #define __dso_handle is used to mitigate the following problems:
+      //  1. Type of __dso_handle is void* making assignemnt to it legal
+      //  2. Making it void* const in cling would mean possible type mismatch
+      //  3. Cannot override void* __dso_handle in child Interpreter
+      //  4. On Unix where the symbol actually exists, __dso_handle will be
+      //     linked into the code before the JIT can say otherwise, so:
+      //      [cling] __dso_handle // codegened __dso_handle always printed
+      //      [cling] __cxa_atexit(f, 0, __dso_handle) // seg-fault
+      //  5. Code that actually uses __dso_handle will fail as a declaration is
+      //     needed which is not possible with the macro.
+      //  6. Assuming 4 is sorted out in user code, calling __cxa_atexit through
+      //     atexit below isn't linking to the __dso_handle symbol.
+
+      Strm << "#define __dso_handle ((void*)" << thisP << ")\n";
+
+      // Use __cxa_atexit to intercept all of the following routines
+      Strm << Linkage << " int __cxa_atexit(void (*f)(void*), void*, void*);\n";
+
+      // C atexit, std::atexit
+      Strm << Linkage << " int atexit(void(*f)()) { "
+           "return __cxa_atexit((void(*)(void*))f, nullptr, __dso_handle); }\n";
+      Globals.push_back("atexit");
+
+      // C++ 11 at_quick_exit, std::at_quick_exit
+      if (LangOpts.CPlusPlus && LangOpts.CPlusPlus11) {
+          Strm << Linkage << " int at_quick_exit(void(*f)()) { "
+           "return __cxa_atexit((void(*)(void*))f, nullptr, __dso_handle); }\n";
+        Globals.push_back("at_quick_exit");
+      }
 
-    std::stringstream initializer;
-#ifdef _WIN32
-    // We have to use the #defined __CLING__ on windows first.
-    //FIXME: Find proper fix.
-    initializer << "#ifdef __CLING__ \n#endif\n";
+#if defined(LLVM_ON_WIN32)
+      // Windows specific: _onexit, _onexit_m, __dllonexit
+      Strm << Linkage << " _onexit_t _onexit(_onexit_t f) { "
+         "__cxa_atexit((void(*)(void*))f, nullptr, __dso_handle); return f;}\n";
+      Globals.push_back("_onexit");
+      Strm << Linkage << " _onexit_t __dllonexit(_onexit_t f, PVFV**, PVFV**) { "
+         "__cxa_atexit((void(*)(void*))f, nullptr, __dso_handle); return f;}\n";
+      Globals.push_back("__dllonexit");
+ #ifdef _M_CEE
+      Strm << Linkage << " _onexit_t_m _onexit_m(_onexit_t f) { "
+         "__cxa_atexit((void(*)(void*))f, nullptr, __dso_handle); return f;}\n";
+      Globals.push_back("_onexit_m");
+ #endif
 #endif
 
-    initializer << "#include \"cling/Interpreter/RuntimeUniverse.h\"\n";
-
-    if (!isInSyntaxOnlyMode()) {
-      // Set up the gCling variable if it can be used
-      initializer << "namespace cling {namespace runtime { "
-        "cling::Interpreter *gCling=(cling::Interpreter*)"
-        << "0x" << std::hex << (uintptr_t)this << " ;} }";
+      // Override the native symbols now, before anything can be emitted.
+      m_Executor->addSymbol("__cxa_atexit", (void*)&local_cxa_atexit, true);
+      // __dso_handle is inserted for the link phase, as macro is useless then
+      m_Executor->addSymbol("__dso_handle", this, true);
     }
-    declare(initializer.str());
-  }
 
-  void Interpreter::IncludeCRuntime() {
-    // Set up the gCling variable if it can be used
-    std::stringstream initializer;
-    initializer << "void* gCling=(void*)" << (uintptr_t)this << ';';
-    declare(initializer.str());
-    // declare("void setValueNoAlloc(void* vpI, void* vpSVR, void* vpQT);");
-    // declare("void setValueNoAlloc(void* vpI, void* vpV, void* vpQT, float value);");
-    // declare("void setValueNoAlloc(void* vpI, void* vpV, void* vpQT, double value);");
-    // declare("void setValueNoAlloc(void* vpI, void* vpV, void* vpQT, long double value);");
-    // declare("void setValueNoAlloc(void* vpI, void* vpV, void* vpQT, unsigned long long value);");
-    // declare("void setValueNoAlloc(void* vpI, void* vpV, void* vpQT, const void* value);");
-    // declare("void* setValueWithAlloc(void* vpI, void* vpV, void* vpQT);");
+    if (m_Opts.Verbose())
+      llvm::errs() << Strm.str();
 
-    declare("#include \"cling/Interpreter/CValuePrinter.h\"");
+    Transaction *T;
+    declare(Strm.str(), &T);
+    return T;
   }
 
   void Interpreter::AddIncludePaths(llvm::StringRef PathStr, const char* Delm) {
@@ -1248,7 +1297,15 @@ namespace cling {
   }
 
   void Interpreter::AddAtExitFunc(void (*Func) (void*), void* Arg) {
-    m_Executor->AddAtExitFunc(Func, Arg);
+    const Transaction* T = getCurrentTransaction();
+    // Should this be ROOT only?
+    if (!T) {
+      // IncrementalParser::commitTransaction will call
+      // Interpreter::executeTransaction if transaction has no parent.
+      T = getLastTransaction();
+    }
+    assert(T && "No Transaction for Interpreter::AddAtExitFunc");
+    m_Executor->AddAtExitFunc(Func, Arg, T->getModule());
   }
 
   void Interpreter::GenerateAutoloadingMap(llvm::StringRef inFile,