LLVM 19.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 function checks whether variable has DWARF expression containing
87 /// operation referencing live address(f.e. DW_OP_addr, DW_OP_addrx...).
88 /// \returns first is true if the expression has an operation referencing an
89 /// address.
90 /// second is the relocation adjustment value if the live address is
91 /// referenced.
92 std::pair<bool, std::optional<int64_t>>
94 assert((DIE.getTag() == dwarf::DW_TAG_variable ||
95 DIE.getTag() == dwarf::DW_TAG_constant) &&
96 "Wrong type of input die");
97
98 const auto *Abbrev = DIE.getAbbreviationDeclarationPtr();
99
100 // Check if DIE has DW_AT_location attribute.
101 DWARFUnit *U = DIE.getDwarfUnit();
102 std::optional<uint32_t> LocationIdx =
103 Abbrev->findAttributeIndex(dwarf::DW_AT_location);
104 if (!LocationIdx)
105 return std::make_pair(false, std::nullopt);
106
107 // Get offset to the DW_AT_location attribute.
108 uint64_t AttrOffset =
109 Abbrev->getAttributeOffsetFromIndex(*LocationIdx, DIE.getOffset(), *U);
110
111 // Get value of the DW_AT_location attribute.
112 std::optional<DWARFFormValue> LocationValue =
113 Abbrev->getAttributeValueFromOffset(*LocationIdx, AttrOffset, *U);
114 if (!LocationValue)
115 return std::make_pair(false, std::nullopt);
116
117 // Check that DW_AT_location attribute is of 'exprloc' class.
118 // Handling value of location expressions for attributes of 'loclist'
119 // class is not implemented yet.
120 std::optional<ArrayRef<uint8_t>> Expr = LocationValue->getAsBlock();
121 if (!Expr)
122 return std::make_pair(false, std::nullopt);
123
124 // Parse 'exprloc' expression.
125 DataExtractor Data(toStringRef(*Expr), U->getContext().isLittleEndian(),
126 U->getAddressByteSize());
127 DWARFExpression Expression(Data, U->getAddressByteSize(),
128 U->getFormParams().Format);
129
130 bool HasLocationAddress = false;
131 uint64_t CurExprOffset = 0;
132 for (DWARFExpression::iterator It = Expression.begin();
133 It != Expression.end(); ++It) {
134 DWARFExpression::iterator NextIt = It;
135 ++NextIt;
136
137 const DWARFExpression::Operation &Op = *It;
138 switch (Op.getCode()) {
139 case dwarf::DW_OP_const2u:
140 case dwarf::DW_OP_const4u:
141 case dwarf::DW_OP_const8u:
142 case dwarf::DW_OP_const2s:
143 case dwarf::DW_OP_const4s:
144 case dwarf::DW_OP_const8s:
145 if (NextIt == Expression.end() || !isTlsAddressCode(NextIt->getCode()))
146 break;
147 [[fallthrough]];
148 case dwarf::DW_OP_addr: {
149 HasLocationAddress = true;
150 // Check relocation for the address.
151 if (std::optional<int64_t> RelocAdjustment =
153 *U, Op, AttrOffset + CurExprOffset,
154 AttrOffset + Op.getEndOffset(), Verbose))
155 return std::make_pair(HasLocationAddress, *RelocAdjustment);
156 } break;
157 case dwarf::DW_OP_constx:
158 case dwarf::DW_OP_addrx: {
159 HasLocationAddress = true;
160 if (std::optional<uint64_t> AddressOffset =
161 DIE.getDwarfUnit()->getIndexedAddressOffset(
162 Op.getRawOperand(0))) {
163 // Check relocation for the address.
164 if (std::optional<int64_t> RelocAdjustment =
166 *U, Op, *AddressOffset,
167 *AddressOffset + DIE.getDwarfUnit()->getAddressByteSize(),
168 Verbose))
169 return std::make_pair(HasLocationAddress, *RelocAdjustment);
170 }
171 } break;
172 default: {
173 // Nothing to do.
174 } break;
175 }
176 CurExprOffset = Op.getEndOffset();
177 }
178
179 return std::make_pair(HasLocationAddress, std::nullopt);
180 }
181
182protected:
183 inline bool isTlsAddressCode(uint8_t DW_OP_Code) {
184 return DW_OP_Code == dwarf::DW_OP_form_tls_address ||
185 DW_OP_Code == dwarf::DW_OP_GNU_push_tls_address;
186 }
187};
188
189} // namespace dwarf_linker
190} // end namespace llvm
191
192#endif // LLVM_DWARFLINKER_ADDRESSESMAP_H
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
AddressRangesMap class maps values to the address ranges.
A structured debug information entry.
Definition: DIE.h:819
unsigned getOffset() const
Get the compile/type unit relative offset of this DIE.
Definition: DIE.h:857
dwarf::Tag getTag() const
Definition: DIE.h:855
Utility class that carries the DWARF compile/type unit and the debug info entry in an object.
Definition: DWARFDie.h:42
This class represents an Operation in the Expression.
uint64_t getRawOperand(unsigned Idx) const
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:307
AddressesMap represents information about valid addresses used by debug information.
Definition: AddressesMap.h:30
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)
Definition: AddressesMap.h:183
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 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...
Definition: AddressesMap.h:93
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 ...
StringRef toStringRef(const std::optional< DWARFFormValue > &V, StringRef Default={})
Take an optional DWARFFormValue and try to extract a string value from it.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18