LLVM 22.0.0git
DWARFDebugFrame.h
Go to the documentation of this file.
1//===- DWARFDebugFrame.h - Parsing of .debug_frame --------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_DEBUGINFO_DWARF_DWARFDEBUGFRAME_H
10#define LLVM_DEBUGINFO_DWARF_DWARFDEBUGFRAME_H
11
13#include "llvm/ADT/iterator.h"
18#include "llvm/Support/Error.h"
20#include <memory>
21#include <vector>
22
23namespace llvm {
24
25class raw_ostream;
26class DWARFDataExtractor;
27class MCRegisterInfo;
28struct DIDumpOptions;
29
30namespace dwarf {
31
32class CIE;
33
34/// Create an UnwindTable from a Common Information Entry (CIE).
35///
36/// \param Cie The Common Information Entry to extract the table from. The
37/// CFIProgram is retrieved from the \a Cie object and used to create the
38/// UnwindTable.
39///
40/// \returns An error if the DWARF Call Frame Information opcodes have state
41/// machine errors, or a valid UnwindTable otherwise.
42LLVM_ABI Expected<UnwindTable> createUnwindTable(const CIE *Cie);
43
44class FDE;
45
46/// Create an UnwindTable from a Frame Descriptor Entry (FDE).
47///
48/// \param Fde The Frame Descriptor Entry to extract the table from. The
49/// CFIProgram is retrieved from the \a Fde object and used to create the
50/// UnwindTable.
51///
52/// \returns An error if the DWARF Call Frame Information opcodes have state
53/// machine errors, or a valid UnwindTable otherwise.
54LLVM_ABI Expected<UnwindTable> createUnwindTable(const FDE *Fde);
55
56/// An entry in either debug_frame or eh_frame. This entry can be a CIE or an
57/// FDE.
59public:
61
63 uint64_t CodeAlign, int64_t DataAlign, Triple::ArchType Arch)
65 CFIs(CodeAlign, DataAlign, Arch) {}
66
67 virtual ~FrameEntry() = default;
68
69 FrameKind getKind() const { return Kind; }
70 uint64_t getOffset() const { return Offset; }
71 uint64_t getLength() const { return Length; }
72 const CFIProgram &cfis() const { return CFIs; }
73 CFIProgram &cfis() { return CFIs; }
74
75 /// Dump the instructions in this CFI fragment
76 virtual void dump(raw_ostream &OS, DIDumpOptions DumpOpts) const = 0;
77
78protected:
80
81 const bool IsDWARF64;
82
83 /// Offset of this entry in the section.
85
86 /// Entry length as specified in DWARF.
88
90};
91
92/// DWARF Common Information Entry (CIE)
93class LLVM_ABI CIE : public FrameEntry {
94public:
95 // CIEs (and FDEs) are simply container classes, so the only sensible way to
96 // create them is by providing the full parsed contents in the constructor.
97 CIE(bool IsDWARF64, uint64_t Offset, uint64_t Length, uint8_t Version,
98 SmallString<8> Augmentation, uint8_t AddressSize,
99 uint8_t SegmentDescriptorSize, uint64_t CodeAlignmentFactor,
100 int64_t DataAlignmentFactor, uint64_t ReturnAddressRegister,
101 SmallString<8> AugmentationData, uint32_t FDEPointerEncoding,
102 uint32_t LSDAPointerEncoding, std::optional<uint64_t> Personality,
103 std::optional<uint32_t> PersonalityEnc, Triple::ArchType Arch)
104 : FrameEntry(FK_CIE, IsDWARF64, Offset, Length, CodeAlignmentFactor,
105 DataAlignmentFactor, Arch),
106 Version(Version), Augmentation(std::move(Augmentation)),
107 AddressSize(AddressSize), SegmentDescriptorSize(SegmentDescriptorSize),
108 CodeAlignmentFactor(CodeAlignmentFactor),
109 DataAlignmentFactor(DataAlignmentFactor),
110 ReturnAddressRegister(ReturnAddressRegister),
111 AugmentationData(std::move(AugmentationData)),
112 FDEPointerEncoding(FDEPointerEncoding),
113 LSDAPointerEncoding(LSDAPointerEncoding), Personality(Personality),
114 PersonalityEnc(PersonalityEnc) {}
115
116 static bool classof(const FrameEntry *FE) { return FE->getKind() == FK_CIE; }
117
118 StringRef getAugmentationString() const { return Augmentation; }
119 uint64_t getCodeAlignmentFactor() const { return CodeAlignmentFactor; }
120 int64_t getDataAlignmentFactor() const { return DataAlignmentFactor; }
121 uint8_t getVersion() const { return Version; }
122 uint64_t getReturnAddressRegister() const { return ReturnAddressRegister; }
123 std::optional<uint64_t> getPersonalityAddress() const { return Personality; }
124 std::optional<uint32_t> getPersonalityEncoding() const {
125 return PersonalityEnc;
126 }
127
128 StringRef getAugmentationData() const { return AugmentationData; }
129
130 uint32_t getFDEPointerEncoding() const { return FDEPointerEncoding; }
131
132 uint32_t getLSDAPointerEncoding() const { return LSDAPointerEncoding; }
133
134 void dump(raw_ostream &OS, DIDumpOptions DumpOpts) const override;
135
136private:
137 /// The following fields are defined in section 6.4.1 of the DWARF standard v4
138 const uint8_t Version;
139 const SmallString<8> Augmentation;
140 const uint8_t AddressSize;
141 const uint8_t SegmentDescriptorSize;
142 const uint64_t CodeAlignmentFactor;
143 const int64_t DataAlignmentFactor;
144 const uint64_t ReturnAddressRegister;
145
146 // The following are used when the CIE represents an EH frame entry.
147 const SmallString<8> AugmentationData;
148 const uint32_t FDEPointerEncoding;
149 const uint32_t LSDAPointerEncoding;
150 const std::optional<uint64_t> Personality;
151 const std::optional<uint32_t> PersonalityEnc;
152};
153
154/// DWARF Frame Description Entry (FDE)
155class LLVM_ABI FDE : public FrameEntry {
156public:
157 FDE(bool IsDWARF64, uint64_t Offset, uint64_t Length, uint64_t CIEPointer,
158 uint64_t InitialLocation, uint64_t AddressRange, CIE *Cie,
159 std::optional<uint64_t> LSDAAddress, Triple::ArchType Arch)
160 : FrameEntry(FK_FDE, IsDWARF64, Offset, Length,
161 Cie ? Cie->getCodeAlignmentFactor() : 0,
162 Cie ? Cie->getDataAlignmentFactor() : 0, Arch),
163 CIEPointer(CIEPointer), InitialLocation(InitialLocation),
164 AddressRange(AddressRange), LinkedCIE(Cie), LSDAAddress(LSDAAddress) {}
165
166 ~FDE() override = default;
167
168 const CIE *getLinkedCIE() const { return LinkedCIE; }
169 uint64_t getCIEPointer() const { return CIEPointer; }
170 uint64_t getInitialLocation() const { return InitialLocation; }
172 std::optional<uint64_t> getLSDAAddress() const { return LSDAAddress; }
173
174 void dump(raw_ostream &OS, DIDumpOptions DumpOpts) const override;
175
176 static bool classof(const FrameEntry *FE) { return FE->getKind() == FK_FDE; }
177
178private:
179 /// The following fields are defined in section 6.4.1 of the DWARFv3 standard.
180 /// Note that CIE pointers in EH FDEs, unlike DWARF FDEs, contain relative
181 /// offsets to the linked CIEs. See the following link for more info:
182 /// https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html
183 const uint64_t CIEPointer;
184 const uint64_t InitialLocation;
186 const CIE *LinkedCIE;
187 const std::optional<uint64_t> LSDAAddress;
188};
189
190} // end namespace dwarf
191
192/// A parsed .debug_frame or .eh_frame section
194 const Triple::ArchType Arch;
195 // True if this is parsing an eh_frame section.
196 const bool IsEH;
197 // Not zero for sane pointer values coming out of eh_frame
198 const uint64_t EHFrameAddress;
199
200 std::vector<std::unique_ptr<dwarf::FrameEntry>> Entries;
201 using iterator = pointee_iterator<decltype(Entries)::const_iterator>;
202
203 /// Return the entry at the given offset or nullptr.
204 dwarf::FrameEntry *getEntryAtOffset(uint64_t Offset) const;
205
206public:
207 // If IsEH is true, assume it is a .eh_frame section. Otherwise,
208 // it is a .debug_frame section. EHFrameAddress should be different
209 // than zero for correct parsing of .eh_frame addresses when they
210 // use a PC-relative encoding.
211 LLVM_ABI DWARFDebugFrame(Triple::ArchType Arch, bool IsEH = false,
212 uint64_t EHFrameAddress = 0);
214
215 /// Dump the section data into the given stream.
216 LLVM_ABI void dump(raw_ostream &OS, DIDumpOptions DumpOpts,
217 std::optional<uint64_t> Offset) const;
218
219 /// Parse the section from raw data. \p Data is assumed to contain the whole
220 /// frame section contents to be parsed.
222
223 /// Return whether the section has any entries.
224 bool empty() const { return Entries.empty(); }
225
226 /// DWARF Frame entries accessors
227 iterator begin() const { return Entries.begin(); }
228 iterator end() const { return Entries.end(); }
230 return iterator_range<iterator>(Entries.begin(), Entries.end());
231 }
232
233 uint64_t getEHFrameAddress() const { return EHFrameAddress; }
234};
235
236} // end namespace llvm
237
238#endif // LLVM_DEBUGINFO_DWARF_DWARFDEBUGFRAME_H
#define LLVM_ABI
Definition: Compiler.h:213
uint64_t Offset
Definition: ELF_riscv.cpp:478
static int getDataAlignmentFactor(MCStreamer &streamer)
Definition: MCDwarf.cpp:1285
raw_pwrite_stream & OS
This file defines the SmallString class.
A class that represents an address range.
Definition: AddressRanges.h:22
A DWARFDataExtractor (typically for an in-memory copy of an object-file section) plus a relocation ma...
A parsed .debug_frame or .eh_frame section.
iterator end() const
iterator_range< iterator > entries() const
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()
iterator begin() const
DWARF Frame entries accessors.
uint64_t getEHFrameAddress() const
bool empty() const
Return whether the section has any entries.
Lightweight error class with error context and mandatory checking.
Definition: Error.h:159
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:26
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
Represent a sequence of Call Frame Information instructions that, when read in order,...
DWARF Common Information Entry (CIE)
static bool classof(const FrameEntry *FE)
CIE(bool IsDWARF64, uint64_t Offset, uint64_t Length, uint8_t Version, SmallString< 8 > Augmentation, uint8_t AddressSize, uint8_t SegmentDescriptorSize, uint64_t CodeAlignmentFactor, int64_t DataAlignmentFactor, uint64_t ReturnAddressRegister, SmallString< 8 > AugmentationData, uint32_t FDEPointerEncoding, uint32_t LSDAPointerEncoding, std::optional< uint64_t > Personality, std::optional< uint32_t > PersonalityEnc, Triple::ArchType Arch)
uint64_t getReturnAddressRegister() const
uint8_t getVersion() const
int64_t getDataAlignmentFactor() const
std::optional< uint32_t > getPersonalityEncoding() const
std::optional< uint64_t > getPersonalityAddress() const
StringRef getAugmentationData() const
uint64_t getCodeAlignmentFactor() const
uint32_t getLSDAPointerEncoding() const
uint32_t getFDEPointerEncoding() const
StringRef getAugmentationString() const
DWARF Frame Description Entry (FDE)
uint64_t getAddressRange() const
uint64_t getInitialLocation() const
uint64_t getCIEPointer() const
std::optional< uint64_t > getLSDAAddress() const
~FDE() override=default
const CIE * getLinkedCIE() const
static bool classof(const FrameEntry *FE)
FDE(bool IsDWARF64, uint64_t Offset, uint64_t Length, uint64_t CIEPointer, uint64_t InitialLocation, uint64_t AddressRange, CIE *Cie, std::optional< uint64_t > LSDAAddress, Triple::ArchType Arch)
An entry in either debug_frame or eh_frame.
FrameEntry(FrameKind K, bool IsDWARF64, uint64_t Offset, uint64_t Length, uint64_t CodeAlign, int64_t DataAlign, Triple::ArchType Arch)
const uint64_t Length
Entry length as specified in DWARF.
const uint64_t Offset
Offset of this entry in the section.
virtual ~FrameEntry()=default
virtual void dump(raw_ostream &OS, DIDumpOptions DumpOpts) const =0
Dump the instructions in this CFI fragment.
const CFIProgram & cfis() const
FrameKind getKind() const
uint64_t getLength() const
uint64_t getOffset() const
A range adaptor for a pair of iterators.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
LLVM_ABI Expected< UnwindTable > createUnwindTable(const CIE *Cie)
Create an UnwindTable from a Common Information Entry (CIE).
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
@ Offset
Definition: DWP.cpp:477
@ Length
Definition: DWP.cpp:477
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1886
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:856
Container for dump options that control which debug information will be dumped.
Definition: DIContext.h:196
An iterator type that allows iterating over the pointees via some other iterator.
Definition: iterator.h:324
Definition: regcomp.c:186