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)
34 : DataExtractor(Data, IsLittleEndian), AddressSize(AddressSize) {}
35
36 /// Get the address size for this extractor.
37 unsigned getAddressSize() const { return AddressSize; }
38
39 /// Set the address size for this extractor.
40 void setAddressSize(unsigned Size) { AddressSize = Size; }
41
42 //------------------------------------------------------------------
43 /// Extract an address from \a *OffsetPtr.
44 ///
45 /// Extract a single address from the data and update the offset
46 /// pointed to by \a OffsetPtr. The size of the extracted address
47 /// is \a getAddressSize(), so the address size has to be
48 /// set correctly prior to extracting any address values.
49 ///
50 /// @param[in,out] OffsetPtr
51 /// A pointer to an offset within the data that will be advanced
52 /// by the appropriate number of bytes if the value is extracted
53 /// correctly. If the offset is out of bounds or there are not
54 /// enough bytes to extract this value, the offset will be left
55 /// unmodified.
56 ///
57 /// @return
58 /// The extracted address value as a 64 integer.
59 uint64_t getAddress(uint64_t *OffsetPtr) const {
60 return getUnsigned(OffsetPtr, AddressSize);
61 }
62
63 /// Extract an address-sized unsigned integer from the location given by the
64 /// cursor. In case of an extraction error, or if the cursor is already in
65 /// an error state, zero is returned.
66 uint64_t getAddress(Cursor &C) const { return getUnsigned(C, AddressSize); }
67
68 /// Test the availability of enough bytes of data for an address from
69 /// \a Offset. The size of an address is \a getAddressSize().
70 ///
71 /// @return
72 /// \b true if \a Offset is a valid offset and there are enough
73 /// bytes for an address available at that offset, \b false
74 /// otherwise.
76 return isValidOffsetForDataOfSize(Offset, AddressSize);
77 }
78
79 /// Extracts a value and returns it as adjusted by the Relocator
81 uint64_t *SectionIndex = nullptr,
82 Error *Err = nullptr) const {
83 return static_cast<const Relocator *>(this)->getRelocatedValueImpl(
84 Size, Off, SectionIndex, Err);
85 }
86
88 uint64_t *SectionIndex = nullptr) const {
89 return getRelocatedValue(Size, &getOffset(C), SectionIndex, &getError(C));
90 }
91
92 /// Extracts an address-sized value.
93 uint64_t getRelocatedAddress(uint64_t *Off, uint64_t *SecIx = nullptr) const {
94 return getRelocatedValue(getAddressSize(), Off, SecIx);
95 }
96
97 uint64_t getRelocatedAddress(Cursor &C, uint64_t *SecIx = nullptr) const {
99 &getError(C));
100 }
101
102 /// Extracts the DWARF "initial length" field, which can either be a 32-bit
103 /// value smaller than 0xfffffff0, or the value 0xffffffff followed by a
104 /// 64-bit length. Returns the actual length, and the DWARF format which is
105 /// encoded in the field. In case of errors, it returns {0, DWARF32} and
106 /// leaves the offset unchanged.
107 std::pair<uint64_t, dwarf::DwarfFormat>
108 getInitialLength(uint64_t *Off, Error *Err = nullptr) const {
109 ErrorAsOutParameter ErrAsOut(Err);
110 if (Err && *Err)
111 return {0, dwarf::DWARF32};
112
113 Cursor C(*Off);
119 } else if (Length >= dwarf::DW_LENGTH_lo_reserved) {
120 cantFail(C.takeError());
121 if (Err)
122 *Err = createStringError(
123 std::errc::invalid_argument,
124 "unsupported reserved unit length of value 0x%8.8" PRIx64, Length);
125 return {0, dwarf::DWARF32};
126 }
127
128 if (C) {
129 *Off = C.tell();
130 return {Length, Format};
131 }
132 if (Err)
133 *Err = C.takeError();
134 else
135 consumeError(C.takeError());
136 return {0, dwarf::DWARF32};
137 }
138
139 std::pair<uint64_t, dwarf::DwarfFormat> getInitialLength(Cursor &C) const {
141 }
142
143 /// Extracts a DWARF-encoded pointer in \p Offset using \p Encoding.
144 /// There is a DWARF encoding that uses a PC-relative adjustment.
145 /// For these values, \p AbsPosOffset is used to fix them, which should
146 /// reflect the absolute address of this pointer.
147 std::optional<uint64_t> getEncodedPointer(uint64_t *Offset, uint8_t Encoding,
148 uint64_t PCRelOffset) const {
149 if (Encoding == dwarf::DW_EH_PE_omit)
150 return std::nullopt;
151
152 uint64_t Result = 0;
153 uint64_t OldOffset = *Offset;
154 // First get value
155 switch (Encoding & 0x0F) {
157 switch (getAddressSize()) {
158 case 2:
159 case 4:
160 case 8:
161 Result = getUnsigned(Offset, getAddressSize());
162 break;
163 default:
164 return std::nullopt;
165 }
166 break;
168 Result = getULEB128(Offset);
169 break;
171 Result = getSLEB128(Offset);
172 break;
174 Result = getUnsigned(Offset, 2);
175 break;
177 Result = getUnsigned(Offset, 4);
178 break;
180 Result = getUnsigned(Offset, 8);
181 break;
183 Result = getSigned(Offset, 2);
184 break;
187 break;
189 Result = getRelocatedValue(8, Offset);
190 break;
191 default:
192 return std::nullopt;
193 }
194 // Then add relative offset, if required
195 switch (Encoding & 0x70) {
197 // do nothing
198 break;
200 Result += PCRelOffset;
201 break;
206 default:
207 *Offset = OldOffset;
208 return std::nullopt;
209 }
210
211 return Result;
212 }
213};
214
215// Non relocating, low-level dwarf-data extractor. Suitable for use from
216// libraries that cannot have build-time dependencies on relocation providers.
217
219 : public DWARFDataExtractorBase<DWARFDataExtractorSimple> {
220public:
222
224 uint64_t *SectionIndex = nullptr,
225 Error *Err = nullptr) const {
226 assert(SectionIndex == nullptr &&
227 "DWARFDATAExtractorSimple cannot take section indices.");
228 return getUnsigned(Off, Size, Err);
229 }
230};
231
232} // end namespace llvm
233#endif // LLVM_DEBUGINFO_DWARF_LOWLEVEL_DWARFDATAEXTRACTORSIMPLE_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file contains constants used for implementing Dwarf debug support.
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.
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
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.
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.
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.
Helper for Errors used as out-parameters.
Definition Error.h:1160
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
@ 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:886
@ DW_EH_PE_datarel
Definition Dwarf.h:887
@ DW_EH_PE_pcrel
Definition Dwarf.h:885
@ DW_EH_PE_sdata4
Definition Dwarf.h:882
@ DW_EH_PE_funcrel
Definition Dwarf.h:888
@ DW_EH_PE_aligned
Definition Dwarf.h:889
@ DW_EH_PE_udata2
Definition Dwarf.h:877
@ DW_EH_PE_sdata8
Definition Dwarf.h:883
@ DW_EH_PE_absptr
Definition Dwarf.h:874
@ DW_EH_PE_sdata2
Definition Dwarf.h:881
@ DW_EH_PE_udata4
Definition Dwarf.h:878
@ DW_EH_PE_udata8
Definition Dwarf.h:879
@ DW_EH_PE_uleb128
Definition Dwarf.h:876
@ DW_EH_PE_sleb128
Definition Dwarf.h:880
@ DW_EH_PE_omit
Definition Dwarf.h:875
@ 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:558
@ Length
Definition DWP.cpp:558
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition Error.h:1321
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