X-Git-Url: https://git.saurik.com/apple/ld64.git/blobdiff_plain/b1c6f52afb9f246c71bc8c8c57a268f11d0895e5..f410558f5d60087e4c310119a1751b437121c3b9:/src/ld/SymbolTable.cpp diff --git a/src/ld/SymbolTable.cpp b/src/ld/SymbolTable.cpp index 3c12a77..e12c1e4 100644 --- a/src/ld/SymbolTable.cpp +++ b/src/ld/SymbolTable.cpp @@ -860,6 +860,41 @@ const ld::Atom* SymbolTable::indirectAtom(IndirectBindingSlot slot) const return _indirectBindingTable[slot]; } + +void SymbolTable::removeDeadUndefs(std::vector& allAtoms, const std::unordered_set& keep) +{ + // mark the indirect entries in use + std::vector indirectUsed; + for (size_t i=0; i < _indirectBindingTable.size(); ++i) + indirectUsed.push_back(false); + for (const ld::Atom* atom : allAtoms) { + for (auto it = atom->fixupsBegin(); it != atom->fixupsEnd(); ++it) { + switch (it->binding) { + case ld::Fixup::bindingsIndirectlyBound: + indirectUsed[it->u.bindingIndex] = true; + break; + default: + break; + } + } + } + + // any indirect entry not in use which points to an undefined proxy can be removed + for (size_t slot=0; slot < indirectUsed.size(); ++slot) { + if ( !indirectUsed[slot] ) { + const ld::Atom* atom = _indirectBindingTable[slot]; + if ( (atom != nullptr) && (atom->definition() == ld::Atom::definitionProxy) && (keep.count(atom) == 0) ) { + const char* name = atom->name(); + _indirectBindingTable[slot] = NULL; + _byNameReverseTable.erase(slot); + _byNameTable.erase(name); + allAtoms.erase(std::remove(allAtoms.begin(), allAtoms.end(), atom), allAtoms.end()); + } + } + } + +} + void SymbolTable::printStatistics() { // fprintf(stderr, "cstring table size: %lu, bucket count: %lu, hash func called %u times\n",