X-Git-Url: https://git.saurik.com/apple/ld64.git/blobdiff_plain/f80fe69f3f29962e8aa43a99f8ed9201548f3d78..c1f6aec514f7e3059b9613d90f479f494f19f7bb:/src/ld/SymbolTable.cpp diff --git a/src/ld/SymbolTable.cpp b/src/ld/SymbolTable.cpp index 309de8b..3c12a77 100644 --- a/src/ld/SymbolTable.cpp +++ b/src/ld/SymbolTable.cpp @@ -132,7 +132,7 @@ void SymbolTable::addDuplicateSymbol(const char *name, const ld::Atom *atom) // check if file is already in the list, add it if not bool found = false; for (DuplicatedSymbolAtomList::iterator it = atoms->begin(); !found && it != atoms->end(); it++) - if (strcmp((*it)->file()->path(), atom->file()->path()) == 0) + if (strcmp((*it)->safeFilePath(), atom->safeFilePath()) == 0) found = true; if (!found) atoms->push_back(atom); @@ -158,7 +158,7 @@ void SymbolTable::checkDuplicateSymbols() const foundDuplicate = true; fprintf(stderr, "duplicate symbol %s in:\n", symbolIt->first); for (DuplicatedSymbolAtomList::iterator atomIt = atoms->begin(); atomIt != atoms->end(); atomIt++) { - fprintf(stderr, " %s\n", (*atomIt)->file()->path()); + fprintf(stderr, " %s\n", (*atomIt)->safeFilePath()); } } } @@ -284,18 +284,18 @@ private: case Options::kCommonsIgnoreDylibs: if ( _options.warnCommons() ) warning("using common symbol %s from %s and ignoring defintion from dylib %s", - proxy.name(), proxy.file()->path(), dylib.file()->path()); + proxy.name(), proxy.safeFilePath(), dylib.safeFilePath()); pickAtom(dylib); break; case Options::kCommonsOverriddenByDylibs: if ( _options.warnCommons() ) warning("replacing common symbol %s from %s with true definition from dylib %s", - proxy.name(), proxy.file()->path(), dylib.file()->path()); + proxy.name(), proxy.safeFilePath(), dylib.safeFilePath()); pickAtom(proxy); break; case Options::kCommonsConflictsDylibsError: throwf("common symbol %s from %s conflicts with defintion from dylib %s", - proxy.name(), proxy.file()->path(), dylib.file()->path()); + proxy.name(), proxy.safeFilePath(), dylib.safeFilePath()); } } @@ -307,7 +307,7 @@ private: } else if ( _atomB.combine() == ld::Atom::combineByName ) { pickAtomA(); } else { - throwf("symbol %s exported from both %s and %s\n", _atomA.name(), _atomA.file()->path(), _atomB.file()->path()); + throwf("symbol %s exported from both %s and %s\n", _atomA.name(), _atomA.safeFilePath(), _atomB.safeFilePath()); } } @@ -322,10 +322,8 @@ private: break; case ld::Atom::definitionTentative: if ( _atomB.size() > _atomA.size() ) { - const char* atomApath = (_atomA.file() != NULL) ? _atomA.file()->path() : ""; - const char* atomBpath = (_atomB.file() != NULL) ? _atomB.file()->path() : ""; warning("tentative definition of '%s' with size %llu from '%s' is being replaced by real definition of smaller size %llu from '%s'", - _atomA.name(), _atomB.size(), atomBpath, _atomA.size(), atomApath); + _atomA.name(), _atomB.size(), _atomB.safeFilePath(), _atomA.size(), _atomA.safeFilePath()); } pickAtomA(); break; @@ -342,10 +340,8 @@ private: switch (_atomB.definition()) { case ld::Atom::definitionRegular: if ( _atomA.size() > _atomB.size() ) { - const char* atomApath = (_atomA.file() != NULL) ? _atomA.file()->path() : ""; - const char* atomBpath = (_atomB.file() != NULL) ? _atomB.file()->path() : ""; warning("tentative definition of '%s' with size %llu from '%s' is being replaced by real definition of smaller size %llu from '%s'", - _atomA.name(), _atomA.size(),atomApath, _atomB.size(), atomBpath); + _atomA.name(), _atomA.size(),_atomA.safeFilePath(), _atomB.size(), _atomB.safeFilePath()); } pickAtomB(); break; @@ -505,7 +501,7 @@ bool SymbolTable::add(const ld::Atom& atom, bool ignoreDuplicates) void SymbolTable::markCoalescedAway(const ld::Atom* atom) { // remove this from list of all atoms used - //fprintf(stderr, "markCoalescedAway(%p) from %s\n", atom, atom->file()->path()); + //fprintf(stderr, "markCoalescedAway(%p) from %s\n", atom, atom->safeFilePath()); (const_cast(atom))->setCoalescedAway(); // @@ -566,6 +562,18 @@ void SymbolTable::tentativeDefs(std::vector& tents) } +void SymbolTable::mustPreserveForBitcode(std::unordered_set& syms) +{ + // return all names in _byNameTable that have no associated atom + for (const auto &entry: _byNameTable) { + const char* name = entry.first; + const ld::Atom* atom = _indirectBindingTable[entry.second]; + if ( (atom == NULL) || (atom->definition() == ld::Atom::definitionProxy) ) + syms.insert(name); + } +} + + bool SymbolTable::hasName(const char* name) { NameToSlot::iterator pos = _byNameTable.find(name); @@ -588,6 +596,99 @@ SymbolTable::IndirectBindingSlot SymbolTable::findSlotForName(const char* name) return slot; } +void SymbolTable::removeDeadAtoms() +{ + // remove dead atoms from: _byNameTable, _byNameReverseTable, and _indirectBindingTable + std::vector namesToRemove; + for (NameToSlot::iterator it=_byNameTable.begin(); it != _byNameTable.end(); ++it) { + IndirectBindingSlot slot = it->second; + const ld::Atom* atom = _indirectBindingTable[slot]; + if ( atom != NULL ) { + if ( !atom->live() && !atom->dontDeadStrip() ) { + //fprintf(stderr, "removing from symbolTable[%u] %s\n", slot, atom->name()); + _indirectBindingTable[slot] = NULL; + // need to completely remove dead atoms from symbol table + _byNameReverseTable.erase(slot); + // can't remove while iterating, do it after iteration + namesToRemove.push_back(it->first); + } + } + } + for (std::vector::iterator it = namesToRemove.begin(); it != namesToRemove.end(); ++it) { + _byNameTable.erase(*it); + } + + // remove dead atoms from _nonLazyPointerTable + for (ReferencesToSlot::iterator it=_nonLazyPointerTable.begin(); it != _nonLazyPointerTable.end(); ) { + const ld::Atom* atom = it->first; + assert(atom != NULL); + if ( !atom->live() && !atom->dontDeadStrip() ) + it = _nonLazyPointerTable.erase(it); + else + ++it; + } + + // remove dead atoms from _cstringTable + for (CStringToSlot::iterator it=_cstringTable.begin(); it != _cstringTable.end(); ) { + const ld::Atom* atom = it->first; + assert(atom != NULL); + if ( !atom->live() && !atom->dontDeadStrip() ) + it = _cstringTable.erase(it); + else + ++it; + } + + // remove dead atoms from _utf16Table + for (UTF16StringToSlot::iterator it=_utf16Table.begin(); it != _utf16Table.end(); ) { + const ld::Atom* atom = it->first; + assert(atom != NULL); + if ( !atom->live() && !atom->dontDeadStrip() ) + it = _utf16Table.erase(it); + else + ++it; + } + + // remove dead atoms from _cfStringTable + for (ReferencesToSlot::iterator it=_cfStringTable.begin(); it != _cfStringTable.end(); ) { + const ld::Atom* atom = it->first; + assert(atom != NULL); + if ( !atom->live() && !atom->dontDeadStrip() ) + it = _cfStringTable.erase(it); + else + ++it; + } + + // remove dead atoms from _literal4Table + for (ContentToSlot::iterator it=_literal4Table.begin(); it != _literal4Table.end(); ) { + const ld::Atom* atom = it->first; + assert(atom != NULL); + if ( !atom->live() && !atom->dontDeadStrip() ) + it = _literal4Table.erase(it); + else + ++it; + } + + // remove dead atoms from _literal8Table + for (ContentToSlot::iterator it=_literal8Table.begin(); it != _literal8Table.end(); ) { + const ld::Atom* atom = it->first; + assert(atom != NULL); + if ( !atom->live() && !atom->dontDeadStrip() ) + it = _literal8Table.erase(it); + else + ++it; + } + + // remove dead atoms from _literal16Table + for (ContentToSlot::iterator it=_literal16Table.begin(); it != _literal16Table.end(); ) { + const ld::Atom* atom = it->first; + assert(atom != NULL); + if ( !atom->live() && !atom->dontDeadStrip() ) + it = _literal16Table.erase(it); + else + ++it; + } +} + // find existing or create new slot SymbolTable::IndirectBindingSlot SymbolTable::findSlotForContent(const ld::Atom* atom, const ld::Atom** existingAtom) @@ -720,6 +821,15 @@ SymbolTable::IndirectBindingSlot SymbolTable::findSlotForReferences(const ld::At slot = _indirectBindingTable.size(); _pointerToCStringTable[atom] = slot; break; + case ld::Section::typeTLVPointers: + pos = _threadPointerTable.find(atom); + if ( pos != _threadPointerTable.end() ) { + *existingAtom = _indirectBindingTable[pos->second]; + return pos->second; + } + slot = _indirectBindingTable.size(); + _threadPointerTable[atom] = slot; + break; default: assert(0 && "section type does not support coalescing by references"); } @@ -779,7 +889,7 @@ void SymbolTable::printStatistics() //ReferencesHash obj; //for(ReferencesHashToSlot::iterator it=_byReferencesTable.begin(); it != _byReferencesTable.end(); ++it) { // if ( obj.operator()(it->first) == 0x2F3AC0EAC744EA70 ) { - // fprintf(stderr, "hash=0x2F3AC0EAC744EA70 for %p %s from %s\n", it->first, it->first->name(), it->first->file()->path()); + // fprintf(stderr, "hash=0x2F3AC0EAC744EA70 for %p %s from %s\n", it->first, it->first->name(), it->first->safeFilePath()); // // } //}