X-Git-Url: https://git.saurik.com/apple/ld64.git/blobdiff_plain/f80fe69f3f29962e8aa43a99f8ed9201548f3d78..ec29ba20dfd4abc0cb74366b39dda06af136e073:/src/ld/passes/order.cpp diff --git a/src/ld/passes/order.cpp b/src/ld/passes/order.cpp index af73d66..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; @@ -531,22 +558,36 @@ void Layout::buildOrdinalOverrideMap() warning("only %u out of %lu order_file symbols were applicable", matchCount, _options.orderedSymbolsCount() ); } - // When order file used on data, turn ordered zero fill symbols into zeroed data if ( ! moveToData.empty() ) { + // only move zero fill symbols to __data if there is a __data section + ld::Internal::FinalSection* dataSect = NULL; for (std::vector::iterator sit=_state.sections.begin(); sit != _state.sections.end(); ++sit) { ld::Internal::FinalSection* sect = *sit; - switch ( sect->type() ) { - case ld::Section::typeZeroFill: - case ld::Section::typeTentativeDefs: - sect->atoms.erase(std::remove_if(sect->atoms.begin(), sect->atoms.end(), InSet(moveToData)), sect->atoms.end()); - break; - case ld::Section::typeUnclassified: - if ( (strcmp(sect->sectionName(), "__data") == 0) && (strcmp(sect->segmentName(), "__DATA") == 0) ) - sect->atoms.insert(sect->atoms.end(), moveToData.begin(), moveToData.end()); - break; - default: - break; + if ( sect->type() == ld::Section::typeUnclassified ) { + if ( (strcmp(sect->sectionName(), "__data") == 0) && (strcmp(sect->segmentName(), "__DATA") == 0) ) + dataSect = sect; + } + } + + if ( dataSect != NULL ) { + // add atoms to __data + dataSect->atoms.insert(dataSect->atoms.end(), moveToData.begin(), moveToData.end()); + // remove atoms from original sections + for (std::vector::iterator sit=_state.sections.begin(); sit != _state.sections.end(); ++sit) { + ld::Internal::FinalSection* sect = *sit; + switch ( sect->type() ) { + case ld::Section::typeZeroFill: + case ld::Section::typeTentativeDefs: + sect->atoms.erase(std::remove_if(sect->atoms.begin(), sect->atoms.end(), InSet(moveToData)), sect->atoms.end()); + break; + default: + break; + } + } + // update atom-to-section map + for (std::set::iterator it=moveToData.begin(); it != moveToData.end(); ++it) { + _state.atomToSection[*it] = dataSect; } } } @@ -555,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(); @@ -564,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()); + } + } + } }