LLVM 24.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"
19#include "llvm/Support/Error.h"
21#include <memory>
22#include <optional>
23#include <vector>
24
25namespace llvm {
26
27class raw_ostream;
28class MCRegisterInfo;
29struct DIDumpOptions;
30
31namespace dwarf {
32
33class CIE;
34
35/// Create an UnwindTable from a Common Information Entry (CIE).
36///
37/// \param Cie The Common Information Entry to extract the table from. The
38/// CFIProgram is retrieved from the \a Cie object and used to create the
39/// UnwindTable.
40///
41/// \returns An error if the DWARF Call Frame Information opcodes have state
42/// machine errors, or a valid UnwindTable otherwise.
43LLVM_ABI Expected<UnwindTable> createUnwindTable(const CIE *Cie);
44
45class FDE;
46
47/// Create an UnwindTable from a Frame Descriptor Entry (FDE).
48///
49/// \param Fde The Frame Descriptor Entry to extract the table from. The
50/// CFIProgram is retrieved from the \a Fde object and used to create the
51/// UnwindTable.
52///
53/// \returns An error if the DWARF Call Frame Information opcodes have state
54/// machine errors, or a valid UnwindTable otherwise.
55LLVM_ABI Expected<UnwindTable> createUnwindTable(const FDE *Fde);
56
57/// An entry in either debug_frame or eh_frame. This entry can be a CIE or an
58/// FDE.
60public:
62
64 uint64_t CodeAlign, int64_t DataAlign, Triple::ArchType Arch)
66 CFIs(CodeAlign, DataAlign, Arch) {}
67
68 virtual ~FrameEntry() = default;
69
70 FrameKind getKind() const { return Kind; }
71 uint64_t getOffset() const { return Offset; }
72 uint64_t getLength() const { return Length; }
73 const CFIProgram &cfis() const { return CFIs; }
74 CFIProgram &cfis() { return CFIs; }
75
76 /// If using lazily parsed CFIs, this returns the section offset where the
77 /// unparsed CFIs start so user can parse them on-demand through the
78 /// CFIProgram parsing interface cfis().parse(Data, ..., getEndOffset()).
79 /// This returns std::nullopt if CFIs are already succesfully parsed.
80 std::optional<uint64_t> getUnparsedCFIStartOffset() const {
82 }
83 void markCFIProgramUnparsed(uint64_t StartOffset) {
84 UnparsedCFIStartOffset = StartOffset;
85 }
88 // End is Offset plus the size of the initial length field plus Length.
89 // The initial length field is 4 bytes in DWARF32 and 12 bytes in DWARF64
90 // (a 0xffffffff escape marker followed by an 8-byte length).
91 return Offset + (IsDWARF64 ? 12 : 4) + Length;
92 }
93
94 /// Dump the instructions in this CFI fragment
95 virtual void dump(raw_ostream &OS, DIDumpOptions DumpOpts) const = 0;
96
97protected:
99
100 const bool IsDWARF64;
101
102 /// Offset of this entry in the section.
104
105 /// Entry length as specified in DWARF.
107
108 /// Offset for lazy parsing; std::nullopt if CFIs are already parsed.
109 std::optional<uint64_t> UnparsedCFIStartOffset;
110
112};
113
114/// DWARF Common Information Entry (CIE)
115class LLVM_ABI CIE : public FrameEntry {
116public:
117 // CIEs (and FDEs) are simply container classes, so the only sensible way to
118 // create them is by providing the full parsed contents in the constructor.
120 SmallString<8> Augmentation, uint8_t AddressSize,
121 uint8_t SegmentDescriptorSize, uint64_t CodeAlignmentFactor,
122 int64_t DataAlignmentFactor, uint64_t ReturnAddressRegister,
123 SmallString<8> AugmentationData, uint32_t FDEPointerEncoding,
124 uint32_t LSDAPointerEncoding, std::optional<uint64_t> Personality,
125 std::optional<uint32_t> PersonalityEnc, Triple::ArchType Arch)
126 : FrameEntry(FK_CIE, IsDWARF64, Offset, Length, CodeAlignmentFactor,
127 DataAlignmentFactor, Arch),
128 Version(Version), Augmentation(std::move(Augmentation)),
129 AddressSize(AddressSize), SegmentDescriptorSize(SegmentDescriptorSize),
130 CodeAlignmentFactor(CodeAlignmentFactor),
131 DataAlignmentFactor(DataAlignmentFactor),
132 ReturnAddressRegister(ReturnAddressRegister),
133 AugmentationData(std::move(AugmentationData)),
134 FDEPointerEncoding(FDEPointerEncoding),
135 LSDAPointerEncoding(LSDAPointerEncoding), Personality(Personality),
136 PersonalityEnc(PersonalityEnc) {}
137
138 static bool classof(const FrameEntry *FE) { return FE->getKind() == FK_CIE; }
139
140 StringRef getAugmentationString() const { return Augmentation; }
141 uint64_t getCodeAlignmentFactor() const { return CodeAlignmentFactor; }
142 int64_t getDataAlignmentFactor() const { return DataAlignmentFactor; }
143 uint8_t getVersion() const { return Version; }
144 uint64_t getReturnAddressRegister() const { return ReturnAddressRegister; }
145 std::optional<uint64_t> getPersonalityAddress() const { return Personality; }
146 std::optional<uint32_t> getPersonalityEncoding() const {
147 return PersonalityEnc;
148 }
149
150 StringRef getAugmentationData() const { return AugmentationData; }
151
152 uint32_t getFDEPointerEncoding() const { return FDEPointerEncoding; }
153
154 uint32_t getLSDAPointerEncoding() const { return LSDAPointerEncoding; }
155
156 void dump(raw_ostream &OS, DIDumpOptions DumpOpts) const override;
157
158private:
159 /// The following fields are defined in section 6.4.1 of the DWARF standard v4
160 const uint8_t Version;
161 const SmallString<8> Augmentation;
162 const uint8_t AddressSize;
163 const uint8_t SegmentDescriptorSize;
164 const uint64_t CodeAlignmentFactor;
165 const int64_t DataAlignmentFactor;
166 const uint64_t ReturnAddressRegister;
167
168 // The following are used when the CIE represents an EH frame entry.
169 const SmallString<8> AugmentationData;
170 const uint32_t FDEPointerEncoding;
171 const uint32_t LSDAPointerEncoding;
172 const std::optional<uint64_t> Personality;
173 const std::optional<uint32_t> PersonalityEnc;
174};
175
176/// DWARF Frame Description Entry (FDE)
177class LLVM_ABI FDE : public FrameEntry {
178public:
180 uint64_t InitialLocation, uint64_t AddressRange, CIE *Cie,
181 std::optional<uint64_t> LSDAAddress, Triple::ArchType Arch)
183 Cie ? Cie->getCodeAlignmentFactor() : 0,
184 Cie ? Cie->getDataAlignmentFactor() : 0, Arch),
185 CIEPointer(CIEPointer), InitialLocation(InitialLocation),
186 AddressRange(AddressRange), LinkedCIE(Cie), LSDAAddress(LSDAAddress) {}
187
188 ~FDE() override = default;
189
190 const CIE *getLinkedCIE() const { return LinkedCIE; }
191 uint64_t getCIEPointer() const { return CIEPointer; }
192 uint64_t getInitialLocation() const { return InitialLocation; }
193 uint64_t getAddressRange() const { return AddressRange; }
194 std::optional<uint64_t> getLSDAAddress() const { return LSDAAddress; }
195
196 void dump(raw_ostream &OS, DIDumpOptions DumpOpts) const override;
197
198 static bool classof(const FrameEntry *FE) { return FE->getKind() == FK_FDE; }
199
200private:
201 /// The following fields are defined in section 6.4.1 of the DWARFv3 standard.
202 /// Note that CIE pointers in EH FDEs, unlike DWARF FDEs, contain relative
203 /// offsets to the linked CIEs. See the following link for more info:
204 /// https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html
205 const uint64_t CIEPointer;
206 const uint64_t InitialLocation;
208 const CIE *LinkedCIE;
209 const std::optional<uint64_t> LSDAAddress;
210};
211
212} // end namespace dwarf
213
214/// A parsed .debug_frame or .eh_frame section
216 const Triple::ArchType Arch;
217 // True if this is parsing an eh_frame section.
218 const bool IsEH;
219 // Not zero for sane pointer values coming out of eh_frame
220 const uint64_t EHFrameAddress;
221
222 std::vector<std::unique_ptr<dwarf::FrameEntry>> Entries;
223 using iterator = pointee_iterator<decltype(Entries)::const_iterator>;
224
225 /// Section contents, retained by parse() when it was asked to leave the CFI
226 /// instruction programs undecoded, so that they can be parsed on demand.
227 std::optional<DWARFDataExtractor> Data;
228
229 /// Return the entry at the given offset or nullptr.
230 dwarf::FrameEntry *getEntryAtOffset(uint64_t Offset) const;
231
232 /// Make sure CFIs of \p Entry are fully parsed, then dump the entry.
233 /// Failure to decode the CFI is reported through \p DumpOpts.
234 void dumpEntry(dwarf::FrameEntry &Entry, raw_ostream &OS,
235 DIDumpOptions DumpOpts) const;
236
237public:
238 // If IsEH is true, assume it is a .eh_frame section. Otherwise,
239 // it is a .debug_frame section. EHFrameAddress should be different
240 // than zero for correct parsing of .eh_frame addresses when they
241 // use a PC-relative encoding.
242 LLVM_ABI DWARFDebugFrame(Triple::ArchType Arch, bool IsEH = false,
243 uint64_t EHFrameAddress = 0);
245
246 /// Dump the section data into the given stream.
247 LLVM_ABI void dump(raw_ostream &OS, DIDumpOptions DumpOpts,
248 std::optional<uint64_t> Offset) const;
249
250 /// Parse the section from raw data. \p Data is assumed to contain the whole
251 /// frame section contents to be parsed.
252 ///
253 /// If \p ParseCFIProgram is false, the CFI instruction program of each entry
254 /// is not decoded; callers can parse individual programs on demand through
255 /// parseCFIProgram(), as long as \p Data stays valid.
256 LLVM_ABI Error parse(DWARFDataExtractor Data, bool ParseCFIProgram = true);
257
258 /// Decode the CFI instruction program of \p Entry if parse() was told to
259 /// skip it.
261
262 /// Decode all the CFI instruction programs that parse() was told to skip.
264
265 /// Return whether the section has any entries.
266 bool empty() const { return Entries.empty(); }
267
268 /// DWARF Frame entries accessors
269 iterator begin() const { return Entries.begin(); }
270 iterator end() const { return Entries.end(); }
271 iterator_range<iterator> entries() const { return Entries; }
272
273 uint64_t getEHFrameAddress() const { return EHFrameAddress; }
274};
275
276} // end namespace llvm
277
278#endif // LLVM_DEBUGINFO_DWARF_DWARFDEBUGFRAME_H
unsigned uint64_t
#define LLVM_ABI
Definition Compiler.h:215
static int getDataAlignmentFactor(MCStreamer &streamer)
Definition MCDwarf.cpp:1340
This file defines the SmallString class.
A class that represents an address range.
A DWARFDataExtractor (typically for an in-memory copy of an object-file section) plus a relocation ma...
iterator_range< iterator > entries() const
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.
iterator begin() const
DWARF Frame entries accessors.
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.
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
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
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
std::optional< uint64_t > getUnparsedCFIStartOffset() const
If using lazily parsed CFIs, this returns the section offset where the unparsed CFIs start so user ca...
uint64_t getEndOffset() const
uint64_t getLength() const
std::optional< uint64_t > UnparsedCFIStartOffset
Offset for lazy parsing; std::nullopt if CFIs are already parsed.
void markCFIProgramUnparsed(uint64_t StartOffset)
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
Calculates the starting offsets for various sections within the .debug_names section.
Definition Dwarf.h:35
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.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
@ Offset
Definition DWP.cpp:577
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:1917
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:878
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:329