+ section_iterator RelocatedSection = SI->getRelocatedSection();
+
+ relocation_iterator I = SI->relocation_begin();
+ relocation_iterator E = SI->relocation_end();
+
+ if (I == E && !ProcessAllSections)
+ continue;
+
+ bool IsCode = RelocatedSection->isText();
+ SectionID =
+ findOrEmitSection(Obj, *RelocatedSection, IsCode, LocalSections);
+ DEBUG(dbgs() << "\tSectionID: " << SectionID << "\n");
+
+ for (; I != E;)
+ I = processRelocationRef(SectionID, I, Obj, LocalSections, Stubs);
+
+ // If there is an attached checker, notify it about the stubs for this
+ // section so that they can be verified.
+ if (Checker)
+ Checker->registerStubMap(Obj.getFileName(), SectionID, Stubs);
+ }
+
+ // Give the subclasses a chance to tie-up any loose ends.
+ finalizeLoad(Obj, LocalSections);
+
+ unsigned SectionsAddedEndIdx = Sections.size();
+
+ return std::make_pair(SectionsAddedBeginIdx, SectionsAddedEndIdx);
+}
+
+// A helper method for computeTotalAllocSize.
+// Computes the memory size required to allocate sections with the given sizes,
+// assuming that all sections are allocated with the given alignment
+static uint64_t
+computeAllocationSizeForSections(std::vector<uint64_t> &SectionSizes,
+ uint64_t Alignment) {
+ uint64_t TotalSize = 0;
+ for (size_t Idx = 0, Cnt = SectionSizes.size(); Idx < Cnt; Idx++) {
+ uint64_t AlignedSize =
+ (SectionSizes[Idx] + Alignment - 1) / Alignment * Alignment;
+ TotalSize += AlignedSize;
+ }
+ return TotalSize;
+}
+
+static bool isRequiredForExecution(const SectionRef &Section) {
+ const ObjectFile *Obj = Section.getObject();
+ if (auto *ELFObj = dyn_cast<object::ELFObjectFileBase>(Obj))
+ return ELFObj->getSectionFlags(Section) & ELF::SHF_ALLOC;
+ assert(isa<MachOObjectFile>(Obj));
+ return true;
+ }
+
+static bool isReadOnlyData(const SectionRef &Section) {
+ const ObjectFile *Obj = Section.getObject();
+ if (auto *ELFObj = dyn_cast<object::ELFObjectFileBase>(Obj))
+ return !(ELFObj->getSectionFlags(Section) &
+ (ELF::SHF_WRITE | ELF::SHF_EXECINSTR));
+ assert(isa<MachOObjectFile>(Obj));
+ return false;
+}
+
+static bool isZeroInit(const SectionRef &Section) {
+ const ObjectFile *Obj = Section.getObject();
+ if (auto *ELFObj = dyn_cast<object::ELFObjectFileBase>(Obj))
+ return ELFObj->getSectionType(Section) == ELF::SHT_NOBITS;
+
+ auto *MachO = cast<MachOObjectFile>(Obj);
+ unsigned SectionType = MachO->getSectionType(Section);
+ return SectionType == MachO::S_ZEROFILL ||
+ SectionType == MachO::S_GB_ZEROFILL;
+}
+
+// Compute an upper bound of the memory size that is required to load all
+// sections
+void RuntimeDyldImpl::computeTotalAllocSize(const ObjectFile &Obj,
+ uint64_t &CodeSize,
+ uint64_t &DataSizeRO,
+ uint64_t &DataSizeRW) {
+ // Compute the size of all sections required for execution
+ std::vector<uint64_t> CodeSectionSizes;
+ std::vector<uint64_t> ROSectionSizes;
+ std::vector<uint64_t> RWSectionSizes;
+ uint64_t MaxAlignment = sizeof(void *);
+
+ // Collect sizes of all sections to be loaded;
+ // also determine the max alignment of all sections
+ for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end();
+ SI != SE; ++SI) {
+ const SectionRef &Section = *SI;
+
+ bool IsRequired = isRequiredForExecution(Section);
+
+ // Consider only the sections that are required to be loaded for execution
+ if (IsRequired) {
+ StringRef Name;
+ uint64_t DataSize = Section.getSize();
+ uint64_t Alignment64 = Section.getAlignment();
+ bool IsCode = Section.isText();
+ bool IsReadOnly = isReadOnlyData(Section);
+ Check(Section.getName(Name));
+ unsigned Alignment = (unsigned)Alignment64 & 0xffffffffL;
+
+ uint64_t StubBufSize = computeSectionStubBufSize(Obj, Section);
+ uint64_t SectionSize = DataSize + StubBufSize;
+
+ // The .eh_frame section (at least on Linux) needs an extra four bytes
+ // padded
+ // with zeroes added at the end. For MachO objects, this section has a
+ // slightly different name, so this won't have any effect for MachO
+ // objects.
+ if (Name == ".eh_frame")
+ SectionSize += 4;
+
+ if (SectionSize > 0) {
+ // save the total size of the section
+ if (IsCode) {
+ CodeSectionSizes.push_back(SectionSize);
+ } else if (IsReadOnly) {
+ ROSectionSizes.push_back(SectionSize);
+ } else {
+ RWSectionSizes.push_back(SectionSize);
+ }
+ // update the max alignment
+ if (Alignment > MaxAlignment) {
+ MaxAlignment = Alignment;
+ }