LLVM 23.0.0git
DWARFDataExtractorSimple.h
Go to the documentation of this file.
1//===- DWARFDataExtractorSimple.h -------------------------------*- 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_LOWLEVEL_DWARFDATAEXTRACTORSIMPLE_H
10#define LLVM_DEBUGINFO_DWARF_LOWLEVEL_DWARFDATAEXTRACTORSIMPLE_H
11
15#include "llvm/Support/Errc.h"
17
18namespace llvm {
19
20/// A DataExtractor suitable use for parsing dwarf from memory. Clients use
21/// Relocator::getRelocatedValueImpl to relocate values as appropriate.
22
23template <typename Relocator>
25 unsigned AddressSize;
26
27public:
28 DWARFDataExtractorBase(StringRef Data, bool IsLittleEndian,
29 unsigned AddressSize)
30 : DataExtractor(Data, IsLittleEndian), AddressSize(AddressSize) {}
31
32 DWARFDataExtractorBase(ArrayRef<uint8_t> Data, bool IsLittleEndian,
33 unsigned AddressSize)
35 StringRef(reinterpret_cast<const char *>(Data.data()), Data.size()),
36 IsLittleEndian),
37 AddressSize(AddressSize) {}
38
39 /// Truncating constructor
43
44 /// Get the address size for this extractor.
45 unsigned getAddressSize() const { return AddressSize; }
46
47 /// Set the address size for this extractor.
48 void setAddressSize(unsigned Size) { AddressSize = Size; }
49
50 //------------------------------------------------------------------
51 /// Extract an address from \a *OffsetPtr.
52 ///
53 /// Extract a single address from the data and update the offset
54 /// pointed to by \a OffsetPtr. The size of the extracted address
55 /// is \a getAddressSize(), so the address size has to be
56 /// set correctly prior to extracting any address values.
57 ///
58 /// @param[in,out] OffsetPtr
59 /// A pointer to an offset within the data that will be advanced
60 /// by the appropriate number of bytes if the value is extracted
61 /// correctly. If the offset is out of bounds or there are not
62 /// enough bytes to extract this value, the offset will be left
63 /// unmodified.
64 ///
65 /// @return
66 /// The extracted address value as a 64 integer.
67 uint64_t getAddress(uint64_t *OffsetPtr) const {
68 return getUnsigned(OffsetPtr, AddressSize);
69 }
70
71 /// Extract an address-sized unsigned integer from the location given by the
72 /// cursor. In case of an extraction error, or if the cursor is already in
73 /// an error state, zero is returned.
74 uint64_t getAddress(Cursor &C) const { return getUnsigned(C, AddressSize); }
75
76 /// Test the availability of enough bytes of data for an address from
77 /// \a Offset. The size of an address is \a getAddressSize().
78 ///
79 /// @return
80 /// \b true if \a Offset is a valid offset and there are enough
81 /// bytes for an address available at that offset, \b false
82 /// otherwise.
84 return isValidOffsetForDataOfSize(Offset, AddressSize);
85 }
86
87 /// Extracts a value and returns it as adjusted by the Relocator
89 uint64_t *SectionIndex = nullptr,
90 Error *Err = nullptr) const {
91 return static_cast<const Relocator *>(this)->getRelocatedValueImpl(
92 Size, Off, SectionIndex, Err);
93 }
94
96 uint64_t *SectionIndex = nullptr) const {
97 return getRelocatedValue(Size, &getOffset(C), SectionIndex, &getError(C));
98 }
99
100 /// Extracts an address-sized value.
101 uint64_t getRelocatedAddress(uint64_t *Off, uint64_t *SecIx = nullptr) const {
102 return getRelocatedValue(getAddressSize(), Off, SecIx);
103 }
104
105 uint64_t getRelocatedAddress(Cursor &C, uint64_t *SecIx = nullptr) const {
106 return getRelocatedValue(getAddressSize(), &getOffset(C), SecIx,
107 &getError(C));
108 }
109
110 /// Extracts the DWARF "initial length" field, which can either be a 32-bit
111 /// value smaller than 0xfffffff0, or the value 0xffffffff followed by a
112 /// 64-bit length. Returns the actual length, and the DWARF format which is
113 /// encoded in the field. In case of errors, it returns {0, DWARF32} and
114 /// leaves the offset unchanged.
115 std::pair<uint64_t, dwarf::DwarfFormat>
116 getInitialLength(uint64_t *Off, Error *Err = nullptr) const {
117 ErrorAsOutParameter ErrAsOut(Err);
118 if (Err && *Err)
119 return {0, dwarf::DWARF32};
120
121 Cursor C(*Off);
127 } else if (Length >= dwarf::DW_LENGTH_lo_reserved) {
128 cantFail(C.takeError());
129 if (Err)
130 *Err = createStringError(
131 std::errc::invalid_argument,
132 "unsupported reserved unit length of value 0x%8.8" PRIx64, Length);
133 return {0, dwarf::DWARF32};
134 }
135
136 if (C) {
137 *Off = C.tell();
138 return {Length, Format};
139 }
140 if (Err)
141 *Err = C.takeError();
142 else
143 consumeError(C.takeError());
144 return {0, dwarf::DWARF32};
145 }
146
147 std::pair<uint64_t, dwarf::DwarfFormat> getInitialLength(Cursor &C) const {
149 }
150
151 /// Extracts a DWARF-encoded pointer in \p Offset using \p Encoding.
152 /// There is a DWARF encoding that uses a PC-relative adjustment.
153 /// For these values, \p AbsPosOffset is used to fix them, which should
154 /// reflect the absolute address of this pointer.
155 std::optional<uint64_t> getEncodedPointer(uint64_t *Offset, uint8_t Encoding,
156 uint64_t PCRelOffset) const {
157 if (Encoding == dwarf::DW_EH_PE_omit)
158 return std::nullopt;
159
160 uint64_t Result = 0;
161 uint64_t OldOffset = *Offset;
162 // First get value
163 switch (Encoding & 0x0F) {
165 switch (getAddressSize()) {
166 case 2:
167 case 4:
168 case 8:
169 Result = getUnsigned(Offset, getAddressSize());
170 break;
171 default:
172 return std::nullopt;
173 }
174 break;
176 Result = getULEB128(Offset);
177 break;
179 Result = getSLEB128(Offset);
180 break;
182 Result = getUnsigned(Offset, 2);
183 break;
185 Result = getUnsigned(Offset, 4);
186 break;
188 Result = getUnsigned(Offset, 8);
189 break;
191 Result = getSigned(Offset, 2);
192 break;
195 break;
197 Result = getRelocatedValue(8, Offset);
198 break;
199 default:
200 return std::nullopt;
201 }
202 // Then add relative offset, if required
203 switch (Encoding & 0x70) {
205 // do nothing
206 break;
208 Result += PCRelOffset;
209 break;
214 default:
215 *Offset = OldOffset;
216 return std::nullopt;
217 }
218
219 return Result;
220 }
221};
222
223// Non relocating, low-level dwarf-data extractor. Suitable for use from
224// libraries that cannot have build-time dependencies on relocation providers.
225
227 : public DWARFDataExtractorBase<DWARFDataExtractorSimple> {
228public:
230
232 uint64_t *SectionIndex = nullptr,
233 Error *Err = nullptr) const {
234 assert(SectionIndex == nullptr &&
235 "DWARFDATAExtractorSimple cannot take section indices.");
236 return getUnsigned(Off, Size, Err);
237 }
238};
239
240} // end namespace llvm
241#endif // LLVM_DEBUGINFO_DWARF_LOWLEVEL_DWARFDATAEXTRACTORSIMPLE_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
#define LLVM_ABI
Definition Compiler.h:213
This file contains constants used for implementing Dwarf debug support.
static StringRef substr(StringRef Str, uint64_t Len)
static Split data
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
unsigned getAddressSize() const
Get the address size for this extractor.
DWARFDataExtractorBase(const DWARFDataExtractorBase &Other, size_t Length)
Truncating constructor.
std::pair< uint64_t, dwarf::DwarfFormat > getInitialLength(uint64_t *Off, Error *Err=nullptr) const
Extracts the DWARF "initial length" field, which can either be a 32-bit value smaller than 0xfffffff0...
uint64_t getAddress(uint64_t *OffsetPtr) const
Extract an address from *OffsetPtr.
std::optional< uint64_t > getEncodedPointer(uint64_t *Offset, uint8_t Encoding, uint64_t PCRelOffset) const
Extracts a DWARF-encoded pointer in Offset using Encoding.
DWARFDataExtractorBase(ArrayRef< uint8_t > Data, bool IsLittleEndian, unsigned AddressSize)
uint64_t getRelocatedAddress(uint64_t *Off, uint64_t *SecIx=nullptr) const
Extracts an address-sized value.
uint64_t getAddress(Cursor &C) const
Extract an address-sized unsigned integer from the location given by the cursor.
uint64_t getRelocatedValue(Cursor &C, uint32_t Size, uint64_t *SectionIndex=nullptr) const
bool isValidOffsetForAddress(uint64_t Offset) const
Test the availability of enough bytes of data for an address from Offset.
void setAddressSize(unsigned Size)
Set the address size for this extractor.
uint64_t getRelocatedAddress(Cursor &C, uint64_t *SecIx=nullptr) const
uint64_t getRelocatedValue(uint32_t Size, uint64_t *Off, uint64_t *SectionIndex=nullptr, Error *Err=nullptr) const
Extracts a value and returns it as adjusted by the Relocator.
DWARFDataExtractorBase(StringRef Data, bool IsLittleEndian, unsigned AddressSize)
std::pair< uint64_t, dwarf::DwarfFormat > getInitialLength(Cursor &C) const
LLVM_ABI uint64_t getRelocatedValueImpl(uint32_t Size, uint64_t *Off, uint64_t *SectionIndex=nullptr, Error *Err=nullptr) const
DWARFDataExtractorBase(StringRef Data, bool IsLittleEndian, unsigned AddressSize)
A class representing a position in a DataExtractor, as well as any error encountered during extractio...
LLVM_ABI uint64_t getUnsigned(uint64_t *offset_ptr, uint32_t byte_size, Error *Err=nullptr) const
Extract an unsigned integer of size byte_size from *offset_ptr.
size_t size() const
Return the number of bytes in the underlying buffer.
static uint64_t & getOffset(Cursor &C)
DataExtractor(StringRef Data, bool IsLittleEndian)
Construct with a buffer that is owned by the caller.
LLVM_ABI int64_t getSigned(uint64_t *offset_ptr, uint32_t size) const
Extract an signed integer of size byte_size from *offset_ptr.
LLVM_ABI uint64_t getULEB128(uint64_t *offset_ptr, llvm::Error *Err=nullptr) const
Extract a unsigned LEB128 value from *offset_ptr.
StringRef getData() const
Get the data pointed to by this extractor.
LLVM_ABI int64_t getSLEB128(uint64_t *OffsetPtr, Error *Err=nullptr) const
Extract a signed LEB128 value from *offset_ptr.
static Error & getError(Cursor &C)
bool isValidOffsetForDataOfSize(uint64_t offset, uint64_t length) const
Test the availability of length bytes of data from offset.
bool isLittleEndian() const
Get the endianness for this extractor.
Helper for Errors used as out-parameters.
Definition Error.h:1160
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
DwarfFormat
Constants that define the DWARF format as 32 or 64 bit.
Definition Dwarf.h:93
@ DWARF64
Definition Dwarf.h:93
@ DWARF32
Definition Dwarf.h:93
@ DW_EH_PE_textrel
Definition Dwarf.h:880
@ DW_EH_PE_datarel
Definition Dwarf.h:881
@ DW_EH_PE_pcrel
Definition Dwarf.h:879
@ DW_EH_PE_sdata4
Definition Dwarf.h:876
@ DW_EH_PE_funcrel
Definition Dwarf.h:882
@ DW_EH_PE_aligned
Definition Dwarf.h:883
@ DW_EH_PE_udata2
Definition Dwarf.h:871
@ DW_EH_PE_sdata8
Definition Dwarf.h:877
@ DW_EH_PE_absptr
Definition Dwarf.h:868
@ DW_EH_PE_sdata2
Definition Dwarf.h:875
@ DW_EH_PE_udata4
Definition Dwarf.h:872
@ DW_EH_PE_udata8
Definition Dwarf.h:873
@ DW_EH_PE_uleb128
Definition Dwarf.h:870
@ DW_EH_PE_sleb128
Definition Dwarf.h:874
@ DW_EH_PE_omit
Definition Dwarf.h:869
@ DW_LENGTH_lo_reserved
Special values for an initial length field.
Definition Dwarf.h:56
@ DW_LENGTH_DWARF64
Indicator of 64-bit DWARF format.
Definition Dwarf.h:57
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:532
@ Length
Definition DWP.cpp:532
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition Error.h:1321
@ Other
Any other memory.
Definition ModRef.h:68
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition Error.h:769
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
Definition MathExtras.h:572
void consumeError(Error Err)
Consume a Error without doing anything.
Definition Error.h:1106