LLVM  17.0.0git
DWARFLinkerCompileUnit.cpp
Go to the documentation of this file.
1 //===- DWARFLinkerCompileUnit.cpp -----------------------------------------===//
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 
12 
13 namespace llvm {
14 
15 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
17  llvm::errs() << "{\n";
18  llvm::errs() << " AddrAdjust: " << AddrAdjust << '\n';
19  llvm::errs() << " Ctxt: " << formatv("{0:x}", Ctxt) << '\n';
20  llvm::errs() << " Clone: " << formatv("{0:x}", Clone) << '\n';
21  llvm::errs() << " ParentIdx: " << ParentIdx << '\n';
22  llvm::errs() << " Keep: " << Keep << '\n';
23  llvm::errs() << " InDebugMap: " << InDebugMap << '\n';
24  llvm::errs() << " Prune: " << Prune << '\n';
25  llvm::errs() << " Incomplete: " << Incomplete << '\n';
26  llvm::errs() << " InModuleScope: " << InModuleScope << '\n';
27  llvm::errs() << " ODRMarkingDone: " << ODRMarkingDone << '\n';
28  llvm::errs() << " UnclonedReference: " << UnclonedReference << '\n';
29  llvm::errs() << "}\n";
30 }
31 #endif // if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
32 
33 /// Check if the DIE at \p Idx is in the scope of a function.
34 static bool inFunctionScope(CompileUnit &U, unsigned Idx) {
35  while (Idx) {
36  if (U.getOrigUnit().getDIEAtIndex(Idx).getTag() == dwarf::DW_TAG_subprogram)
37  return true;
38  Idx = U.getInfo(Idx).ParentIdx;
39  }
40  return false;
41 }
42 
44  if (!Language) {
46  Language = dwarf::toUnsigned(CU.find(dwarf::DW_AT_language), 0);
47  }
48  return Language;
49 }
50 
52  if (SysRoot.empty()) {
54  SysRoot = dwarf::toStringRef(CU.find(dwarf::DW_AT_LLVM_sysroot)).str();
55  }
56  return SysRoot;
57 }
58 
60  unsigned Idx = 0;
61 
62  for (auto &I : Info) {
63  // Mark everything that wasn't explicit marked for pruning.
64  I.Keep = !I.Prune;
65  auto DIE = OrigUnit.getDIEAtIndex(Idx++);
66 
67  // Try to guess which DIEs must go to the accelerator tables. We do that
68  // just for variables, because functions will be handled depending on
69  // whether they carry a DW_AT_low_pc attribute or not.
70  if (DIE.getTag() != dwarf::DW_TAG_variable &&
71  DIE.getTag() != dwarf::DW_TAG_constant)
72  continue;
73 
74  std::optional<DWARFFormValue> Value;
75  if (!(Value = DIE.find(dwarf::DW_AT_location))) {
76  if ((Value = DIE.find(dwarf::DW_AT_const_value)) &&
77  !inFunctionScope(*this, I.ParentIdx))
78  I.InDebugMap = true;
79  continue;
80  }
81  if (auto Block = Value->getAsBlock()) {
82  if (Block->size() > OrigUnit.getAddressByteSize() &&
83  (*Block)[0] == dwarf::DW_OP_addr)
84  I.InDebugMap = true;
85  }
86  }
87 }
88 
90  NextUnitOffset = StartOffset;
91  if (NewUnit) {
92  NextUnitOffset += (DwarfVersion >= 5) ? 12 : 11; // Header size
93  NextUnitOffset += NewUnit->getUnitDie().getSize();
94  }
95  return NextUnitOffset;
96 }
97 
98 /// Keep track of a forward cross-cu reference from this unit
99 /// to \p Die that lives in \p RefUnit.
101  DeclContext *Ctxt, PatchLocation Attr) {
102  ForwardDIEReferences.emplace_back(Die, RefUnit, Ctxt, Attr);
103 }
104 
106  for (const auto &Ref : ForwardDIEReferences) {
107  DIE *RefDie;
108  const CompileUnit *RefUnit;
109  PatchLocation Attr;
110  DeclContext *Ctxt;
111  std::tie(RefDie, RefUnit, Ctxt, Attr) = Ref;
112  if (Ctxt && Ctxt->hasCanonicalDIE()) {
113  assert(Ctxt->getCanonicalDIEOffset() &&
114  "Canonical die offset is not set");
115  Attr.set(Ctxt->getCanonicalDIEOffset());
116  } else {
117  assert(RefDie->getOffset() && "Referenced die offset is not set");
118  Attr.set(RefDie->getOffset() + RefUnit->getStartOffset());
119  }
120  }
121 }
122 
123 void CompileUnit::addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset) {
124  Labels.insert({LabelLowPc, PcOffset});
125 }
126 
128  int64_t PcOffset) {
129  Ranges.insert({FuncLowPc, FuncHighPc}, PcOffset);
130  if (LowPc)
131  LowPc = std::min(*LowPc, FuncLowPc + PcOffset);
132  else
133  LowPc = FuncLowPc + PcOffset;
134  this->HighPc = std::max(HighPc, FuncHighPc + PcOffset);
135 }
136 
138  if (Die.getTag() != dwarf::DW_TAG_compile_unit)
139  RangeAttributes.push_back(Attr);
140  else
141  UnitRangeAttribute = Attr;
142 }
143 
144 void CompileUnit::noteLocationAttribute(PatchLocation Attr, int64_t PcOffset) {
145  LocationAttributes.emplace_back(Attr, PcOffset);
146 }
147 
150  Namespaces.emplace_back(Name, Die);
151 }
152 
155  bool SkipPubSection) {
156  ObjC.emplace_back(Name, Die, SkipPubSection);
157 }
158 
161  bool SkipPubSection) {
162  Pubnames.emplace_back(Name, Die, SkipPubSection);
163 }
164 
167  bool ObjcClassImplementation,
168  uint32_t QualifiedNameHash) {
169  Pubtypes.emplace_back(Name, Die, QualifiedNameHash, ObjcClassImplementation);
170 }
171 
172 } // namespace llvm
llvm::CompileUnit::DIEInfo::AddrAdjust
int64_t AddrAdjust
Address offset to apply to the described entity.
Definition: DWARFLinkerCompileUnit.h:53
llvm::CompileUnit::getOrigUnit
DWARFUnit & getOrigUnit() const
Definition: DWARFLinkerCompileUnit.h:110
llvm::CompileUnit::DIEInfo::Ctxt
DeclContext * Ctxt
ODR Declaration context.
Definition: DWARFLinkerCompileUnit.h:56
LLVM_DUMP_METHOD
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition: Compiler.h:492
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::CompileUnit::getInfo
DIEInfo & getInfo(unsigned Idx)
Definition: DWARFLinkerCompileUnit.h:130
llvm::DeclContext
A DeclContext is a named program scope that is used for ODR uniquing of types.
Definition: DWARFLinkerDeclContext.h:78
llvm::inFunctionScope
static bool inFunctionScope(CompileUnit &U, unsigned Idx)
Check if the DIE at Idx is in the scope of a function.
Definition: DWARFLinkerCompileUnit.cpp:34
llvm::dwarf::toUnsigned
std::optional< uint64_t > toUnsigned(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an unsigned constant.
Definition: DWARFFormValue.h:225
llvm::CompileUnit::DIEInfo::ParentIdx
uint32_t ParentIdx
The index of this DIE's parent.
Definition: DWARFLinkerCompileUnit.h:62
llvm::CompileUnit::DIEInfo::UnclonedReference
bool UnclonedReference
Is this a reference to a DIE that hasn't been cloned yet?
Definition: DWARFLinkerCompileUnit.h:83
llvm::CompileUnit::addTypeAccelerator
void addTypeAccelerator(const DIE *Die, DwarfStringPoolEntryRef Name, bool ObjcClassImplementation, uint32_t QualifiedNameHash)
Add a type accelerator entry for Die with Name which is stored in the string table at Offset.
Definition: DWARFLinkerCompileUnit.cpp:165
llvm::CompileUnit::DIEInfo::Prune
bool Prune
Is this a pure forward declaration we can strip?
Definition: DWARFLinkerCompileUnit.h:71
llvm::CompileUnit::getLanguage
uint16_t getLanguage()
Definition: DWARFLinkerCompileUnit.cpp:43
llvm::CompileUnit::noteRangeAttribute
void noteRangeAttribute(const DIE &Die, PatchLocation Attr)
Keep track of a DW_AT_range attribute that we will need to patch up later.
Definition: DWARFLinkerCompileUnit.cpp:137
llvm::DIE
A structured debug information entry.
Definition: DIE.h:739
llvm::max
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:337
llvm::errs
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Definition: raw_ostream.cpp:891
llvm::CompileUnit::DIEInfo::InDebugMap
bool InDebugMap
Was this DIE's entity found in the map?
Definition: DWARFLinkerCompileUnit.h:68
llvm::CompileUnit::DIEInfo::dump
LLVM_DUMP_METHOD void dump()
Definition: DWARFLinkerCompileUnit.cpp:16
llvm::DIE::getTag
dwarf::Tag getTag() const
Definition: DIE.h:775
DWARFLinkerCompileUnit.h
llvm::DwarfStringPoolEntryRef
DwarfStringPoolEntryRef: Dwarf string pool entry reference.
Definition: DwarfStringPoolEntry.h:44
llvm::CompileUnit::addObjCAccelerator
void addObjCAccelerator(const DIE *Die, DwarfStringPoolEntryRef Name, bool SkipPubnamesSection=false)
Add various accelerator entries for Die with Name which is stored in the string table at Offset.
Definition: DWARFLinkerCompileUnit.cpp:153
llvm::dwarf::toStringRef
StringRef toStringRef(const std::optional< DWARFFormValue > &V, StringRef Default={})
Take an optional DWARFFormValue and try to extract a string value from it.
Definition: DWARFFormValue.h:192
llvm::DWARFUnit::getUnitDIE
DWARFDie getUnitDIE(bool ExtractUnitDIEOnly=true)
Definition: DWARFUnit.h:426
llvm::formatv
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
Definition: FormatVariadic.h:251
llvm::CompileUnit::DIEInfo::Clone
DIE * Clone
Cloned version of that DIE.
Definition: DWARFLinkerCompileUnit.h:59
llvm::AddressRangesMap::insert
void insert(AddressRange Range, T Value)
Definition: AddressRanges.h:106
llvm::ModRefInfo::Ref
@ Ref
The access may reference the value stored in memory.
FormatVariadic.h
llvm::DeclContext::getCanonicalDIEOffset
uint32_t getCanonicalDIEOffset() const
Definition: DWARFLinkerDeclContext.h:99
uint64_t
llvm::CompileUnit::addLabelLowPc
void addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset)
Add the low_pc of a label that is relocated by applying offset PCOffset.
Definition: DWARFLinkerCompileUnit.cpp:123
llvm::CompileUnit::DIEInfo::Keep
bool Keep
Is the DIE part of the linked output?
Definition: DWARFLinkerCompileUnit.h:65
llvm::CompileUnit
Stores all information relating to a compile unit, be it in its original instance in the object file ...
Definition: DWARFLinkerCompileUnit.h:48
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::CompileUnit::getStartOffset
uint64_t getStartOffset() const
Definition: DWARFLinkerCompileUnit.h:138
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::DWARFUnit::getDIEAtIndex
DWARFDie getDIEAtIndex(unsigned Index)
Return the DIE object at the given index Index.
Definition: DWARFUnit.h:504
llvm::CompileUnit::addFunctionRange
void addFunctionRange(uint64_t LowPC, uint64_t HighPC, int64_t PCOffset)
Add a function range [LowPC, HighPC) that is relocated by applying offset PCOffset.
Definition: DWARFLinkerCompileUnit.cpp:127
llvm::CompileUnit::DIEInfo::ODRMarkingDone
bool ODRMarkingDone
Is ODR marking done?
Definition: DWARFLinkerCompileUnit.h:80
llvm::min
Expected< ExpressionValue > min(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:357
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
llvm::CompileUnit::addNameAccelerator
void addNameAccelerator(const DIE *Die, DwarfStringPoolEntryRef Name, bool SkipPubnamesSection=false)
Add a name accelerator entry for Die with Name.
Definition: DWARFLinkerCompileUnit.cpp:159
uint32_t
llvm::CompileUnit::noteLocationAttribute
void noteLocationAttribute(PatchLocation Attr, int64_t PcOffset)
Keep track of a location attribute pointing to a location list in the debug_loc section.
Definition: DWARFLinkerCompileUnit.cpp:144
llvm::CompileUnit::addNamespaceAccelerator
void addNamespaceAccelerator(const DIE *Die, DwarfStringPoolEntryRef Name)
Add a name accelerator entry for Die with Name.
Definition: DWARFLinkerCompileUnit.cpp:148
llvm::CompileUnit::computeNextUnitOffset
uint64_t computeNextUnitOffset(uint16_t DwarfVersion)
Compute the end offset for this unit.
Definition: DWARFLinkerCompileUnit.cpp:89
llvm::DenseMapBase::insert
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:207
llvm::CompileUnit::getSysRoot
StringRef getSysRoot()
Return the DW_AT_LLVM_sysroot of the compile unit or an empty StringRef.
Definition: DWARFLinkerCompileUnit.cpp:51
llvm::DWARFUnit::getAddressByteSize
uint8_t getAddressByteSize() const
Definition: DWARFUnit.h:319
uint16_t
llvm::CompileUnit::fixupForwardReferences
void fixupForwardReferences()
Apply all fixups recorded by noteForwardReference().
Definition: DWARFLinkerCompileUnit.cpp:105
llvm::PatchLocation
Definition: DWARFLinkerCompileUnit.h:27
llvm::PatchLocation::set
void set(uint64_t New) const
Definition: DWARFLinkerCompileUnit.h:33
llvm::TargetStackID::Value
Value
Definition: TargetFrameLowering.h:27
llvm::DWARFDie::getTag
dwarf::Tag getTag() const
Definition: DWARFDie.h:71
DWARFLinkerDeclContext.h
llvm::DeclContext::hasCanonicalDIE
bool hasCanonicalDIE() const
Definition: DWARFLinkerDeclContext.h:97
llvm::CompileUnit::noteForwardReference
void noteForwardReference(DIE *Die, const CompileUnit *RefUnit, DeclContext *Ctxt, PatchLocation Attr)
Keep track of a forward reference to DIE Die in RefUnit by Attr.
Definition: DWARFLinkerCompileUnit.cpp:100
llvm::CompileUnit::DIEInfo::InModuleScope
bool InModuleScope
Is DIE in the clang module scope?
Definition: DWARFLinkerCompileUnit.h:77
llvm::StringRef::str
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:222
llvm::DWARFDie
Utility class that carries the DWARF compile/type unit and the debug info entry in an object.
Definition: DWARFDie.h:42
llvm::CompileUnit::DIEInfo::Incomplete
bool Incomplete
Does DIE transitively refer an incomplete decl?
Definition: DWARFLinkerCompileUnit.h:74
llvm::DIE::getOffset
unsigned getOffset() const
Get the compile/type unit relative offset of this DIE.
Definition: DIE.h:777
CU
Definition: AArch64AsmBackend.cpp:505
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
llvm::CompileUnit::markEverythingAsKept
void markEverythingAsKept()
Mark every DIE in this unit as kept.
Definition: DWARFLinkerCompileUnit.cpp:59