File indexing completed on 2026-05-10 08:43:48
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_DWARFLINKER_CLASSIC_DWARFLINKERCOMPILEUNIT_H
0010 #define LLVM_DWARFLINKER_CLASSIC_DWARFLINKERCOMPILEUNIT_H
0011
0012 #include "llvm/ADT/AddressRanges.h"
0013 #include "llvm/ADT/DenseMap.h"
0014 #include "llvm/CodeGen/DIE.h"
0015 #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
0016 #include <optional>
0017
0018 namespace llvm {
0019 namespace dwarf_linker {
0020 namespace classic {
0021
0022 class DeclContext;
0023
0024
0025
0026 using RangesTy = AddressRangesMap;
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 struct PatchLocation {
0037 DIE::value_iterator I;
0038 int64_t RelocAdjustment = 0;
0039
0040 PatchLocation() = default;
0041 PatchLocation(DIE::value_iterator I) : I(I) {}
0042 PatchLocation(DIE::value_iterator I, int64_t Reloc)
0043 : I(I), RelocAdjustment(Reloc) {}
0044
0045 void set(uint64_t New) const {
0046 assert(I);
0047 const auto &Old = *I;
0048 assert(Old.getType() == DIEValue::isInteger);
0049 *I = DIEValue(Old.getAttribute(), Old.getForm(), DIEInteger(New));
0050 }
0051
0052 uint64_t get() const {
0053 assert(I);
0054 return I->getDIEInteger().getValue();
0055 }
0056 };
0057
0058 using RngListAttributesTy = SmallVector<PatchLocation>;
0059 using LocListAttributesTy = SmallVector<PatchLocation>;
0060
0061
0062
0063 class CompileUnit {
0064 public:
0065
0066 struct DIEInfo {
0067
0068 int64_t AddrAdjust;
0069
0070
0071 DeclContext *Ctxt;
0072
0073
0074 DIE *Clone;
0075
0076
0077 uint32_t ParentIdx;
0078
0079
0080 bool Keep : 1;
0081
0082
0083 bool InDebugMap : 1;
0084
0085
0086 bool Prune : 1;
0087
0088
0089 bool Incomplete : 1;
0090
0091
0092 bool InModuleScope : 1;
0093
0094
0095 bool ODRMarkingDone : 1;
0096
0097
0098 bool UnclonedReference : 1;
0099
0100
0101 bool HasLocationExpressionAddr : 1;
0102
0103 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
0104 LLVM_DUMP_METHOD void dump();
0105 #endif
0106 };
0107
0108 CompileUnit(DWARFUnit &OrigUnit, unsigned ID, bool CanUseODR,
0109 StringRef ClangModuleName)
0110 : OrigUnit(OrigUnit), ID(ID), ClangModuleName(ClangModuleName) {
0111 Info.resize(OrigUnit.getNumDIEs());
0112
0113 auto CUDie = OrigUnit.getUnitDIE(false);
0114 if (!CUDie) {
0115 HasODR = false;
0116 return;
0117 }
0118 if (auto Lang = dwarf::toUnsigned(CUDie.find(dwarf::DW_AT_language)))
0119 HasODR = CanUseODR && (*Lang == dwarf::DW_LANG_C_plus_plus ||
0120 *Lang == dwarf::DW_LANG_C_plus_plus_03 ||
0121 *Lang == dwarf::DW_LANG_C_plus_plus_11 ||
0122 *Lang == dwarf::DW_LANG_C_plus_plus_14 ||
0123 *Lang == dwarf::DW_LANG_ObjC_plus_plus);
0124 else
0125 HasODR = false;
0126 }
0127
0128 DWARFUnit &getOrigUnit() const { return OrigUnit; }
0129
0130 unsigned getUniqueID() const { return ID; }
0131
0132 void createOutputDIE() { NewUnit.emplace(OrigUnit.getUnitDIE().getTag()); }
0133
0134 DIE *getOutputUnitDIE() const {
0135 if (NewUnit)
0136 return &const_cast<BasicDIEUnit &>(*NewUnit).getUnitDie();
0137 return nullptr;
0138 }
0139
0140 dwarf::Tag getTag() const { return OrigUnit.getUnitDIE().getTag(); }
0141
0142 bool hasODR() const { return HasODR; }
0143 bool isClangModule() const { return !ClangModuleName.empty(); }
0144 uint16_t getLanguage();
0145
0146 StringRef getSysRoot();
0147
0148 const std::string &getClangModuleName() const { return ClangModuleName; }
0149
0150 DIEInfo &getInfo(unsigned Idx) { return Info[Idx]; }
0151 const DIEInfo &getInfo(unsigned Idx) const { return Info[Idx]; }
0152
0153 DIEInfo &getInfo(const DWARFDie &Die) {
0154 unsigned Idx = getOrigUnit().getDIEIndex(Die);
0155 return Info[Idx];
0156 }
0157
0158 uint64_t getStartOffset() const { return StartOffset; }
0159 uint64_t getNextUnitOffset() const { return NextUnitOffset; }
0160 void setStartOffset(uint64_t DebugInfoSize) { StartOffset = DebugInfoSize; }
0161
0162 std::optional<uint64_t> getLowPc() const { return LowPc; }
0163 uint64_t getHighPc() const { return HighPc; }
0164 bool hasLabelAt(uint64_t Addr) const { return Labels.count(Addr); }
0165
0166 const RangesTy &getFunctionRanges() const { return Ranges; }
0167
0168 const RngListAttributesTy &getRangesAttributes() { return RangeAttributes; }
0169
0170 std::optional<PatchLocation> getUnitRangesAttribute() const {
0171 return UnitRangeAttribute;
0172 }
0173
0174 const LocListAttributesTy &getLocationAttributes() const {
0175 return LocationAttributes;
0176 }
0177
0178
0179
0180
0181 void markEverythingAsKept();
0182
0183
0184
0185
0186 uint64_t computeNextUnitOffset(uint16_t DwarfVersion);
0187
0188
0189
0190
0191
0192 void noteForwardReference(DIE *Die, const CompileUnit *RefUnit,
0193 DeclContext *Ctxt, PatchLocation Attr);
0194
0195
0196 void fixupForwardReferences();
0197
0198
0199
0200 void addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset);
0201
0202
0203
0204 void addFunctionRange(uint64_t LowPC, uint64_t HighPC, int64_t PCOffset);
0205
0206
0207 void noteRangeAttribute(const DIE &Die, PatchLocation Attr);
0208
0209
0210
0211 void noteLocationAttribute(PatchLocation Attr);
0212
0213
0214 void addNamespaceAccelerator(const DIE *Die, DwarfStringPoolEntryRef Name);
0215
0216
0217 void addNameAccelerator(const DIE *Die, DwarfStringPoolEntryRef Name,
0218 bool SkipPubnamesSection = false);
0219
0220
0221
0222
0223 void addObjCAccelerator(const DIE *Die, DwarfStringPoolEntryRef Name,
0224 bool SkipPubnamesSection = false);
0225
0226
0227
0228 void addTypeAccelerator(const DIE *Die, DwarfStringPoolEntryRef Name,
0229 bool ObjcClassImplementation,
0230 uint32_t QualifiedNameHash);
0231
0232 struct AccelInfo {
0233
0234 DwarfStringPoolEntryRef Name;
0235
0236
0237 const DIE *Die;
0238
0239
0240 uint32_t QualifiedNameHash;
0241
0242
0243 bool SkipPubSection;
0244
0245
0246 bool ObjcClassImplementation;
0247
0248 AccelInfo(DwarfStringPoolEntryRef Name, const DIE *Die,
0249 bool SkipPubSection = false)
0250 : Name(Name), Die(Die), SkipPubSection(SkipPubSection) {}
0251
0252 AccelInfo(DwarfStringPoolEntryRef Name, const DIE *Die,
0253 uint32_t QualifiedNameHash, bool ObjCClassIsImplementation)
0254 : Name(Name), Die(Die), QualifiedNameHash(QualifiedNameHash),
0255 SkipPubSection(false),
0256 ObjcClassImplementation(ObjCClassIsImplementation) {}
0257 };
0258
0259 const std::vector<AccelInfo> &getPubnames() const { return Pubnames; }
0260 const std::vector<AccelInfo> &getPubtypes() const { return Pubtypes; }
0261 const std::vector<AccelInfo> &getNamespaces() const { return Namespaces; }
0262 const std::vector<AccelInfo> &getObjC() const { return ObjC; }
0263
0264 MCSymbol *getLabelBegin() { return LabelBegin; }
0265 void setLabelBegin(MCSymbol *S) { LabelBegin = S; }
0266
0267 private:
0268 DWARFUnit &OrigUnit;
0269 unsigned ID;
0270 std::vector<DIEInfo> Info;
0271 std::optional<BasicDIEUnit> NewUnit;
0272 MCSymbol *LabelBegin = nullptr;
0273
0274 uint64_t StartOffset;
0275 uint64_t NextUnitOffset;
0276
0277 std::optional<uint64_t> LowPc;
0278 uint64_t HighPc = 0;
0279
0280
0281
0282
0283
0284
0285
0286 std::vector<
0287 std::tuple<DIE *, const CompileUnit *, DeclContext *, PatchLocation>>
0288 ForwardDIEReferences;
0289
0290
0291
0292
0293 RangesTy Ranges;
0294
0295
0296 SmallDenseMap<uint64_t, uint64_t, 1> Labels;
0297
0298
0299
0300
0301 RngListAttributesTy RangeAttributes;
0302 std::optional<PatchLocation> UnitRangeAttribute;
0303
0304
0305
0306
0307
0308
0309
0310 LocListAttributesTy LocationAttributes;
0311
0312
0313
0314
0315 std::vector<AccelInfo> Pubnames;
0316 std::vector<AccelInfo> Pubtypes;
0317 std::vector<AccelInfo> Namespaces;
0318 std::vector<AccelInfo> ObjC;
0319
0320
0321
0322 bool HasODR;
0323
0324
0325 uint16_t Language = 0;
0326
0327
0328 std::string SysRoot;
0329
0330
0331 std::string ClangModuleName;
0332 };
0333
0334 }
0335 }
0336 }
0337
0338 #endif