+void OutputFile::makeSplitSegInfoV2(ld::Internal& state)
+{
+ static const bool log = false;
+ if ( !_options.sharedRegionEligible() )
+ return;
+
+ for (std::vector<ld::Internal::FinalSection*>::iterator sit = state.sections.begin(); sit != state.sections.end(); ++sit) {
+ ld::Internal::FinalSection* sect = *sit;
+ if ( sect->isSectionHidden() )
+ continue;
+ bool codeSection = (sect->type() == ld::Section::typeCode);
+ if (log) fprintf(stderr, "sect: %s, address=0x%llX\n", sect->sectionName(), sect->address);
+ for (std::vector<const ld::Atom*>::iterator ait = sect->atoms.begin(); ait != sect->atoms.end(); ++ait) {
+ const ld::Atom* atom = *ait;
+ const ld::Atom* target = NULL;
+ const ld::Atom* fromTarget = NULL;
+ uint32_t picBase = 0;
+ uint64_t accumulator = 0;
+ bool thumbTarget;
+ bool hadSubtract = false;
+ uint8_t fromSectionIndex = atom->machoSection();
+ uint8_t toSectionIndex;
+ uint8_t kind = 0;
+ uint64_t fromOffset = 0;
+ uint64_t toOffset = 0;
+ uint64_t addend = 0;
+ for (ld::Fixup::iterator fit = atom->fixupsBegin(), end=atom->fixupsEnd(); fit != end; ++fit) {
+ if ( fit->firstInCluster() ) {
+ target = NULL;
+ fromTarget = NULL;
+ kind = 0;
+ addend = 0;
+ toSectionIndex = 255;
+ fromOffset = atom->finalAddress() + fit->offsetInAtom - sect->address;
+ }
+ if ( this->setsTarget(fit->kind) ) {
+ accumulator = addressOf(state, fit, &target);
+ thumbTarget = targetIsThumb(state, fit);
+ if ( thumbTarget )
+ accumulator |= 1;
+ toOffset = accumulator - state.atomToSection[target]->address;
+ if ( target->definition() != ld::Atom::definitionProxy ) {
+ if ( target->section().type() == ld::Section::typeMachHeader )
+ toSectionIndex = 0;
+ else
+ toSectionIndex = target->machoSection();
+ }
+ }
+ switch ( fit->kind ) {
+ case ld::Fixup::kindSubtractTargetAddress:
+ accumulator -= addressOf(state, fit, &fromTarget);
+ hadSubtract = true;
+ break;
+ case ld::Fixup::kindAddAddend:
+ accumulator += fit->u.addend;
+ addend = fit->u.addend;
+ break;
+ case ld::Fixup::kindSubtractAddend:
+ accumulator -= fit->u.addend;
+ picBase = fit->u.addend;
+ break;
+ case ld::Fixup::kindSetLazyOffset:
+ break;
+ case ld::Fixup::kindStoreBigEndian32:
+ case ld::Fixup::kindStoreLittleEndian32:
+ case ld::Fixup::kindStoreTargetAddressLittleEndian32:
+ if ( kind != DYLD_CACHE_ADJ_V2_IMAGE_OFF_32 ) {
+ if ( hadSubtract )
+ kind = DYLD_CACHE_ADJ_V2_DELTA_32;
+ else
+ kind = DYLD_CACHE_ADJ_V2_POINTER_32;
+ }
+ break;
+ case ld::Fixup::kindStoreLittleEndian64:
+ case ld::Fixup::kindStoreTargetAddressLittleEndian64:
+ if ( hadSubtract )
+ kind = DYLD_CACHE_ADJ_V2_DELTA_64;
+ else
+ kind = DYLD_CACHE_ADJ_V2_POINTER_64;
+ break;
+ case ld::Fixup::kindStoreX86PCRel32:
+ case ld::Fixup::kindStoreX86PCRel32_1:
+ case ld::Fixup::kindStoreX86PCRel32_2:
+ case ld::Fixup::kindStoreX86PCRel32_4:
+ case ld::Fixup::kindStoreX86PCRel32GOTLoad:
+ case ld::Fixup::kindStoreX86PCRel32GOTLoadNowLEA:
+ case ld::Fixup::kindStoreX86PCRel32GOT:
+ case ld::Fixup::kindStoreX86PCRel32TLVLoad:
+ case ld::Fixup::kindStoreX86PCRel32TLVLoadNowLEA:
+ case ld::Fixup::kindStoreTargetAddressX86PCRel32:
+ case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoad:
+ case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoadNowLEA:
+ case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoad:
+ case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoadNowLEA:
+#if SUPPORT_ARCH_arm64
+ case ld::Fixup::kindStoreARM64PCRelToGOT:
+#endif
+ if ( (fromSectionIndex != toSectionIndex) || !codeSection )
+ kind = DYLD_CACHE_ADJ_V2_DELTA_32;
+ break;
+#if SUPPORT_ARCH_arm64
+ case ld::Fixup::kindStoreARM64Page21:
+ case ld::Fixup::kindStoreARM64GOTLoadPage21:
+ case ld::Fixup::kindStoreARM64GOTLeaPage21:
+ case ld::Fixup::kindStoreARM64TLVPLoadPage21:
+ case ld::Fixup::kindStoreTargetAddressARM64Page21:
+ case ld::Fixup::kindStoreTargetAddressARM64GOTLoadPage21:
+ case ld::Fixup::kindStoreTargetAddressARM64GOTLeaPage21:
+ if ( fromSectionIndex != toSectionIndex )
+ kind = DYLD_CACHE_ADJ_V2_ARM64_ADRP;
+ break;
+ case ld::Fixup::kindStoreARM64PageOff12:
+ case ld::Fixup::kindStoreARM64GOTLeaPageOff12:
+ case ld::Fixup::kindStoreARM64TLVPLoadNowLeaPageOff12:
+ case ld::Fixup::kindStoreTargetAddressARM64PageOff12:
+ case ld::Fixup::kindStoreTargetAddressARM64GOTLeaPageOff12:
+ case ld::Fixup::kindStoreTargetAddressARM64GOTLoadPageOff12:
+ case ld::Fixup::kindStoreTargetAddressARM64TLVPLoadPageOff12:
+ case ld::Fixup::kindStoreTargetAddressARM64TLVPLoadNowLeaPageOff12:
+ if ( fromSectionIndex != toSectionIndex )
+ kind = DYLD_CACHE_ADJ_V2_ARM64_OFF12;
+ break;
+ case ld::Fixup::kindStoreARM64Branch26:
+ case ld::Fixup::kindStoreTargetAddressARM64Branch26:
+ if ( fromSectionIndex != toSectionIndex )
+ kind = DYLD_CACHE_ADJ_V2_ARM64_BR26;
+ break;
+#endif
+ case ld::Fixup::kindStoreARMHigh16:
+ case ld::Fixup::kindStoreARMLow16:
+ if ( (fromSectionIndex != toSectionIndex) && (fromTarget == atom) ) {
+ kind = DYLD_CACHE_ADJ_V2_ARM_MOVW_MOVT;
+ }
+ break;
+ case ld::Fixup::kindStoreARMBranch24:
+ case ld::Fixup::kindStoreTargetAddressARMBranch24:
+ if ( fromSectionIndex != toSectionIndex )
+ kind = DYLD_CACHE_ADJ_V2_ARM_BR24;
+ break;
+ case ld::Fixup::kindStoreThumbLow16:
+ case ld::Fixup::kindStoreThumbHigh16:
+ if ( (fromSectionIndex != toSectionIndex) && (fromTarget == atom) ) {
+ kind = DYLD_CACHE_ADJ_V2_THUMB_MOVW_MOVT;
+ }
+ break;
+ case ld::Fixup::kindStoreThumbBranch22:
+ case ld::Fixup::kindStoreTargetAddressThumbBranch22:
+ if ( fromSectionIndex != toSectionIndex )
+ kind = DYLD_CACHE_ADJ_V2_THUMB_BR22;
+ break;
+ case ld::Fixup::kindSetTargetImageOffset:
+ kind = DYLD_CACHE_ADJ_V2_IMAGE_OFF_32;
+ accumulator = addressOf(state, fit, &target);
+ assert(target != NULL);
+ toSectionIndex = target->machoSection();
+ toOffset = accumulator - state.atomToSection[target]->address;
+ hadSubtract = true;
+ break;
+ default:
+ break;
+ }
+ if ( fit->lastInCluster() ) {
+ if ( (kind != 0) && (target != NULL) && (target->definition() != ld::Atom::definitionProxy) ) {
+ if ( !hadSubtract && addend )
+ toOffset += addend;
+ assert(toSectionIndex != 255);
+ if (log) fprintf(stderr, "from (%d.%s + 0x%llX) to (%d.%s + 0x%llX), kind=%d, atomAddr=0x%llX, sectAddr=0x%llx\n",
+ fromSectionIndex, sect->sectionName(), fromOffset, toSectionIndex, state.atomToSection[target]->sectionName(),
+ toOffset, kind, atom->finalAddress(), sect->address);
+ _splitSegV2Infos.push_back(SplitSegInfoV2Entry(fromSectionIndex, fromOffset, toSectionIndex, toOffset, kind));
+ }
+ }
+ }
+ }
+ }
+}
+