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<const char*, const ld::Atom*, CStringHash, CStringEquals> NameToAtom;
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)
{
}
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;
}
}
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;
}
}
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;
warning("only %u out of %lu order_file symbols were applicable", matchCount, _options.orderedSymbolsCount() );
}
-
// <rdar://problem/8612550> When order file used on data, turn ordered zero fill symbols into zeroed data
if ( ! moveToData.empty() ) {
+ // <rdar://problem/14919139> only move zero fill symbols to __data if there is a __data section
+ ld::Internal::FinalSection* dataSect = NULL;
for (std::vector<ld::Internal::FinalSection*>::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<ld::Internal::FinalSection*>::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<const ld::Atom*>::iterator it=moveToData.begin(); it != moveToData.end(); ++it) {
+ _state.atomToSection[*it] = dataSect;
}
}
}
void Layout::doPass()
{
+ const bool log = false;
+ if ( log ) {
+ fprintf(stderr, "Unordered atoms:\n");
+ for (std::vector<ld::Internal::FinalSection*>::iterator sit=_state.sections.begin(); sit != _state.sections.end(); ++sit) {
+ ld::Internal::FinalSection* sect = *sit;
+ for (std::vector<const ld::Atom*>::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();
// sort atoms in each section
for (std::vector<ld::Internal::FinalSection*>::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<ld::Internal::FinalSection*>::iterator sit=_state.sections.begin(); sit != _state.sections.end(); ++sit) {
- // ld::Internal::FinalSection* sect = *sit;
- // for (std::vector<const ld::Atom*>::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<ld::Internal::FinalSection*>::iterator sit=_state.sections.begin(); sit != _state.sections.end(); ++sit) {
+ ld::Internal::FinalSection* sect = *sit;
+ for (std::vector<const ld::Atom*>::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());
+ }
+ }
+ }
}