LLVM 23.0.0git
AddressesMap.h
Go to the documentation of this file.
1//===- AddressesMap.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_DWARFLINKER_ADDRESSESMAP_H
10#define LLVM_DWARFLINKER_ADDRESSESMAP_H
11
17#include <cstdint>
18
19namespace llvm {
20namespace dwarf_linker {
21
22/// Mapped value in the address map is the offset to apply to the
23/// linked address.
25
26/// AddressesMap represents information about valid addresses used
27/// by debug information. Valid addresses are those which points to
28/// live code sections. i.e. relocations for these addresses point
29/// into sections which would be/are placed into resulting binary.
31public:
32 virtual ~AddressesMap() = default;
33
34 /// Checks that there are valid relocations in the .debug_info
35 /// section.
36 virtual bool hasValidRelocs() = 0;
37
38 /// Checks that the specified DWARF expression operand \p Op references live
39 /// code section and returns the relocation adjustment value (to get the
40 /// linked address this value might be added to the source expression operand
41 /// address). Print debug output if \p Verbose is true.
42 /// \returns relocation adjustment value or std::nullopt if there is no
43 /// corresponding live address.
44 virtual std::optional<int64_t> getExprOpAddressRelocAdjustment(
45 DWARFUnit &U, const DWARFExpression::Operation &Op, uint64_t StartOffset,
46 uint64_t EndOffset, bool Verbose) = 0;
47
48 /// Checks that the specified subprogram \p DIE references the live code
49 /// section and returns the relocation adjustment value (to get the linked
50 /// address this value might be added to the source subprogram address).
51 /// Allowed kinds of input DIE: DW_TAG_subprogram, DW_TAG_label.
52 /// Print debug output if \p Verbose is true.
53 /// \returns relocation adjustment value or std::nullopt if there is no
54 /// corresponding live address.
55 virtual std::optional<int64_t>
57
58 // Returns the library install name associated to the AddessesMap.
59 virtual std::optional<StringRef> getLibraryInstallName() = 0;
60
61 /// Apply the valid relocations to the buffer \p Data, taking into
62 /// account that Data is at \p BaseOffset in the .debug_info section.
63 ///
64 /// \returns true whether any reloc has been applied.
66 bool IsLittleEndian) = 0;
67
68 /// Check if the linker needs to gather and save relocation info.
69 virtual bool needToSaveValidRelocs() = 0;
70
71 /// Update and save relocation values to be serialized
72 virtual void updateAndSaveValidRelocs(bool IsDWARF5,
73 uint64_t OriginalUnitOffset,
74 int64_t LinkedOffset,
75 uint64_t StartOffset,
76 uint64_t EndOffset) = 0;
77
78 /// Update the valid relocations that used OriginalUnitOffset as the compile
79 /// unit offset, and update their values to reflect OutputUnitOffset.
80 virtual void updateRelocationsWithUnitOffset(uint64_t OriginalUnitOffset,
81 uint64_t OutputUnitOffset) = 0;
82
83 /// Erases all data.
84 virtual void clear() = 0;
85
86 /// This is used for assembly files where labels may not have high_pc
87 /// but the debug map has range information from symbols.
94
95 /// Returns the address range containing \p Addr if available.
96 /// \returns the range [LowPC, HighPC) containing Addr.
97 virtual std::optional<AssemblyRange>
99 return std::nullopt;
100 }
101
102 /// This function checks whether variable has DWARF expression containing
103 /// operation referencing live address(f.e. DW_OP_addr, DW_OP_addrx...).
104 /// \returns first is true if the expression has an operation referencing an
105 /// address.
106 /// second is the relocation adjustment value if the live address is
107 /// referenced.
108 std::pair<bool, std::optional<int64_t>>
110 assert((DIE.getTag() == dwarf::DW_TAG_variable ||
111 DIE.getTag() == dwarf::DW_TAG_constant) &&
112 "Wrong type of input die");
113
114 const auto *Abbrev = DIE.getAbbreviationDeclarationPtr();
115
116 // Check if DIE has DW_AT_location attribute.
117 DWARFUnit *U = DIE.getDwarfUnit();
118 std::optional<uint32_t> LocationIdx =
119 Abbrev->findAttributeIndex(dwarf::DW_AT_location);
120 if (!LocationIdx)
121 return std::make_pair(false, std::nullopt);
122
123 // Get offset to the DW_AT_location attribute.
124 uint64_t AttrOffset =
125 Abbrev->getAttributeOffsetFromIndex(*LocationIdx, DIE.getOffset(), *U);
126
127 // Get value of the DW_AT_location attribute.
128 std::optional<DWARFFormValue> LocationValue =
129 Abbrev->getAttributeValueFromOffset(*LocationIdx, AttrOffset, *U);
130 if (!LocationValue)
131 return std::make_pair(false, std::nullopt);
132
133 // Check that DW_AT_location attribute is of 'exprloc' class.
134 // Handling value of location expressions for attributes of 'loclist'
135 // class is not implemented yet.
136 std::optional<ArrayRef<uint8_t>> Expr = LocationValue->getAsBlock();
137 if (!Expr)
138 return std::make_pair(false, std::nullopt);
139
140 // Parse 'exprloc' expression.
141 DataExtractor Data(toStringRef(*Expr), U->getContext().isLittleEndian(),
142 U->getAddressByteSize());
143 DWARFExpression Expression(Data, U->getAddressByteSize(),
144 U->getFormParams().Format);
145
146 bool HasLocationAddress = false;
147 uint64_t CurExprOffset = 0;
148 for (DWARFExpression::iterator It = Expression.begin();
149 It != Expression.end(); ++It) {
150 DWARFExpression::iterator NextIt = It;
151 ++NextIt;
152
153 const DWARFExpression::Operation &Op = *It;
154 switch (Op.getCode()) {
155 case dwarf::DW_OP_const2u:
156 case dwarf::DW_OP_const4u:
157 case dwarf::DW_OP_const8u:
158 case dwarf::DW_OP_const2s:
159 case dwarf::DW_OP_const4s:
160 case dwarf::DW_OP_const8s:
161 if (NextIt == Expression.end() || !isTlsAddressCode(NextIt->getCode()))
162 break;
163 [[fallthrough]];
164 case dwarf::DW_OP_addr: {
165 HasLocationAddress = true;
166 // Check relocation for the address.
167 if (std::optional<int64_t> RelocAdjustment =
169 *U, Op, AttrOffset + CurExprOffset,
170 AttrOffset + Op.getEndOffset(), Verbose))
171 return std::make_pair(HasLocationAddress, *RelocAdjustment);
172 } break;
173 case dwarf::DW_OP_constx:
174 case dwarf::DW_OP_addrx: {
175 HasLocationAddress = true;
176 if (std::optional<uint64_t> AddressOffset =
177 DIE.getDwarfUnit()->getIndexedAddressOffset(
178 Op.getRawOperand(0))) {
179 // Check relocation for the address.
180 if (std::optional<int64_t> RelocAdjustment =
182 *U, Op, *AddressOffset,
183 *AddressOffset + DIE.getDwarfUnit()->getAddressByteSize(),
184 Verbose))
185 return std::make_pair(HasLocationAddress, *RelocAdjustment);
186 }
187 } break;
188 default: {
189 // Nothing to do.
190 } break;
191 }
192 CurExprOffset = Op.getEndOffset();
193 }
194
195 return std::make_pair(HasLocationAddress, std::nullopt);
196 }
197
198protected:
199 inline bool isTlsAddressCode(uint8_t DW_OP_Code) {
200 return DW_OP_Code == dwarf::DW_OP_form_tls_address ||
201 DW_OP_Code == dwarf::DW_OP_GNU_push_tls_address;
202 }
203};
204
205} // namespace dwarf_linker
206} // end namespace llvm
207
208#endif // LLVM_DWARFLINKER_ADDRESSESMAP_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AddressRangesMap class maps values to the address ranges.
A structured debug information entry.
Definition DIE.h:828
unsigned getOffset() const
Get the compile/type unit relative offset of this DIE.
Definition DIE.h:866
dwarf::Tag getTag() const
Definition DIE.h:864
Utility class that carries the DWARF compile/type unit and the debug info entry in an object.
Definition DWARFDie.h:43
This class represents an Operation in the Expression.
An iterator to go through the expression operations.
Class representing an expression and its matching format.
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Definition ArrayRef.h:298
AddressesMap represents information about valid addresses used by debug information.
virtual bool hasValidRelocs()=0
Checks that there are valid relocations in the .debug_info section.
virtual void updateAndSaveValidRelocs(bool IsDWARF5, uint64_t OriginalUnitOffset, int64_t LinkedOffset, uint64_t StartOffset, uint64_t EndOffset)=0
Update and save relocation values to be serialized.
virtual void clear()=0
Erases all data.
virtual bool needToSaveValidRelocs()=0
Check if the linker needs to gather and save relocation info.
virtual std::optional< StringRef > getLibraryInstallName()=0
bool isTlsAddressCode(uint8_t DW_OP_Code)
virtual bool applyValidRelocs(MutableArrayRef< char > Data, uint64_t BaseOffset, bool IsLittleEndian)=0
Apply the valid relocations to the buffer Data, taking into account that Data is at BaseOffset in the...
virtual std::optional< int64_t > getExprOpAddressRelocAdjustment(DWARFUnit &U, const DWARFExpression::Operation &Op, uint64_t StartOffset, uint64_t EndOffset, bool Verbose)=0
Checks that the specified DWARF expression operand Op references live code section and returns the re...
virtual std::optional< AssemblyRange > getAssemblyRangeForAddress(uint64_t Addr)
Returns the address range containing Addr if available.
virtual void updateRelocationsWithUnitOffset(uint64_t OriginalUnitOffset, uint64_t OutputUnitOffset)=0
Update the valid relocations that used OriginalUnitOffset as the compile unit offset,...
std::pair< bool, std::optional< int64_t > > getVariableRelocAdjustment(const DWARFDie &DIE, bool Verbose)
This function checks whether variable has DWARF expression containing operation referencing live addr...
virtual std::optional< int64_t > getSubprogramRelocAdjustment(const DWARFDie &DIE, bool Verbose)=0
Checks that the specified subprogram DIE references the live code section and returns the relocation ...
AddressRangesMap RangesTy
Mapped value in the address map is the offset to apply to the linked address.
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
FunctionAddr VTableAddr uintptr_t uintptr_t Data
Definition InstrProf.h:189
DWARFExpression::Operation Op
StringRef toStringRef(bool B)
Construct a string ref from a boolean.
AssemblyRange(uint64_t LowPC, uint64_t HighPC)