X-Git-Url: https://git.saurik.com/apple/ld64.git/blobdiff_plain/eaf282aaf65b222563e6b3db98e12d720fb161bf..7f09b9353af9897bf18933788d6a59c152c29edd:/src/ld/LinkEditClassic.hpp diff --git a/src/ld/LinkEditClassic.hpp b/src/ld/LinkEditClassic.hpp index ee1c207..ce7c820 100644 --- a/src/ld/LinkEditClassic.hpp +++ b/src/ld/LinkEditClassic.hpp @@ -669,39 +669,18 @@ bool SymbolTableAtom::hasStabs(uint32_t& ssos, uint32_t& ssoe, uint32_t& sos, template void SymbolTableAtom::encode() { - uint32_t symbolIndex = 0; + // Note: We lay out the symbol table so that the strings for the stabs (local) symbols are at the + // end of the string pool. The stabs strings are not used when calculated the UUID for the image. + // If the stabs strings were not last, the string offsets for all other symbols may very which would alter the UUID. - // make nlist entries for all local symbols - std::vector& localAtoms = this->_writer._localAtoms; - std::vector& globalAtoms = this->_writer._exportedAtoms; - _locals.reserve(localAtoms.size()+this->_state.stabs.size()); - this->_writer._localSymbolsStartIndex = 0; - // make nlist entries for all debug notes - _stabsIndexStart = symbolIndex; - _stabsStringsOffsetStart = this->_writer._stringPoolAtom->currentOffset(); - for (std::vector::const_iterator sit=this->_state.stabs.begin(); sit != this->_state.stabs.end(); ++sit) { - macho_nlist

entry; - entry.set_n_type(sit->type); - entry.set_n_sect(sectionIndexForStab(*sit)); - entry.set_n_desc(sit->desc); - entry.set_n_value(valueForStab(*sit)); - entry.set_n_strx(stringOffsetForStab(*sit, this->_writer._stringPoolAtom)); - _locals.push_back(entry); - ++symbolIndex; - } - _stabsIndexEnd = symbolIndex; - _stabsStringsOffsetEnd = this->_writer._stringPoolAtom->currentOffset(); - for (std::vector::const_iterator it=localAtoms.begin(); it != localAtoms.end(); ++it) { - const ld::Atom* atom = *it; - if ( this->addLocal(atom, this->_writer._stringPoolAtom) ) - this->_writer._atomToSymbolIndex[atom] = symbolIndex++; - } - this->_writer._localSymbolsCount = symbolIndex; - + // reserve space for local symbols + uint32_t localsCount = _state.stabs.size() + this->_writer._localAtoms.size(); // make nlist entries for all global symbols + std::vector& globalAtoms = this->_writer._exportedAtoms; _globals.reserve(globalAtoms.size()); - this->_writer._globalSymbolsStartIndex = symbolIndex; + uint32_t symbolIndex = localsCount; + this->_writer._globalSymbolsStartIndex = localsCount; for (std::vector::const_iterator it=globalAtoms.begin(); it != globalAtoms.end(); ++it) { const ld::Atom* atom = *it; this->addGlobal(atom, this->_writer._stringPoolAtom); @@ -718,6 +697,31 @@ void SymbolTableAtom::encode() this->_writer._atomToSymbolIndex[*it] = symbolIndex++; } this->_writer._importSymbolsCount = symbolIndex - this->_writer._importSymbolsStartIndex; + + // go back to start and make nlist entries for all local symbols + std::vector& localAtoms = this->_writer._localAtoms; + _locals.reserve(localsCount); + symbolIndex = 0; + this->_writer._localSymbolsStartIndex = 0; + _stabsIndexStart = 0; + _stabsStringsOffsetStart = this->_writer._stringPoolAtom->currentOffset(); + for (const ld::relocatable::File::Stab& stab : _state.stabs) { + macho_nlist

entry; + entry.set_n_type(stab.type); + entry.set_n_sect(sectionIndexForStab(stab)); + entry.set_n_desc(stab.desc); + entry.set_n_value(valueForStab(stab)); + entry.set_n_strx(stringOffsetForStab(stab, this->_writer._stringPoolAtom)); + _locals.push_back(entry); + ++symbolIndex; + } + _stabsIndexEnd = symbolIndex; + _stabsStringsOffsetEnd = this->_writer._stringPoolAtom->currentOffset(); + for (const ld::Atom* atom : localAtoms) { + if ( this->addLocal(atom, this->_writer._stringPoolAtom) ) + this->_writer._atomToSymbolIndex[atom] = symbolIndex++; + } + this->_writer._localSymbolsCount = symbolIndex; } template @@ -2002,7 +2006,6 @@ private: uint32_t symIndexOfLazyPointerAtom(const ld::Atom*); uint32_t symIndexOfNonLazyPointerAtom(const ld::Atom*); uint32_t symbolIndex(const ld::Atom*); - bool kextBundlesDontHaveIndirectSymbolTable(); std::vector _entries; @@ -2034,9 +2037,11 @@ uint32_t IndirectSymbolTableAtom::symIndexOfStubAtom(const ld::Atom* stubAtom { for (ld::Fixup::iterator fit = stubAtom->fixupsBegin(); fit != stubAtom->fixupsEnd(); ++fit) { if ( fit->binding == ld::Fixup::bindingDirectlyBound ) { - assert((fit->u.target->contentType() == ld::Atom::typeLazyPointer) - || (fit->u.target->contentType() == ld::Atom::typeLazyDylibPointer)); - return symIndexOfLazyPointerAtom(fit->u.target); + ld::Atom::ContentType type = fit->u.target->contentType(); + if (( type == ld::Atom::typeLazyPointer) || (type == ld::Atom::typeLazyDylibPointer) ) + return symIndexOfLazyPointerAtom(fit->u.target); + if ( type == ld::Atom::typeNonLazyPointer ) + return symIndexOfNonLazyPointerAtom(fit->u.target); } } throw "internal error: stub missing fixup to lazy pointer"; @@ -2152,12 +2157,6 @@ void IndirectSymbolTableAtom::encodeNonLazyPointerSection(ld::Internal::Final } } -template -bool IndirectSymbolTableAtom::kextBundlesDontHaveIndirectSymbolTable() -{ - return true; -} - template void IndirectSymbolTableAtom::encode() { @@ -2165,8 +2164,8 @@ void IndirectSymbolTableAtom::encode() if ( (this->_options.outputKind() == Options::kStaticExecutable) && !_options.positionIndependentExecutable() ) return; - // x86_64 kext bundles should not have an indirect symbol table - if ( (this->_options.outputKind() == Options::kKextBundle) && kextBundlesDontHaveIndirectSymbolTable() ) + // x86_64 kext bundles should not have an indirect symbol table unless using stubs + if ( (this->_options.outputKind() == Options::kKextBundle) && !this->_options.kextsUseStubs() ) return; // slidable static executables (-static -pie) should not have an indirect symbol table