File indexing completed on 2026-05-10 08:43:49
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_DWARFLINKER_ADDRESSESMAP_H
0010 #define LLVM_DWARFLINKER_ADDRESSESMAP_H
0011
0012 #include "llvm/ADT/AddressRanges.h"
0013 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
0014 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
0015 #include "llvm/DebugInfo/DWARF/DWARFExpression.h"
0016 #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
0017 #include <cstdint>
0018
0019 namespace llvm {
0020 namespace dwarf_linker {
0021
0022
0023
0024 using RangesTy = AddressRangesMap;
0025
0026
0027
0028
0029
0030 class AddressesMap {
0031 public:
0032 virtual ~AddressesMap() = default;
0033
0034
0035
0036 virtual bool hasValidRelocs() = 0;
0037
0038
0039
0040
0041
0042
0043
0044 virtual std::optional<int64_t> getExprOpAddressRelocAdjustment(
0045 DWARFUnit &U, const DWARFExpression::Operation &Op, uint64_t StartOffset,
0046 uint64_t EndOffset, bool Verbose) = 0;
0047
0048
0049
0050
0051
0052
0053
0054
0055 virtual std::optional<int64_t>
0056 getSubprogramRelocAdjustment(const DWARFDie &DIE, bool Verbose) = 0;
0057
0058
0059 virtual std::optional<StringRef> getLibraryInstallName() = 0;
0060
0061
0062
0063
0064
0065 virtual bool applyValidRelocs(MutableArrayRef<char> Data, uint64_t BaseOffset,
0066 bool IsLittleEndian) = 0;
0067
0068
0069 virtual bool needToSaveValidRelocs() = 0;
0070
0071
0072 virtual void updateAndSaveValidRelocs(bool IsDWARF5,
0073 uint64_t OriginalUnitOffset,
0074 int64_t LinkedOffset,
0075 uint64_t StartOffset,
0076 uint64_t EndOffset) = 0;
0077
0078
0079
0080 virtual void updateRelocationsWithUnitOffset(uint64_t OriginalUnitOffset,
0081 uint64_t OutputUnitOffset) = 0;
0082
0083
0084 virtual void clear() = 0;
0085
0086
0087
0088
0089
0090
0091
0092 std::pair<bool, std::optional<int64_t>>
0093 getVariableRelocAdjustment(const DWARFDie &DIE, bool Verbose) {
0094 assert((DIE.getTag() == dwarf::DW_TAG_variable ||
0095 DIE.getTag() == dwarf::DW_TAG_constant) &&
0096 "Wrong type of input die");
0097
0098 const auto *Abbrev = DIE.getAbbreviationDeclarationPtr();
0099
0100
0101 DWARFUnit *U = DIE.getDwarfUnit();
0102 std::optional<uint32_t> LocationIdx =
0103 Abbrev->findAttributeIndex(dwarf::DW_AT_location);
0104 if (!LocationIdx)
0105 return std::make_pair(false, std::nullopt);
0106
0107
0108 uint64_t AttrOffset =
0109 Abbrev->getAttributeOffsetFromIndex(*LocationIdx, DIE.getOffset(), *U);
0110
0111
0112 std::optional<DWARFFormValue> LocationValue =
0113 Abbrev->getAttributeValueFromOffset(*LocationIdx, AttrOffset, *U);
0114 if (!LocationValue)
0115 return std::make_pair(false, std::nullopt);
0116
0117
0118
0119
0120 std::optional<ArrayRef<uint8_t>> Expr = LocationValue->getAsBlock();
0121 if (!Expr)
0122 return std::make_pair(false, std::nullopt);
0123
0124
0125 DataExtractor Data(toStringRef(*Expr), U->getContext().isLittleEndian(),
0126 U->getAddressByteSize());
0127 DWARFExpression Expression(Data, U->getAddressByteSize(),
0128 U->getFormParams().Format);
0129
0130 bool HasLocationAddress = false;
0131 uint64_t CurExprOffset = 0;
0132 for (DWARFExpression::iterator It = Expression.begin();
0133 It != Expression.end(); ++It) {
0134 DWARFExpression::iterator NextIt = It;
0135 ++NextIt;
0136
0137 const DWARFExpression::Operation &Op = *It;
0138 switch (Op.getCode()) {
0139 case dwarf::DW_OP_const2u:
0140 case dwarf::DW_OP_const4u:
0141 case dwarf::DW_OP_const8u:
0142 case dwarf::DW_OP_const2s:
0143 case dwarf::DW_OP_const4s:
0144 case dwarf::DW_OP_const8s:
0145 if (NextIt == Expression.end() || !isTlsAddressCode(NextIt->getCode()))
0146 break;
0147 [[fallthrough]];
0148 case dwarf::DW_OP_addr: {
0149 HasLocationAddress = true;
0150
0151 if (std::optional<int64_t> RelocAdjustment =
0152 getExprOpAddressRelocAdjustment(
0153 *U, Op, AttrOffset + CurExprOffset,
0154 AttrOffset + Op.getEndOffset(), Verbose))
0155 return std::make_pair(HasLocationAddress, *RelocAdjustment);
0156 } break;
0157 case dwarf::DW_OP_constx:
0158 case dwarf::DW_OP_addrx: {
0159 HasLocationAddress = true;
0160 if (std::optional<uint64_t> AddressOffset =
0161 DIE.getDwarfUnit()->getIndexedAddressOffset(
0162 Op.getRawOperand(0))) {
0163
0164 if (std::optional<int64_t> RelocAdjustment =
0165 getExprOpAddressRelocAdjustment(
0166 *U, Op, *AddressOffset,
0167 *AddressOffset + DIE.getDwarfUnit()->getAddressByteSize(),
0168 Verbose))
0169 return std::make_pair(HasLocationAddress, *RelocAdjustment);
0170 }
0171 } break;
0172 default: {
0173
0174 } break;
0175 }
0176 CurExprOffset = Op.getEndOffset();
0177 }
0178
0179 return std::make_pair(HasLocationAddress, std::nullopt);
0180 }
0181
0182 protected:
0183 inline bool isTlsAddressCode(uint8_t DW_OP_Code) {
0184 return DW_OP_Code == dwarf::DW_OP_form_tls_address ||
0185 DW_OP_Code == dwarf::DW_OP_GNU_push_tls_address;
0186 }
0187 };
0188
0189 }
0190 }
0191
0192 #endif