--- src/ld/InputFiles.cpp 2014-04-04 15:42:29.000000000 -0700 +++ src/ld/InputFiles.cpp 2014-05-16 14:28:58.000000000 -0700 @@ -50,6 +50,8 @@ #include #include #include +#include +#include #include #include --- src/ld/InputFiles.h 2014-04-04 15:42:29.000000000 -0700 +++ src/ld/InputFiles.h 2014-05-16 14:28:58.000000000 -0700 @@ -107,7 +107,11 @@ private: static void parseWorkerThread(InputFiles *inputFiles); void startThread(void (*threadFunc)(InputFiles *)) const; - typedef std::unordered_map InstallNameToDylib; + class CStringEquals { + public: + bool operator()(const char* left, const char* right) const { return (strcmp(left, right) == 0); } + }; + typedef __gnu_cxx::hash_map, CStringEquals> InstallNameToDylib; const Options& _options; std::vector _inputFiles; --- src/ld/LinkEditClassic.hpp 2014-04-04 15:42:29.000000000 -0700 +++ src/ld/LinkEditClassic.hpp 2014-05-16 14:28:58.000000000 -0700 @@ -32,7 +32,6 @@ #include #include -#include #include "Options.h" #include "ld.hpp" @@ -91,8 +90,13 @@ public: uint32_t currentOffset(); private: + class CStringEquals + { + public: + bool operator()(const char* left, const char* right) const { return (strcmp(left, right) == 0); } + }; enum { kBufferSize = 0x01000000 }; - typedef std::unordered_map StringToOffset; + typedef __gnu_cxx::hash_map, CStringEquals> StringToOffset; const uint32_t _pointerSize; std::vector _fullBuffers; --- src/ld/Options.h 2014-04-04 15:42:29.000000000 -0700 +++ src/ld/Options.h 2014-05-16 14:28:58.000000000 -0700 @@ -30,8 +30,8 @@ #include #include -#include -#include +#include +#include #include "ld.hpp" #include "Snapshot.h" @@ -376,8 +376,13 @@ public: const std::vector& sectionRenames() const { return fSectionRenames; } private: - typedef std::unordered_map NameToOrder; - typedef std::unordered_set NameSet; + class CStringEquals + { + public: + bool operator()(const char* left, const char* right) const { return (strcmp(left, right) == 0); } + }; + typedef __gnu_cxx::hash_map, CStringEquals> NameToOrder; + typedef __gnu_cxx::hash_set, CStringEquals> NameSet; enum ExportMode { kExportDefault, kExportSome, kDontExportSome }; enum LibrarySearchMode { kSearchDylibAndArchiveInEachDir, kSearchAllDirsForDylibsThenAllDirsForArchives }; enum InterposeMode { kInterposeNone, kInterposeAllExternal, kInterposeSome }; --- src/ld/OutputFile.cpp 2014-04-04 15:42:29.000000000 -0700 +++ src/ld/OutputFile.cpp 2014-05-16 14:28:58.000000000 -0700 @@ -50,7 +50,8 @@ #include #include #include -#include +#include +#include #include #include @@ -4598,6 +4599,12 @@ public: }; +class CStringEquals +{ +public: + bool operator()(const char* left, const char* right) const { return (strcmp(left, right) == 0); } +}; + const char* OutputFile::assureFullPath(const char* path) { if ( path[0] == '/' ) @@ -4683,7 +4690,7 @@ void OutputFile::synthesizeDebugNotes(ld const char* filename = NULL; bool wroteStartSO = false; state.stabs.reserve(atomsNeedingDebugNotes.size()*4); - std::unordered_set seenFiles; + __gnu_cxx::hash_set, CStringEquals> seenFiles; for (std::vector::iterator it=atomsNeedingDebugNotes.begin(); it != atomsNeedingDebugNotes.end(); it++) { const ld::Atom* atom = *it; const ld::File* atomFile = atom->file(); --- src/ld/Resolver.cpp 2014-04-04 15:42:29.000000000 -0700 +++ src/ld/Resolver.cpp 2014-05-16 14:28:58.000000000 -0700 @@ -47,6 +47,8 @@ #include #include #include +#include +#include #include #include --- src/ld/Resolver.h 2014-04-04 15:42:29.000000000 -0700 +++ src/ld/Resolver.h 2014-05-16 14:28:58.000000000 -0700 @@ -42,7 +42,6 @@ #include #include -#include #include "Options.h" #include "ld.hpp" @@ -103,7 +102,11 @@ private: void doLinkerOption(const std::vector& linkerOption, const char* fileName); void dumpAtoms(); - typedef std::unordered_set StringSet; + class CStringEquals { + public: + bool operator()(const char* left, const char* right) const { return (strcmp(left, right) == 0); } + }; + typedef __gnu_cxx::hash_set, CStringEquals> StringSet; class NotLive { public: --- src/ld/SymbolTable.cpp 2014-04-04 15:42:29.000000000 -0700 +++ src/ld/SymbolTable.cpp 2014-05-16 14:28:58.000000000 -0700 @@ -41,6 +41,8 @@ #include #include #include +#include +#include #include "Options.h" @@ -772,7 +774,7 @@ void SymbolTable::printStatistics() count[b] = 0; } for(unsigned int i=0; i < _cstringTable.bucket_count(); ++i) { - unsigned int n = _cstringTable.bucket_size(i); + unsigned int n = _cstringTable.elems_in_bucket(i); if ( n < 10 ) count[n] += 1; else --- src/ld/SymbolTable.h 2014-04-04 15:42:29.000000000 -0700 +++ src/ld/SymbolTable.h 2014-05-16 14:28:58.000000000 -0700 @@ -42,7 +42,7 @@ #include #include -#include +#include #include "Options.h" #include "ld.hpp" @@ -57,38 +57,42 @@ public: typedef uint32_t IndirectBindingSlot; private: - typedef std::unordered_map NameToSlot; + class CStringEquals { + public: + bool operator()(const char* left, const char* right) const { return (strcmp(left, right) == 0); } + }; + typedef __gnu_cxx::hash_map, CStringEquals> NameToSlot; class ContentFuncs { public: size_t operator()(const ld::Atom*) const; bool operator()(const ld::Atom* left, const ld::Atom* right) const; }; - typedef std::unordered_map ContentToSlot; + typedef __gnu_cxx::hash_map ContentToSlot; class ReferencesHashFuncs { public: size_t operator()(const ld::Atom*) const; bool operator()(const ld::Atom* left, const ld::Atom* right) const; }; - typedef std::unordered_map ReferencesToSlot; + typedef __gnu_cxx::hash_map ReferencesToSlot; class CStringHashFuncs { public: size_t operator()(const ld::Atom*) const; bool operator()(const ld::Atom* left, const ld::Atom* right) const; }; - typedef std::unordered_map CStringToSlot; + typedef __gnu_cxx::hash_map CStringToSlot; class UTF16StringHashFuncs { public: size_t operator()(const ld::Atom*) const; bool operator()(const ld::Atom* left, const ld::Atom* right) const; }; - typedef std::unordered_map UTF16StringToSlot; + typedef __gnu_cxx::hash_map UTF16StringToSlot; typedef std::map SlotToName; - typedef std::unordered_map NameToMap; + typedef __gnu_cxx::hash_map, CStringEquals> NameToMap; typedef std::vector DuplicatedSymbolAtomList; typedef std::map DuplicateSymbols; --- src/ld/ld.cpp 2014-04-04 15:42:29.000000000 -0700 +++ src/ld/ld.cpp 2014-05-16 14:28:58.000000000 -0700 @@ -54,7 +54,8 @@ extern "C" double log2 ( double ); #include #include #include -#include +#include +#include #include #include "Options.h" @@ -148,7 +149,7 @@ private: struct SectionEquals { bool operator()(const ld::Section* left, const ld::Section* right) const; }; - typedef std::unordered_map SectionInToOut; + typedef __gnu_cxx::hash_map SectionInToOut; SectionInToOut _sectionInToFinalMap; @@ -169,7 +170,7 @@ std::vector InternalState:: size_t InternalState::SectionHash::operator()(const ld::Section* sect) const { size_t hash = 0; - ld::CStringHash temp; + __gnu_cxx::hash temp; hash += temp.operator()(sect->segmentName()); hash += temp.operator()(sect->sectionName()); return hash; --- src/ld/ld.hpp 2014-04-04 15:42:29.000000000 -0700 +++ src/ld/ld.hpp 2014-05-16 14:43:37.000000000 -0700 @@ -32,7 +32,7 @@ #include #include -#include +#include #include "configure.h" @@ -821,7 +821,7 @@ struct CStringEquals bool operator()(const char* left, const char* right) const { return (strcmp(left, right) == 0); } }; -typedef std::unordered_set CStringSet; +typedef __gnu_cxx::hash_set, CStringEquals> CStringSet; class Internal { --- src/ld/parsers/archive_file.cpp 2014-04-04 15:42:29.000000000 -0700 +++ src/ld/parsers/archive_file.cpp 2014-05-16 14:28:58.000000000 -0700 @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include "MachOFileAbstraction.hpp" #include "Architectures.hpp" @@ -112,7 +112,12 @@ private: struct MemberState { ld::relocatable::File* file; const Entry *entry; bool logged; bool loaded; uint32_t index;}; bool loadMember(MemberState& state, ld::File::AtomHandler& handler, const char *format, ...) const; - typedef std::unordered_map NameToEntryMap; + class CStringEquals + { + public: + bool operator()(const char* left, const char* right) const { return (strcmp(left, right) == 0); } + }; + typedef __gnu_cxx::hash_map, CStringEquals> NameToEntryMap; typedef typename A::P P; typedef typename A::P::E E; --- src/ld/parsers/lto_file.cpp 2014-05-16 14:28:17.000000000 -0700 +++ src/ld/parsers/lto_file.cpp 2014-05-16 14:28:58.000000000 -0700 @@ -30,11 +30,10 @@ #include #include #include -#include #include #include -#include -#include +#include +#include #include @@ -219,8 +218,13 @@ private: static void ltoDiagnosticHandler(lto_codegen_diagnostic_severity_t, const char*, void*); #endif - typedef std::unordered_set CStringSet; - typedef std::unordered_map CStringToAtom; + class CStringEquals + { + public: + bool operator()(const char* left, const char* right) const { return (strcmp(left, right) == 0); } + }; + typedef __gnu_cxx::hash_set, CStringEquals> CStringSet; + typedef __gnu_cxx::hash_map, CStringEquals> CStringToAtom; class AtomSyncer : public ld::File::AtomHandler { public: --- src/ld/parsers/macho_dylib_file.cpp 2014-05-16 14:28:17.000000000 -0700 +++ src/ld/parsers/macho_dylib_file.cpp 2014-05-16 14:28:58.000000000 -0700 @@ -34,8 +34,8 @@ #include #include #include -#include -#include +#include +#include #include "Architectures.hpp" #include "MachOFileAbstraction.hpp" @@ -180,17 +180,14 @@ private: friend class ExportAtom; friend class ImportAtom; - struct CStringHash { - std::size_t operator()(const char* __s) const { - unsigned long __h = 0; - for ( ; *__s; ++__s) - __h = 5 * __h + *__s; - return size_t(__h); - }; + class CStringEquals + { + public: + bool operator()(const char* left, const char* right) const { return (strcmp(left, right) == 0); } }; struct AtomAndWeak { ld::Atom* atom; bool weakDef; bool tlv; pint_t address; }; - typedef std::unordered_map NameToAtomMap; - typedef std::unordered_set NameSet; + typedef __gnu_cxx::hash_map, CStringEquals> NameToAtomMap; + typedef __gnu_cxx::hash_set, CStringEquals> NameSet; struct Dependent { const char* path; File* dylib; bool reExport; }; @@ -548,14 +545,14 @@ void File::buildExportHashTableFromSy if ( _s_logHashtable ) fprintf(stderr, "ld: building hashtable of %u toc entries for %s\n", dynamicInfo->nextdefsym(), this->path()); const macho_nlist

* start = &symbolTable[dynamicInfo->iextdefsym()]; const macho_nlist

* end = &start[dynamicInfo->nextdefsym()]; - _atoms.reserve(dynamicInfo->nextdefsym()); // set initial bucket count + _atoms.resize(dynamicInfo->nextdefsym()); // set initial bucket count for (const macho_nlist

* sym=start; sym < end; ++sym) { this->addSymbol(&strings[sym->n_strx()], (sym->n_desc() & N_WEAK_DEF) != 0, false, sym->n_value()); } } else { int32_t count = dynamicInfo->ntoc(); - _atoms.reserve(count); // set initial bucket count + _atoms.resize(count); // set initial bucket count if ( _s_logHashtable ) fprintf(stderr, "ld: building hashtable of %u entries for %s\n", count, this->path()); const struct dylib_table_of_contents* toc = (dylib_table_of_contents*)(fileContent + dynamicInfo->tocoff()); for (int32_t i = 0; i < count; ++i) { --- src/ld/passes/dtrace_dof.cpp 2014-04-04 15:42:29.000000000 -0700 +++ src/ld/passes/dtrace_dof.cpp 2014-05-16 14:28:58.000000000 -0700 @@ -30,8 +30,7 @@ #include #include -#include -#include +#include #include "ld.hpp" #include "MachOFileAbstraction.hpp" @@ -105,14 +104,20 @@ Atom::Atom(File& f, const char* n, cons +class CStringEquals +{ +public: + bool operator()(const char* left, const char* right) const { return (strcmp(left, right) == 0); } +}; + struct DTraceProbeInfo { DTraceProbeInfo(const ld::Atom* a, uint32_t o, const char* n) : atom(a), offset(o), probeName(n) {} const ld::Atom* atom; uint32_t offset; const char* probeName; }; -typedef std::unordered_map, CStringHash, CStringEquals> ProviderToProbes; -typedef std::unordered_set CStringSet; +typedef __gnu_cxx::hash_map, __gnu_cxx::hash, CStringEquals> ProviderToProbes; +typedef __gnu_cxx::hash_set, CStringEquals> CStringSet; --- src/ld/passes/got.cpp 2014-04-04 15:42:29.000000000 -0700 +++ src/ld/passes/got.cpp 2014-05-16 14:28:58.000000000 -0700 @@ -30,6 +30,7 @@ #include #include +#include #include "MachOFileAbstraction.hpp" #include "ld.hpp" --- src/ld/passes/order.cpp 2014-04-04 15:42:29.000000000 -0700 +++ src/ld/passes/order.cpp 2014-05-16 14:28:58.000000000 -0700 @@ -32,7 +32,6 @@ #include #include #include -#include #include "ld.hpp" #include "order.h" @@ -84,7 +83,11 @@ private: const Layout& _layout; }; - typedef std::unordered_map NameToAtom; + class CStringEquals { + public: + bool operator()(const char* left, const char* right) const { return (strcmp(left, right) == 0); } + }; + typedef __gnu_cxx::hash_map, CStringEquals> NameToAtom; typedef std::map AtomToAtom; --- src/ld/passes/tlvp.cpp 2014-04-04 15:42:29.000000000 -0700 +++ src/ld/passes/tlvp.cpp 2014-05-16 14:28:58.000000000 -0700 @@ -30,6 +30,7 @@ #include #include +#include #include "ld.hpp" #include "tlvp.h" --- src/other/dyldinfo.cpp 2014-04-04 15:42:29.000000000 -0700 +++ src/other/dyldinfo.cpp 2014-05-16 14:28:58.000000000 -0700 @@ -33,7 +33,7 @@ #include #include -#include +#include #include "configure.h" #include "MachOFileAbstraction.hpp" @@ -87,6 +87,14 @@ private: typedef typename A::P::E E; typedef typename A::P::uint_t pint_t; + class CStringEquals + { + public: + bool operator()(const char* left, const char* right) const { return (strcmp(left, right) == 0); } + }; + + typedef __gnu_cxx::hash_set, CStringEquals> StringSet; + DyldInfoPrinter(const uint8_t* fileContent, uint32_t fileLength, const char* path, bool printArch); void printRebaseInfo(); void printRebaseInfoOpcodes(); --- src/other/machochecker.cpp 2014-04-04 15:42:29.000000000 -0700 +++ src/other/machochecker.cpp 2014-05-16 14:28:58.000000000 -0700 @@ -33,7 +33,7 @@ #include #include -#include +#include #include "configure.h" @@ -110,21 +110,13 @@ private: typedef typename A::P::E E; typedef typename A::P::uint_t pint_t; - // utility classes for using std::unordered_map with c-strings - struct CStringHash { - size_t operator()(const char* __s) const { - size_t __h = 0; - for ( ; *__s; ++__s) - __h = 5 * __h + *__s; - return __h; - }; - }; - struct CStringEquals + class CStringEquals { + public: bool operator()(const char* left, const char* right) const { return (strcmp(left, right) == 0); } }; - typedef std::unordered_set StringSet; + typedef __gnu_cxx::hash_set, CStringEquals> StringSet; MachOChecker(const uint8_t* fileContent, uint32_t fileLength, const char* path); void checkMachHeader(); --- src/other/unwinddump.cpp 2014-04-04 15:42:29.000000000 -0700 +++ src/other/unwinddump.cpp 2014-05-16 14:28:58.000000000 -0700 @@ -33,7 +33,7 @@ #include #include -#include +#include #include "configure.h" #include "MachOFileAbstraction.hpp" @@ -71,6 +71,14 @@ private: typedef typename A::P::E E; typedef typename A::P::uint_t pint_t; + class CStringEquals + { + public: + bool operator()(const char* left, const char* right) const { return (strcmp(left, right) == 0); } + }; + + typedef __gnu_cxx::hash_set, CStringEquals> StringSet; + UnwindPrinter(const uint8_t* fileContent, uint32_t fileLength, const char* path, bool showFunctionNames); bool findUnwindSection();