]> git.saurik.com Git - apple/ld64.git/blobdiff - src/ld/LinkEditClassic.hpp
ld64-274.2.tar.gz
[apple/ld64.git] / src / ld / LinkEditClassic.hpp
index 3389f5ce69e4c8cc440377aa455e7c2859827c17..ce7c8201ec69ea5756ca7c69a21fc7d7e2107899 100644 (file)
@@ -669,39 +669,18 @@ bool SymbolTableAtom<A>::hasStabs(uint32_t& ssos, uint32_t& ssoe, uint32_t& sos,
 template <typename A>
 void SymbolTableAtom<A>::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<const ld::Atom*>& localAtoms = this->_writer._localAtoms;
-       std::vector<const ld::Atom*>& 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<ld::relocatable::File::Stab>::const_iterator sit=this->_state.stabs.begin(); sit != this->_state.stabs.end(); ++sit) {
-               macho_nlist<P> 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 ld::Atom*>::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<const ld::Atom*>& globalAtoms = this->_writer._exportedAtoms;
        _globals.reserve(globalAtoms.size());
-       this->_writer._globalSymbolsStartIndex = symbolIndex;
+       uint32_t symbolIndex = localsCount;
+       this->_writer._globalSymbolsStartIndex = localsCount;
        for (std::vector<const ld::Atom*>::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<A>::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<const ld::Atom*>& 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<P> 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 <typename A>
@@ -1614,9 +1618,17 @@ void SectionRelocationsAtom<arm>::encodeSectionReloc(ld::Internal::FinalSection*
                        {
                                int len = 0;
                                uint32_t otherHalf = 0;
-                               uint32_t value = entry.toTarget->finalAddress()+entry.toAddend;
-                               if ( entry.fromTarget != NULL ) 
-                                       value -= (entry.fromTarget->finalAddress()+entry.fromAddend);
+                               uint32_t value;
+                               if ( entry.fromTarget != NULL )  {
+                                 // this is a sect-diff
+                                 value = (entry.toTarget->finalAddress()+entry.toAddend) - (entry.fromTarget->finalAddress()+entry.fromAddend);
+                               }
+                               else {
+                                       // this is an absolute address
+                                       value = entry.toAddend;
+                                       if ( !external )
+                                               value += entry.toTarget->finalAddress();
+                               }
                                switch ( entry.kind ) {
                                        case ld::Fixup::kindStoreARMLow16:
                                                len = 0;
@@ -1994,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<uint32_t>                                           _entries;
@@ -2026,9 +2037,11 @@ uint32_t IndirectSymbolTableAtom<A>::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";
@@ -2144,12 +2157,6 @@ void IndirectSymbolTableAtom<A>::encodeNonLazyPointerSection(ld::Internal::Final
        }
 }
 
-template <typename A>
-bool IndirectSymbolTableAtom<A>::kextBundlesDontHaveIndirectSymbolTable()
-{
-       return true;    
-}
-
 template <typename A>
 void IndirectSymbolTableAtom<A>::encode()
 {
@@ -2157,8 +2164,8 @@ void IndirectSymbolTableAtom<A>::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