forked from OSchip/llvm-project
add register section, remove contentType from sectionKey
llvm-svn: 173709
This commit is contained in:
parent
e6c3fa0b27
commit
072fb1a403
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue