X-Git-Url: https://git.saurik.com/apple/ld64.git/blobdiff_plain/e667b16e39593d19d0e25a8440a563eac3572653..2a0ed0a31db9961dcb7c87964091b22401c4d69b:/src/ld/passes/branch_island.cpp diff --git a/src/ld/passes/branch_island.cpp b/src/ld/passes/branch_island.cpp index a8fb325..65e3cf2 100644 --- a/src/ld/passes/branch_island.cpp +++ b/src/ld/passes/branch_island.cpp @@ -389,7 +389,7 @@ static uint64_t maxDistanceBetweenIslands(const Options& opts, bool seenThumbBra // -static void makeIslandsForSection(const Options& opts, ld::Internal& state, ld::Internal::FinalSection* textSection) +static void makeIslandsForSection(const Options& opts, ld::Internal& state, ld::Internal::FinalSection* textSection, unsigned stubCount) { // assign section offsets to each atom in __text section, watch for thumb branches, and find total size bool hasThumbBranches = false; @@ -448,7 +448,7 @@ static void makeIslandsForSection(const Options& opts, ld::Internal& state, ld:: (const_cast(atom))->setSectionOffset(offset); offset += atom->size(); } - uint64_t totalTextSize = offset; + uint64_t totalTextSize = offset + stubCount*16; if ( (totalTextSize < textSizeWhenMightNeedBranchIslands(opts, hasThumbBranches)) && !haveCrossSectionBranches ) return; if (_s_log) fprintf(stderr, "ld: section %s size=%llu, might need branch islands\n", textSection->sectionName(), totalTextSize); @@ -552,7 +552,7 @@ static void makeIslandsForSection(const Options& opts, ld::Internal& state, ld:: if ( target->section().type() == ld::Section::typeStub ) dstAddr = totalTextSize; int64_t displacement = dstAddr - srcAddr; - TargetAndOffset finalTargetAndOffset = { target, addend }; + TargetAndOffset finalTargetAndOffset = { target, (uint32_t)addend }; const int64_t kBranchLimit = kBetweenRegions; if ( crossSectionBranch && ((displacement > kBranchLimit) || (displacement < (-kBranchLimit))) ) { const ld::Atom* island; @@ -565,6 +565,7 @@ static void makeIslandsForSection(const Options& opts, ld::Internal& state, ld:: island, island->name(), displacement); ++islandCount; regionsIslands[0]->push_back(island); + state.atomToSection[island] = textSection; } else { island = pos->second; @@ -588,6 +589,7 @@ static void makeIslandsForSection(const Options& opts, ld::Internal& state, ld:: (*region)[finalTargetAndOffset] = island; if (_s_log) fprintf(stderr, "added forward branching island %p %s to region %d for %s\n", island, island->name(), i, atom->name()); regionsIslands[i]->push_back(island); + state.atomToSection[island] = textSection; ++islandCount; nextTarget = island; } @@ -614,6 +616,7 @@ static void makeIslandsForSection(const Options& opts, ld::Internal& state, ld:: (*region)[finalTargetAndOffset] = island; if (_s_log) fprintf(stderr, "added back branching island %p %s to region %d for %s\n", island, island->name(), i, atom->name()); regionsIslands[i]->push_back(island); + state.atomToSection[island] = textSection; ++islandCount; prevTarget = island; } @@ -720,11 +723,19 @@ void doPass(const Options& opts, ld::Internal& state) buildAddressMap(opts, state); } + // scan sections for number of stubs + unsigned stubCount = 0; + for (std::vector::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::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); + makeIslandsForSection(opts, state, sect, stubCount); } }