+bool RuntimeDyldMachO::isCompatibleFile(const object::ObjectFile *Obj) const {
+ return Obj->isMachO();
+}
+
+static unsigned char *processFDE(unsigned char *P, intptr_t DeltaForText,
+ intptr_t DeltaForEH) {
+ DEBUG(dbgs() << "Processing FDE: Delta for text: " << DeltaForText
+ << ", Delta for EH: " << DeltaForEH << "\n");
+ uint32_t Length = *((uint32_t *)P);
+ P += 4;
+ unsigned char *Ret = P + Length;
+ uint32_t Offset = *((uint32_t *)P);
+ if (Offset == 0) // is a CIE
+ return Ret;
+
+ P += 4;
+ intptr_t FDELocation = *((intptr_t *)P);
+ intptr_t NewLocation = FDELocation - DeltaForText;
+ *((intptr_t *)P) = NewLocation;
+ P += sizeof(intptr_t);
+
+ // Skip the FDE address range
+ P += sizeof(intptr_t);
+
+ uint8_t Augmentationsize = *P;
+ P += 1;
+ if (Augmentationsize != 0) {
+ intptr_t LSDA = *((intptr_t *)P);
+ intptr_t NewLSDA = LSDA - DeltaForEH;
+ *((intptr_t *)P) = NewLSDA;
+ }
+
+ return Ret;
+}
+
+static intptr_t computeDelta(SectionEntry *A, SectionEntry *B) {
+ intptr_t ObjDistance = A->ObjAddress - B->ObjAddress;
+ intptr_t MemDistance = A->LoadAddress - B->LoadAddress;
+ return ObjDistance - MemDistance;
+}
+
+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 = nullptr;
+ 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);
+ }
+ UnregisteredEHFrameSections.clear();
+}
+
+std::unique_ptr<RuntimeDyldMachO>
+llvm::RuntimeDyldMachO::create(Triple::ArchType Arch, RTDyldMemoryManager *MM) {
+ switch (Arch) {
+ default:
+ llvm_unreachable("Unsupported target for RuntimeDyldMachO.");
+ break;
+ case Triple::arm: return make_unique<RuntimeDyldMachOARM>(MM);
+ case Triple::aarch64: return make_unique<RuntimeDyldMachOAArch64>(MM);
+ case Triple::x86: return make_unique<RuntimeDyldMachOI386>(MM);
+ case Triple::x86_64: return make_unique<RuntimeDyldMachOX86_64>(MM);
+ }
+}
+