40 "unable to get CIE for FDE at offset 0x%" PRIx64,
51 return std::move(CieError);
58 return std::move(FdeError);
61 AllRows.insert(AllRows.end(), CieRows.begin(), CieRows.end());
62 AllRows.insert(AllRows.end(), FdeRows.begin(), FdeRows.end());
66 if (Row.getRegisterLocations().hasLocations() ||
68 AllRows.push_back(Row);
80 return std::move(CieError);
83 if (Row.getRegisterLocations().hasLocations() ||
114 if (DumpOpts.
IsEH && Version != 1)
115 OS <<
"WARNING: unsupported CIE version\n";
116 OS <<
format(
" Version: %d\n", Version)
117 <<
" Augmentation: \"" << Augmentation <<
"\"\n";
120 OS <<
format(
" Segment desc size: %u\n",
123 OS <<
format(
" Code alignment factor: %u\n", (
uint32_t)CodeAlignmentFactor);
124 OS <<
format(
" Data alignment factor: %d\n", (int32_t)DataAlignmentFactor);
125 OS <<
format(
" Return address column: %d\n", (int32_t)ReturnAddressRegister);
127 OS <<
format(
" Personality Address: %016" PRIx64
"\n", *Personality);
128 if (!AugmentationData.
empty()) {
129 OS <<
" Augmentation data: ";
130 for (
uint8_t Byte : AugmentationData)
131 OS <<
' ' << hexdigit(Byte >> 4) << hexdigit(Byte & 0xf);
144 "decoding the CIE opcodes into rows failed"),
145 RowsOrErr.takeError()));
158 OS <<
"<invalid offset>";
159 OS <<
format(
" pc=%08" PRIx64
"...%08" PRIx64
"\n", InitialLocation,
163 OS <<
format(
" LSDA Address: %016" PRIx64
"\n", *LSDAAddress);
172 "decoding the FDE opcodes into rows failed"),
173 RowsOrErr.takeError()));
180 : Arch(Arch), IsEH(IsEH), EHFrameAddress(EHFrameAddress) {}
187 for (
int i = 0; i <
Length; ++i) {
210 auto Cie = std::make_unique<CIE>(
211 IsDWARF64, StartOffset, 0, 0,
SmallString<8>(), 0, 0, 0, 0, 0,
213 CIEs[StartOffset] = Cie.get();
214 Entries.push_back(std::move(Cie));
232 if (Id ==
getCIEId(IsDWARF64, IsEH)) {
234 const char *Augmentation =
Data.getCStr(&
Offset);
235 StringRef AugmentationString(Augmentation ? Augmentation :
"");
238 Data.setAddressSize(AddressSize);
241 int64_t DataAlignmentFactor =
Data.getSLEB128(&
Offset);
249 std::optional<uint64_t> Personality;
250 std::optional<uint32_t> PersonalityEncoding;
252 std::optional<uint64_t> AugmentationLength;
257 for (
unsigned i = 0, e = AugmentationString.
size(); i != e; ++i) {
258 switch (AugmentationString[i]) {
262 "unknown augmentation character %c in entry at 0x%" PRIx64,
263 AugmentationString[i], StartOffset);
271 "duplicate personality in entry at 0x%" PRIx64, StartOffset);
273 Personality =
Data.getEncodedPointer(
274 &
Offset, *PersonalityEncoding,
275 EHFrameAddress ? EHFrameAddress +
Offset : 0);
288 "'z' must be the first character at 0x%" PRIx64, StartOffset);
291 AugmentationLength =
Data.getULEB128(&
Offset);
292 StartAugmentationOffset =
Offset;
293 EndAugmentationOffset =
Offset + *AugmentationLength;
306 if (AugmentationLength) {
307 if (
Offset != EndAugmentationOffset)
309 "parsing augmentation data at 0x%" PRIx64
312 AugmentationData =
Data.getData().slice(StartAugmentationOffset,
313 EndAugmentationOffset);
317 auto Cie = std::make_unique<CIE>(
319 AddressSize, SegmentDescriptorSize, CodeAlignmentFactor,
320 DataAlignmentFactor, ReturnAddressRegister, AugmentationData,
321 FDEPointerEncoding, LSDAPointerEncoding, Personality,
322 PersonalityEncoding, Arch);
323 CIEs[StartOffset] = Cie.get();
324 Entries.emplace_back(std::move(Cie));
330 std::optional<uint64_t> LSDAAddress;
331 CIE *Cie = CIEs[IsEH ? (StartStructureOffset - CIEPointer) : CIEPointer];
337 "parsing FDE data at 0x%" PRIx64
338 " failed due to missing CIE",
342 EHFrameAddress +
Offset)) {
343 InitialLocation = *Val;
345 if (
auto Val =
Data.getEncodedPointer(
351 if (!AugmentationString.
empty()) {
359 LSDAAddress =
Data.getEncodedPointer(
361 EHFrameAddress ?
Offset + EHFrameAddress : 0);
364 if (
Offset != EndAugmentationOffset)
366 "parsing augmentation data at 0x%" PRIx64
371 InitialLocation =
Data.getRelocatedAddress(&
Offset);
375 Entries.emplace_back(
new FDE(IsDWARF64, StartOffset,
Length, CIEPointer,
381 Entries.back()->cfis().parse(
Data, &
Offset, EndStructureOffset))
384 if (
Offset != EndStructureOffset)
387 "parsing entry instructions at 0x%" PRIx64
" failed", StartOffset);
394 auto It =
partition_point(Entries, [=](
const std::unique_ptr<FrameEntry> &E) {
395 return E->getOffset() <
Offset;
397 if (It != Entries.end() && (*It)->getOffset() ==
Offset)
403 std::optional<uint64_t>
Offset)
const {
404 DumpOpts.
IsEH = IsEH;
406 if (
auto *Entry = getEntryAtOffset(*
Offset))
407 Entry->dump(
OS, DumpOpts);
412 for (
const auto &Entry : Entries)
413 Entry->dump(
OS, DumpOpts);
#define LLVM_ATTRIBUTE_UNUSED
static void LLVM_ATTRIBUTE_UNUSED dumpDataAux(DataExtractor Data, uint64_t Offset, int Length)
constexpr uint64_t getCIEId(bool IsDWARF64, bool IsEH)
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)
Parse the section from raw data.
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...
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
constexpr size_t size() const
size - 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...
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)
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.
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.
Error joinErrors(Error E1, Error E2)
Concatenate errors.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Container for dump options that control which debug information will be dumped.
std::function< void(Error)> RecoverableErrorHandler