42 "unable to get CIE for FDE at offset 0x%" PRIx64,
53 return std::move(CieError);
60 return std::move(FdeError);
63 AllRows.insert(AllRows.end(), CieRows.begin(), CieRows.end());
64 AllRows.insert(AllRows.end(), FdeRows.begin(), FdeRows.end());
68 if (Row.getRegisterLocations().hasLocations() ||
70 AllRows.push_back(Row);
82 return std::move(CieError);
85 if (Row.getRegisterLocations().hasLocations() ||
118 if (DumpOpts.
IsEH && Version != 1)
119 OS <<
"WARNING: unsupported CIE version\n";
120 OS <<
formatv(
" Version: {0}\n", Version)
121 <<
" Augmentation: \"" << Augmentation <<
"\"\n";
124 OS <<
formatv(
" Segment desc size: {0}\n",
127 OS <<
formatv(
" Code alignment factor: {0}\n",
129 OS <<
formatv(
" Data alignment factor: {0}\n", (int32_t)DataAlignmentFactor);
130 OS <<
formatv(
" Return address column: {0}\n",
131 (int32_t)ReturnAddressRegister);
133 OS <<
formatv(
" Personality Address: {0:x-16}\n", *Personality);
134 if (!AugmentationData.empty()) {
135 OS <<
" Augmentation data: ";
136 for (
uint8_t Byte : AugmentationData)
150 "decoding the CIE opcodes into rows failed"),
151 RowsOrErr.takeError()));
164 OS <<
formatv(
"{0:x-8}", LinkedCIE->getOffset());
166 OS <<
"<invalid offset>";
167 OS <<
formatv(
" pc={0:x-8}...{1:x-8}\n", InitialLocation,
168 InitialLocation + AddressRange);
171 OS <<
formatv(
" LSDA Address: {0:x-16}\n", *LSDAAddress);
180 "decoding the FDE opcodes into rows failed"),
181 RowsOrErr.takeError()));
188 : Arch(Arch), IsEH(IsEH), EHFrameAddress(EHFrameAddress) {}
195 for (
int i = 0; i <
Length; ++i) {
218 auto Cie = std::make_unique<CIE>(
219 IsDWARF64, StartOffset, 0, 0,
SmallString<8>(), 0, 0, 0, 0, 0,
221 CIEs[StartOffset] = Cie.get();
222 Entries.push_back(std::move(Cie));
240 if (Id ==
getCIEId(IsDWARF64, IsEH)) {
242 const char *Augmentation =
Data.getCStr(&
Offset);
243 StringRef AugmentationString(Augmentation ? Augmentation :
"");
246 Data.setAddressSize(AddressSize);
249 int64_t DataAlignmentFactor =
Data.getSLEB128(&
Offset);
257 std::optional<uint64_t> Personality;
258 std::optional<uint32_t> PersonalityEncoding;
260 std::optional<uint64_t> AugmentationLength;
265 for (
unsigned i = 0, e = AugmentationString.
size(); i != e; ++i) {
266 switch (AugmentationString[i]) {
270 "unknown augmentation character %c in entry at 0x%" PRIx64,
271 AugmentationString[i], StartOffset);
279 "duplicate personality in entry at 0x%" PRIx64, StartOffset);
281 Personality =
Data.getEncodedPointer(
282 &
Offset, *PersonalityEncoding,
283 EHFrameAddress ? EHFrameAddress +
Offset : 0);
296 "'z' must be the first character at 0x%" PRIx64, StartOffset);
299 AugmentationLength =
Data.getULEB128(&
Offset);
300 StartAugmentationOffset =
Offset;
301 EndAugmentationOffset =
Offset + *AugmentationLength;
314 if (AugmentationLength) {
315 if (
Offset != EndAugmentationOffset)
317 "parsing augmentation data at 0x%" PRIx64
320 AugmentationData =
Data.getData().slice(StartAugmentationOffset,
321 EndAugmentationOffset);
325 auto Cie = std::make_unique<CIE>(
327 AddressSize, SegmentDescriptorSize, CodeAlignmentFactor,
328 DataAlignmentFactor, ReturnAddressRegister, AugmentationData,
329 FDEPointerEncoding, LSDAPointerEncoding, Personality,
330 PersonalityEncoding, Arch);
331 CIEs[StartOffset] = Cie.get();
332 Entries.emplace_back(std::move(Cie));
338 std::optional<uint64_t> LSDAAddress;
339 CIE *Cie = CIEs[IsEH ? (StartStructureOffset - CIEPointer) : CIEPointer];
345 "parsing FDE data at 0x%" PRIx64
346 " failed due to missing CIE",
350 EHFrameAddress +
Offset)) {
351 InitialLocation = *Val;
353 if (
auto Val =
Data.getEncodedPointer(
359 if (!AugmentationString.
empty()) {
367 LSDAAddress =
Data.getEncodedPointer(
369 EHFrameAddress ?
Offset + EHFrameAddress : 0);
372 if (
Offset != EndAugmentationOffset)
374 "parsing augmentation data at 0x%" PRIx64
379 InitialLocation =
Data.getRelocatedAddress(&
Offset);
383 Entries.emplace_back(
new FDE(IsDWARF64, StartOffset,
Length, CIEPointer,
389 Entries.back()->cfis().parse(
Data, &
Offset, EndStructureOffset))
392 if (
Offset != EndStructureOffset)
395 "parsing entry instructions at 0x%" PRIx64
" failed", StartOffset);
402 auto It =
partition_point(Entries, [=](
const std::unique_ptr<FrameEntry> &E) {
403 return E->getOffset() <
Offset;
405 if (It != Entries.end() && (*It)->getOffset() ==
Offset)
411 std::optional<uint64_t>
Offset)
const {
412 DumpOpts.
IsEH = IsEH;
414 if (
auto *Entry = getEntryAtOffset(*
Offset))
415 Entry->dump(OS, DumpOpts);
420 for (
const auto &Entry : Entries)
421 Entry->dump(OS, DumpOpts);
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)
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...
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.
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)
FunctionAddr VTableAddr uintptr_t uintptr_t Version
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.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
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