llvm.org GIT mirror llvm / 966c1da
[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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@359950 91177308-0d34-0410-b5e6-96231b3b80d8 Lang Hames 1 year, 5 months ago
2 changed file(s) with 73 addition(s) and 9 deletion(s). Raw diff Collapse all Expand all
295295 void printEdge(raw_ostream &OS, const Atom &FixupAtom, const Edge &E,
296296 StringRef EdgeKindName);
297297
298 /// Represents a section address range via a pair of DefinedAtom pointers to
299 /// the first and last atoms in the section.
300 class SectionRange {
301 public:
302 SectionRange() = default;
303 SectionRange(DefinedAtom *First, DefinedAtom *Last)
304 : First(First), Last(Last) {}
305 DefinedAtom *getFirstAtom() const {
306 assert((!Last || First) && "First can not be null if end is non-null");
307 return First;
308 }
309 DefinedAtom *getLastAtom() const {
310 assert((First || !Last) && "Last can not be null if start is non-null");
311 return Last;
312 }
313 bool isEmpty() const {
314 assert((First || !Last) && "Last can not be null if start is non-null");
315 return !First;
316 }
317 JITTargetAddress getStart() const;
318 JITTargetAddress getEnd() const;
319 uint64_t getSize() const;
320
321 private:
322 DefinedAtom *First = nullptr;
323 DefinedAtom *Last = nullptr;
324 };
325
298326 /// Represents an object file section.
299327 class Section {
300328 friend class AtomGraph;
335363
336364 /// Return true if this section contains no atoms.
337365 bool atoms_empty() const { return DefinedAtoms.empty(); }
366
367 /// Returns the range of this section as the pair of atoms with the lowest
368 /// and highest target address. This operation is expensive, as it
369 /// must traverse all atoms in the section.
370 ///
371 /// Note: If the section is empty, both values will be null. The section
372 /// address will evaluate to null, and the size to zero. If the section
373 /// contains a single atom both values will point to it, the address will
374 /// evaluate to the address of that atom, and the size will be the size of
375 /// that atom.
376 SectionRange getRange() const;
338377
339378 private:
340379 void addAtom(DefinedAtom &DA) {
456495 unsigned Ordinal = 0;
457496 uint32_t Alignment = 0;
458497 };
498
499 inline JITTargetAddress SectionRange::getStart() const {
500 return First ? First->getAddress() : 0;
501 }
502
503 inline JITTargetAddress SectionRange::getEnd() const {
504 return Last ? Last->getAddress() + Last->getSize() : 0;
505 }
506
507 inline uint64_t SectionRange::getSize() const { return getEnd() - getStart(); }
508
509 inline SectionRange Section::getRange() const {
510 if (atoms_empty())
511 return SectionRange();
512 DefinedAtom *First = *DefinedAtoms.begin(), *Last = *DefinedAtoms.end();
513 for (auto *DA : atoms()) {
514 if (DA->getAddress() < First->getAddress())
515 First = DA;
516 if (DA->getAddress() > Last->getAddress())
517 Last = DA;
518 }
519 return SectionRange(First, Last);
520 }
459521
460522 class AtomGraph {
461523 private:
620682 section_iterator(Sections.end()));
621683 }
622684
685 /// Returns the section with the given name if it exists, otherwise returns
686 /// null.
687 Section *findSectionByName(StringRef Name) {
688 for (auto &S : sections())
689 if (S.getName() == Name)
690 return &S;
691 return nullptr;
692 }
693
623694 iterator_range external_atoms() {
624695 return make_range(ExternalAtoms.begin(), ExternalAtoms.end());
625696 }
520520 // Search for a non-empty eh-frame and record the address of the first atom
521521 // in it.
522522 JITTargetAddress Addr = 0;
523 for (auto &S : G.sections())
524 if (S.getName() == EHFrameSectionName && !S.atoms_empty()) {
525 Addr = (*S.atoms().begin())->getAddress();
526 for (auto *DA : S.atoms())
527 if (DA->getAddress() < Addr)
528 Addr = DA->getAddress();
529 break;
530 }
531
523 if (auto *S = G.findSectionByName(EHFrameSectionName))
524 Addr = S->getRange().getStart();
532525 StoreFrameAddress(Addr);
533526 return Error::success();
534527 };