//===- SFrameParser.h -------------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLVM_OBJECT_SFRAME_H #define LLVM_OBJECT_SFRAME_H #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/fallible_iterator.h" #include "llvm/BinaryFormat/SFrame.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Error.h" #include namespace llvm { namespace object { template class SFrameParser { class FallibleFREIterator; public: static Expected create(ArrayRef Contents, uint64_t SectionAddress); const sframe::Preamble &getPreamble() const { return Header.Preamble; } const sframe::Header &getHeader() const { return Header; } Expected> getAuxHeader() const; bool usesFixedRAOffset() const { return getHeader().ABIArch == sframe::ABI::AMD64EndianLittle; } bool usesFixedFPOffset() const { return false; // Not used in any currently defined ABI. } using FDERange = ArrayRef>; Expected fdes() const; // Decodes the start address of the given FDE, which must be one of the // objects returned by the `fdes()` function. uint64_t getAbsoluteStartAddress(typename FDERange::iterator FDE) const; // Returns the offset (in the SFrame section) of the given FDE, which must be // one of the objects returned by the `fdes()` function. uint64_t offsetOf(typename FDERange::iterator FDE) const; struct FrameRowEntry { uint32_t StartAddress; sframe::FREInfo Info; SmallVector Offsets; }; using fre_iterator = fallible_iterator; iterator_range fres(const sframe::FuncDescEntry &FDE, Error &Err) const; std::optional getCFAOffset(const FrameRowEntry &FRE) const; std::optional getRAOffset(const FrameRowEntry &FRE) const; std::optional getFPOffset(const FrameRowEntry &FRE) const; ArrayRef getExtraOffsets(const FrameRowEntry &FRE) const; private: ArrayRef Data; uint64_t SectionAddress; const sframe::Header &Header; SFrameParser(ArrayRef Data, uint64_t SectionAddress, const sframe::Header &Header) : Data(Data), SectionAddress(SectionAddress), Header(Header) {} uint64_t getFDEBase() const { return sizeof(Header) + Header.AuxHdrLen + Header.FDEOff; } uint64_t getFREBase() const { return getFDEBase() + Header.NumFDEs * sizeof(sframe::FuncDescEntry); } }; template class SFrameParser::FallibleFREIterator { public: // NB: This iterator starts out in the before_begin() state. It must be // ++'ed to reach the first element. FallibleFREIterator(ArrayRef Data, sframe::FREType FREType, uint32_t Idx, uint32_t Size, uint64_t Offset) : Data(Data), FREType(FREType), Idx(Idx), Size(Size), Offset(Offset) {} LLVM_ABI Error inc(); const FrameRowEntry &operator*() const { return FRE; } friend bool operator==(const FallibleFREIterator &LHS, const FallibleFREIterator &RHS) { assert(LHS.Data.data() == RHS.Data.data()); assert(LHS.Data.size() == RHS.Data.size()); assert(LHS.FREType == RHS.FREType); assert(LHS.Size == RHS.Size); return LHS.Idx == RHS.Idx; } private: ArrayRef Data; sframe::FREType FREType; uint32_t Idx; uint32_t Size; uint64_t Offset; FrameRowEntry FRE; }; extern template class LLVM_TEMPLATE_ABI SFrameParser; extern template class LLVM_TEMPLATE_ABI SFrameParser; } // end namespace object } // end namespace llvm #endif // LLVM_OBJECT_SFRAME_H