[llvm] r192504 - Adding multiple object support to MCJIT EH frame handling

Andrew Kaylor andrew.kaylor at intel.com
Fri Oct 11 14:25:48 PDT 2013


Author: akaylor
Date: Fri Oct 11 16:25:48 2013
New Revision: 192504

URL: http://llvm.org/viewvc/llvm-project?rev=192504&view=rev
Log:
Adding multiple object support to MCJIT EH frame handling

Added:
    llvm/trunk/test/ExecutionEngine/MCJIT/multi-module-eh-a.ll
    llvm/trunk/test/ExecutionEngine/MCJIT/multi-module-eh-b.ir
Modified:
    llvm/trunk/include/llvm/ExecutionEngine/RTDyldMemoryManager.h
    llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h
    llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp
    llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h
    llvm/trunk/lib/ExecutionEngine/RTDyldMemoryManager.cpp
    llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
    llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
    llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
    llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
    llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
    llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h
    llvm/trunk/tools/lli/RemoteMemoryManager.cpp
    llvm/trunk/tools/lli/RemoteMemoryManager.h

Modified: llvm/trunk/include/llvm/ExecutionEngine/RTDyldMemoryManager.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/RTDyldMemoryManager.h?rev=192504&r1=192503&r2=192504&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ExecutionEngine/RTDyldMemoryManager.h (original)
+++ llvm/trunk/include/llvm/ExecutionEngine/RTDyldMemoryManager.h Fri Oct 11 16:25:48 2013
@@ -53,7 +53,12 @@ public:
     StringRef SectionName, bool IsReadOnly) = 0;
 
   /// Register the EH frames with the runtime so that c++ exceptions work.
-  virtual void registerEHFrames(StringRef SectionData);
+  ///
+  /// \p Addr parameter provides the local address of the EH frame section
+  /// data, while \p LoadAddr provides the address of the data in the target
+  /// address space.  If the section has not been remapped (which will usually
+  /// be the case for local execution) these two values will be the same.
+  virtual void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size);
 
   /// This method returns the address of the specified function or variable.
   /// It is used to resolve symbols during module linking.

Modified: llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h?rev=192504&r1=192503&r2=192504&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h (original)
+++ llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h Fri Oct 11 16:25:48 2013
@@ -64,9 +64,14 @@ public:
   /// This is the address which will be used for relocation resolution.
   void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress);
 
-  StringRef getErrorString();
+  /// Register any EH frame sections that have been loaded but not previously
+  /// registered with the memory manager.  Note, RuntimeDyld is responsible
+  /// for identifying the EH frame and calling the memory manager with the
+  /// EH frame section data.  However, the memory manager itself will handle
+  /// the actual target-specific EH frame registration.
+  void registerEHFrames();
 
-  StringRef getEHFrameSection();
+  StringRef getErrorString();
 };
 
 } // end namespace llvm

Modified: llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp?rev=192504&r1=192503&r2=192504&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp Fri Oct 11 16:25:48 2013
@@ -178,14 +178,12 @@ void MCJIT::finalizeLoadedModules() {
 
     if (ModuleStates[M].hasBeenLoaded() &&
         !ModuleStates[M].hasBeenFinalized()) {
-      // FIXME: This should be module specific!
-      StringRef EHData = Dyld.getEHFrameSection();
-      if (!EHData.empty())
-        MemMgr.registerEHFrames(EHData);
       ModuleStates[M] = ModuleFinalized;
     }
   }
 
+  Dyld.registerEHFrames();
+
   // Set page permissions.
   MemMgr.finalizeMemory();
 }
@@ -221,14 +219,12 @@ void MCJIT::finalizeObject() {
 
     if (ModuleStates[M].hasBeenLoaded() &&
         !ModuleStates[M].hasBeenFinalized()) {
-      // FIXME: This should be module specific!
-      StringRef EHData = Dyld.getEHFrameSection();
-      if (!EHData.empty())
-        MemMgr.registerEHFrames(EHData);
       ModuleStates[M] = ModuleFinalized;
     }
   }
 
+  Dyld.registerEHFrames();
+
   // Set page permissions.
   MemMgr.finalizeMemory();
 }
@@ -248,10 +244,7 @@ void MCJIT::finalizeModule(Module *M) {
   // Resolve any outstanding relocations.
   Dyld.resolveRelocations();
 
-  // FIXME: Should this be module specific?
-  StringRef EHData = Dyld.getEHFrameSection();
-  if (!EHData.empty())
-    MemMgr.registerEHFrames(EHData);
+  Dyld.registerEHFrames();
 
   // Set page permissions.
   MemMgr.finalizeMemory();

Modified: llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h?rev=192504&r1=192503&r2=192504&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h (original)
+++ llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h Fri Oct 11 16:25:48 2013
@@ -51,8 +51,8 @@ public:
     ClientMM->notifyObjectLoaded(EE, Obj);
   }
 
-  virtual void registerEHFrames(StringRef SectionData) {
-    ClientMM->registerEHFrames(SectionData);
+  virtual void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) {
+    ClientMM->registerEHFrames(Addr, LoadAddr, Size);
   }
 
   virtual bool finalizeMemory(std::string *ErrMsg = 0) {

Modified: llvm/trunk/lib/ExecutionEngine/RTDyldMemoryManager.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RTDyldMemoryManager.cpp?rev=192504&r1=192503&r2=192504&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/RTDyldMemoryManager.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/RTDyldMemoryManager.cpp Fri Oct 11 16:25:48 2013
@@ -54,10 +54,15 @@ static const char *processFDE(const char
 }
 #endif
 
-void RTDyldMemoryManager::registerEHFrames(StringRef SectionData) {
+// This implementation handles frame registration for local targets.
+// Memory managers for remote targets should re-implement this function
+// and use the LoadAddr parameter.
+void RTDyldMemoryManager::registerEHFrames(uint8_t *Addr,
+                                           uint64_t LoadAddr,
+                                           size_t Size) {
 #if HAVE_EHTABLE_SUPPORT
-  const char *P = SectionData.data();
-  const char *End = SectionData.data() + SectionData.size();
+  const char *P = (const char *)Addr;
+  const char *End = P + Size;
   do  {
     P = processFDE(P);
   } while(P != End);

Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp?rev=192504&r1=192503&r2=192504&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp Fri Oct 11 16:25:48 2013
@@ -29,8 +29,7 @@ RuntimeDyldImpl::~RuntimeDyldImpl() {}
 
 namespace llvm {
 
-StringRef RuntimeDyldImpl::getEHFrameSection() {
-  return StringRef();
+void RuntimeDyldImpl::registerEHFrames() {
 }
 
 // Resolve the relocations for all symbols we currently know about.
@@ -171,7 +170,7 @@ ObjectImage *RuntimeDyldImpl::loadObject
   }
 
   // Give the subclasses a chance to tie-up any loose ends.
-  finalizeLoad();
+  finalizeLoad(LocalSections);
 
   return obj.take();
 }
@@ -592,8 +591,8 @@ StringRef RuntimeDyld::getErrorString()
   return Dyld->getErrorString();
 }
 
-StringRef RuntimeDyld::getEHFrameSection() {
-  return Dyld->getEHFrameSection();
+void RuntimeDyld::registerEHFrames() {
+  return Dyld->registerEHFrames();
 }
 
 } // end namespace llvm

Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp?rev=192504&r1=192503&r2=192504&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp Fri Oct 11 16:25:48 2013
@@ -151,12 +151,17 @@ void DyldELFObject<ELFT>::updateSymbolAd
 
 namespace llvm {
 
-StringRef RuntimeDyldELF::getEHFrameSection() {
-  for (int i = 0, e = Sections.size(); i != e; ++i) {
-    if (Sections[i].Name == ".eh_frame")
-      return StringRef((const char*)Sections[i].Address, Sections[i].Size);
+void RuntimeDyldELF::registerEHFrames() {
+  if (!MemMgr)
+    return;
+  for (int i = 0, e = UnregisteredEHFrameSections.size(); i != e; ++i) {
+    SID EHFrameSID = UnregisteredEHFrameSections[i];
+    uint8_t *EHFrameAddr = Sections[EHFrameSID].Address;
+    uint64_t EHFrameLoadAddr = Sections[EHFrameSID].LoadAddress;
+    size_t EHFrameSize = Sections[EHFrameSID].Size;
+    MemMgr->registerEHFrames(EHFrameAddr, EHFrameLoadAddr, EHFrameSize);
   }
-  return StringRef();
+  UnregisteredEHFrameSections.clear();
 }
 
 ObjectImage *RuntimeDyldELF::createObjectImage(ObjectBuffer *Buffer) {
@@ -1342,7 +1347,8 @@ uint64_t RuntimeDyldELF::findGOTEntry(ui
   return 0;
 }
 
-void RuntimeDyldELF::finalizeLoad() {
+void RuntimeDyldELF::finalizeLoad(ObjSectionToIDMap &SectionMap) {
+  // If necessary, allocate the global offset table
   if (MemMgr) {
     // Allocate the GOT if necessary
     size_t numGOTEntries = GOTEntries.size();
@@ -1365,6 +1371,18 @@ void RuntimeDyldELF::finalizeLoad() {
   else {
     report_fatal_error("Unable to allocate memory for GOT!");
   }
+
+  // Look for and record the EH frame section.
+  ObjSectionToIDMap::iterator i, e;
+  for (i = SectionMap.begin(), e = SectionMap.end(); i != e; ++i) {
+    const SectionRef &Section = i->first;
+    StringRef Name;
+    Section.getName(Name);
+    if (Name == ".eh_frame") {
+      UnregisteredEHFrameSections.push_back(i->second);
+      break;
+    }
+  }
 }
 
 bool RuntimeDyldELF::isCompatibleFormat(const ObjectBuffer *Buffer) const {

Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h?rev=192504&r1=192503&r2=192504&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h (original)
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h Fri Oct 11 16:25:48 2013
@@ -94,11 +94,15 @@ class RuntimeDyldELF : public RuntimeDyl
 
   // Relocation entries for symbols whose position-independant offset is
   // updated in a global offset table.
-  typedef unsigned SID; // Type for SectionIDs
   typedef SmallVector<RelocationValueRef, 2> GOTRelocations;
   GOTRelocations GOTEntries; // List of entries requiring finalization.
   SmallVector<std::pair<SID, GOTRelocations>, 8> GOTs; // Allocated tables.
 
+  // When a module is loaded we save the SectionID of the EH frame section
+  // in a table until we receive a request to register all unregistered
+  // EH frame sections with the memory manager.
+  SmallVector<SID, 2> UnregisteredEHFrameSections;
+
 public:
   RuntimeDyldELF(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm)
                                           {}
@@ -112,8 +116,8 @@ public:
                                     StubMap &Stubs);
   virtual bool isCompatibleFormat(const ObjectBuffer *Buffer) const;
   virtual ObjectImage *createObjectImage(ObjectBuffer *InputBuffer);
-  virtual StringRef getEHFrameSection();
-  virtual void finalizeLoad();
+  virtual void registerEHFrames();
+  virtual void finalizeLoad(ObjSectionToIDMap &SectionMap);
   virtual ~RuntimeDyldELF();
 };
 

Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h?rev=192504&r1=192503&r2=192504&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h (original)
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h Fri Oct 11 16:25:48 2013
@@ -147,6 +147,9 @@ protected:
   typedef SmallVector<SectionEntry, 64> SectionList;
   SectionList Sections;
 
+  typedef unsigned SID; // Type for SectionIDs
+  #define RTDYLD_INVALID_SECTION_ID ((SID)(-1)) 
+
   // Keep a map of sections from object file to the SectionID which
   // references it.
   typedef std::map<SectionRef, unsigned> ObjSectionToIDMap;
@@ -357,9 +360,9 @@ public:
 
   virtual bool isCompatibleFormat(const ObjectBuffer *Buffer) const = 0;
 
-  virtual StringRef getEHFrameSection();
+  virtual void registerEHFrames();
 
-  virtual void finalizeLoad() {}
+  virtual void finalizeLoad(ObjSectionToIDMap &SectionMap) {}
 };
 
 } // end namespace llvm

Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp?rev=192504&r1=192503&r2=192504&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp Fri Oct 11 16:25:48 2013
@@ -55,33 +55,58 @@ static intptr_t computeDelta(SectionEntr
   return ObjDistance - MemDistance;
 }
 
-StringRef RuntimeDyldMachO::getEHFrameSection() {
-  SectionEntry *Text = NULL;
-  SectionEntry *EHFrame = NULL;
-  SectionEntry *ExceptTab = NULL;
-  for (int i = 0, e = Sections.size(); i != e; ++i) {
-    if (Sections[i].Name == "__eh_frame")
-      EHFrame = &Sections[i];
-    else if (Sections[i].Name == "__text")
-      Text = &Sections[i];
-    else if (Sections[i].Name == "__gcc_except_tab")
-      ExceptTab = &Sections[i];
-  }
-  if (Text == NULL || EHFrame == NULL)
-    return StringRef();
+void RuntimeDyldMachO::registerEHFrames() {
+
+  if (!MemMgr)
+    return;
+  for (int i = 0, e = UnregisteredEHFrameSections.size(); i != e; ++i) {
+    EHFrameRelatedSections &SectionInfo = UnregisteredEHFrameSections[i];
+    if (SectionInfo.EHFrameSID == RTDYLD_INVALID_SECTION_ID ||
+        SectionInfo.TextSID == RTDYLD_INVALID_SECTION_ID)
+      continue;
+    SectionEntry *Text = &Sections[SectionInfo.TextSID];
+    SectionEntry *EHFrame = &Sections[SectionInfo.EHFrameSID];
+    SectionEntry *ExceptTab = NULL;
+    if (SectionInfo.ExceptTabSID != RTDYLD_INVALID_SECTION_ID)
+      ExceptTab = &Sections[SectionInfo.ExceptTabSID];
 
-  intptr_t DeltaForText = computeDelta(Text, EHFrame);
-  intptr_t DeltaForEH = 0;
-  if (ExceptTab)
-    DeltaForEH = computeDelta(ExceptTab, EHFrame);
-
-  unsigned char *P = EHFrame->Address;
-  unsigned char *End = P + EHFrame->Size;
-  do  {
-    P = processFDE(P, DeltaForText, DeltaForEH);
-  } while(P != End);
+    intptr_t DeltaForText = computeDelta(Text, EHFrame);
+    intptr_t DeltaForEH = 0;
+    if (ExceptTab)
+      DeltaForEH = computeDelta(ExceptTab, EHFrame);
 
-  return StringRef((char*)EHFrame->Address, EHFrame->Size);
+    unsigned char *P = EHFrame->Address;
+    unsigned char *End = P + EHFrame->Size;
+    do  {
+      P = processFDE(P, DeltaForText, DeltaForEH);
+    } while(P != End);
+
+    MemMgr->registerEHFrames(EHFrame->Address,
+                             EHFrame->LoadAddress,
+                             EHFrame->Size);
+  }
+  UnregisteredEHFrameSections.clear();
+}
+
+void RuntimeDyldMachO::finalizeLoad(ObjSectionToIDMap &SectionMap) {
+  unsigned EHFrameSID = RTDYLD_INVALID_SECTION_ID;
+  unsigned TextSID = RTDYLD_INVALID_SECTION_ID;
+  unsigned ExceptTabSID = RTDYLD_INVALID_SECTION_ID;
+  ObjSectionToIDMap::iterator i, e;
+  for (i = SectionMap.begin(), e = SectionMap.end(); i != e; ++i) {
+    const SectionRef &Section = i->first;
+    StringRef Name;
+    Section.getName(Name);
+    if (Name == "__eh_frame")
+      EHFrameSID = i->second;
+    else if (Name == "__text")
+      TextSID = i->second;
+    else if (Name == "__gcc_except_tab")
+      ExceptTabSID = i->second;
+  }
+  UnregisteredEHFrameSections.push_back(EHFrameRelatedSections(EHFrameSID,
+                                                               TextSID,
+                                                               ExceptTabSID));
 }
 
 // The target location for the relocation is described by RE.SectionID and

Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h?rev=192504&r1=192503&r2=192504&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h (original)
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h Fri Oct 11 16:25:48 2013
@@ -54,6 +54,22 @@ class RuntimeDyldMachO : public RuntimeD
                          int64_t Addend,
                          bool isPCRel,
                          unsigned Size);
+
+  struct EHFrameRelatedSections {
+    EHFrameRelatedSections() : EHFrameSID(RTDYLD_INVALID_SECTION_ID),
+                               TextSID(RTDYLD_INVALID_SECTION_ID),
+                               ExceptTabSID(RTDYLD_INVALID_SECTION_ID) {}
+    EHFrameRelatedSections(SID EH, SID T, SID Ex) 
+      : EHFrameSID(EH), TextSID(T), ExceptTabSID(Ex) {}
+    SID EHFrameSID;
+    SID TextSID;
+    SID ExceptTabSID;
+  };
+
+  // When a module is loaded we save the SectionID of the EH frame section
+  // in a table until we receive a request to register all unregistered
+  // EH frame sections with the memory manager.
+  SmallVector<EHFrameRelatedSections, 2> UnregisteredEHFrameSections;
 public:
   RuntimeDyldMachO(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {}
 
@@ -65,7 +81,8 @@ public:
                                     const SymbolTableMap &Symbols,
                                     StubMap &Stubs);
   virtual bool isCompatibleFormat(const ObjectBuffer *Buffer) const;
-  virtual StringRef getEHFrameSection();
+  virtual void registerEHFrames();
+  virtual void finalizeLoad(ObjSectionToIDMap &SectionMap);
 };
 
 } // end namespace llvm

Added: llvm/trunk/test/ExecutionEngine/MCJIT/multi-module-eh-a.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/multi-module-eh-a.ll?rev=192504&view=auto
==============================================================================
--- llvm/trunk/test/ExecutionEngine/MCJIT/multi-module-eh-a.ll (added)
+++ llvm/trunk/test/ExecutionEngine/MCJIT/multi-module-eh-a.ll Fri Oct 11 16:25:48 2013
@@ -0,0 +1,35 @@
+; RUN: %lli_mcjit -extra-modules=%p/multi-module-eh-b.ir %s
+; XFAIL: arm, cygwin, win32, mingw
+declare i8* @__cxa_allocate_exception(i64)
+declare void @__cxa_throw(i8*, i8*, i8*)
+declare i32 @__gxx_personality_v0(...)
+declare void @__cxa_end_catch()
+declare i8* @__cxa_begin_catch(i8*)
+
+ at _ZTIi = external constant i8*
+
+declare i32 @FB()
+
+define void @throwException() {
+  %exception = tail call i8* @__cxa_allocate_exception(i64 4)
+  call void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null)
+  unreachable
+}
+
+define i32 @main() {
+entry:
+  invoke void @throwException()
+          to label %try.cont unwind label %lpad
+
+lpad:
+  %p = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+          catch i8* bitcast (i8** @_ZTIi to i8*)
+  %e = extractvalue { i8*, i32 } %p, 0
+  call i8* @__cxa_begin_catch(i8* %e)
+  call void @__cxa_end_catch()
+  br label %try.cont
+
+try.cont:
+  %r = call i32 @FB( )
+  ret i32 %r
+}

Added: llvm/trunk/test/ExecutionEngine/MCJIT/multi-module-eh-b.ir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/multi-module-eh-b.ir?rev=192504&view=auto
==============================================================================
--- llvm/trunk/test/ExecutionEngine/MCJIT/multi-module-eh-b.ir (added)
+++ llvm/trunk/test/ExecutionEngine/MCJIT/multi-module-eh-b.ir Fri Oct 11 16:25:48 2013
@@ -0,0 +1,30 @@
+declare i8* @__cxa_allocate_exception(i64)
+declare void @__cxa_throw(i8*, i8*, i8*)
+declare i32 @__gxx_personality_v0(...)
+declare void @__cxa_end_catch()
+declare i8* @__cxa_begin_catch(i8*)
+
+ at _ZTIi = external constant i8*
+
+define void @throwException_B() {
+  %exception = tail call i8* @__cxa_allocate_exception(i64 4)
+  call void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null)
+  unreachable
+}
+
+define i32 @FB() {
+entry:
+  invoke void @throwException_B()
+          to label %try.cont unwind label %lpad
+
+lpad:
+  %p = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+          catch i8* bitcast (i8** @_ZTIi to i8*)
+  %e = extractvalue { i8*, i32 } %p, 0
+  call i8* @__cxa_begin_catch(i8* %e)
+  call void @__cxa_end_catch()
+  br label %try.cont
+
+try.cont:
+  ret i32 0
+}

Modified: llvm/trunk/tools/lli/RemoteMemoryManager.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/RemoteMemoryManager.cpp?rev=192504&r1=192503&r2=192504&view=diff
==============================================================================
--- llvm/trunk/tools/lli/RemoteMemoryManager.cpp (original)
+++ llvm/trunk/tools/lli/RemoteMemoryManager.cpp Fri Oct 11 16:25:48 2013
@@ -204,27 +204,3 @@ uint8_t *RemoteMemoryManager::allocateGl
 void RemoteMemoryManager::deallocateFunctionBody(void *Body) {
   llvm_unreachable("Unexpected!");
 }
-
-static int jit_noop() {
-  return 0;
-}
-
-void *RemoteMemoryManager::getPointerToNamedFunction(const std::string &Name,
-                                                        bool AbortOnFailure) {
-  // We should not invoke parent's ctors/dtors from generated main()!
-  // On Mingw and Cygwin, the symbol __main is resolved to
-  // callee's(eg. tools/lli) one, to invoke wrong duplicated ctors
-  // (and register wrong callee's dtors with atexit(3)).
-  // We expect ExecutionEngine::runStaticConstructorsDestructors()
-  // is called before ExecutionEngine::runFunctionAsMain() is called.
-  if (Name == "__main") return (void*)(intptr_t)&jit_noop;
-
-  // FIXME: Would it be responsible to provide GOT?
-  if (AbortOnFailure) {
-    if (Name == "_GLOBAL_OFFSET_TABLE_")
-      report_fatal_error("Program used external function '" + Name +
-                         "' which could not be resolved!");
-  }
-
-  return NULL;
-}

Modified: llvm/trunk/tools/lli/RemoteMemoryManager.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/RemoteMemoryManager.h?rev=192504&r1=192503&r2=192504&view=diff
==============================================================================
--- llvm/trunk/tools/lli/RemoteMemoryManager.h (original)
+++ llvm/trunk/tools/lli/RemoteMemoryManager.h Fri Oct 11 16:25:48 2013
@@ -74,13 +74,20 @@ public:
                                unsigned SectionID, StringRef SectionName,
                                bool IsReadOnly);
 
-  void *getPointerToNamedFunction(const std::string &Name,
-                                  bool AbortOnFailure = true);
+  // For now, remote symbol resolution is not support in lli.  The MCJIT
+  // interface does support this, but clients must provide their own
+  // mechanism for finding remote symbol addresses.  MCJIT will resolve
+  // symbols from Modules it contains.
+  uint64_t getSymbolAddress(const std::string &Name) {}
 
   void notifyObjectLoaded(ExecutionEngine *EE, const ObjectImage *Obj);
 
   bool finalizeMemory(std::string *ErrMsg);
 
+  // For now, remote EH frame registration isn't supported.  Remote symbol
+  // resolution is a prerequisite to supporting remote EH frame registration.
+  void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) {}
+
   // This is a non-interface function used by lli
   void setRemoteTarget(RemoteTarget *T) { Target = T; }
 





More information about the llvm-commits mailing list