41 "unable to get CIE for FDE at offset 0x%" PRIx64,
52 return std::move(CieError);
59 return std::move(FdeError);
62 AllRows.insert(AllRows.end(), CieRows.begin(), CieRows.end());
63 AllRows.insert(AllRows.end(), FdeRows.begin(), FdeRows.end());
67 if (Row.getRegisterLocations().hasLocations() ||
69 AllRows.push_back(Row);
81 return std::move(CieError);
84 if (Row.getRegisterLocations().hasLocations() ||
117 if (DumpOpts.
IsEH && Version != 1)
118 OS <<
"WARNING: unsupported CIE version\n";
119 OS <<
formatv(
" Version: {0}\n", Version)
120 <<
" Augmentation: \"" << Augmentation <<
"\"\n";
123 OS <<
formatv(
" Segment desc size: {0}\n",
126 OS <<
formatv(
" Code alignment factor: {0}\n",
128 OS <<
formatv(
" Data alignment factor: {0}\n", (int32_t)DataAlignmentFactor);
129 OS <<
formatv(
" Return address column: {0}\n",
130 (int32_t)ReturnAddressRegister);
132 OS <<
formatv(
" Personality Address: {0:x-16}\n", *Personality);
133 if (!AugmentationData.empty()) {
134 OS <<
" Augmentation data: ";
135 for (
uint8_t Byte : AugmentationData)
149 "decoding the CIE opcodes into rows failed"),
150 RowsOrErr.takeError()));
163 OS <<
formatv(
"{0:x-8}", LinkedCIE->getOffset());
165 OS <<
"<invalid offset>";
166 OS <<
formatv(
" pc={0:x-8}...{1:x-8}\n", InitialLocation,
167 InitialLocation + AddressRange);
170 OS <<
formatv(
" LSDA Address: {0:x-16}\n", *LSDAAddress);
179 "decoding the FDE opcodes into rows failed"),
180 RowsOrErr.takeError()));
186 bool IsEH, uint64_t EHFrameAddress)
187 : Arch(Arch), IsEH(IsEH), EHFrameAddress(EHFrameAddress) {}
194 for (
int i = 0; i <
Length; ++i) {
207 if (!ParseCFIProgram)
210 while (Data.isValidOffset(
Offset)) {
211 uint64_t StartOffset =
Offset;
222 auto Cie = std::make_unique<CIE>(
223 IsDWARF64, StartOffset, 0, 0,
SmallString<8>(), 0, 0, 0, 0, 0,
225 CIEs[StartOffset] = Cie.get();
226 Entries.push_back(std::move(Cie));
234 uint64_t StartStructureOffset =
Offset;
239 uint64_t Id = Data.getRelocatedValue((IsDWARF64 && !IsEH) ? 8 : 4, &
Offset,
244 if (Id ==
getCIEId(IsDWARF64, IsEH)) {
246 const char *Augmentation = Data.getCStr(&
Offset);
247 StringRef AugmentationString(Augmentation ? Augmentation :
"");
250 Data.setAddressSize(AddressSize);
252 uint64_t CodeAlignmentFactor = Data.getULEB128(&
Offset);
253 int64_t DataAlignmentFactor = Data.getSLEB128(&
Offset);
254 uint64_t ReturnAddressRegister =
261 std::optional<uint64_t> Personality;
262 std::optional<uint32_t> PersonalityEncoding;
264 std::optional<uint64_t> AugmentationLength;
265 uint64_t StartAugmentationOffset;
266 uint64_t EndAugmentationOffset;
269 for (
unsigned i = 0, e = AugmentationString.
size(); i != e; ++i) {
270 switch (AugmentationString[i]) {
274 "unknown augmentation character %c in entry at 0x%" PRIx64,
275 AugmentationString[i], StartOffset);
277 LSDAPointerEncoding = Data.getU8(&
Offset);
283 "duplicate personality in entry at 0x%" PRIx64, StartOffset);
284 PersonalityEncoding = Data.getU8(&
Offset);
285 Personality = Data.getEncodedPointer(
286 &
Offset, *PersonalityEncoding,
287 EHFrameAddress ? EHFrameAddress +
Offset : 0);
291 FDEPointerEncoding = Data.getU8(&
Offset);
300 "'z' must be the first character at 0x%" PRIx64, StartOffset);
303 AugmentationLength = Data.getULEB128(&
Offset);
304 StartAugmentationOffset =
Offset;
305 EndAugmentationOffset =
Offset + *AugmentationLength;
318 if (AugmentationLength) {
319 if (
Offset != EndAugmentationOffset)
321 "parsing augmentation data at 0x%" PRIx64
324 AugmentationData = Data.getData().
slice(StartAugmentationOffset,
325 EndAugmentationOffset);
329 auto Cie = std::make_unique<CIE>(
331 AddressSize, SegmentDescriptorSize, CodeAlignmentFactor,
332 DataAlignmentFactor, ReturnAddressRegister, AugmentationData,
333 FDEPointerEncoding, LSDAPointerEncoding, Personality,
334 PersonalityEncoding, Arch);
335 CIEs[StartOffset] = Cie.get();
336 Entries.emplace_back(std::move(Cie));
339 uint64_t CIEPointer = Id;
340 uint64_t InitialLocation = 0;
342 std::optional<uint64_t> LSDAAddress;
343 CIE *Cie = CIEs[IsEH ? (StartStructureOffset - CIEPointer) : CIEPointer];
349 "parsing FDE data at 0x%" PRIx64
350 " failed due to missing CIE",
354 EHFrameAddress +
Offset)) {
355 InitialLocation = *Val;
357 if (
auto Val = Data.getEncodedPointer(
363 if (!AugmentationString.
empty()) {
365 uint64_t AugmentationLength = Data.getULEB128(&
Offset);
367 uint64_t EndAugmentationOffset =
Offset + AugmentationLength;
371 LSDAAddress = Data.getEncodedPointer(
373 EHFrameAddress ?
Offset + EHFrameAddress : 0);
376 if (
Offset != EndAugmentationOffset)
378 "parsing augmentation data at 0x%" PRIx64
383 InitialLocation = Data.getRelocatedAddress(&
Offset);
387 Entries.emplace_back(
new FDE(IsDWARF64, StartOffset,
Length, CIEPointer,
392 if (!ParseCFIProgram) {
395 Entries.back()->markCFIProgramUnparsed(
Offset);
396 Offset = EndStructureOffset;
401 Entries.back()->cfis().parse(Data, &
Offset, EndStructureOffset))
404 if (
Offset != EndStructureOffset)
407 "parsing entry instructions at 0x%" PRIx64
" failed", StartOffset);
414 auto It =
partition_point(Entries, [=](
const std::unique_ptr<FrameEntry> &E) {
415 return E->getOffset() <
Offset;
417 if (It != Entries.end() && (*It)->getOffset() ==
Offset)
423 std::optional<uint64_t> StartOffset = Entry.getUnparsedCFIStartOffset();
430 "cannot parse the instructions of the entry at 0x%" PRIx64
431 " on demand: the section contents were not retained",
434 uint64_t
Offset = *StartOffset;
435 uint64_t EndOffset = Entry.getEndOffset();
437 "entry does not know where its instructions begin");
440 Entry.cfis().clear();
441 if (
Error E = Entry.cfis().parse(EntryData, &
Offset, EndOffset))
446 "parsing entry instructions at 0x%" PRIx64
451 Entry.markCFIProgramParsed();
456 for (
const auto &Entry : Entries)
465 if (
const CIE *Cie = Fde->getLinkedCIE())
466 if (
FrameEntry *CieEntry = getEntryAtOffset(Cie->getOffset()))
473 Entry.dump(OS, DumpOpts);
477 std::optional<uint64_t>
Offset)
const {
478 DumpOpts.
IsEH = IsEH;
480 if (
auto *Entry = getEntryAtOffset(*
Offset))
481 dumpEntry(*Entry, OS, DumpOpts);
486 for (
const auto &Entry : Entries)
487 dumpEntry(*Entry, OS, DumpOpts);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
constexpr uint64_t getCIEId(bool IsDWARF64, bool IsEH)
static void dumpDataAux(DataExtractor Data, uint64_t Offset, int Length)
This file defines the DenseMap class.
This file contains constants used for implementing Dwarf debug support.
A class that represents an address range.
LLVM_ABI DWARFDebugFrame(Triple::ArchType Arch, bool IsEH=false, uint64_t EHFrameAddress=0)
LLVM_ABI void dump(raw_ostream &OS, DIDumpOptions DumpOpts, std::optional< uint64_t > Offset) const
Dump the section data into the given stream.
LLVM_ABI ~DWARFDebugFrame()
LLVM_ABI Error parse(DWARFDataExtractor Data, bool ParseCFIProgram=true)
Parse the section from raw data.
LLVM_ABI Error parseAllCFIPrograms() const
Decode all the CFI instruction programs that parse() was told to skip.
LLVM_ABI Error parseCFIProgram(dwarf::FrameEntry &Entry) const
Decode the CFI instruction program of Entry if parse() was told to skip it.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Represent a constant reference to a string, i.e.
constexpr bool empty() const
Check if the string is empty.
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
constexpr size_t size() const
Get the string size.
DWARF Common Information Entry (CIE)
void dump(raw_ostream &OS, DIDumpOptions DumpOpts) const override
Dump the instructions in this CFI fragment.
uint32_t getLSDAPointerEncoding() const
uint32_t getFDEPointerEncoding() const
StringRef getAugmentationString() const
DWARF Frame Description Entry (FDE)
uint64_t getInitialLocation() const
const CIE * getLinkedCIE() const
void dump(raw_ostream &OS, DIDumpOptions DumpOpts) const override
Dump the instructions in this CFI fragment.
An entry in either debug_frame or eh_frame.
const uint64_t Length
Entry length as specified in DWARF.
const uint64_t Offset
Offset of this entry in the section.
const CFIProgram & cfis() const
uint64_t getOffset() const
A class that can track all registers with locations in a UnwindRow object.
@ Unspecified
Not specified.
A class that represents a single row in the unwind table that is decoded by parsing the DWARF Call Fr...
void setAddress(uint64_t Addr)
Set the address for this UnwindRow.
A class that contains all UnwindRow objects for an FDE or a single unwind row for a CIE.
std::vector< UnwindRow > RowContainer
This class implements an extremely fast bulk output stream that can only output to a stream.
raw_ostream & write_hex(unsigned long long N)
Output N in hexadecimal, without any prefix or padding.
LLVM_ABI StringRef FormatString(DwarfFormat Format)
Calculates the starting offsets for various sections within the .debug_names section.
const uint32_t DW_CIE_ID
Special ID values that distinguish a CIE from a FDE in DWARF CFI.
LLVM_ABI void printUnwindTable(const UnwindTable &Rows, raw_ostream &OS, DIDumpOptions DumpOpts, unsigned IndentLevel=0)
Print a UnwindTable to the stream.
const uint64_t DW64_CIE_ID
DwarfFormat
Constants that define the DWARF format as 32 or 64 bit.
LLVM_ABI Expected< UnwindTable > createUnwindTable(const CIE *Cie)
Create an UnwindTable from a Common Information Entry (CIE).
LLVM_ABI Expected< UnwindTable::RowContainer > parseRows(const CFIProgram &CFIP, UnwindRow &CurrRow, const RegisterLocations *InitialLocs)
Parse the information in the CFIProgram and update the CurrRow object that the state machine describe...
LLVM_ABI void printCFIProgram(const CFIProgram &P, raw_ostream &OS, const DIDumpOptions &DumpOpts, unsigned IndentLevel, std::optional< uint64_t > Address)
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
auto partition_point(R &&Range, Predicate P)
Binary search for the first iterator in a range where a predicate is false.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
Error joinErrors(Error E1, Error E2)
Concatenate errors.
char hexdigit(unsigned X, bool LowerCase=false)
hexdigit - Return the hexadecimal character for the given number X (which should be less than 16).
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
support::detail::AlignAdapter< T > fmt_align(T &&Item, AlignStyle Where, size_t Amount, char Fill=' ')
Container for dump options that control which debug information will be dumped.
std::function< void(Error)> RecoverableErrorHandler