Index: lib/ReaderWriter/ELF/DefaultLayout.h =================================================================== --- lib/ReaderWriter/ELF/DefaultLayout.h +++ lib/ReaderWriter/ELF/DefaultLayout.h @@ -29,8 +29,6 @@ #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/Errc.h" #include "llvm/Support/Format.h" -#include -#include namespace lld { namespace elf { @@ -89,8 +87,10 @@ // The Key used for creating Sections // The sections are created using - // SectionName, contentPermissions + // SectionName, contentPermissions,path struct SectionKey { + SectionKey() : _name(""), _perm(DefinedAtom::perm___), _path("") {} + SectionKey(StringRef name, DefinedAtom::ContentPermissions perm, StringRef path) : _name(name), _perm(perm), _path(path) {} @@ -101,14 +101,13 @@ StringRef _path; }; - struct SectionKeyHash { - int64_t operator()(const SectionKey &k) const { + struct SectionKeyInfo { + static SectionKey getEmptyKey() { return SectionKey(); } + static SectionKey getTombstoneKey() { return SectionKey(); } + static unsigned getHashValue(const SectionKey &k) { return llvm::hash_combine(k._name, k._perm, k._path); } - }; - - struct SectionKeyEq { - bool operator()(const SectionKey &lhs, const SectionKey &rhs) const { + static bool isEqual(const SectionKey &lhs, const SectionKey &rhs) { return ((lhs._name == rhs._name) && (lhs._perm == rhs._perm) && (lhs._path == rhs._path)); } @@ -117,46 +116,62 @@ typedef typename std::vector *>::iterator ChunkIter; typedef typename std::vector *>::iterator SegmentIter; - // The additional segments are used to figure out - // if there is a segment by that type already created - // For example : PT_TLS, we have two sections .tdata/.tbss - // that are part of PT_TLS, we need to create this additional - // segment only once - typedef std::pair AdditionalSegmentKey; - // The segments are created using - // SegmentName, Segment flags - typedef std::pair SegmentKey; - - // HashKey for the Segment - class SegmentHashKey { - public: - int64_t operator() (const SegmentKey &k) const { - // k.first = SegmentName - // k.second = SegmentFlags - return llvm::hash_combine(k.first, k.second); + struct SegmentKey { + SegmentKey() : _name(""), _perm(-1) {} + SegmentKey(StringRef name, int64_t perm) : _name(name), _perm(perm) {} + // Data members + StringRef _name; + int64_t _perm; + }; + + struct SegmentKeyInfo { + static SegmentKey getEmptyKey() { return SegmentKey(); } + static SegmentKey getTombstoneKey() { return SegmentKey(); } + static unsigned getHashValue(const SegmentKey &k) { + return llvm::hash_combine(k._name, k._perm); } + static bool isEqual(const SegmentKey &lhs, const SegmentKey &rhs) { + return ((lhs._name == rhs._name) && (lhs._perm == rhs._perm)); + } + }; + + struct AdditionalSegmentKey { + AdditionalSegmentKey() : _segmentType(-1), _perm(-1) {} + AdditionalSegmentKey(int64_t segmentType, int64_t perm) + : _segmentType(segmentType), _perm(perm) {} + // Data members + int64_t _segmentType; + int64_t _perm; }; - class AdditionalSegmentHashKey { - public: - int64_t operator() (int64_t segmentType, int64_t segmentFlag) const { - // k.first = SegmentName - // k.second = SegmentFlags - return llvm::hash_combine(segmentType, segmentFlag); + struct AdditionalSegmentKeyInfo { + static AdditionalSegmentKey getEmptyKey() { return AdditionalSegmentKey(); } + static AdditionalSegmentKey getTombstoneKey() { + return AdditionalSegmentKey(); + } + static unsigned getHashValue(const AdditionalSegmentKey &k) { + return llvm::hash_combine(k._segmentType, k._perm); + } + static bool isEqual(const AdditionalSegmentKey &lhs, + const AdditionalSegmentKey &rhs) { + return ((lhs._segmentType == rhs._segmentType) && + (lhs._perm == rhs._perm)); } }; // Output Sections contain the map of Sectionnames to a vector of sections, // that have been merged to form a single section - typedef llvm::StringMap *> OutputSectionMapT; + typedef llvm::DenseMap *, StringRefMappingInfo> + OutputSectionMapT; typedef typename std::vector *>::iterator OutputSectionIter; - typedef std::unordered_map *, SectionKeyHash, - SectionKeyEq> SectionMapT; - typedef std::map *> AdditionalSegmentMapT; - typedef std::unordered_map *, SegmentHashKey> - SegmentMapT; + typedef llvm::DenseMap *, SectionKeyInfo> + SectionMapT; + typedef llvm::DenseMap *, + AdditionalSegmentKeyInfo> AdditionalSegmentMapT; + typedef llvm::DenseMap *, SegmentKeyInfo> + SegmentMapT; /// \brief find a absolute atom pair given a absolute atom name struct FindByName { Index: lib/ReaderWriter/ELF/DynamicFile.h =================================================================== --- lib/ReaderWriter/ELF/DynamicFile.h +++ lib/ReaderWriter/ELF/DynamicFile.h @@ -15,7 +15,6 @@ #include "lld/ReaderWriter/ELFLinkingContext.h" #include "llvm/Object/ELF.h" #include "llvm/Support/Path.h" -#include namespace lld { namespace elf { @@ -102,7 +101,7 @@ std::unique_ptr _mb; ELFLinkingContext &_ctx; bool _useShlibUndefines; - mutable std::unordered_map _nameToSym; + mutable llvm::StringMap _nameToSym; }; template Index: lib/ReaderWriter/ELF/ELFFile.h =================================================================== --- lib/ReaderWriter/ELF/ELFFile.h +++ lib/ReaderWriter/ELF/ELFFile.h @@ -11,10 +11,12 @@ #define LLD_READER_WRITER_ELF_FILE_H #include "Atoms.h" +#include "ReaderWriterUtils.h" #include "lld/Core/File.h" #include "lld/Core/Reference.h" #include "lld/ReaderWriter/ELFLinkingContext.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/MapVector.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSet.h" @@ -32,9 +34,7 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" -#include #include -#include namespace lld { @@ -52,27 +52,6 @@ typedef typename llvm::object::ELFFile::Elf_Rel_Iter Elf_Rel_Iter; typedef typename llvm::object::ELFFile::Elf_Word Elf_Word; - // A Map is used to hold the atoms that have been divided up - // after reading the section that contains Merge String attributes - struct MergeSectionKey { - MergeSectionKey(const Elf_Shdr *shdr, int64_t offset) - : _shdr(shdr), _offset(offset) {} - // Data members - const Elf_Shdr *_shdr; - int64_t _offset; - }; - struct MergeSectionEq { - int64_t operator()(const MergeSectionKey &k) const { - return llvm::hash_combine((int64_t)(k._shdr->sh_name), - (int64_t)k._offset); - } - bool operator()(const MergeSectionKey &lhs, - const MergeSectionKey &rhs) const { - return ((lhs._shdr->sh_name == rhs._shdr->sh_name) && - (lhs._offset == rhs._offset)); - } - }; - struct MergeString { MergeString(int64_t offset, StringRef str, const Elf_Shdr *shdr, StringRef sectionName) @@ -113,8 +92,36 @@ return *it; } - typedef std::unordered_map MergedSectionMapT; + // A Map is used to hold the atoms that have been divided up + // after reading the section that contains Merge String attributes + struct MergeSectionKey { + MergeSectionKey() : _shdr(nullptr), _offset(0) {} + MergeSectionKey(const Elf_Shdr *shdr, int64_t offset) + : _shdr(shdr), _offset(offset) {} + // Data members + const Elf_Shdr *_shdr; + int64_t _offset; + }; + + struct MergeSectionKeyInfo { + static MergeSectionKey getEmptyKey() { return MergeSectionKey(); } + static MergeSectionKey getTombstoneKey() { return MergeSectionKey(); } + static unsigned getHashValue(const MergeSectionKey &k) { + return llvm::hash_combine((int64_t)(k._shdr->sh_name), + (int64_t)k._offset); + } + static bool isEqual(const MergeSectionKey &lhs, + const MergeSectionKey &rhs) { + if (!lhs._shdr && !rhs._shdr) + return true; + return (lhs._shdr && rhs._shdr && + (lhs._shdr->sh_name == rhs._shdr->sh_name) && + (lhs._offset == rhs._offset)); + } + }; + + typedef llvm::DenseMap + MergedSectionMapT; typedef typename MergedSectionMapT::iterator MergedSectionMapIterT; public: @@ -410,10 +417,11 @@ /// list of relocations references. In ELF, if a section named, ".text" has /// relocations will also have a section named ".rel.text" or ".rela.text" /// which will hold the entries. - std::unordered_map> - _relocationAddendReferences; + llvm::DenseMap, StringRefMappingInfo> + _relocationAddendReferences; MergedSectionMapT _mergedSectionMap; - std::unordered_map> _relocationReferences; + llvm::DenseMap, StringRefMappingInfo> + _relocationReferences; std::vector *> _references; llvm::DenseMap _symbolToAtomMapping; llvm::DenseMap *, const Elf_Sym *> @@ -430,7 +438,7 @@ /// \brief the section and the symbols that are contained within it to create /// used to create atoms - std::map> _sectionSymbols; + llvm::MapVector> _sectionSymbols; /// \brief Sections that have merge string property std::vector _mergeStringSections; Index: lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h =================================================================== --- lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h +++ lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h @@ -125,7 +125,7 @@ private: /// \brief Map PLT Atoms to their layouts. - std::unordered_map _pltLayoutMap; + llvm::DenseMap _pltLayoutMap; }; } // elf Index: lib/ReaderWriter/ELF/Reader.cpp =================================================================== --- lib/ReaderWriter/ELF/Reader.cpp +++ lib/ReaderWriter/ELF/Reader.cpp @@ -14,7 +14,6 @@ //===----------------------------------------------------------------------===// #include "ELFReader.h" -#include #include using llvm::support::endianness; Index: lib/ReaderWriter/ELF/ReaderWriterUtils.h =================================================================== --- /dev/null +++ lib/ReaderWriter/ELF/ReaderWriterUtils.h @@ -0,0 +1,30 @@ +//===- lib/ReaderWriter/ELF/ReaderWriterUtils.h----------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#ifndef LLD_READER_WRITER_ELF_READER_WRITER_UTILS_H +#define LLD_READER_WRITER_ELF_READER_WRITER_UTILS_H + +#include "llvm/ADT/StringExtras.h" + +namespace lld { +namespace elf { +// Helper for creating a llvm DenseMap of StringRef's. +struct StringRefMappingInfo { + static StringRef getEmptyKey() { return StringRef(); } + static StringRef getTombstoneKey() { return StringRef(" ", 0); } + static unsigned getHashValue(StringRef const val) { + return llvm::HashString(val); + } + static bool isEqual(StringRef const lhs, StringRef const rhs) { + return lhs.equals(rhs); + } +}; +} +} + +#endif Index: lib/ReaderWriter/ELF/SectionChunks.h =================================================================== --- lib/ReaderWriter/ELF/SectionChunks.h +++ lib/ReaderWriter/ELF/SectionChunks.h @@ -12,6 +12,7 @@ #include "Chunk.h" #include "Layout.h" +#include "ReaderWriterUtils.h" #include "TargetHandler.h" #include "Writer.h" #include "lld/Core/DefinedAtom.h" @@ -19,7 +20,6 @@ #include "lld/Core/range.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/StringExtras.h" #include "llvm/Object/ELF.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Debug.h" @@ -586,16 +586,6 @@ private: std::vector _strings; - struct StringRefMappingInfo { - static StringRef getEmptyKey() { return StringRef(); } - static StringRef getTombstoneKey() { return StringRef(" ", 0); } - static unsigned getHashValue(StringRef const val) { - return llvm::HashString(val); - } - static bool isEqual(StringRef const lhs, StringRef const rhs) { - return lhs.equals(rhs); - } - }; typedef typename llvm::DenseMap StringMapT; typedef typename StringMapT::iterator StringMapTIter;