X-Git-Url: https://git.saurik.com/apple/ld64.git/blobdiff_plain/9543cb2f21e50a417dc8cf37eb7173f353536979..7f09b9353af9897bf18933788d6a59c152c29edd:/src/ld/passes/order.cpp diff --git a/src/ld/passes/order.cpp b/src/ld/passes/order.cpp index 684cb79..a7d31f3 100644 --- a/src/ld/passes/order.cpp +++ b/src/ld/passes/order.cpp @@ -78,10 +78,11 @@ private: class Comparer { public: - Comparer(const Layout& l) : _layout(l) {} + Comparer(const Layout& l, ld::Internal& s) : _layout(l), _state(s) {} bool operator()(const ld::Atom* left, const ld::Atom* right); private: const Layout& _layout; + ld::Internal& _state; }; typedef std::unordered_map NameToAtom; @@ -114,7 +115,7 @@ private: bool Layout::_s_log = false; Layout::Layout(const Options& opts, ld::Internal& state) - : _options(opts), _state(state), _comparer(*this), _haveOrderFile(opts.orderedSymbolsCount() != 0) + : _options(opts), _state(state), _comparer(*this, state), _haveOrderFile(opts.orderedSymbolsCount() != 0) { } @@ -167,11 +168,21 @@ bool Layout::Comparer::operator()(const ld::Atom* left, const ld::Atom* right) bool leftIsAlias = left->isAlias(); if ( leftIsAlias ) { for (ld::Fixup::iterator fit=left->fixupsBegin(); fit != left->fixupsEnd(); ++fit) { + const ld::Atom* target = NULL; if ( fit->kind == ld::Fixup::kindNoneFollowOn ) { - assert(fit->binding == ld::Fixup::bindingDirectlyBound); - if ( fit->u.target == right ) + switch ( fit->binding ) { + case ld::Fixup::bindingsIndirectlyBound: + target = _state.indirectBindingTable[fit->u.bindingIndex]; + break; + case ld::Fixup::bindingDirectlyBound: + target = fit->u.target; + break; + default: + break; + } + if ( target == right ) return true; // left already before right - left = fit->u.target; // sort as if alias was its target + left = target; // sort as if alias was its target break; } } @@ -179,11 +190,21 @@ bool Layout::Comparer::operator()(const ld::Atom* left, const ld::Atom* right) bool rightIsAlias = right->isAlias(); if ( rightIsAlias ) { for (ld::Fixup::iterator fit=right->fixupsBegin(); fit != right->fixupsEnd(); ++fit) { + const ld::Atom* target = NULL; if ( fit->kind == ld::Fixup::kindNoneFollowOn ) { - assert(fit->binding == ld::Fixup::bindingDirectlyBound); - if ( fit->u.target == left ) + switch ( fit->binding ) { + case ld::Fixup::bindingsIndirectlyBound: + target = _state.indirectBindingTable[fit->u.bindingIndex]; + break; + case ld::Fixup::bindingDirectlyBound: + target = fit->u.target; + break; + default: + break; + } + if ( target == left ) return false; // need to swap, alias is after target - right = fit->u.target; // continue with sort as if right was target + right = target; // continue with sort as if right was target break; } } @@ -489,8 +510,14 @@ void Layout::buildOrdinalOverrideMap() switch ( atom->section().type() ) { case ld::Section::typeZeroFill: case ld::Section::typeTentativeDefs: - if ( atom->size() <= 512 ) - moveToData.insert(atom); + if ( atom->size() <= 512 ) { + const char* dstSeg; + bool wildCardMatch; + const ld::File* f = atom->file(); + const char* path = (f != NULL) ? f->path() : NULL; + if ( !_options.moveRwSymbol(atom->name(), path, dstSeg, wildCardMatch) ) + moveToData.insert(atom); + } break; default: break; @@ -558,6 +585,10 @@ void Layout::buildOrdinalOverrideMap() break; } } + // update atom-to-section map + for (std::set::iterator it=moveToData.begin(); it != moveToData.end(); ++it) { + _state.atomToSection[*it] = dataSect; + } } } @@ -565,6 +596,18 @@ void Layout::buildOrdinalOverrideMap() void Layout::doPass() { + const bool log = false; + if ( log ) { + fprintf(stderr, "Unordered atoms:\n"); + for (std::vector::iterator sit=_state.sections.begin(); sit != _state.sections.end(); ++sit) { + ld::Internal::FinalSection* sect = *sit; + for (std::vector::iterator ait=sect->atoms.begin(); ait != sect->atoms.end(); ++ait) { + const ld::Atom* atom = *ait; + fprintf(stderr, "\t%p\t%s\t%s\n", atom, sect->sectionName(), atom->name()); + } + } + } + // handle .o files that cannot have their atoms rearranged this->buildFollowOnTables(); @@ -574,19 +617,22 @@ void Layout::doPass() // sort atoms in each section for (std::vector::iterator sit=_state.sections.begin(); sit != _state.sections.end(); ++sit) { ld::Internal::FinalSection* sect = *sit; - //fprintf(stderr, "sorting section %s\n", sect->sectionName()); + if ( sect->type() == ld::Section::typeTempAlias ) + continue; + if ( log ) fprintf(stderr, "sorting section %s\n", sect->sectionName()); std::sort(sect->atoms.begin(), sect->atoms.end(), _comparer); } - //fprintf(stderr, "Sorted atoms:\n"); - //for (std::vector::iterator sit=_state.sections.begin(); sit != _state.sections.end(); ++sit) { - // ld::Internal::FinalSection* sect = *sit; - // for (std::vector::iterator ait=sect->atoms.begin(); ait != sect->atoms.end(); ++ait) { - // const ld::Atom* atom = *ait; - // fprintf(stderr, "\t%p\t%s\t%s\n", atom, sect->sectionName(), atom->name()); - // } - //} - + if ( log ) { + fprintf(stderr, "Sorted atoms:\n"); + for (std::vector::iterator sit=_state.sections.begin(); sit != _state.sections.end(); ++sit) { + ld::Internal::FinalSection* sect = *sit; + for (std::vector::iterator ait=sect->atoms.begin(); ait != sect->atoms.end(); ++ait) { + const ld::Atom* atom = *ait; + fprintf(stderr, "\t%p\t%s\t%s\n", atom, sect->sectionName(), atom->name()); + } + } + } }