diff options
author | Shankar Easwaran <shankare@codeaurora.org> | 2013-01-28 19:21:04 +0000 |
---|---|---|
committer | Shankar Easwaran <shankare@codeaurora.org> | 2013-01-28 19:21:04 +0000 |
commit | 072fb1a403963a37ad256bd83f3e56a80e4b4275 (patch) | |
tree | 45738bbd1dedf6390a937046ee9e6936b83395f1 | |
parent | e6c3fa0b27b4961ab11658576eea3cbd189eb086 (diff) | |
download | bcm5719-llvm-072fb1a403963a37ad256bd83f3e56a80e4b4275.tar.gz bcm5719-llvm-072fb1a403963a37ad256bd83f3e56a80e4b4275.zip |
add register section, remove contentType from sectionKey
llvm-svn: 173709
-rw-r--r-- | lld/lib/ReaderWriter/ELF/DefaultELFLayout.h | 93 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/ELFTargetHandler.h | 59 |
2 files changed, 106 insertions, 46 deletions
diff --git a/lld/lib/ReaderWriter/ELF/DefaultELFLayout.h b/lld/lib/ReaderWriter/ELF/DefaultELFLayout.h index fb97a1d0c1d..f7525322cab 100644 --- a/lld/lib/ReaderWriter/ELF/DefaultELFLayout.h +++ b/lld/lib/ReaderWriter/ELF/DefaultELFLayout.h @@ -84,9 +84,29 @@ public: // The Key used for creating Sections // The sections are created using - // SectionName, [contentType, contentPermissions] - typedef std::pair<StringRef, - std::pair<int32_t, int32_t>> Key; + // SectionName, contentPermissions + struct SectionKey { + SectionKey(StringRef name, DefinedAtom::ContentPermissions perm) + : _name(name), _perm(perm) { + } + + // Data members + const StringRef _name; + DefinedAtom::ContentPermissions _perm; + }; + + struct SectionKeyHash { + int64_t operator()(const SectionKey &k) const { + return llvm::hash_combine(k._name, k._perm); + } + }; + + struct SectionKeyEq { + bool operator()(const SectionKey &lhs, const SectionKey &rhs) const { + return ((lhs._name == rhs._name) && (lhs._perm == rhs._perm)); + } + }; + typedef typename std::vector<Chunk<ELFT> *>::iterator ChunkIter; // The key used for Segments // The segments are created using @@ -95,18 +115,8 @@ public: // Merged Sections contain the map of Sectionnames to a vector of sections, // that have been merged to form a single section typedef std::map<StringRef, MergedSections<ELFT> *> MergedSectionMapT; - typedef typename std::vector<MergedSections<ELFT> *>::iterator - MergedSectionIter; - - // HashKey for the Section - class HashKey { - public: - int64_t operator() (const Key &k) const { - // k.first = section Name - // k.second = [contentType, Permissions] - return llvm::hash_combine(k.first, k.second.first, k.second.second); - } - }; + typedef typename std::vector< + MergedSections<ELFT> *>::iterator MergedSectionIter; // HashKey for the Segment class SegmentHashKey { @@ -118,9 +128,9 @@ public: } }; - typedef std::unordered_map<Key, Section<ELFT>*, HashKey> SectionMapT; - typedef std::unordered_map<SegmentKey, - Segment<ELFT>*, + typedef std::unordered_map<SectionKey, Section<ELFT> *, SectionKeyHash, + SectionKeyEq> SectionMapT; + typedef std::unordered_map<SegmentKey, Segment<ELFT> *, SegmentHashKey> SegmentMapT; /// \brief All absolute atoms are created in the ELF Layout by using @@ -384,42 +394,35 @@ template<class ELFT> error_code DefaultELFLayout<ELFT>::addAtom(const Atom *atom) { if (const DefinedAtom *definedAtom = dyn_cast<DefinedAtom>(atom)) { - const StringRef sectionName = - getSectionName(definedAtom->customSectionName(), - definedAtom->contentType()); + const StringRef sectionName = getSectionName( + definedAtom->customSectionName(), definedAtom->contentType()); const lld::DefinedAtom::ContentPermissions permissions = - definedAtom->permissions(); + definedAtom->permissions(); const lld::DefinedAtom::ContentType contentType = - definedAtom->contentType(); - const Key key(sectionName, std::make_pair(contentType, permissions)); - const std::pair<Key, Section<ELFT> *>currentSection(key, nullptr); - std::pair<typename SectionMapT::iterator, bool> - sectionInsert(_sectionMap.insert(currentSection)); + definedAtom->contentType(); + const SectionKey sectionKey(sectionName, permissions); Section<ELFT> *section; - // the section is already in the map - if (!sectionInsert.second) { - section = sectionInsert.first->second; - section->setContentPermissions(permissions); - } else { - SectionOrder section_order = getSectionOrder(sectionName, - contentType, - permissions); - section = new (_allocator.Allocate<Section<ELFT>>()) Section<ELFT>( - sectionName, contentType, permissions, section_order); - sectionInsert.first->second = section; + + if (_sectionMap.find(sectionKey) == _sectionMap.end()) { + SectionOrder section_order = + getSectionOrder(sectionName, contentType, permissions); + section = new (_allocator.Allocate<Section<ELFT> >()) + Section<ELFT>(sectionName, contentType, permissions, section_order); section->setOrder(section_order); _sections.push_back(section); + _sectionMap.insert(std::make_pair(sectionKey, section)); + } else { + section = _sectionMap[sectionKey]; } section->appendAtom(atom); - } - // Absolute atoms are not part of any section, they are global for the whole - // link - else if (const AbsoluteAtom *absoluteAtom = dyn_cast<AbsoluteAtom>(atom)) { - _absoluteAtoms.push_back(AbsoluteAtomPair(absoluteAtom, + } else if (const AbsoluteAtom *absoluteAtom = dyn_cast<AbsoluteAtom>(atom)) { + // Absolute atoms are not part of any section, they are global for the whole + // link + _absoluteAtoms.push_back(AbsoluteAtomPair(absoluteAtom, absoluteAtom->value())); - } - else + } else { llvm_unreachable("Only absolute / defined atoms can be added here"); + } return error_code::success(); } diff --git a/lld/lib/ReaderWriter/ELF/ELFTargetHandler.h b/lld/lib/ReaderWriter/ELF/ELFTargetHandler.h index 641350bcfed..06c9af2d314 100644 --- a/lld/lib/ReaderWriter/ELF/ELFTargetHandler.h +++ b/lld/lib/ReaderWriter/ELF/ELFTargetHandler.h @@ -18,6 +18,7 @@ #include <memory> #include <vector> +#include <unordered_map> /// \brief All ELF targets would want to override the way the ELF file gets /// processed by the linker. This class serves as an interface which would be @@ -89,6 +90,10 @@ public: // segment or not bool hasOutputSegment(Section<ELFT> *section) = 0; + /// Returns the target Section for a section name and content Type + Section<ELFT> *getSection(const StringRef name, + DefinedAtom::ContentPermissions permissions) = 0; + private: const ELFTargetInfo &_targetInfo; const DefaultELFLayout<ELFT> &_layout; @@ -99,9 +104,32 @@ private: template <class ELFT> class ELFTargetHandler : public ELFTargetHandlerBase { public: - ELFTargetHandler(ELFTargetInfo &targetInfo) : _targetInfo(targetInfo) {} + /// Register a Target, so that the target backend may choose on how to merge + /// individual atoms within the section, this is a way to control output order + /// of atoms that is determined by the target + void registerTargetSection(StringRef name, + DefinedAtom::ContentPermissions perm) { + const TargetSectionKey targetSection(name, perm); + if (_registeredTargetSections.find(targetSection) == + _registeredTargetSections.end()) + _registeredTargetSections.insert(std::make_pair(targetSection, true)); + } + + /// Check if the section is registered given the section name and its + /// contentType, if they are registered the target would need to + /// create a section so that atoms insert, atom virtual address assignment + /// could be overridden and controlled by the Target + bool isSectionRegisteredByTarget(StringRef name, + DefinedAtom::ContentPermissions perm) { + const TargetSectionKey targetSection(name, perm); + if (_registeredTargetSections.find(targetSection) == + _registeredTargetSections.end()) + return false; + return true; + } + /// If the target overrides ELF header information, this API would /// return true, so that the target can set all fields specific to /// that target @@ -132,8 +160,37 @@ public: /// symbols over to small data, this would also be used virtual void allocateCommons() = 0; +private: + struct TargetSectionKey { + TargetSectionKey(StringRef name, DefinedAtom::ContentPermissions perm) + : _name(name), _perm(perm) { + } + + // Data members + const StringRef _name; + DefinedAtom::ContentPermissions _perm; + }; + + struct TargetSectionKeyHash { + int64_t operator()(const TargetSectionKey &k) const { + return llvm::hash_combine(k._name, k._perm); + } + }; + + struct TargetSectionKeyEq { + bool operator()(const TargetSectionKey &lhs, + const TargetSectionKey &rhs) const { + return ((lhs._name == rhs._name) && (lhs._perm == rhs._perm)); + } + }; + + typedef std::unordered_map<TargetSectionKey, bool, TargetSectionKeyHash, + TargetSectionKeyEq> RegisteredTargetSectionMapT; + typedef typename RegisteredTargetSectionMapT::iterator RegisteredTargetSectionMapIterT; + protected: const ELFTargetInfo &_targetInfo; + RegisteredTargetSectionMapT _registeredTargetSections; }; } // elf |