[llvm] r359950 - [JITLink] Add two useful Section operations: find by name, get address range.
Lang Hames via llvm-commits
llvm-commits at lists.llvm.org
Fri May 3 17:23:09 PDT 2019
Author: lhames
Date: Fri May 3 17:23:09 2019
New Revision: 359950
URL: http://llvm.org/viewvc/llvm-project?rev=359950&view=rev
Log:
[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.
Modified:
llvm/trunk/include/llvm/ExecutionEngine/JITLink/JITLink.h
llvm/trunk/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp
Modified: llvm/trunk/include/llvm/ExecutionEngine/JITLink/JITLink.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/JITLink/JITLink.h?rev=359950&r1=359949&r2=359950&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ExecutionEngine/JITLink/JITLink.h (original)
+++ llvm/trunk/include/llvm/ExecutionEngine/JITLink/JITLink.h Fri May 3 17:23:09 2019
@@ -296,6 +296,34 @@ raw_ostream &operator<<(raw_ostream &OS,
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());
}
Modified: llvm/trunk/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp?rev=359950&r1=359949&r2=359950&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp Fri May 3 17:23:09 2019
@@ -521,15 +521,8 @@ createEHFrameRecorderPass(const Triple &
// 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();
};
More information about the llvm-commits
mailing list