mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-24 12:29:33 +00:00
Adding multiple object support to MCJIT EH frame handling
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192504 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
b19b474de9
commit
528f6d787b
@ -53,7 +53,12 @@ public:
|
|||||||
StringRef SectionName, bool IsReadOnly) = 0;
|
StringRef SectionName, bool IsReadOnly) = 0;
|
||||||
|
|
||||||
/// Register the EH frames with the runtime so that c++ exceptions work.
|
/// 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.
|
/// This method returns the address of the specified function or variable.
|
||||||
/// It is used to resolve symbols during module linking.
|
/// It is used to resolve symbols during module linking.
|
||||||
|
@ -64,9 +64,14 @@ public:
|
|||||||
/// This is the address which will be used for relocation resolution.
|
/// This is the address which will be used for relocation resolution.
|
||||||
void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress);
|
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
|
} // end namespace llvm
|
||||||
|
@ -178,14 +178,12 @@ void MCJIT::finalizeLoadedModules() {
|
|||||||
|
|
||||||
if (ModuleStates[M].hasBeenLoaded() &&
|
if (ModuleStates[M].hasBeenLoaded() &&
|
||||||
!ModuleStates[M].hasBeenFinalized()) {
|
!ModuleStates[M].hasBeenFinalized()) {
|
||||||
// FIXME: This should be module specific!
|
|
||||||
StringRef EHData = Dyld.getEHFrameSection();
|
|
||||||
if (!EHData.empty())
|
|
||||||
MemMgr.registerEHFrames(EHData);
|
|
||||||
ModuleStates[M] = ModuleFinalized;
|
ModuleStates[M] = ModuleFinalized;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Dyld.registerEHFrames();
|
||||||
|
|
||||||
// Set page permissions.
|
// Set page permissions.
|
||||||
MemMgr.finalizeMemory();
|
MemMgr.finalizeMemory();
|
||||||
}
|
}
|
||||||
@ -221,14 +219,12 @@ void MCJIT::finalizeObject() {
|
|||||||
|
|
||||||
if (ModuleStates[M].hasBeenLoaded() &&
|
if (ModuleStates[M].hasBeenLoaded() &&
|
||||||
!ModuleStates[M].hasBeenFinalized()) {
|
!ModuleStates[M].hasBeenFinalized()) {
|
||||||
// FIXME: This should be module specific!
|
|
||||||
StringRef EHData = Dyld.getEHFrameSection();
|
|
||||||
if (!EHData.empty())
|
|
||||||
MemMgr.registerEHFrames(EHData);
|
|
||||||
ModuleStates[M] = ModuleFinalized;
|
ModuleStates[M] = ModuleFinalized;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Dyld.registerEHFrames();
|
||||||
|
|
||||||
// Set page permissions.
|
// Set page permissions.
|
||||||
MemMgr.finalizeMemory();
|
MemMgr.finalizeMemory();
|
||||||
}
|
}
|
||||||
@ -248,10 +244,7 @@ void MCJIT::finalizeModule(Module *M) {
|
|||||||
// Resolve any outstanding relocations.
|
// Resolve any outstanding relocations.
|
||||||
Dyld.resolveRelocations();
|
Dyld.resolveRelocations();
|
||||||
|
|
||||||
// FIXME: Should this be module specific?
|
Dyld.registerEHFrames();
|
||||||
StringRef EHData = Dyld.getEHFrameSection();
|
|
||||||
if (!EHData.empty())
|
|
||||||
MemMgr.registerEHFrames(EHData);
|
|
||||||
|
|
||||||
// Set page permissions.
|
// Set page permissions.
|
||||||
MemMgr.finalizeMemory();
|
MemMgr.finalizeMemory();
|
||||||
|
@ -51,8 +51,8 @@ public:
|
|||||||
ClientMM->notifyObjectLoaded(EE, Obj);
|
ClientMM->notifyObjectLoaded(EE, Obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void registerEHFrames(StringRef SectionData) {
|
virtual void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) {
|
||||||
ClientMM->registerEHFrames(SectionData);
|
ClientMM->registerEHFrames(Addr, LoadAddr, Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool finalizeMemory(std::string *ErrMsg = 0) {
|
virtual bool finalizeMemory(std::string *ErrMsg = 0) {
|
||||||
|
@ -54,10 +54,15 @@ static const char *processFDE(const char *Entry) {
|
|||||||
}
|
}
|
||||||
#endif
|
#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
|
#if HAVE_EHTABLE_SUPPORT
|
||||||
const char *P = SectionData.data();
|
const char *P = (const char *)Addr;
|
||||||
const char *End = SectionData.data() + SectionData.size();
|
const char *End = P + Size;
|
||||||
do {
|
do {
|
||||||
P = processFDE(P);
|
P = processFDE(P);
|
||||||
} while(P != End);
|
} while(P != End);
|
||||||
|
@ -29,8 +29,7 @@ RuntimeDyldImpl::~RuntimeDyldImpl() {}
|
|||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
StringRef RuntimeDyldImpl::getEHFrameSection() {
|
void RuntimeDyldImpl::registerEHFrames() {
|
||||||
return StringRef();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve the relocations for all symbols we currently know about.
|
// Resolve the relocations for all symbols we currently know about.
|
||||||
@ -171,7 +170,7 @@ ObjectImage *RuntimeDyldImpl::loadObject(ObjectBuffer *InputBuffer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Give the subclasses a chance to tie-up any loose ends.
|
// Give the subclasses a chance to tie-up any loose ends.
|
||||||
finalizeLoad();
|
finalizeLoad(LocalSections);
|
||||||
|
|
||||||
return obj.take();
|
return obj.take();
|
||||||
}
|
}
|
||||||
@ -592,8 +591,8 @@ StringRef RuntimeDyld::getErrorString() {
|
|||||||
return Dyld->getErrorString();
|
return Dyld->getErrorString();
|
||||||
}
|
}
|
||||||
|
|
||||||
StringRef RuntimeDyld::getEHFrameSection() {
|
void RuntimeDyld::registerEHFrames() {
|
||||||
return Dyld->getEHFrameSection();
|
return Dyld->registerEHFrames();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace llvm
|
} // end namespace llvm
|
||||||
|
@ -151,12 +151,17 @@ void DyldELFObject<ELFT>::updateSymbolAddress(const SymbolRef &SymRef,
|
|||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
StringRef RuntimeDyldELF::getEHFrameSection() {
|
void RuntimeDyldELF::registerEHFrames() {
|
||||||
for (int i = 0, e = Sections.size(); i != e; ++i) {
|
if (!MemMgr)
|
||||||
if (Sections[i].Name == ".eh_frame")
|
return;
|
||||||
return StringRef((const char*)Sections[i].Address, Sections[i].Size);
|
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) {
|
ObjectImage *RuntimeDyldELF::createObjectImage(ObjectBuffer *Buffer) {
|
||||||
@ -1342,7 +1347,8 @@ uint64_t RuntimeDyldELF::findGOTEntry(uint64_t LoadAddress,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RuntimeDyldELF::finalizeLoad() {
|
void RuntimeDyldELF::finalizeLoad(ObjSectionToIDMap &SectionMap) {
|
||||||
|
// If necessary, allocate the global offset table
|
||||||
if (MemMgr) {
|
if (MemMgr) {
|
||||||
// Allocate the GOT if necessary
|
// Allocate the GOT if necessary
|
||||||
size_t numGOTEntries = GOTEntries.size();
|
size_t numGOTEntries = GOTEntries.size();
|
||||||
@ -1365,6 +1371,18 @@ void RuntimeDyldELF::finalizeLoad() {
|
|||||||
else {
|
else {
|
||||||
report_fatal_error("Unable to allocate memory for GOT!");
|
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 {
|
bool RuntimeDyldELF::isCompatibleFormat(const ObjectBuffer *Buffer) const {
|
||||||
|
@ -94,11 +94,15 @@ class RuntimeDyldELF : public RuntimeDyldImpl {
|
|||||||
|
|
||||||
// Relocation entries for symbols whose position-independant offset is
|
// Relocation entries for symbols whose position-independant offset is
|
||||||
// updated in a global offset table.
|
// updated in a global offset table.
|
||||||
typedef unsigned SID; // Type for SectionIDs
|
|
||||||
typedef SmallVector<RelocationValueRef, 2> GOTRelocations;
|
typedef SmallVector<RelocationValueRef, 2> GOTRelocations;
|
||||||
GOTRelocations GOTEntries; // List of entries requiring finalization.
|
GOTRelocations GOTEntries; // List of entries requiring finalization.
|
||||||
SmallVector<std::pair<SID, GOTRelocations>, 8> GOTs; // Allocated tables.
|
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:
|
public:
|
||||||
RuntimeDyldELF(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm)
|
RuntimeDyldELF(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm)
|
||||||
{}
|
{}
|
||||||
@ -112,8 +116,8 @@ public:
|
|||||||
StubMap &Stubs);
|
StubMap &Stubs);
|
||||||
virtual bool isCompatibleFormat(const ObjectBuffer *Buffer) const;
|
virtual bool isCompatibleFormat(const ObjectBuffer *Buffer) const;
|
||||||
virtual ObjectImage *createObjectImage(ObjectBuffer *InputBuffer);
|
virtual ObjectImage *createObjectImage(ObjectBuffer *InputBuffer);
|
||||||
virtual StringRef getEHFrameSection();
|
virtual void registerEHFrames();
|
||||||
virtual void finalizeLoad();
|
virtual void finalizeLoad(ObjSectionToIDMap &SectionMap);
|
||||||
virtual ~RuntimeDyldELF();
|
virtual ~RuntimeDyldELF();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -147,6 +147,9 @@ protected:
|
|||||||
typedef SmallVector<SectionEntry, 64> SectionList;
|
typedef SmallVector<SectionEntry, 64> SectionList;
|
||||||
SectionList Sections;
|
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
|
// Keep a map of sections from object file to the SectionID which
|
||||||
// references it.
|
// references it.
|
||||||
typedef std::map<SectionRef, unsigned> ObjSectionToIDMap;
|
typedef std::map<SectionRef, unsigned> ObjSectionToIDMap;
|
||||||
@ -357,9 +360,9 @@ public:
|
|||||||
|
|
||||||
virtual bool isCompatibleFormat(const ObjectBuffer *Buffer) const = 0;
|
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
|
} // end namespace llvm
|
||||||
|
@ -55,33 +55,58 @@ static intptr_t computeDelta(SectionEntry *A, SectionEntry *B) {
|
|||||||
return ObjDistance - MemDistance;
|
return ObjDistance - MemDistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringRef RuntimeDyldMachO::getEHFrameSection() {
|
void RuntimeDyldMachO::registerEHFrames() {
|
||||||
SectionEntry *Text = NULL;
|
|
||||||
SectionEntry *EHFrame = NULL;
|
if (!MemMgr)
|
||||||
SectionEntry *ExceptTab = NULL;
|
return;
|
||||||
for (int i = 0, e = Sections.size(); i != e; ++i) {
|
for (int i = 0, e = UnregisteredEHFrameSections.size(); i != e; ++i) {
|
||||||
if (Sections[i].Name == "__eh_frame")
|
EHFrameRelatedSections &SectionInfo = UnregisteredEHFrameSections[i];
|
||||||
EHFrame = &Sections[i];
|
if (SectionInfo.EHFrameSID == RTDYLD_INVALID_SECTION_ID ||
|
||||||
else if (Sections[i].Name == "__text")
|
SectionInfo.TextSID == RTDYLD_INVALID_SECTION_ID)
|
||||||
Text = &Sections[i];
|
continue;
|
||||||
else if (Sections[i].Name == "__gcc_except_tab")
|
SectionEntry *Text = &Sections[SectionInfo.TextSID];
|
||||||
ExceptTab = &Sections[i];
|
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);
|
||||||
|
|
||||||
|
MemMgr->registerEHFrames(EHFrame->Address,
|
||||||
|
EHFrame->LoadAddress,
|
||||||
|
EHFrame->Size);
|
||||||
}
|
}
|
||||||
if (Text == NULL || EHFrame == NULL)
|
UnregisteredEHFrameSections.clear();
|
||||||
return StringRef();
|
}
|
||||||
|
|
||||||
intptr_t DeltaForText = computeDelta(Text, EHFrame);
|
void RuntimeDyldMachO::finalizeLoad(ObjSectionToIDMap &SectionMap) {
|
||||||
intptr_t DeltaForEH = 0;
|
unsigned EHFrameSID = RTDYLD_INVALID_SECTION_ID;
|
||||||
if (ExceptTab)
|
unsigned TextSID = RTDYLD_INVALID_SECTION_ID;
|
||||||
DeltaForEH = computeDelta(ExceptTab, EHFrame);
|
unsigned ExceptTabSID = RTDYLD_INVALID_SECTION_ID;
|
||||||
|
ObjSectionToIDMap::iterator i, e;
|
||||||
unsigned char *P = EHFrame->Address;
|
for (i = SectionMap.begin(), e = SectionMap.end(); i != e; ++i) {
|
||||||
unsigned char *End = P + EHFrame->Size;
|
const SectionRef &Section = i->first;
|
||||||
do {
|
StringRef Name;
|
||||||
P = processFDE(P, DeltaForText, DeltaForEH);
|
Section.getName(Name);
|
||||||
} while(P != End);
|
if (Name == "__eh_frame")
|
||||||
|
EHFrameSID = i->second;
|
||||||
return StringRef((char*)EHFrame->Address, EHFrame->Size);
|
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
|
// The target location for the relocation is described by RE.SectionID and
|
||||||
|
@ -54,6 +54,22 @@ class RuntimeDyldMachO : public RuntimeDyldImpl {
|
|||||||
int64_t Addend,
|
int64_t Addend,
|
||||||
bool isPCRel,
|
bool isPCRel,
|
||||||
unsigned Size);
|
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:
|
public:
|
||||||
RuntimeDyldMachO(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {}
|
RuntimeDyldMachO(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {}
|
||||||
|
|
||||||
@ -65,7 +81,8 @@ public:
|
|||||||
const SymbolTableMap &Symbols,
|
const SymbolTableMap &Symbols,
|
||||||
StubMap &Stubs);
|
StubMap &Stubs);
|
||||||
virtual bool isCompatibleFormat(const ObjectBuffer *Buffer) const;
|
virtual bool isCompatibleFormat(const ObjectBuffer *Buffer) const;
|
||||||
virtual StringRef getEHFrameSection();
|
virtual void registerEHFrames();
|
||||||
|
virtual void finalizeLoad(ObjSectionToIDMap &SectionMap);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace llvm
|
} // end namespace llvm
|
||||||
|
35
test/ExecutionEngine/MCJIT/multi-module-eh-a.ll
Normal file
35
test/ExecutionEngine/MCJIT/multi-module-eh-a.ll
Normal file
@ -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*)
|
||||||
|
|
||||||
|
@_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
|
||||||
|
}
|
30
test/ExecutionEngine/MCJIT/multi-module-eh-b.ir
Normal file
30
test/ExecutionEngine/MCJIT/multi-module-eh-b.ir
Normal file
@ -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*)
|
||||||
|
|
||||||
|
@_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
|
||||||
|
}
|
@ -204,27 +204,3 @@ uint8_t *RemoteMemoryManager::allocateGlobal(uintptr_t Size, unsigned Alignment)
|
|||||||
void RemoteMemoryManager::deallocateFunctionBody(void *Body) {
|
void RemoteMemoryManager::deallocateFunctionBody(void *Body) {
|
||||||
llvm_unreachable("Unexpected!");
|
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;
|
|
||||||
}
|
|
||||||
|
@ -74,13 +74,20 @@ public:
|
|||||||
unsigned SectionID, StringRef SectionName,
|
unsigned SectionID, StringRef SectionName,
|
||||||
bool IsReadOnly);
|
bool IsReadOnly);
|
||||||
|
|
||||||
void *getPointerToNamedFunction(const std::string &Name,
|
// For now, remote symbol resolution is not support in lli. The MCJIT
|
||||||
bool AbortOnFailure = true);
|
// 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);
|
void notifyObjectLoaded(ExecutionEngine *EE, const ObjectImage *Obj);
|
||||||
|
|
||||||
bool finalizeMemory(std::string *ErrMsg);
|
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
|
// This is a non-interface function used by lli
|
||||||
void setRemoteTarget(RemoteTarget *T) { Target = T; }
|
void setRemoteTarget(RemoteTarget *T) { Target = T; }
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user