+static void buildAddressMap(const Options& opts, ld::Internal& state) {
+ // Assign addresses to sections
+ state.setSectionSizesAndAlignments();
+ state.assignFileOffsets();
+
+ // Assign addresses to atoms in a side table
+ const bool log = false;
+ if ( log ) fprintf(stderr, "buildAddressMap()\n");
+ for (std::vector<ld::Internal::FinalSection*>::iterator sit = state.sections.begin(); sit != state.sections.end(); ++sit) {
+ ld::Internal::FinalSection* sect = *sit;
+ uint16_t maxAlignment = 0;
+ uint64_t offset = 0;
+ if ( log ) fprintf(stderr, " section=%s/%s, address=0x%08llX\n", sect->segmentName(), 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;
+ uint32_t atomAlignmentPowerOf2 = atom->alignment().powerOf2;
+ uint32_t atomModulus = atom->alignment().modulus;
+ if ( atomAlignmentPowerOf2 > maxAlignment )
+ maxAlignment = atomAlignmentPowerOf2;
+ // calculate section offset for this atom
+ uint64_t alignment = 1 << atomAlignmentPowerOf2;
+ uint64_t currentModulus = (offset % alignment);
+ uint64_t requiredModulus = atomModulus;
+ if ( currentModulus != requiredModulus ) {
+ if ( requiredModulus > currentModulus )
+ offset += requiredModulus-currentModulus;
+ else
+ offset += requiredModulus+alignment-currentModulus;
+ }
+
+ if ( log ) fprintf(stderr, " 0x%08llX atom=%p, name=%s\n", sect->address+offset, atom, atom->name());
+ sAtomToAddress[atom] = sect->address + offset;
+
+ offset += atom->size();
+ }
+ }
+
+
+}
+
+void doPass(const Options& opts, ld::Internal& state)
+{
+ // only make branch islands in final linked images
+ if ( opts.outputKind() == Options::kObjectFile )
+ return;
+
+ // Allow user to disable branch island generation
+ if ( !opts.allowBranchIslands() )
+ return;
+
+ // only ARM[64] needs branch islands
+ switch ( opts.architecture() ) {
+ case CPU_TYPE_ARM:
+#if SUPPORT_ARCH_arm64
+ case CPU_TYPE_ARM64:
+#endif
+ break;
+ default:
+ return;
+ }
+
+ if ( opts.outputKind() == Options::kPreload ) {
+ buildAddressMap(opts, state);
+ }
+
+ // scan sections for number of stubs
+ unsigned stubCount = 0;
+ for (std::vector<ld::Internal::FinalSection*>::iterator sit=state.sections.begin(); sit != state.sections.end(); ++sit) {
+ ld::Internal::FinalSection* sect = *sit;
+ if ( sect->type() == ld::Section::typeStub )
+ stubCount = sect->atoms.size();
+ }
+
+ // scan sections and add island to each code section
+ for (std::vector<ld::Internal::FinalSection*>::iterator sit=state.sections.begin(); sit != state.sections.end(); ++sit) {
+ ld::Internal::FinalSection* sect = *sit;
+ if ( sect->type() == ld::Section::typeCode )
+ makeIslandsForSection(opts, state, sect, stubCount);
+ }
+}
+
+