From 389e5cca8e5145c9378730479de4b42870a8b347 Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Wed, 1 Feb 2017 21:18:54 -0800
Subject: [PATCH 4/6] [MCJIT] Call JIT notifiers only after code sections are
 ready.

Previously JIT notifiers were called before relocations were
performed (leading to ominious function call of "0"), and before
memory marked executable (confusing some profilers).

Move notifications to finalizeLoadedModules().
---
 lib/ExecutionEngine/MCJIT/MCJIT.cpp | 16 ++++++++++++++--
 lib/ExecutionEngine/MCJIT/MCJIT.h   |  2 ++
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/lib/ExecutionEngine/MCJIT/MCJIT.cpp b/lib/ExecutionEngine/MCJIT/MCJIT.cpp
index 1164d60ffc1..2dd92164794 100644
--- a/lib/ExecutionEngine/MCJIT/MCJIT.cpp
+++ b/lib/ExecutionEngine/MCJIT/MCJIT.cpp
@@ -222,8 +222,10 @@ void MCJIT::generateCodeForModule(Module *M) {
   if (Dyld.hasError())
     report_fatal_error(Dyld.getErrorString());
 
-  NotifyObjectEmitted(*LoadedObject.get(), *L);
-
+  // Can't call notifiers yet as relocations have not yet been performed, and
+  // memory hasn't been marked executable.
+  PendingLoadedObjects.push_back(LoadedObject->get());
+  PendingLoadedObjectInfos.push_back(std::move(L));
   Buffers.push_back(std::move(ObjectToLoad));
   LoadedObjects.push_back(std::move(*LoadedObject));
 
@@ -243,6 +245,16 @@ void MCJIT::finalizeLoadedModules() {
 
   // Set page permissions.
   MemMgr->finalizeMemory();
+
+  // Notify listeners about loaded objects now that memory is marked executable
+  // and relocations have been performed.
+  for (size_t i = 0; i < PendingLoadedObjects.size(); i++) {
+    auto &Obj = PendingLoadedObjects[i];
+    auto &Info = PendingLoadedObjectInfos[i];
+    NotifyObjectEmitted(*Obj, *Info);
+  }
+  PendingLoadedObjects.clear();
+  PendingLoadedObjectInfos.clear();
 }
 
 // FIXME: Rename this.
diff --git a/lib/ExecutionEngine/MCJIT/MCJIT.h b/lib/ExecutionEngine/MCJIT/MCJIT.h
index daf578f5daa..418578fc7a3 100644
--- a/lib/ExecutionEngine/MCJIT/MCJIT.h
+++ b/lib/ExecutionEngine/MCJIT/MCJIT.h
@@ -189,6 +189,8 @@ class MCJIT : public ExecutionEngine {
   SmallVector<std::unique_ptr<MemoryBuffer>, 2> Buffers;
 
   SmallVector<std::unique_ptr<object::ObjectFile>, 2> LoadedObjects;
+  SmallVector<object::ObjectFile*, 2> PendingLoadedObjects;
+  SmallVector<std::unique_ptr<RuntimeDyld::LoadedObjectInfo>, 2> PendingLoadedObjectInfos;
 
   // An optional ObjectCache to be notified of compiled objects and used to
   // perform lookup of pre-compiled code to avoid re-compilation.
-- 
2.14.1.536.g6867272d5b.dirty

