mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
[JITLink] Add two useful Section operations: find by name, get address range.
These operations were already used in eh-frame registration, and are likely to be used in other runtime registrations, so this commit moves them into a header where they can be re-used. llvm-svn: 359950
This commit is contained in:
parent
7123588a09
commit
fa6b018ca6
@ -296,6 +296,34 @@ raw_ostream &operator<<(raw_ostream &OS, const Atom &A);
|
||||
void printEdge(raw_ostream &OS, const Atom &FixupAtom, const Edge &E,
|
||||
StringRef EdgeKindName);
|
||||
|
||||
/// Represents a section address range via a pair of DefinedAtom pointers to
|
||||
/// the first and last atoms in the section.
|
||||
class SectionRange {
|
||||
public:
|
||||
SectionRange() = default;
|
||||
SectionRange(DefinedAtom *First, DefinedAtom *Last)
|
||||
: First(First), Last(Last) {}
|
||||
DefinedAtom *getFirstAtom() const {
|
||||
assert((!Last || First) && "First can not be null if end is non-null");
|
||||
return First;
|
||||
}
|
||||
DefinedAtom *getLastAtom() const {
|
||||
assert((First || !Last) && "Last can not be null if start is non-null");
|
||||
return Last;
|
||||
}
|
||||
bool isEmpty() const {
|
||||
assert((First || !Last) && "Last can not be null if start is non-null");
|
||||
return !First;
|
||||
}
|
||||
JITTargetAddress getStart() const;
|
||||
JITTargetAddress getEnd() const;
|
||||
uint64_t getSize() const;
|
||||
|
||||
private:
|
||||
DefinedAtom *First = nullptr;
|
||||
DefinedAtom *Last = nullptr;
|
||||
};
|
||||
|
||||
/// Represents an object file section.
|
||||
class Section {
|
||||
friend class AtomGraph;
|
||||
@ -337,6 +365,17 @@ public:
|
||||
/// Return true if this section contains no atoms.
|
||||
bool atoms_empty() const { return DefinedAtoms.empty(); }
|
||||
|
||||
/// Returns the range of this section as the pair of atoms with the lowest
|
||||
/// and highest target address. This operation is expensive, as it
|
||||
/// must traverse all atoms in the section.
|
||||
///
|
||||
/// Note: If the section is empty, both values will be null. The section
|
||||
/// address will evaluate to null, and the size to zero. If the section
|
||||
/// contains a single atom both values will point to it, the address will
|
||||
/// evaluate to the address of that atom, and the size will be the size of
|
||||
/// that atom.
|
||||
SectionRange getRange() const;
|
||||
|
||||
private:
|
||||
void addAtom(DefinedAtom &DA) {
|
||||
assert(!DefinedAtoms.count(&DA) && "Atom is already in this section");
|
||||
@ -458,6 +497,29 @@ private:
|
||||
uint32_t Alignment = 0;
|
||||
};
|
||||
|
||||
inline JITTargetAddress SectionRange::getStart() const {
|
||||
return First ? First->getAddress() : 0;
|
||||
}
|
||||
|
||||
inline JITTargetAddress SectionRange::getEnd() const {
|
||||
return Last ? Last->getAddress() + Last->getSize() : 0;
|
||||
}
|
||||
|
||||
inline uint64_t SectionRange::getSize() const { return getEnd() - getStart(); }
|
||||
|
||||
inline SectionRange Section::getRange() const {
|
||||
if (atoms_empty())
|
||||
return SectionRange();
|
||||
DefinedAtom *First = *DefinedAtoms.begin(), *Last = *DefinedAtoms.end();
|
||||
for (auto *DA : atoms()) {
|
||||
if (DA->getAddress() < First->getAddress())
|
||||
First = DA;
|
||||
if (DA->getAddress() > Last->getAddress())
|
||||
Last = DA;
|
||||
}
|
||||
return SectionRange(First, Last);
|
||||
}
|
||||
|
||||
class AtomGraph {
|
||||
private:
|
||||
using SectionList = std::vector<std::unique_ptr<Section>>;
|
||||
@ -621,6 +683,15 @@ public:
|
||||
section_iterator(Sections.end()));
|
||||
}
|
||||
|
||||
/// Returns the section with the given name if it exists, otherwise returns
|
||||
/// null.
|
||||
Section *findSectionByName(StringRef Name) {
|
||||
for (auto &S : sections())
|
||||
if (S.getName() == Name)
|
||||
return &S;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
iterator_range<external_atom_iterator> external_atoms() {
|
||||
return make_range(ExternalAtoms.begin(), ExternalAtoms.end());
|
||||
}
|
||||
|
@ -521,15 +521,8 @@ createEHFrameRecorderPass(const Triple &TT,
|
||||
// Search for a non-empty eh-frame and record the address of the first atom
|
||||
// in it.
|
||||
JITTargetAddress Addr = 0;
|
||||
for (auto &S : G.sections())
|
||||
if (S.getName() == EHFrameSectionName && !S.atoms_empty()) {
|
||||
Addr = (*S.atoms().begin())->getAddress();
|
||||
for (auto *DA : S.atoms())
|
||||
if (DA->getAddress() < Addr)
|
||||
Addr = DA->getAddress();
|
||||
break;
|
||||
}
|
||||
|
||||
if (auto *S = G.findSectionByName(EHFrameSectionName))
|
||||
Addr = S->getRange().getStart();
|
||||
StoreFrameAddress(Addr);
|
||||
return Error::success();
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user