1*0fca6ea1SDimitry Andric //===-- LVDWARFReader.cpp -------------------------------------------------===//
2*0fca6ea1SDimitry Andric //
3*0fca6ea1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0fca6ea1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0fca6ea1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0fca6ea1SDimitry Andric //
7*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===//
8*0fca6ea1SDimitry Andric //
9*0fca6ea1SDimitry Andric // This implements the LVDWARFReader class.
10*0fca6ea1SDimitry Andric // It supports ELF, Mach-O and Wasm binary formats.
11*0fca6ea1SDimitry Andric //
12*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===//
13*0fca6ea1SDimitry Andric
14*0fca6ea1SDimitry Andric #include "llvm/DebugInfo/LogicalView/Readers/LVDWARFReader.h"
15*0fca6ea1SDimitry Andric #include "llvm/DebugInfo/DIContext.h"
16*0fca6ea1SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
17*0fca6ea1SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFExpression.h"
18*0fca6ea1SDimitry Andric #include "llvm/DebugInfo/LogicalView/Core/LVLine.h"
19*0fca6ea1SDimitry Andric #include "llvm/DebugInfo/LogicalView/Core/LVScope.h"
20*0fca6ea1SDimitry Andric #include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h"
21*0fca6ea1SDimitry Andric #include "llvm/DebugInfo/LogicalView/Core/LVType.h"
22*0fca6ea1SDimitry Andric #include "llvm/Object/Error.h"
23*0fca6ea1SDimitry Andric #include "llvm/Object/MachO.h"
24*0fca6ea1SDimitry Andric #include "llvm/Support/FormatVariadic.h"
25*0fca6ea1SDimitry Andric
26*0fca6ea1SDimitry Andric using namespace llvm;
27*0fca6ea1SDimitry Andric using namespace llvm::object;
28*0fca6ea1SDimitry Andric using namespace llvm::logicalview;
29*0fca6ea1SDimitry Andric
30*0fca6ea1SDimitry Andric #define DEBUG_TYPE "DWARFReader"
31*0fca6ea1SDimitry Andric
createElement(dwarf::Tag Tag)32*0fca6ea1SDimitry Andric LVElement *LVDWARFReader::createElement(dwarf::Tag Tag) {
33*0fca6ea1SDimitry Andric CurrentScope = nullptr;
34*0fca6ea1SDimitry Andric CurrentSymbol = nullptr;
35*0fca6ea1SDimitry Andric CurrentType = nullptr;
36*0fca6ea1SDimitry Andric CurrentRanges.clear();
37*0fca6ea1SDimitry Andric
38*0fca6ea1SDimitry Andric if (!options().getPrintSymbols()) {
39*0fca6ea1SDimitry Andric switch (Tag) {
40*0fca6ea1SDimitry Andric // As the command line options did not specify a request to print
41*0fca6ea1SDimitry Andric // logical symbols (--print=symbols or --print=all or --print=elements),
42*0fca6ea1SDimitry Andric // skip its creation.
43*0fca6ea1SDimitry Andric case dwarf::DW_TAG_formal_parameter:
44*0fca6ea1SDimitry Andric case dwarf::DW_TAG_unspecified_parameters:
45*0fca6ea1SDimitry Andric case dwarf::DW_TAG_member:
46*0fca6ea1SDimitry Andric case dwarf::DW_TAG_variable:
47*0fca6ea1SDimitry Andric case dwarf::DW_TAG_inheritance:
48*0fca6ea1SDimitry Andric case dwarf::DW_TAG_constant:
49*0fca6ea1SDimitry Andric case dwarf::DW_TAG_call_site_parameter:
50*0fca6ea1SDimitry Andric case dwarf::DW_TAG_GNU_call_site_parameter:
51*0fca6ea1SDimitry Andric return nullptr;
52*0fca6ea1SDimitry Andric default:
53*0fca6ea1SDimitry Andric break;
54*0fca6ea1SDimitry Andric }
55*0fca6ea1SDimitry Andric }
56*0fca6ea1SDimitry Andric
57*0fca6ea1SDimitry Andric switch (Tag) {
58*0fca6ea1SDimitry Andric // Types.
59*0fca6ea1SDimitry Andric case dwarf::DW_TAG_base_type:
60*0fca6ea1SDimitry Andric CurrentType = createType();
61*0fca6ea1SDimitry Andric CurrentType->setIsBase();
62*0fca6ea1SDimitry Andric if (options().getAttributeBase())
63*0fca6ea1SDimitry Andric CurrentType->setIncludeInPrint();
64*0fca6ea1SDimitry Andric return CurrentType;
65*0fca6ea1SDimitry Andric case dwarf::DW_TAG_const_type:
66*0fca6ea1SDimitry Andric CurrentType = createType();
67*0fca6ea1SDimitry Andric CurrentType->setIsConst();
68*0fca6ea1SDimitry Andric CurrentType->setName("const");
69*0fca6ea1SDimitry Andric return CurrentType;
70*0fca6ea1SDimitry Andric case dwarf::DW_TAG_enumerator:
71*0fca6ea1SDimitry Andric CurrentType = createTypeEnumerator();
72*0fca6ea1SDimitry Andric return CurrentType;
73*0fca6ea1SDimitry Andric case dwarf::DW_TAG_imported_declaration:
74*0fca6ea1SDimitry Andric CurrentType = createTypeImport();
75*0fca6ea1SDimitry Andric CurrentType->setIsImportDeclaration();
76*0fca6ea1SDimitry Andric return CurrentType;
77*0fca6ea1SDimitry Andric case dwarf::DW_TAG_imported_module:
78*0fca6ea1SDimitry Andric CurrentType = createTypeImport();
79*0fca6ea1SDimitry Andric CurrentType->setIsImportModule();
80*0fca6ea1SDimitry Andric return CurrentType;
81*0fca6ea1SDimitry Andric case dwarf::DW_TAG_pointer_type:
82*0fca6ea1SDimitry Andric CurrentType = createType();
83*0fca6ea1SDimitry Andric CurrentType->setIsPointer();
84*0fca6ea1SDimitry Andric CurrentType->setName("*");
85*0fca6ea1SDimitry Andric return CurrentType;
86*0fca6ea1SDimitry Andric case dwarf::DW_TAG_ptr_to_member_type:
87*0fca6ea1SDimitry Andric CurrentType = createType();
88*0fca6ea1SDimitry Andric CurrentType->setIsPointerMember();
89*0fca6ea1SDimitry Andric CurrentType->setName("*");
90*0fca6ea1SDimitry Andric return CurrentType;
91*0fca6ea1SDimitry Andric case dwarf::DW_TAG_reference_type:
92*0fca6ea1SDimitry Andric CurrentType = createType();
93*0fca6ea1SDimitry Andric CurrentType->setIsReference();
94*0fca6ea1SDimitry Andric CurrentType->setName("&");
95*0fca6ea1SDimitry Andric return CurrentType;
96*0fca6ea1SDimitry Andric case dwarf::DW_TAG_restrict_type:
97*0fca6ea1SDimitry Andric CurrentType = createType();
98*0fca6ea1SDimitry Andric CurrentType->setIsRestrict();
99*0fca6ea1SDimitry Andric CurrentType->setName("restrict");
100*0fca6ea1SDimitry Andric return CurrentType;
101*0fca6ea1SDimitry Andric case dwarf::DW_TAG_rvalue_reference_type:
102*0fca6ea1SDimitry Andric CurrentType = createType();
103*0fca6ea1SDimitry Andric CurrentType->setIsRvalueReference();
104*0fca6ea1SDimitry Andric CurrentType->setName("&&");
105*0fca6ea1SDimitry Andric return CurrentType;
106*0fca6ea1SDimitry Andric case dwarf::DW_TAG_subrange_type:
107*0fca6ea1SDimitry Andric CurrentType = createTypeSubrange();
108*0fca6ea1SDimitry Andric return CurrentType;
109*0fca6ea1SDimitry Andric case dwarf::DW_TAG_template_value_parameter:
110*0fca6ea1SDimitry Andric CurrentType = createTypeParam();
111*0fca6ea1SDimitry Andric CurrentType->setIsTemplateValueParam();
112*0fca6ea1SDimitry Andric return CurrentType;
113*0fca6ea1SDimitry Andric case dwarf::DW_TAG_template_type_parameter:
114*0fca6ea1SDimitry Andric CurrentType = createTypeParam();
115*0fca6ea1SDimitry Andric CurrentType->setIsTemplateTypeParam();
116*0fca6ea1SDimitry Andric return CurrentType;
117*0fca6ea1SDimitry Andric case dwarf::DW_TAG_GNU_template_template_param:
118*0fca6ea1SDimitry Andric CurrentType = createTypeParam();
119*0fca6ea1SDimitry Andric CurrentType->setIsTemplateTemplateParam();
120*0fca6ea1SDimitry Andric return CurrentType;
121*0fca6ea1SDimitry Andric case dwarf::DW_TAG_typedef:
122*0fca6ea1SDimitry Andric CurrentType = createTypeDefinition();
123*0fca6ea1SDimitry Andric return CurrentType;
124*0fca6ea1SDimitry Andric case dwarf::DW_TAG_unspecified_type:
125*0fca6ea1SDimitry Andric CurrentType = createType();
126*0fca6ea1SDimitry Andric CurrentType->setIsUnspecified();
127*0fca6ea1SDimitry Andric return CurrentType;
128*0fca6ea1SDimitry Andric case dwarf::DW_TAG_volatile_type:
129*0fca6ea1SDimitry Andric CurrentType = createType();
130*0fca6ea1SDimitry Andric CurrentType->setIsVolatile();
131*0fca6ea1SDimitry Andric CurrentType->setName("volatile");
132*0fca6ea1SDimitry Andric return CurrentType;
133*0fca6ea1SDimitry Andric
134*0fca6ea1SDimitry Andric // Symbols.
135*0fca6ea1SDimitry Andric case dwarf::DW_TAG_formal_parameter:
136*0fca6ea1SDimitry Andric CurrentSymbol = createSymbol();
137*0fca6ea1SDimitry Andric CurrentSymbol->setIsParameter();
138*0fca6ea1SDimitry Andric return CurrentSymbol;
139*0fca6ea1SDimitry Andric case dwarf::DW_TAG_unspecified_parameters:
140*0fca6ea1SDimitry Andric CurrentSymbol = createSymbol();
141*0fca6ea1SDimitry Andric CurrentSymbol->setIsUnspecified();
142*0fca6ea1SDimitry Andric CurrentSymbol->setName("...");
143*0fca6ea1SDimitry Andric return CurrentSymbol;
144*0fca6ea1SDimitry Andric case dwarf::DW_TAG_member:
145*0fca6ea1SDimitry Andric CurrentSymbol = createSymbol();
146*0fca6ea1SDimitry Andric CurrentSymbol->setIsMember();
147*0fca6ea1SDimitry Andric return CurrentSymbol;
148*0fca6ea1SDimitry Andric case dwarf::DW_TAG_variable:
149*0fca6ea1SDimitry Andric CurrentSymbol = createSymbol();
150*0fca6ea1SDimitry Andric CurrentSymbol->setIsVariable();
151*0fca6ea1SDimitry Andric return CurrentSymbol;
152*0fca6ea1SDimitry Andric case dwarf::DW_TAG_inheritance:
153*0fca6ea1SDimitry Andric CurrentSymbol = createSymbol();
154*0fca6ea1SDimitry Andric CurrentSymbol->setIsInheritance();
155*0fca6ea1SDimitry Andric return CurrentSymbol;
156*0fca6ea1SDimitry Andric case dwarf::DW_TAG_call_site_parameter:
157*0fca6ea1SDimitry Andric case dwarf::DW_TAG_GNU_call_site_parameter:
158*0fca6ea1SDimitry Andric CurrentSymbol = createSymbol();
159*0fca6ea1SDimitry Andric CurrentSymbol->setIsCallSiteParameter();
160*0fca6ea1SDimitry Andric return CurrentSymbol;
161*0fca6ea1SDimitry Andric case dwarf::DW_TAG_constant:
162*0fca6ea1SDimitry Andric CurrentSymbol = createSymbol();
163*0fca6ea1SDimitry Andric CurrentSymbol->setIsConstant();
164*0fca6ea1SDimitry Andric return CurrentSymbol;
165*0fca6ea1SDimitry Andric
166*0fca6ea1SDimitry Andric // Scopes.
167*0fca6ea1SDimitry Andric case dwarf::DW_TAG_catch_block:
168*0fca6ea1SDimitry Andric CurrentScope = createScope();
169*0fca6ea1SDimitry Andric CurrentScope->setIsCatchBlock();
170*0fca6ea1SDimitry Andric return CurrentScope;
171*0fca6ea1SDimitry Andric case dwarf::DW_TAG_lexical_block:
172*0fca6ea1SDimitry Andric CurrentScope = createScope();
173*0fca6ea1SDimitry Andric CurrentScope->setIsLexicalBlock();
174*0fca6ea1SDimitry Andric return CurrentScope;
175*0fca6ea1SDimitry Andric case dwarf::DW_TAG_try_block:
176*0fca6ea1SDimitry Andric CurrentScope = createScope();
177*0fca6ea1SDimitry Andric CurrentScope->setIsTryBlock();
178*0fca6ea1SDimitry Andric return CurrentScope;
179*0fca6ea1SDimitry Andric case dwarf::DW_TAG_compile_unit:
180*0fca6ea1SDimitry Andric case dwarf::DW_TAG_skeleton_unit:
181*0fca6ea1SDimitry Andric CurrentScope = createScopeCompileUnit();
182*0fca6ea1SDimitry Andric CompileUnit = static_cast<LVScopeCompileUnit *>(CurrentScope);
183*0fca6ea1SDimitry Andric return CurrentScope;
184*0fca6ea1SDimitry Andric case dwarf::DW_TAG_inlined_subroutine:
185*0fca6ea1SDimitry Andric CurrentScope = createScopeFunctionInlined();
186*0fca6ea1SDimitry Andric return CurrentScope;
187*0fca6ea1SDimitry Andric case dwarf::DW_TAG_namespace:
188*0fca6ea1SDimitry Andric CurrentScope = createScopeNamespace();
189*0fca6ea1SDimitry Andric return CurrentScope;
190*0fca6ea1SDimitry Andric case dwarf::DW_TAG_template_alias:
191*0fca6ea1SDimitry Andric CurrentScope = createScopeAlias();
192*0fca6ea1SDimitry Andric return CurrentScope;
193*0fca6ea1SDimitry Andric case dwarf::DW_TAG_array_type:
194*0fca6ea1SDimitry Andric CurrentScope = createScopeArray();
195*0fca6ea1SDimitry Andric return CurrentScope;
196*0fca6ea1SDimitry Andric case dwarf::DW_TAG_call_site:
197*0fca6ea1SDimitry Andric case dwarf::DW_TAG_GNU_call_site:
198*0fca6ea1SDimitry Andric CurrentScope = createScopeFunction();
199*0fca6ea1SDimitry Andric CurrentScope->setIsCallSite();
200*0fca6ea1SDimitry Andric return CurrentScope;
201*0fca6ea1SDimitry Andric case dwarf::DW_TAG_entry_point:
202*0fca6ea1SDimitry Andric CurrentScope = createScopeFunction();
203*0fca6ea1SDimitry Andric CurrentScope->setIsEntryPoint();
204*0fca6ea1SDimitry Andric return CurrentScope;
205*0fca6ea1SDimitry Andric case dwarf::DW_TAG_subprogram:
206*0fca6ea1SDimitry Andric CurrentScope = createScopeFunction();
207*0fca6ea1SDimitry Andric CurrentScope->setIsSubprogram();
208*0fca6ea1SDimitry Andric return CurrentScope;
209*0fca6ea1SDimitry Andric case dwarf::DW_TAG_subroutine_type:
210*0fca6ea1SDimitry Andric CurrentScope = createScopeFunctionType();
211*0fca6ea1SDimitry Andric return CurrentScope;
212*0fca6ea1SDimitry Andric case dwarf::DW_TAG_label:
213*0fca6ea1SDimitry Andric CurrentScope = createScopeFunction();
214*0fca6ea1SDimitry Andric CurrentScope->setIsLabel();
215*0fca6ea1SDimitry Andric return CurrentScope;
216*0fca6ea1SDimitry Andric case dwarf::DW_TAG_class_type:
217*0fca6ea1SDimitry Andric CurrentScope = createScopeAggregate();
218*0fca6ea1SDimitry Andric CurrentScope->setIsClass();
219*0fca6ea1SDimitry Andric return CurrentScope;
220*0fca6ea1SDimitry Andric case dwarf::DW_TAG_structure_type:
221*0fca6ea1SDimitry Andric CurrentScope = createScopeAggregate();
222*0fca6ea1SDimitry Andric CurrentScope->setIsStructure();
223*0fca6ea1SDimitry Andric return CurrentScope;
224*0fca6ea1SDimitry Andric case dwarf::DW_TAG_union_type:
225*0fca6ea1SDimitry Andric CurrentScope = createScopeAggregate();
226*0fca6ea1SDimitry Andric CurrentScope->setIsUnion();
227*0fca6ea1SDimitry Andric return CurrentScope;
228*0fca6ea1SDimitry Andric case dwarf::DW_TAG_enumeration_type:
229*0fca6ea1SDimitry Andric CurrentScope = createScopeEnumeration();
230*0fca6ea1SDimitry Andric return CurrentScope;
231*0fca6ea1SDimitry Andric case dwarf::DW_TAG_GNU_formal_parameter_pack:
232*0fca6ea1SDimitry Andric CurrentScope = createScopeFormalPack();
233*0fca6ea1SDimitry Andric return CurrentScope;
234*0fca6ea1SDimitry Andric case dwarf::DW_TAG_GNU_template_parameter_pack:
235*0fca6ea1SDimitry Andric CurrentScope = createScopeTemplatePack();
236*0fca6ea1SDimitry Andric return CurrentScope;
237*0fca6ea1SDimitry Andric default:
238*0fca6ea1SDimitry Andric // Collect TAGs not implemented.
239*0fca6ea1SDimitry Andric if (options().getInternalTag() && Tag)
240*0fca6ea1SDimitry Andric CompileUnit->addDebugTag(Tag, CurrentOffset);
241*0fca6ea1SDimitry Andric break;
242*0fca6ea1SDimitry Andric }
243*0fca6ea1SDimitry Andric return nullptr;
244*0fca6ea1SDimitry Andric }
245*0fca6ea1SDimitry Andric
processOneAttribute(const DWARFDie & Die,LVOffset * OffsetPtr,const AttributeSpec & AttrSpec)246*0fca6ea1SDimitry Andric void LVDWARFReader::processOneAttribute(const DWARFDie &Die,
247*0fca6ea1SDimitry Andric LVOffset *OffsetPtr,
248*0fca6ea1SDimitry Andric const AttributeSpec &AttrSpec) {
249*0fca6ea1SDimitry Andric uint64_t OffsetOnEntry = *OffsetPtr;
250*0fca6ea1SDimitry Andric DWARFUnit *U = Die.getDwarfUnit();
251*0fca6ea1SDimitry Andric const DWARFFormValue &FormValue =
252*0fca6ea1SDimitry Andric DWARFFormValue::createFromUnit(AttrSpec.Form, U, OffsetPtr);
253*0fca6ea1SDimitry Andric
254*0fca6ea1SDimitry Andric // We are processing .debug_info section, implicit_const attribute
255*0fca6ea1SDimitry Andric // values are not really stored here, but in .debug_abbrev section.
256*0fca6ea1SDimitry Andric auto GetAsUnsignedConstant = [&]() -> int64_t {
257*0fca6ea1SDimitry Andric return AttrSpec.isImplicitConst() ? AttrSpec.getImplicitConstValue()
258*0fca6ea1SDimitry Andric : *FormValue.getAsUnsignedConstant();
259*0fca6ea1SDimitry Andric };
260*0fca6ea1SDimitry Andric
261*0fca6ea1SDimitry Andric auto GetFlag = [](const DWARFFormValue &FormValue) -> bool {
262*0fca6ea1SDimitry Andric return FormValue.isFormClass(DWARFFormValue::FC_Flag);
263*0fca6ea1SDimitry Andric };
264*0fca6ea1SDimitry Andric
265*0fca6ea1SDimitry Andric auto GetBoundValue = [](const DWARFFormValue &FormValue) -> int64_t {
266*0fca6ea1SDimitry Andric switch (FormValue.getForm()) {
267*0fca6ea1SDimitry Andric case dwarf::DW_FORM_ref_addr:
268*0fca6ea1SDimitry Andric case dwarf::DW_FORM_ref1:
269*0fca6ea1SDimitry Andric case dwarf::DW_FORM_ref2:
270*0fca6ea1SDimitry Andric case dwarf::DW_FORM_ref4:
271*0fca6ea1SDimitry Andric case dwarf::DW_FORM_ref8:
272*0fca6ea1SDimitry Andric case dwarf::DW_FORM_ref_udata:
273*0fca6ea1SDimitry Andric case dwarf::DW_FORM_ref_sig8:
274*0fca6ea1SDimitry Andric return *FormValue.getAsReferenceUVal();
275*0fca6ea1SDimitry Andric case dwarf::DW_FORM_data1:
276*0fca6ea1SDimitry Andric case dwarf::DW_FORM_flag:
277*0fca6ea1SDimitry Andric case dwarf::DW_FORM_data2:
278*0fca6ea1SDimitry Andric case dwarf::DW_FORM_data4:
279*0fca6ea1SDimitry Andric case dwarf::DW_FORM_data8:
280*0fca6ea1SDimitry Andric case dwarf::DW_FORM_udata:
281*0fca6ea1SDimitry Andric case dwarf::DW_FORM_ref_sup4:
282*0fca6ea1SDimitry Andric case dwarf::DW_FORM_ref_sup8:
283*0fca6ea1SDimitry Andric return *FormValue.getAsUnsignedConstant();
284*0fca6ea1SDimitry Andric case dwarf::DW_FORM_sdata:
285*0fca6ea1SDimitry Andric return *FormValue.getAsSignedConstant();
286*0fca6ea1SDimitry Andric default:
287*0fca6ea1SDimitry Andric return 0;
288*0fca6ea1SDimitry Andric }
289*0fca6ea1SDimitry Andric };
290*0fca6ea1SDimitry Andric
291*0fca6ea1SDimitry Andric LLVM_DEBUG({
292*0fca6ea1SDimitry Andric dbgs() << " " << hexValue(OffsetOnEntry)
293*0fca6ea1SDimitry Andric << formatv(" {0}", AttrSpec.Attr) << "\n";
294*0fca6ea1SDimitry Andric });
295*0fca6ea1SDimitry Andric
296*0fca6ea1SDimitry Andric switch (AttrSpec.Attr) {
297*0fca6ea1SDimitry Andric case dwarf::DW_AT_accessibility:
298*0fca6ea1SDimitry Andric CurrentElement->setAccessibilityCode(*FormValue.getAsUnsignedConstant());
299*0fca6ea1SDimitry Andric break;
300*0fca6ea1SDimitry Andric case dwarf::DW_AT_artificial:
301*0fca6ea1SDimitry Andric CurrentElement->setIsArtificial();
302*0fca6ea1SDimitry Andric break;
303*0fca6ea1SDimitry Andric case dwarf::DW_AT_bit_size:
304*0fca6ea1SDimitry Andric CurrentElement->setBitSize(*FormValue.getAsUnsignedConstant());
305*0fca6ea1SDimitry Andric break;
306*0fca6ea1SDimitry Andric case dwarf::DW_AT_call_file:
307*0fca6ea1SDimitry Andric CurrentElement->setCallFilenameIndex(GetAsUnsignedConstant());
308*0fca6ea1SDimitry Andric break;
309*0fca6ea1SDimitry Andric case dwarf::DW_AT_call_line:
310*0fca6ea1SDimitry Andric CurrentElement->setCallLineNumber(IncrementFileIndex
311*0fca6ea1SDimitry Andric ? GetAsUnsignedConstant() + 1
312*0fca6ea1SDimitry Andric : GetAsUnsignedConstant());
313*0fca6ea1SDimitry Andric break;
314*0fca6ea1SDimitry Andric case dwarf::DW_AT_comp_dir:
315*0fca6ea1SDimitry Andric CompileUnit->setCompilationDirectory(dwarf::toStringRef(FormValue));
316*0fca6ea1SDimitry Andric break;
317*0fca6ea1SDimitry Andric case dwarf::DW_AT_const_value:
318*0fca6ea1SDimitry Andric if (FormValue.isFormClass(DWARFFormValue::FC_Block)) {
319*0fca6ea1SDimitry Andric ArrayRef<uint8_t> Expr = *FormValue.getAsBlock();
320*0fca6ea1SDimitry Andric // Store the expression as a hexadecimal string.
321*0fca6ea1SDimitry Andric CurrentElement->setValue(
322*0fca6ea1SDimitry Andric llvm::toHex(llvm::toStringRef(Expr), /*LowerCase=*/true));
323*0fca6ea1SDimitry Andric } else if (FormValue.isFormClass(DWARFFormValue::FC_Constant)) {
324*0fca6ea1SDimitry Andric // In the case of negative values, generate the string representation
325*0fca6ea1SDimitry Andric // for a positive value prefixed with the negative sign.
326*0fca6ea1SDimitry Andric if (FormValue.getForm() == dwarf::DW_FORM_sdata) {
327*0fca6ea1SDimitry Andric std::stringstream Stream;
328*0fca6ea1SDimitry Andric int64_t Value = *FormValue.getAsSignedConstant();
329*0fca6ea1SDimitry Andric if (Value < 0) {
330*0fca6ea1SDimitry Andric Stream << "-";
331*0fca6ea1SDimitry Andric Value = std::abs(Value);
332*0fca6ea1SDimitry Andric }
333*0fca6ea1SDimitry Andric Stream << hexString(Value, 2);
334*0fca6ea1SDimitry Andric CurrentElement->setValue(Stream.str());
335*0fca6ea1SDimitry Andric } else
336*0fca6ea1SDimitry Andric CurrentElement->setValue(
337*0fca6ea1SDimitry Andric hexString(*FormValue.getAsUnsignedConstant(), 2));
338*0fca6ea1SDimitry Andric } else
339*0fca6ea1SDimitry Andric CurrentElement->setValue(dwarf::toStringRef(FormValue));
340*0fca6ea1SDimitry Andric break;
341*0fca6ea1SDimitry Andric case dwarf::DW_AT_count:
342*0fca6ea1SDimitry Andric CurrentElement->setCount(*FormValue.getAsUnsignedConstant());
343*0fca6ea1SDimitry Andric break;
344*0fca6ea1SDimitry Andric case dwarf::DW_AT_decl_line:
345*0fca6ea1SDimitry Andric CurrentElement->setLineNumber(GetAsUnsignedConstant());
346*0fca6ea1SDimitry Andric break;
347*0fca6ea1SDimitry Andric case dwarf::DW_AT_decl_file:
348*0fca6ea1SDimitry Andric CurrentElement->setFilenameIndex(IncrementFileIndex
349*0fca6ea1SDimitry Andric ? GetAsUnsignedConstant() + 1
350*0fca6ea1SDimitry Andric : GetAsUnsignedConstant());
351*0fca6ea1SDimitry Andric break;
352*0fca6ea1SDimitry Andric case dwarf::DW_AT_enum_class:
353*0fca6ea1SDimitry Andric if (GetFlag(FormValue))
354*0fca6ea1SDimitry Andric CurrentElement->setIsEnumClass();
355*0fca6ea1SDimitry Andric break;
356*0fca6ea1SDimitry Andric case dwarf::DW_AT_external:
357*0fca6ea1SDimitry Andric if (GetFlag(FormValue))
358*0fca6ea1SDimitry Andric CurrentElement->setIsExternal();
359*0fca6ea1SDimitry Andric break;
360*0fca6ea1SDimitry Andric case dwarf::DW_AT_GNU_discriminator:
361*0fca6ea1SDimitry Andric CurrentElement->setDiscriminator(*FormValue.getAsUnsignedConstant());
362*0fca6ea1SDimitry Andric break;
363*0fca6ea1SDimitry Andric case dwarf::DW_AT_inline:
364*0fca6ea1SDimitry Andric CurrentElement->setInlineCode(*FormValue.getAsUnsignedConstant());
365*0fca6ea1SDimitry Andric break;
366*0fca6ea1SDimitry Andric case dwarf::DW_AT_lower_bound:
367*0fca6ea1SDimitry Andric CurrentElement->setLowerBound(GetBoundValue(FormValue));
368*0fca6ea1SDimitry Andric break;
369*0fca6ea1SDimitry Andric case dwarf::DW_AT_name:
370*0fca6ea1SDimitry Andric CurrentElement->setName(dwarf::toStringRef(FormValue));
371*0fca6ea1SDimitry Andric break;
372*0fca6ea1SDimitry Andric case dwarf::DW_AT_linkage_name:
373*0fca6ea1SDimitry Andric case dwarf::DW_AT_MIPS_linkage_name:
374*0fca6ea1SDimitry Andric CurrentElement->setLinkageName(dwarf::toStringRef(FormValue));
375*0fca6ea1SDimitry Andric break;
376*0fca6ea1SDimitry Andric case dwarf::DW_AT_producer:
377*0fca6ea1SDimitry Andric if (options().getAttributeProducer())
378*0fca6ea1SDimitry Andric CurrentElement->setProducer(dwarf::toStringRef(FormValue));
379*0fca6ea1SDimitry Andric break;
380*0fca6ea1SDimitry Andric case dwarf::DW_AT_upper_bound:
381*0fca6ea1SDimitry Andric CurrentElement->setUpperBound(GetBoundValue(FormValue));
382*0fca6ea1SDimitry Andric break;
383*0fca6ea1SDimitry Andric case dwarf::DW_AT_virtuality:
384*0fca6ea1SDimitry Andric CurrentElement->setVirtualityCode(*FormValue.getAsUnsignedConstant());
385*0fca6ea1SDimitry Andric break;
386*0fca6ea1SDimitry Andric
387*0fca6ea1SDimitry Andric case dwarf::DW_AT_abstract_origin:
388*0fca6ea1SDimitry Andric case dwarf::DW_AT_call_origin:
389*0fca6ea1SDimitry Andric case dwarf::DW_AT_extension:
390*0fca6ea1SDimitry Andric case dwarf::DW_AT_import:
391*0fca6ea1SDimitry Andric case dwarf::DW_AT_specification:
392*0fca6ea1SDimitry Andric case dwarf::DW_AT_type:
393*0fca6ea1SDimitry Andric updateReference(AttrSpec.Attr, FormValue);
394*0fca6ea1SDimitry Andric break;
395*0fca6ea1SDimitry Andric
396*0fca6ea1SDimitry Andric case dwarf::DW_AT_low_pc:
397*0fca6ea1SDimitry Andric if (options().getGeneralCollectRanges()) {
398*0fca6ea1SDimitry Andric FoundLowPC = true;
399*0fca6ea1SDimitry Andric // For toolchains that support the removal of unused code, the linker
400*0fca6ea1SDimitry Andric // marks functions that have been removed, by setting the value for the
401*0fca6ea1SDimitry Andric // low_pc to the max address.
402*0fca6ea1SDimitry Andric if (std::optional<uint64_t> Value = FormValue.getAsAddress()) {
403*0fca6ea1SDimitry Andric CurrentLowPC = *Value;
404*0fca6ea1SDimitry Andric } else {
405*0fca6ea1SDimitry Andric uint64_t UValue = FormValue.getRawUValue();
406*0fca6ea1SDimitry Andric if (U->getAddrOffsetSectionItem(UValue)) {
407*0fca6ea1SDimitry Andric CurrentLowPC = *FormValue.getAsAddress();
408*0fca6ea1SDimitry Andric } else {
409*0fca6ea1SDimitry Andric FoundLowPC = false;
410*0fca6ea1SDimitry Andric // We are dealing with an index into the .debug_addr section.
411*0fca6ea1SDimitry Andric LLVM_DEBUG({
412*0fca6ea1SDimitry Andric dbgs() << format("indexed (%8.8x) address = ", (uint32_t)UValue);
413*0fca6ea1SDimitry Andric });
414*0fca6ea1SDimitry Andric }
415*0fca6ea1SDimitry Andric }
416*0fca6ea1SDimitry Andric if (FoundLowPC) {
417*0fca6ea1SDimitry Andric if (CurrentLowPC == MaxAddress)
418*0fca6ea1SDimitry Andric CurrentElement->setIsDiscarded();
419*0fca6ea1SDimitry Andric // Consider the case of WebAssembly.
420*0fca6ea1SDimitry Andric CurrentLowPC += WasmCodeSectionOffset;
421*0fca6ea1SDimitry Andric if (CurrentElement->isCompileUnit())
422*0fca6ea1SDimitry Andric setCUBaseAddress(CurrentLowPC);
423*0fca6ea1SDimitry Andric }
424*0fca6ea1SDimitry Andric }
425*0fca6ea1SDimitry Andric break;
426*0fca6ea1SDimitry Andric
427*0fca6ea1SDimitry Andric case dwarf::DW_AT_high_pc:
428*0fca6ea1SDimitry Andric if (options().getGeneralCollectRanges()) {
429*0fca6ea1SDimitry Andric FoundHighPC = true;
430*0fca6ea1SDimitry Andric if (std::optional<uint64_t> Address = FormValue.getAsAddress())
431*0fca6ea1SDimitry Andric // High PC is an address.
432*0fca6ea1SDimitry Andric CurrentHighPC = *Address;
433*0fca6ea1SDimitry Andric if (std::optional<uint64_t> Offset = FormValue.getAsUnsignedConstant())
434*0fca6ea1SDimitry Andric // High PC is an offset from LowPC.
435*0fca6ea1SDimitry Andric // Don't add the WebAssembly offset if we have seen a DW_AT_low_pc, as
436*0fca6ea1SDimitry Andric // the CurrentLowPC has already that offset added. Basically, use the
437*0fca6ea1SDimitry Andric // original DW_AT_loc_pc value.
438*0fca6ea1SDimitry Andric CurrentHighPC =
439*0fca6ea1SDimitry Andric (FoundLowPC ? CurrentLowPC - WasmCodeSectionOffset : CurrentLowPC) +
440*0fca6ea1SDimitry Andric *Offset;
441*0fca6ea1SDimitry Andric // Store the real upper limit for the address range.
442*0fca6ea1SDimitry Andric if (UpdateHighAddress && CurrentHighPC > 0)
443*0fca6ea1SDimitry Andric --CurrentHighPC;
444*0fca6ea1SDimitry Andric // Consider the case of WebAssembly.
445*0fca6ea1SDimitry Andric CurrentHighPC += WasmCodeSectionOffset;
446*0fca6ea1SDimitry Andric if (CurrentElement->isCompileUnit())
447*0fca6ea1SDimitry Andric setCUHighAddress(CurrentHighPC);
448*0fca6ea1SDimitry Andric }
449*0fca6ea1SDimitry Andric break;
450*0fca6ea1SDimitry Andric
451*0fca6ea1SDimitry Andric case dwarf::DW_AT_ranges:
452*0fca6ea1SDimitry Andric if (RangesDataAvailable && options().getGeneralCollectRanges()) {
453*0fca6ea1SDimitry Andric auto GetRanges = [](const DWARFFormValue &FormValue,
454*0fca6ea1SDimitry Andric DWARFUnit *U) -> Expected<DWARFAddressRangesVector> {
455*0fca6ea1SDimitry Andric if (FormValue.getForm() == dwarf::DW_FORM_rnglistx)
456*0fca6ea1SDimitry Andric return U->findRnglistFromIndex(*FormValue.getAsSectionOffset());
457*0fca6ea1SDimitry Andric return U->findRnglistFromOffset(*FormValue.getAsSectionOffset());
458*0fca6ea1SDimitry Andric };
459*0fca6ea1SDimitry Andric Expected<DWARFAddressRangesVector> RangesOrError =
460*0fca6ea1SDimitry Andric GetRanges(FormValue, U);
461*0fca6ea1SDimitry Andric if (!RangesOrError) {
462*0fca6ea1SDimitry Andric LLVM_DEBUG({
463*0fca6ea1SDimitry Andric std::string TheError(toString(RangesOrError.takeError()));
464*0fca6ea1SDimitry Andric dbgs() << format("error decoding address ranges = ",
465*0fca6ea1SDimitry Andric TheError.c_str());
466*0fca6ea1SDimitry Andric });
467*0fca6ea1SDimitry Andric consumeError(RangesOrError.takeError());
468*0fca6ea1SDimitry Andric break;
469*0fca6ea1SDimitry Andric }
470*0fca6ea1SDimitry Andric // The address ranges are absolute. There is no need to add any addend.
471*0fca6ea1SDimitry Andric DWARFAddressRangesVector Ranges = RangesOrError.get();
472*0fca6ea1SDimitry Andric for (DWARFAddressRange &Range : Ranges) {
473*0fca6ea1SDimitry Andric // This seems to be a tombstone for empty ranges.
474*0fca6ea1SDimitry Andric if (Range.LowPC == Range.HighPC)
475*0fca6ea1SDimitry Andric continue;
476*0fca6ea1SDimitry Andric // Store the real upper limit for the address range.
477*0fca6ea1SDimitry Andric if (UpdateHighAddress && Range.HighPC > 0)
478*0fca6ea1SDimitry Andric --Range.HighPC;
479*0fca6ea1SDimitry Andric // Consider the case of WebAssembly.
480*0fca6ea1SDimitry Andric Range.LowPC += WasmCodeSectionOffset;
481*0fca6ea1SDimitry Andric Range.HighPC += WasmCodeSectionOffset;
482*0fca6ea1SDimitry Andric // Add the pair of addresses.
483*0fca6ea1SDimitry Andric CurrentScope->addObject(Range.LowPC, Range.HighPC);
484*0fca6ea1SDimitry Andric // If the scope is the CU, do not update the ranges set.
485*0fca6ea1SDimitry Andric if (!CurrentElement->isCompileUnit())
486*0fca6ea1SDimitry Andric CurrentRanges.emplace_back(Range.LowPC, Range.HighPC);
487*0fca6ea1SDimitry Andric }
488*0fca6ea1SDimitry Andric }
489*0fca6ea1SDimitry Andric break;
490*0fca6ea1SDimitry Andric
491*0fca6ea1SDimitry Andric // Get the location list for the symbol.
492*0fca6ea1SDimitry Andric case dwarf::DW_AT_data_member_location:
493*0fca6ea1SDimitry Andric if (options().getAttributeAnyLocation())
494*0fca6ea1SDimitry Andric processLocationMember(AttrSpec.Attr, FormValue, Die, OffsetOnEntry);
495*0fca6ea1SDimitry Andric break;
496*0fca6ea1SDimitry Andric
497*0fca6ea1SDimitry Andric // Get the location list for the symbol.
498*0fca6ea1SDimitry Andric case dwarf::DW_AT_location:
499*0fca6ea1SDimitry Andric case dwarf::DW_AT_string_length:
500*0fca6ea1SDimitry Andric case dwarf::DW_AT_use_location:
501*0fca6ea1SDimitry Andric if (options().getAttributeAnyLocation() && CurrentSymbol)
502*0fca6ea1SDimitry Andric processLocationList(AttrSpec.Attr, FormValue, Die, OffsetOnEntry);
503*0fca6ea1SDimitry Andric break;
504*0fca6ea1SDimitry Andric
505*0fca6ea1SDimitry Andric case dwarf::DW_AT_call_data_value:
506*0fca6ea1SDimitry Andric case dwarf::DW_AT_call_value:
507*0fca6ea1SDimitry Andric case dwarf::DW_AT_GNU_call_site_data_value:
508*0fca6ea1SDimitry Andric case dwarf::DW_AT_GNU_call_site_value:
509*0fca6ea1SDimitry Andric if (options().getAttributeAnyLocation() && CurrentSymbol)
510*0fca6ea1SDimitry Andric processLocationList(AttrSpec.Attr, FormValue, Die, OffsetOnEntry,
511*0fca6ea1SDimitry Andric /*CallSiteLocation=*/true);
512*0fca6ea1SDimitry Andric break;
513*0fca6ea1SDimitry Andric
514*0fca6ea1SDimitry Andric default:
515*0fca6ea1SDimitry Andric break;
516*0fca6ea1SDimitry Andric }
517*0fca6ea1SDimitry Andric }
518*0fca6ea1SDimitry Andric
processOneDie(const DWARFDie & InputDIE,LVScope * Parent,DWARFDie & SkeletonDie)519*0fca6ea1SDimitry Andric LVScope *LVDWARFReader::processOneDie(const DWARFDie &InputDIE, LVScope *Parent,
520*0fca6ea1SDimitry Andric DWARFDie &SkeletonDie) {
521*0fca6ea1SDimitry Andric // If the input DIE corresponds to the compile unit, it can be:
522*0fca6ea1SDimitry Andric // a) Simple DWARF: a standard DIE. Ignore the skeleton DIE (is empty).
523*0fca6ea1SDimitry Andric // b) Split DWARF: the DIE for the split DWARF. The skeleton is the DIE
524*0fca6ea1SDimitry Andric // for the skeleton DWARF. Process both DIEs.
525*0fca6ea1SDimitry Andric const DWARFDie &DIE = SkeletonDie.isValid() ? SkeletonDie : InputDIE;
526*0fca6ea1SDimitry Andric DWARFDataExtractor DebugInfoData =
527*0fca6ea1SDimitry Andric DIE.getDwarfUnit()->getDebugInfoExtractor();
528*0fca6ea1SDimitry Andric LVOffset Offset = DIE.getOffset();
529*0fca6ea1SDimitry Andric
530*0fca6ea1SDimitry Andric // Reset values for the current DIE.
531*0fca6ea1SDimitry Andric CurrentLowPC = 0;
532*0fca6ea1SDimitry Andric CurrentHighPC = 0;
533*0fca6ea1SDimitry Andric CurrentOffset = Offset;
534*0fca6ea1SDimitry Andric CurrentEndOffset = 0;
535*0fca6ea1SDimitry Andric FoundLowPC = false;
536*0fca6ea1SDimitry Andric FoundHighPC = false;
537*0fca6ea1SDimitry Andric
538*0fca6ea1SDimitry Andric // Process supported attributes.
539*0fca6ea1SDimitry Andric if (DebugInfoData.isValidOffset(Offset)) {
540*0fca6ea1SDimitry Andric
541*0fca6ea1SDimitry Andric LLVM_DEBUG({
542*0fca6ea1SDimitry Andric dbgs() << "DIE: " << hexValue(Offset) << formatv(" {0}", DIE.getTag())
543*0fca6ea1SDimitry Andric << "\n";
544*0fca6ea1SDimitry Andric });
545*0fca6ea1SDimitry Andric
546*0fca6ea1SDimitry Andric // Create the logical view element for the current DIE.
547*0fca6ea1SDimitry Andric dwarf::Tag Tag = DIE.getTag();
548*0fca6ea1SDimitry Andric CurrentElement = createElement(Tag);
549*0fca6ea1SDimitry Andric if (!CurrentElement)
550*0fca6ea1SDimitry Andric return CurrentScope;
551*0fca6ea1SDimitry Andric
552*0fca6ea1SDimitry Andric CurrentElement->setTag(Tag);
553*0fca6ea1SDimitry Andric CurrentElement->setOffset(Offset);
554*0fca6ea1SDimitry Andric
555*0fca6ea1SDimitry Andric if (options().getAttributeAnySource() && CurrentElement->isCompileUnit())
556*0fca6ea1SDimitry Andric addCompileUnitOffset(Offset,
557*0fca6ea1SDimitry Andric static_cast<LVScopeCompileUnit *>(CurrentElement));
558*0fca6ea1SDimitry Andric
559*0fca6ea1SDimitry Andric // Insert the newly created element into the element symbol table. If the
560*0fca6ea1SDimitry Andric // element is in the list, it means there are previously created elements
561*0fca6ea1SDimitry Andric // referencing this element.
562*0fca6ea1SDimitry Andric if (ElementTable.find(Offset) == ElementTable.end()) {
563*0fca6ea1SDimitry Andric // No previous references to this offset.
564*0fca6ea1SDimitry Andric ElementTable.emplace(std::piecewise_construct,
565*0fca6ea1SDimitry Andric std::forward_as_tuple(Offset),
566*0fca6ea1SDimitry Andric std::forward_as_tuple(CurrentElement));
567*0fca6ea1SDimitry Andric } else {
568*0fca6ea1SDimitry Andric // There are previous references to this element. We need to update the
569*0fca6ea1SDimitry Andric // element and all the references pointing to this element.
570*0fca6ea1SDimitry Andric LVElementEntry &Reference = ElementTable[Offset];
571*0fca6ea1SDimitry Andric Reference.Element = CurrentElement;
572*0fca6ea1SDimitry Andric // Traverse the element set and update the elements (backtracking).
573*0fca6ea1SDimitry Andric for (LVElement *Target : Reference.References)
574*0fca6ea1SDimitry Andric Target->setReference(CurrentElement);
575*0fca6ea1SDimitry Andric for (LVElement *Target : Reference.Types)
576*0fca6ea1SDimitry Andric Target->setType(CurrentElement);
577*0fca6ea1SDimitry Andric // Clear the pending elements.
578*0fca6ea1SDimitry Andric Reference.References.clear();
579*0fca6ea1SDimitry Andric Reference.Types.clear();
580*0fca6ea1SDimitry Andric }
581*0fca6ea1SDimitry Andric
582*0fca6ea1SDimitry Andric // Add the current element to its parent as there are attributes
583*0fca6ea1SDimitry Andric // (locations) that require the scope level.
584*0fca6ea1SDimitry Andric if (CurrentScope)
585*0fca6ea1SDimitry Andric Parent->addElement(CurrentScope);
586*0fca6ea1SDimitry Andric else if (CurrentSymbol)
587*0fca6ea1SDimitry Andric Parent->addElement(CurrentSymbol);
588*0fca6ea1SDimitry Andric else if (CurrentType)
589*0fca6ea1SDimitry Andric Parent->addElement(CurrentType);
590*0fca6ea1SDimitry Andric
591*0fca6ea1SDimitry Andric // Process the attributes for the given DIE.
592*0fca6ea1SDimitry Andric auto ProcessAttributes = [&](const DWARFDie &TheDIE,
593*0fca6ea1SDimitry Andric DWARFDataExtractor &DebugData) {
594*0fca6ea1SDimitry Andric CurrentEndOffset = Offset;
595*0fca6ea1SDimitry Andric uint32_t abbrCode = DebugData.getULEB128(&CurrentEndOffset);
596*0fca6ea1SDimitry Andric if (abbrCode) {
597*0fca6ea1SDimitry Andric if (const DWARFAbbreviationDeclaration *AbbrevDecl =
598*0fca6ea1SDimitry Andric TheDIE.getAbbreviationDeclarationPtr())
599*0fca6ea1SDimitry Andric if (AbbrevDecl)
600*0fca6ea1SDimitry Andric for (const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec :
601*0fca6ea1SDimitry Andric AbbrevDecl->attributes())
602*0fca6ea1SDimitry Andric processOneAttribute(TheDIE, &CurrentEndOffset, AttrSpec);
603*0fca6ea1SDimitry Andric }
604*0fca6ea1SDimitry Andric };
605*0fca6ea1SDimitry Andric
606*0fca6ea1SDimitry Andric ProcessAttributes(DIE, DebugInfoData);
607*0fca6ea1SDimitry Andric
608*0fca6ea1SDimitry Andric // If the input DIE is for a compile unit, process its attributes in
609*0fca6ea1SDimitry Andric // the case of split DWARF, to override any common attribute values.
610*0fca6ea1SDimitry Andric if (SkeletonDie.isValid()) {
611*0fca6ea1SDimitry Andric DWARFDataExtractor DebugInfoData =
612*0fca6ea1SDimitry Andric InputDIE.getDwarfUnit()->getDebugInfoExtractor();
613*0fca6ea1SDimitry Andric LVOffset Offset = InputDIE.getOffset();
614*0fca6ea1SDimitry Andric if (DebugInfoData.isValidOffset(Offset))
615*0fca6ea1SDimitry Andric ProcessAttributes(InputDIE, DebugInfoData);
616*0fca6ea1SDimitry Andric }
617*0fca6ea1SDimitry Andric }
618*0fca6ea1SDimitry Andric
619*0fca6ea1SDimitry Andric if (CurrentScope) {
620*0fca6ea1SDimitry Andric if (CurrentScope->getCanHaveRanges()) {
621*0fca6ea1SDimitry Andric // If the scope has ranges, they are already added to the scope.
622*0fca6ea1SDimitry Andric // Add any collected LowPC/HighPC values.
623*0fca6ea1SDimitry Andric bool IsCompileUnit = CurrentScope->getIsCompileUnit();
624*0fca6ea1SDimitry Andric if (FoundLowPC && FoundHighPC) {
625*0fca6ea1SDimitry Andric CurrentScope->addObject(CurrentLowPC, CurrentHighPC);
626*0fca6ea1SDimitry Andric if (!IsCompileUnit) {
627*0fca6ea1SDimitry Andric // If the scope is a function, add it to the public names.
628*0fca6ea1SDimitry Andric if ((options().getAttributePublics() ||
629*0fca6ea1SDimitry Andric options().getPrintAnyLine()) &&
630*0fca6ea1SDimitry Andric CurrentScope->getIsFunction() &&
631*0fca6ea1SDimitry Andric !CurrentScope->getIsInlinedFunction())
632*0fca6ea1SDimitry Andric CompileUnit->addPublicName(CurrentScope, CurrentLowPC,
633*0fca6ea1SDimitry Andric CurrentHighPC);
634*0fca6ea1SDimitry Andric }
635*0fca6ea1SDimitry Andric }
636*0fca6ea1SDimitry Andric
637*0fca6ea1SDimitry Andric // Look for scopes with ranges and no linkage name information that
638*0fca6ea1SDimitry Andric // are referencing another scopes via DW_AT_specification. They are
639*0fca6ea1SDimitry Andric // possible candidates for a comdat scope.
640*0fca6ea1SDimitry Andric if (CurrentScope->getHasRanges() &&
641*0fca6ea1SDimitry Andric !CurrentScope->getLinkageNameIndex() &&
642*0fca6ea1SDimitry Andric CurrentScope->getHasReferenceSpecification()) {
643*0fca6ea1SDimitry Andric // Get the linkage name in order to search for a possible comdat.
644*0fca6ea1SDimitry Andric std::optional<DWARFFormValue> LinkageDIE =
645*0fca6ea1SDimitry Andric DIE.findRecursively(dwarf::DW_AT_linkage_name);
646*0fca6ea1SDimitry Andric if (LinkageDIE.has_value()) {
647*0fca6ea1SDimitry Andric StringRef Name(dwarf::toStringRef(LinkageDIE));
648*0fca6ea1SDimitry Andric if (!Name.empty())
649*0fca6ea1SDimitry Andric CurrentScope->setLinkageName(Name);
650*0fca6ea1SDimitry Andric }
651*0fca6ea1SDimitry Andric }
652*0fca6ea1SDimitry Andric
653*0fca6ea1SDimitry Andric // If the current scope is in the 'LinkageNames' table, update its
654*0fca6ea1SDimitry Andric // logical scope. For other scopes, always we will assume the default
655*0fca6ea1SDimitry Andric // ".text" section index.
656*0fca6ea1SDimitry Andric LVSectionIndex SectionIndex = updateSymbolTable(CurrentScope);
657*0fca6ea1SDimitry Andric if (CurrentScope->getIsComdat())
658*0fca6ea1SDimitry Andric CompileUnit->setHasComdatScopes();
659*0fca6ea1SDimitry Andric
660*0fca6ea1SDimitry Andric // Update section index contained ranges.
661*0fca6ea1SDimitry Andric if (SectionIndex) {
662*0fca6ea1SDimitry Andric if (!CurrentRanges.empty()) {
663*0fca6ea1SDimitry Andric for (LVAddressRange &Range : CurrentRanges)
664*0fca6ea1SDimitry Andric addSectionRange(SectionIndex, CurrentScope, Range.first,
665*0fca6ea1SDimitry Andric Range.second);
666*0fca6ea1SDimitry Andric CurrentRanges.clear();
667*0fca6ea1SDimitry Andric }
668*0fca6ea1SDimitry Andric // If the scope is the CU, do not update the ranges set.
669*0fca6ea1SDimitry Andric if (FoundLowPC && FoundHighPC && !IsCompileUnit) {
670*0fca6ea1SDimitry Andric addSectionRange(SectionIndex, CurrentScope, CurrentLowPC,
671*0fca6ea1SDimitry Andric CurrentHighPC);
672*0fca6ea1SDimitry Andric }
673*0fca6ea1SDimitry Andric }
674*0fca6ea1SDimitry Andric }
675*0fca6ea1SDimitry Andric // Mark member functions.
676*0fca6ea1SDimitry Andric if (Parent->getIsAggregate())
677*0fca6ea1SDimitry Andric CurrentScope->setIsMember();
678*0fca6ea1SDimitry Andric }
679*0fca6ea1SDimitry Andric
680*0fca6ea1SDimitry Andric // Keep track of symbols with locations.
681*0fca6ea1SDimitry Andric if (options().getAttributeAnyLocation() && CurrentSymbol &&
682*0fca6ea1SDimitry Andric CurrentSymbol->getHasLocation())
683*0fca6ea1SDimitry Andric SymbolsWithLocations.push_back(CurrentSymbol);
684*0fca6ea1SDimitry Andric
685*0fca6ea1SDimitry Andric // If we have template parameters, mark the parent as template.
686*0fca6ea1SDimitry Andric if (CurrentType && CurrentType->getIsTemplateParam())
687*0fca6ea1SDimitry Andric Parent->setIsTemplate();
688*0fca6ea1SDimitry Andric
689*0fca6ea1SDimitry Andric return CurrentScope;
690*0fca6ea1SDimitry Andric }
691*0fca6ea1SDimitry Andric
traverseDieAndChildren(DWARFDie & DIE,LVScope * Parent,DWARFDie & SkeletonDie)692*0fca6ea1SDimitry Andric void LVDWARFReader::traverseDieAndChildren(DWARFDie &DIE, LVScope *Parent,
693*0fca6ea1SDimitry Andric DWARFDie &SkeletonDie) {
694*0fca6ea1SDimitry Andric // Process the current DIE.
695*0fca6ea1SDimitry Andric LVScope *Scope = processOneDie(DIE, Parent, SkeletonDie);
696*0fca6ea1SDimitry Andric if (Scope) {
697*0fca6ea1SDimitry Andric LVOffset Lower = DIE.getOffset();
698*0fca6ea1SDimitry Andric LVOffset Upper = CurrentEndOffset;
699*0fca6ea1SDimitry Andric DWARFDie DummyDie;
700*0fca6ea1SDimitry Andric // Traverse the children chain.
701*0fca6ea1SDimitry Andric DWARFDie Child = DIE.getFirstChild();
702*0fca6ea1SDimitry Andric while (Child) {
703*0fca6ea1SDimitry Andric traverseDieAndChildren(Child, Scope, DummyDie);
704*0fca6ea1SDimitry Andric Upper = Child.getOffset();
705*0fca6ea1SDimitry Andric Child = Child.getSibling();
706*0fca6ea1SDimitry Andric }
707*0fca6ea1SDimitry Andric // Calculate contributions to the debug info section.
708*0fca6ea1SDimitry Andric if (options().getPrintSizes() && Upper)
709*0fca6ea1SDimitry Andric CompileUnit->addSize(Scope, Lower, Upper);
710*0fca6ea1SDimitry Andric }
711*0fca6ea1SDimitry Andric }
712*0fca6ea1SDimitry Andric
processLocationGaps()713*0fca6ea1SDimitry Andric void LVDWARFReader::processLocationGaps() {
714*0fca6ea1SDimitry Andric if (options().getAttributeAnyLocation())
715*0fca6ea1SDimitry Andric for (LVSymbol *Symbol : SymbolsWithLocations)
716*0fca6ea1SDimitry Andric Symbol->fillLocationGaps();
717*0fca6ea1SDimitry Andric }
718*0fca6ea1SDimitry Andric
createLineAndFileRecords(const DWARFDebugLine::LineTable * Lines)719*0fca6ea1SDimitry Andric void LVDWARFReader::createLineAndFileRecords(
720*0fca6ea1SDimitry Andric const DWARFDebugLine::LineTable *Lines) {
721*0fca6ea1SDimitry Andric if (!Lines)
722*0fca6ea1SDimitry Andric return;
723*0fca6ea1SDimitry Andric
724*0fca6ea1SDimitry Andric // Get the source filenames.
725*0fca6ea1SDimitry Andric if (!Lines->Prologue.FileNames.empty())
726*0fca6ea1SDimitry Andric for (const DWARFDebugLine::FileNameEntry &Entry :
727*0fca6ea1SDimitry Andric Lines->Prologue.FileNames) {
728*0fca6ea1SDimitry Andric std::string Directory;
729*0fca6ea1SDimitry Andric if (Lines->getDirectoryForEntry(Entry, Directory))
730*0fca6ea1SDimitry Andric Directory = transformPath(Directory);
731*0fca6ea1SDimitry Andric if (Directory.empty())
732*0fca6ea1SDimitry Andric Directory = std::string(CompileUnit->getCompilationDirectory());
733*0fca6ea1SDimitry Andric std::string File = transformPath(dwarf::toStringRef(Entry.Name));
734*0fca6ea1SDimitry Andric std::string String;
735*0fca6ea1SDimitry Andric raw_string_ostream(String) << Directory << "/" << File;
736*0fca6ea1SDimitry Andric CompileUnit->addFilename(String);
737*0fca6ea1SDimitry Andric }
738*0fca6ea1SDimitry Andric
739*0fca6ea1SDimitry Andric // In DWARF5 the file indexes start at 0;
740*0fca6ea1SDimitry Andric bool IncrementIndex = Lines->Prologue.getVersion() >= 5;
741*0fca6ea1SDimitry Andric
742*0fca6ea1SDimitry Andric // Get the source lines if requested by command line option.
743*0fca6ea1SDimitry Andric if (options().getPrintLines() && Lines->Rows.size())
744*0fca6ea1SDimitry Andric for (const DWARFDebugLine::Row &Row : Lines->Rows) {
745*0fca6ea1SDimitry Andric // Here we collect logical debug lines in CULines. Later on,
746*0fca6ea1SDimitry Andric // the 'processLines()' function will move each created logical line
747*0fca6ea1SDimitry Andric // to its enclosing logical scope, using the debug ranges information
748*0fca6ea1SDimitry Andric // and they will be released when its scope parent is deleted.
749*0fca6ea1SDimitry Andric LVLineDebug *Line = createLineDebug();
750*0fca6ea1SDimitry Andric CULines.push_back(Line);
751*0fca6ea1SDimitry Andric // Consider the case of WebAssembly.
752*0fca6ea1SDimitry Andric Line->setAddress(Row.Address.Address + WasmCodeSectionOffset);
753*0fca6ea1SDimitry Andric Line->setFilename(
754*0fca6ea1SDimitry Andric CompileUnit->getFilename(IncrementIndex ? Row.File + 1 : Row.File));
755*0fca6ea1SDimitry Andric Line->setLineNumber(Row.Line);
756*0fca6ea1SDimitry Andric if (Row.Discriminator)
757*0fca6ea1SDimitry Andric Line->setDiscriminator(Row.Discriminator);
758*0fca6ea1SDimitry Andric if (Row.IsStmt)
759*0fca6ea1SDimitry Andric Line->setIsNewStatement();
760*0fca6ea1SDimitry Andric if (Row.BasicBlock)
761*0fca6ea1SDimitry Andric Line->setIsBasicBlock();
762*0fca6ea1SDimitry Andric if (Row.EndSequence)
763*0fca6ea1SDimitry Andric Line->setIsEndSequence();
764*0fca6ea1SDimitry Andric if (Row.EpilogueBegin)
765*0fca6ea1SDimitry Andric Line->setIsEpilogueBegin();
766*0fca6ea1SDimitry Andric if (Row.PrologueEnd)
767*0fca6ea1SDimitry Andric Line->setIsPrologueEnd();
768*0fca6ea1SDimitry Andric LLVM_DEBUG({
769*0fca6ea1SDimitry Andric dbgs() << "Address: " << hexValue(Line->getAddress())
770*0fca6ea1SDimitry Andric << " Line: " << Line->lineNumberAsString(/*ShowZero=*/true)
771*0fca6ea1SDimitry Andric << "\n";
772*0fca6ea1SDimitry Andric });
773*0fca6ea1SDimitry Andric }
774*0fca6ea1SDimitry Andric }
775*0fca6ea1SDimitry Andric
getRegisterName(LVSmall Opcode,ArrayRef<uint64_t> Operands)776*0fca6ea1SDimitry Andric std::string LVDWARFReader::getRegisterName(LVSmall Opcode,
777*0fca6ea1SDimitry Andric ArrayRef<uint64_t> Operands) {
778*0fca6ea1SDimitry Andric // The 'prettyPrintRegisterOp' function uses the DWARFUnit to support
779*0fca6ea1SDimitry Andric // DW_OP_regval_type. At this point we are operating on a logical view
780*0fca6ea1SDimitry Andric // item, with no access to the underlying DWARF data used by LLVM.
781*0fca6ea1SDimitry Andric // We do not support DW_OP_regval_type here.
782*0fca6ea1SDimitry Andric if (Opcode == dwarf::DW_OP_regval_type)
783*0fca6ea1SDimitry Andric return {};
784*0fca6ea1SDimitry Andric
785*0fca6ea1SDimitry Andric std::string string;
786*0fca6ea1SDimitry Andric raw_string_ostream Stream(string);
787*0fca6ea1SDimitry Andric DIDumpOptions DumpOpts;
788*0fca6ea1SDimitry Andric auto *MCRegInfo = MRI.get();
789*0fca6ea1SDimitry Andric auto GetRegName = [&MCRegInfo](uint64_t DwarfRegNum, bool IsEH) -> StringRef {
790*0fca6ea1SDimitry Andric if (!MCRegInfo)
791*0fca6ea1SDimitry Andric return {};
792*0fca6ea1SDimitry Andric if (std::optional<unsigned> LLVMRegNum =
793*0fca6ea1SDimitry Andric MCRegInfo->getLLVMRegNum(DwarfRegNum, IsEH))
794*0fca6ea1SDimitry Andric if (const char *RegName = MCRegInfo->getName(*LLVMRegNum))
795*0fca6ea1SDimitry Andric return StringRef(RegName);
796*0fca6ea1SDimitry Andric return {};
797*0fca6ea1SDimitry Andric };
798*0fca6ea1SDimitry Andric DumpOpts.GetNameForDWARFReg = GetRegName;
799*0fca6ea1SDimitry Andric DWARFExpression::prettyPrintRegisterOp(/*U=*/nullptr, Stream, DumpOpts,
800*0fca6ea1SDimitry Andric Opcode, Operands);
801*0fca6ea1SDimitry Andric return Stream.str();
802*0fca6ea1SDimitry Andric }
803*0fca6ea1SDimitry Andric
createScopes()804*0fca6ea1SDimitry Andric Error LVDWARFReader::createScopes() {
805*0fca6ea1SDimitry Andric LLVM_DEBUG({
806*0fca6ea1SDimitry Andric W.startLine() << "\n";
807*0fca6ea1SDimitry Andric W.printString("File", Obj.getFileName().str());
808*0fca6ea1SDimitry Andric W.printString("Format", FileFormatName);
809*0fca6ea1SDimitry Andric });
810*0fca6ea1SDimitry Andric
811*0fca6ea1SDimitry Andric if (Error Err = LVReader::createScopes())
812*0fca6ea1SDimitry Andric return Err;
813*0fca6ea1SDimitry Andric
814*0fca6ea1SDimitry Andric // As the DwarfContext object is valid only during the scopes creation,
815*0fca6ea1SDimitry Andric // we need to create our own Target information, to be used during the
816*0fca6ea1SDimitry Andric // logical view printing, in the case of instructions being requested.
817*0fca6ea1SDimitry Andric std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(Obj);
818*0fca6ea1SDimitry Andric if (!DwarfContext)
819*0fca6ea1SDimitry Andric return createStringError(errc::invalid_argument,
820*0fca6ea1SDimitry Andric "Could not create DWARF information: %s",
821*0fca6ea1SDimitry Andric getFilename().str().c_str());
822*0fca6ea1SDimitry Andric
823*0fca6ea1SDimitry Andric if (Error Err = loadTargetInfo(Obj))
824*0fca6ea1SDimitry Andric return Err;
825*0fca6ea1SDimitry Andric
826*0fca6ea1SDimitry Andric // Create a mapping for virtual addresses.
827*0fca6ea1SDimitry Andric mapVirtualAddress(Obj);
828*0fca6ea1SDimitry Andric
829*0fca6ea1SDimitry Andric // Select the correct compile unit range, depending if we are dealing with
830*0fca6ea1SDimitry Andric // a standard or split DWARF object.
831*0fca6ea1SDimitry Andric DWARFContext::compile_unit_range CompileUnits =
832*0fca6ea1SDimitry Andric DwarfContext->getNumCompileUnits() ? DwarfContext->compile_units()
833*0fca6ea1SDimitry Andric : DwarfContext->dwo_compile_units();
834*0fca6ea1SDimitry Andric for (const std::unique_ptr<DWARFUnit> &CU : CompileUnits) {
835*0fca6ea1SDimitry Andric
836*0fca6ea1SDimitry Andric // Deduction of index used for the line records.
837*0fca6ea1SDimitry Andric //
838*0fca6ea1SDimitry Andric // For the following test case: test.cpp
839*0fca6ea1SDimitry Andric // void foo(void ParamPtr) { }
840*0fca6ea1SDimitry Andric
841*0fca6ea1SDimitry Andric // Both GCC and Clang generate DWARF-5 .debug_line layout.
842*0fca6ea1SDimitry Andric
843*0fca6ea1SDimitry Andric // * GCC (GNU C++17 11.3.0) - All DW_AT_decl_file use index 1.
844*0fca6ea1SDimitry Andric //
845*0fca6ea1SDimitry Andric // .debug_info:
846*0fca6ea1SDimitry Andric // format = DWARF32, version = 0x0005
847*0fca6ea1SDimitry Andric // DW_TAG_compile_unit
848*0fca6ea1SDimitry Andric // DW_AT_name ("test.cpp")
849*0fca6ea1SDimitry Andric // DW_TAG_subprogram ("foo")
850*0fca6ea1SDimitry Andric // DW_AT_decl_file (1)
851*0fca6ea1SDimitry Andric // DW_TAG_formal_parameter ("ParamPtr")
852*0fca6ea1SDimitry Andric // DW_AT_decl_file (1)
853*0fca6ea1SDimitry Andric // .debug_line:
854*0fca6ea1SDimitry Andric // Line table prologue: format (DWARF32), version (5)
855*0fca6ea1SDimitry Andric // include_directories[0] = "..."
856*0fca6ea1SDimitry Andric // file_names[0]: name ("test.cpp"), dir_index (0)
857*0fca6ea1SDimitry Andric // file_names[1]: name ("test.cpp"), dir_index (0)
858*0fca6ea1SDimitry Andric
859*0fca6ea1SDimitry Andric // * Clang (14.0.6) - All DW_AT_decl_file use index 0.
860*0fca6ea1SDimitry Andric //
861*0fca6ea1SDimitry Andric // .debug_info:
862*0fca6ea1SDimitry Andric // format = DWARF32, version = 0x0005
863*0fca6ea1SDimitry Andric // DW_AT_producer ("clang version 14.0.6")
864*0fca6ea1SDimitry Andric // DW_AT_name ("test.cpp")
865*0fca6ea1SDimitry Andric //
866*0fca6ea1SDimitry Andric // DW_TAG_subprogram ("foo")
867*0fca6ea1SDimitry Andric // DW_AT_decl_file (0)
868*0fca6ea1SDimitry Andric // DW_TAG_formal_parameter ("ParamPtr")
869*0fca6ea1SDimitry Andric // DW_AT_decl_file (0)
870*0fca6ea1SDimitry Andric // .debug_line:
871*0fca6ea1SDimitry Andric // Line table prologue: format (DWARF32), version (5)
872*0fca6ea1SDimitry Andric // include_directories[0] = "..."
873*0fca6ea1SDimitry Andric // file_names[0]: name ("test.cpp"), dir_index (0)
874*0fca6ea1SDimitry Andric
875*0fca6ea1SDimitry Andric // From DWARFDebugLine::getFileNameByIndex documentation:
876*0fca6ea1SDimitry Andric // In Dwarf 4, the files are 1-indexed.
877*0fca6ea1SDimitry Andric // In Dwarf 5, the files are 0-indexed.
878*0fca6ea1SDimitry Andric // Additional discussions here:
879*0fca6ea1SDimitry Andric // https://www.mail-archive.com/dwarf-discuss@lists.dwarfstd.org/msg00883.html
880*0fca6ea1SDimitry Andric
881*0fca6ea1SDimitry Andric // The DWARF reader is expecting the files are 1-indexed, so using
882*0fca6ea1SDimitry Andric // the .debug_line header information decide if the indexed require
883*0fca6ea1SDimitry Andric // an internal adjustment.
884*0fca6ea1SDimitry Andric
885*0fca6ea1SDimitry Andric // For the case of GCC (DWARF5), if the entries[0] and [1] are the
886*0fca6ea1SDimitry Andric // same, do not perform any adjustment.
887*0fca6ea1SDimitry Andric auto DeduceIncrementFileIndex = [&]() -> bool {
888*0fca6ea1SDimitry Andric if (CU->getVersion() < 5)
889*0fca6ea1SDimitry Andric // DWARF-4 or earlier -> Don't increment index.
890*0fca6ea1SDimitry Andric return false;
891*0fca6ea1SDimitry Andric
892*0fca6ea1SDimitry Andric if (const DWARFDebugLine::LineTable *LT =
893*0fca6ea1SDimitry Andric CU->getContext().getLineTableForUnit(CU.get())) {
894*0fca6ea1SDimitry Andric // Check if there are at least 2 entries and if they are the same.
895*0fca6ea1SDimitry Andric if (LT->hasFileAtIndex(0) && LT->hasFileAtIndex(1)) {
896*0fca6ea1SDimitry Andric const DWARFDebugLine::FileNameEntry &EntryZero =
897*0fca6ea1SDimitry Andric LT->Prologue.getFileNameEntry(0);
898*0fca6ea1SDimitry Andric const DWARFDebugLine::FileNameEntry &EntryOne =
899*0fca6ea1SDimitry Andric LT->Prologue.getFileNameEntry(1);
900*0fca6ea1SDimitry Andric // Check directory indexes.
901*0fca6ea1SDimitry Andric if (EntryZero.DirIdx != EntryOne.DirIdx)
902*0fca6ea1SDimitry Andric // DWARF-5 -> Increment index.
903*0fca6ea1SDimitry Andric return true;
904*0fca6ea1SDimitry Andric // Check filename.
905*0fca6ea1SDimitry Andric std::string FileZero;
906*0fca6ea1SDimitry Andric std::string FileOne;
907*0fca6ea1SDimitry Andric StringRef None;
908*0fca6ea1SDimitry Andric LT->getFileNameByIndex(
909*0fca6ea1SDimitry Andric 0, None, DILineInfoSpecifier::FileLineInfoKind::RawValue,
910*0fca6ea1SDimitry Andric FileZero);
911*0fca6ea1SDimitry Andric LT->getFileNameByIndex(
912*0fca6ea1SDimitry Andric 1, None, DILineInfoSpecifier::FileLineInfoKind::RawValue,
913*0fca6ea1SDimitry Andric FileOne);
914*0fca6ea1SDimitry Andric return FileZero.compare(FileOne);
915*0fca6ea1SDimitry Andric }
916*0fca6ea1SDimitry Andric }
917*0fca6ea1SDimitry Andric
918*0fca6ea1SDimitry Andric // DWARF-5 -> Increment index.
919*0fca6ea1SDimitry Andric return true;
920*0fca6ea1SDimitry Andric };
921*0fca6ea1SDimitry Andric // The DWARF reader expects the indexes as 1-indexed.
922*0fca6ea1SDimitry Andric IncrementFileIndex = DeduceIncrementFileIndex();
923*0fca6ea1SDimitry Andric
924*0fca6ea1SDimitry Andric DWARFDie UnitDie = CU->getUnitDIE();
925*0fca6ea1SDimitry Andric SmallString<16> DWOAlternativeLocation;
926*0fca6ea1SDimitry Andric if (UnitDie) {
927*0fca6ea1SDimitry Andric std::optional<const char *> DWOFileName =
928*0fca6ea1SDimitry Andric CU->getVersion() >= 5
929*0fca6ea1SDimitry Andric ? dwarf::toString(UnitDie.find(dwarf::DW_AT_dwo_name))
930*0fca6ea1SDimitry Andric : dwarf::toString(UnitDie.find(dwarf::DW_AT_GNU_dwo_name));
931*0fca6ea1SDimitry Andric StringRef From(DWOFileName.value_or(""));
932*0fca6ea1SDimitry Andric DWOAlternativeLocation = createAlternativePath(From);
933*0fca6ea1SDimitry Andric }
934*0fca6ea1SDimitry Andric
935*0fca6ea1SDimitry Andric // The current CU can be a normal compile unit (standard) or a skeleton
936*0fca6ea1SDimitry Andric // compile unit (split). For both cases, the returned die, will be used
937*0fca6ea1SDimitry Andric // to create the logical scopes.
938*0fca6ea1SDimitry Andric DWARFDie CUDie = CU->getNonSkeletonUnitDIE(
939*0fca6ea1SDimitry Andric /*ExtractUnitDIEOnly=*/false,
940*0fca6ea1SDimitry Andric /*DWOAlternativeLocation=*/DWOAlternativeLocation);
941*0fca6ea1SDimitry Andric if (!CUDie.isValid())
942*0fca6ea1SDimitry Andric continue;
943*0fca6ea1SDimitry Andric
944*0fca6ea1SDimitry Andric // The current unit corresponds to the .dwo file. We need to get the
945*0fca6ea1SDimitry Andric // skeleton unit and query for any ranges that will enclose any ranges
946*0fca6ea1SDimitry Andric // in the non-skeleton unit.
947*0fca6ea1SDimitry Andric DWARFDie DummyDie;
948*0fca6ea1SDimitry Andric DWARFDie SkeletonDie =
949*0fca6ea1SDimitry Andric CUDie.getDwarfUnit()->isDWOUnit() ? CU->getUnitDIE(false) : DummyDie;
950*0fca6ea1SDimitry Andric // Disable the ranges processing if we have just a single .dwo object,
951*0fca6ea1SDimitry Andric // as any DW_AT_ranges will access not available range information.
952*0fca6ea1SDimitry Andric RangesDataAvailable =
953*0fca6ea1SDimitry Andric (!CUDie.getDwarfUnit()->isDWOUnit() ||
954*0fca6ea1SDimitry Andric (SkeletonDie.isValid() ? !SkeletonDie.getDwarfUnit()->isDWOUnit()
955*0fca6ea1SDimitry Andric : true));
956*0fca6ea1SDimitry Andric
957*0fca6ea1SDimitry Andric traverseDieAndChildren(CUDie, Root, SkeletonDie);
958*0fca6ea1SDimitry Andric
959*0fca6ea1SDimitry Andric createLineAndFileRecords(DwarfContext->getLineTableForUnit(CU.get()));
960*0fca6ea1SDimitry Andric if (Error Err = createInstructions())
961*0fca6ea1SDimitry Andric return Err;
962*0fca6ea1SDimitry Andric
963*0fca6ea1SDimitry Andric // Process the compilation unit, as there are cases where enclosed
964*0fca6ea1SDimitry Andric // functions have the same ranges values. Insert the compilation unit
965*0fca6ea1SDimitry Andric // ranges at the end, to allow enclosing ranges to be first in the list.
966*0fca6ea1SDimitry Andric LVSectionIndex SectionIndex = getSectionIndex(CompileUnit);
967*0fca6ea1SDimitry Andric addSectionRange(SectionIndex, CompileUnit);
968*0fca6ea1SDimitry Andric LVRange *ScopesWithRanges = getSectionRanges(SectionIndex);
969*0fca6ea1SDimitry Andric ScopesWithRanges->sort();
970*0fca6ea1SDimitry Andric
971*0fca6ea1SDimitry Andric processLines(&CULines, SectionIndex);
972*0fca6ea1SDimitry Andric processLocationGaps();
973*0fca6ea1SDimitry Andric
974*0fca6ea1SDimitry Andric // These are per compile unit.
975*0fca6ea1SDimitry Andric ScopesWithRanges->clear();
976*0fca6ea1SDimitry Andric SymbolsWithLocations.clear();
977*0fca6ea1SDimitry Andric CULines.clear();
978*0fca6ea1SDimitry Andric }
979*0fca6ea1SDimitry Andric
980*0fca6ea1SDimitry Andric return Error::success();
981*0fca6ea1SDimitry Andric }
982*0fca6ea1SDimitry Andric
983*0fca6ea1SDimitry Andric // Get the location information for the associated attribute.
processLocationList(dwarf::Attribute Attr,const DWARFFormValue & FormValue,const DWARFDie & Die,uint64_t OffsetOnEntry,bool CallSiteLocation)984*0fca6ea1SDimitry Andric void LVDWARFReader::processLocationList(dwarf::Attribute Attr,
985*0fca6ea1SDimitry Andric const DWARFFormValue &FormValue,
986*0fca6ea1SDimitry Andric const DWARFDie &Die,
987*0fca6ea1SDimitry Andric uint64_t OffsetOnEntry,
988*0fca6ea1SDimitry Andric bool CallSiteLocation) {
989*0fca6ea1SDimitry Andric
990*0fca6ea1SDimitry Andric auto ProcessLocationExpression = [&](const DWARFExpression &Expression) {
991*0fca6ea1SDimitry Andric for (const DWARFExpression::Operation &Op : Expression)
992*0fca6ea1SDimitry Andric CurrentSymbol->addLocationOperands(Op.getCode(), Op.getRawOperands());
993*0fca6ea1SDimitry Andric };
994*0fca6ea1SDimitry Andric
995*0fca6ea1SDimitry Andric DWARFUnit *U = Die.getDwarfUnit();
996*0fca6ea1SDimitry Andric DWARFContext &DwarfContext = U->getContext();
997*0fca6ea1SDimitry Andric bool IsLittleEndian = DwarfContext.isLittleEndian();
998*0fca6ea1SDimitry Andric if (FormValue.isFormClass(DWARFFormValue::FC_Block) ||
999*0fca6ea1SDimitry Andric (DWARFAttribute::mayHaveLocationExpr(Attr) &&
1000*0fca6ea1SDimitry Andric FormValue.isFormClass(DWARFFormValue::FC_Exprloc))) {
1001*0fca6ea1SDimitry Andric ArrayRef<uint8_t> Expr = *FormValue.getAsBlock();
1002*0fca6ea1SDimitry Andric DataExtractor Data(StringRef((const char *)Expr.data(), Expr.size()),
1003*0fca6ea1SDimitry Andric IsLittleEndian, 0);
1004*0fca6ea1SDimitry Andric DWARFExpression Expression(Data, U->getAddressByteSize(),
1005*0fca6ea1SDimitry Andric U->getFormParams().Format);
1006*0fca6ea1SDimitry Andric
1007*0fca6ea1SDimitry Andric // Add location and operation entries.
1008*0fca6ea1SDimitry Andric CurrentSymbol->addLocation(Attr, /*LowPC=*/0, /*HighPC=*/-1,
1009*0fca6ea1SDimitry Andric /*SectionOffset=*/0, OffsetOnEntry,
1010*0fca6ea1SDimitry Andric CallSiteLocation);
1011*0fca6ea1SDimitry Andric ProcessLocationExpression(Expression);
1012*0fca6ea1SDimitry Andric return;
1013*0fca6ea1SDimitry Andric }
1014*0fca6ea1SDimitry Andric
1015*0fca6ea1SDimitry Andric if (DWARFAttribute::mayHaveLocationList(Attr) &&
1016*0fca6ea1SDimitry Andric FormValue.isFormClass(DWARFFormValue::FC_SectionOffset)) {
1017*0fca6ea1SDimitry Andric uint64_t Offset = *FormValue.getAsSectionOffset();
1018*0fca6ea1SDimitry Andric if (FormValue.getForm() == dwarf::DW_FORM_loclistx) {
1019*0fca6ea1SDimitry Andric std::optional<uint64_t> LoclistOffset = U->getLoclistOffset(Offset);
1020*0fca6ea1SDimitry Andric if (!LoclistOffset)
1021*0fca6ea1SDimitry Andric return;
1022*0fca6ea1SDimitry Andric Offset = *LoclistOffset;
1023*0fca6ea1SDimitry Andric }
1024*0fca6ea1SDimitry Andric uint64_t BaseAddr = 0;
1025*0fca6ea1SDimitry Andric if (std::optional<SectionedAddress> BA = U->getBaseAddress())
1026*0fca6ea1SDimitry Andric BaseAddr = BA->Address;
1027*0fca6ea1SDimitry Andric LVAddress LowPC = 0;
1028*0fca6ea1SDimitry Andric LVAddress HighPC = 0;
1029*0fca6ea1SDimitry Andric
1030*0fca6ea1SDimitry Andric auto ProcessLocationEntry = [&](const DWARFLocationEntry &Entry) {
1031*0fca6ea1SDimitry Andric if (Entry.Kind == dwarf::DW_LLE_base_address) {
1032*0fca6ea1SDimitry Andric BaseAddr = Entry.Value0;
1033*0fca6ea1SDimitry Andric return;
1034*0fca6ea1SDimitry Andric }
1035*0fca6ea1SDimitry Andric if (Entry.Kind == dwarf::DW_LLE_offset_pair) {
1036*0fca6ea1SDimitry Andric LowPC = BaseAddr + Entry.Value0;
1037*0fca6ea1SDimitry Andric HighPC = BaseAddr + Entry.Value1;
1038*0fca6ea1SDimitry Andric DWARFAddressRange Range{LowPC, HighPC, Entry.SectionIndex};
1039*0fca6ea1SDimitry Andric if (Range.SectionIndex == SectionedAddress::UndefSection)
1040*0fca6ea1SDimitry Andric Range.SectionIndex = Entry.SectionIndex;
1041*0fca6ea1SDimitry Andric DWARFLocationExpression Loc{Range, Entry.Loc};
1042*0fca6ea1SDimitry Andric DWARFDataExtractor Data(Loc.Expr, IsLittleEndian,
1043*0fca6ea1SDimitry Andric U->getAddressByteSize());
1044*0fca6ea1SDimitry Andric DWARFExpression Expression(Data, U->getAddressByteSize());
1045*0fca6ea1SDimitry Andric
1046*0fca6ea1SDimitry Andric // Store the real upper limit for the address range.
1047*0fca6ea1SDimitry Andric if (UpdateHighAddress && HighPC > 0)
1048*0fca6ea1SDimitry Andric --HighPC;
1049*0fca6ea1SDimitry Andric // Add location and operation entries.
1050*0fca6ea1SDimitry Andric CurrentSymbol->addLocation(Attr, LowPC, HighPC, Offset, OffsetOnEntry,
1051*0fca6ea1SDimitry Andric CallSiteLocation);
1052*0fca6ea1SDimitry Andric ProcessLocationExpression(Expression);
1053*0fca6ea1SDimitry Andric }
1054*0fca6ea1SDimitry Andric };
1055*0fca6ea1SDimitry Andric Error E = U->getLocationTable().visitLocationList(
1056*0fca6ea1SDimitry Andric &Offset, [&](const DWARFLocationEntry &E) {
1057*0fca6ea1SDimitry Andric ProcessLocationEntry(E);
1058*0fca6ea1SDimitry Andric return true;
1059*0fca6ea1SDimitry Andric });
1060*0fca6ea1SDimitry Andric if (E)
1061*0fca6ea1SDimitry Andric consumeError(std::move(E));
1062*0fca6ea1SDimitry Andric }
1063*0fca6ea1SDimitry Andric }
1064*0fca6ea1SDimitry Andric
processLocationMember(dwarf::Attribute Attr,const DWARFFormValue & FormValue,const DWARFDie & Die,uint64_t OffsetOnEntry)1065*0fca6ea1SDimitry Andric void LVDWARFReader::processLocationMember(dwarf::Attribute Attr,
1066*0fca6ea1SDimitry Andric const DWARFFormValue &FormValue,
1067*0fca6ea1SDimitry Andric const DWARFDie &Die,
1068*0fca6ea1SDimitry Andric uint64_t OffsetOnEntry) {
1069*0fca6ea1SDimitry Andric // Check if the value is an integer constant.
1070*0fca6ea1SDimitry Andric if (FormValue.isFormClass(DWARFFormValue::FC_Constant))
1071*0fca6ea1SDimitry Andric // Add a record to hold a constant as location.
1072*0fca6ea1SDimitry Andric CurrentSymbol->addLocationConstant(Attr, *FormValue.getAsUnsignedConstant(),
1073*0fca6ea1SDimitry Andric OffsetOnEntry);
1074*0fca6ea1SDimitry Andric else
1075*0fca6ea1SDimitry Andric // This is a location description, or a reference to one.
1076*0fca6ea1SDimitry Andric processLocationList(Attr, FormValue, Die, OffsetOnEntry);
1077*0fca6ea1SDimitry Andric }
1078*0fca6ea1SDimitry Andric
1079*0fca6ea1SDimitry Andric // Update the current element with the reference.
updateReference(dwarf::Attribute Attr,const DWARFFormValue & FormValue)1080*0fca6ea1SDimitry Andric void LVDWARFReader::updateReference(dwarf::Attribute Attr,
1081*0fca6ea1SDimitry Andric const DWARFFormValue &FormValue) {
1082*0fca6ea1SDimitry Andric // FIXME: We are assuming that at most one Reference (DW_AT_specification,
1083*0fca6ea1SDimitry Andric // DW_AT_abstract_origin, ...) and at most one Type (DW_AT_import, DW_AT_type)
1084*0fca6ea1SDimitry Andric // appear in any single DIE, but this may not be true.
1085*0fca6ea1SDimitry Andric uint64_t Offset;
1086*0fca6ea1SDimitry Andric if (std::optional<uint64_t> Off = FormValue.getAsRelativeReference())
1087*0fca6ea1SDimitry Andric Offset = FormValue.getUnit()->getOffset() + *Off;
1088*0fca6ea1SDimitry Andric else if (Off = FormValue.getAsDebugInfoReference(); Off)
1089*0fca6ea1SDimitry Andric Offset = *Off;
1090*0fca6ea1SDimitry Andric else
1091*0fca6ea1SDimitry Andric llvm_unreachable("Unsupported reference type");
1092*0fca6ea1SDimitry Andric
1093*0fca6ea1SDimitry Andric // Get target for the given reference, if already created.
1094*0fca6ea1SDimitry Andric LVElement *Target = getElementForOffset(
1095*0fca6ea1SDimitry Andric Offset, CurrentElement,
1096*0fca6ea1SDimitry Andric /*IsType=*/Attr == dwarf::DW_AT_import || Attr == dwarf::DW_AT_type);
1097*0fca6ea1SDimitry Andric // Check if we are dealing with cross CU references.
1098*0fca6ea1SDimitry Andric if (FormValue.getForm() == dwarf::DW_FORM_ref_addr) {
1099*0fca6ea1SDimitry Andric if (Target) {
1100*0fca6ea1SDimitry Andric // The global reference is ready. Mark it as global.
1101*0fca6ea1SDimitry Andric Target->setIsGlobalReference();
1102*0fca6ea1SDimitry Andric // Remove global reference from the unseen list.
1103*0fca6ea1SDimitry Andric removeGlobalOffset(Offset);
1104*0fca6ea1SDimitry Andric } else
1105*0fca6ea1SDimitry Andric // Record the unseen cross CU reference.
1106*0fca6ea1SDimitry Andric addGlobalOffset(Offset);
1107*0fca6ea1SDimitry Andric }
1108*0fca6ea1SDimitry Andric
1109*0fca6ea1SDimitry Andric // At this point, 'Target' can be null, in the case of the target element
1110*0fca6ea1SDimitry Andric // not being seen. But the correct bit is set, to indicate that the target
1111*0fca6ea1SDimitry Andric // is being referenced by (abstract_origin, extension, specification) or
1112*0fca6ea1SDimitry Andric // (import, type).
1113*0fca6ea1SDimitry Andric // We must differentiate between the kind of reference. This is needed to
1114*0fca6ea1SDimitry Andric // complete inlined function instances with dropped abstract references,
1115*0fca6ea1SDimitry Andric // in order to facilitate a logical comparison.
1116*0fca6ea1SDimitry Andric switch (Attr) {
1117*0fca6ea1SDimitry Andric case dwarf::DW_AT_abstract_origin:
1118*0fca6ea1SDimitry Andric case dwarf::DW_AT_call_origin:
1119*0fca6ea1SDimitry Andric CurrentElement->setReference(Target);
1120*0fca6ea1SDimitry Andric CurrentElement->setHasReferenceAbstract();
1121*0fca6ea1SDimitry Andric break;
1122*0fca6ea1SDimitry Andric case dwarf::DW_AT_extension:
1123*0fca6ea1SDimitry Andric CurrentElement->setReference(Target);
1124*0fca6ea1SDimitry Andric CurrentElement->setHasReferenceExtension();
1125*0fca6ea1SDimitry Andric break;
1126*0fca6ea1SDimitry Andric case dwarf::DW_AT_specification:
1127*0fca6ea1SDimitry Andric CurrentElement->setReference(Target);
1128*0fca6ea1SDimitry Andric CurrentElement->setHasReferenceSpecification();
1129*0fca6ea1SDimitry Andric break;
1130*0fca6ea1SDimitry Andric case dwarf::DW_AT_import:
1131*0fca6ea1SDimitry Andric case dwarf::DW_AT_type:
1132*0fca6ea1SDimitry Andric CurrentElement->setType(Target);
1133*0fca6ea1SDimitry Andric break;
1134*0fca6ea1SDimitry Andric default:
1135*0fca6ea1SDimitry Andric break;
1136*0fca6ea1SDimitry Andric }
1137*0fca6ea1SDimitry Andric }
1138*0fca6ea1SDimitry Andric
1139*0fca6ea1SDimitry Andric // Get an element given the DIE offset.
getElementForOffset(LVOffset Offset,LVElement * Element,bool IsType)1140*0fca6ea1SDimitry Andric LVElement *LVDWARFReader::getElementForOffset(LVOffset Offset,
1141*0fca6ea1SDimitry Andric LVElement *Element, bool IsType) {
1142*0fca6ea1SDimitry Andric auto Iter = ElementTable.try_emplace(Offset).first;
1143*0fca6ea1SDimitry Andric // Update the element and all the references pointing to this element.
1144*0fca6ea1SDimitry Andric LVElementEntry &Entry = Iter->second;
1145*0fca6ea1SDimitry Andric if (!Entry.Element) {
1146*0fca6ea1SDimitry Andric if (IsType)
1147*0fca6ea1SDimitry Andric Entry.Types.insert(Element);
1148*0fca6ea1SDimitry Andric else
1149*0fca6ea1SDimitry Andric Entry.References.insert(Element);
1150*0fca6ea1SDimitry Andric }
1151*0fca6ea1SDimitry Andric return Entry.Element;
1152*0fca6ea1SDimitry Andric }
1153*0fca6ea1SDimitry Andric
loadTargetInfo(const ObjectFile & Obj)1154*0fca6ea1SDimitry Andric Error LVDWARFReader::loadTargetInfo(const ObjectFile &Obj) {
1155*0fca6ea1SDimitry Andric // Detect the architecture from the object file. We usually don't need OS
1156*0fca6ea1SDimitry Andric // info to lookup a target and create register info.
1157*0fca6ea1SDimitry Andric Triple TT;
1158*0fca6ea1SDimitry Andric TT.setArch(Triple::ArchType(Obj.getArch()));
1159*0fca6ea1SDimitry Andric TT.setVendor(Triple::UnknownVendor);
1160*0fca6ea1SDimitry Andric TT.setOS(Triple::UnknownOS);
1161*0fca6ea1SDimitry Andric
1162*0fca6ea1SDimitry Andric // Features to be passed to target/subtarget
1163*0fca6ea1SDimitry Andric Expected<SubtargetFeatures> Features = Obj.getFeatures();
1164*0fca6ea1SDimitry Andric SubtargetFeatures FeaturesValue;
1165*0fca6ea1SDimitry Andric if (!Features) {
1166*0fca6ea1SDimitry Andric consumeError(Features.takeError());
1167*0fca6ea1SDimitry Andric FeaturesValue = SubtargetFeatures();
1168*0fca6ea1SDimitry Andric }
1169*0fca6ea1SDimitry Andric FeaturesValue = *Features;
1170*0fca6ea1SDimitry Andric return loadGenericTargetInfo(TT.str(), FeaturesValue.getString());
1171*0fca6ea1SDimitry Andric }
1172*0fca6ea1SDimitry Andric
mapRangeAddress(const ObjectFile & Obj)1173*0fca6ea1SDimitry Andric void LVDWARFReader::mapRangeAddress(const ObjectFile &Obj) {
1174*0fca6ea1SDimitry Andric for (auto Iter = Obj.symbol_begin(); Iter != Obj.symbol_end(); ++Iter) {
1175*0fca6ea1SDimitry Andric const SymbolRef &Symbol = *Iter;
1176*0fca6ea1SDimitry Andric
1177*0fca6ea1SDimitry Andric Expected<SymbolRef::Type> TypeOrErr = Symbol.getType();
1178*0fca6ea1SDimitry Andric if (!TypeOrErr) {
1179*0fca6ea1SDimitry Andric consumeError(TypeOrErr.takeError());
1180*0fca6ea1SDimitry Andric continue;
1181*0fca6ea1SDimitry Andric }
1182*0fca6ea1SDimitry Andric
1183*0fca6ea1SDimitry Andric // Process only symbols that represent a function.
1184*0fca6ea1SDimitry Andric SymbolRef::Type Type = *TypeOrErr;
1185*0fca6ea1SDimitry Andric if (Type != SymbolRef::ST_Function)
1186*0fca6ea1SDimitry Andric continue;
1187*0fca6ea1SDimitry Andric
1188*0fca6ea1SDimitry Andric // In the case of a Mach-O STAB symbol, get its section only if
1189*0fca6ea1SDimitry Andric // the STAB symbol's section field refers to a valid section index.
1190*0fca6ea1SDimitry Andric // Otherwise the symbol may error trying to load a section that
1191*0fca6ea1SDimitry Andric // does not exist.
1192*0fca6ea1SDimitry Andric const MachOObjectFile *MachO = dyn_cast<const MachOObjectFile>(&Obj);
1193*0fca6ea1SDimitry Andric bool IsSTAB = false;
1194*0fca6ea1SDimitry Andric if (MachO) {
1195*0fca6ea1SDimitry Andric DataRefImpl SymDRI = Symbol.getRawDataRefImpl();
1196*0fca6ea1SDimitry Andric uint8_t NType =
1197*0fca6ea1SDimitry Andric (MachO->is64Bit() ? MachO->getSymbol64TableEntry(SymDRI).n_type
1198*0fca6ea1SDimitry Andric : MachO->getSymbolTableEntry(SymDRI).n_type);
1199*0fca6ea1SDimitry Andric if (NType & MachO::N_STAB)
1200*0fca6ea1SDimitry Andric IsSTAB = true;
1201*0fca6ea1SDimitry Andric }
1202*0fca6ea1SDimitry Andric
1203*0fca6ea1SDimitry Andric Expected<section_iterator> IterOrErr = Symbol.getSection();
1204*0fca6ea1SDimitry Andric if (!IterOrErr) {
1205*0fca6ea1SDimitry Andric consumeError(IterOrErr.takeError());
1206*0fca6ea1SDimitry Andric continue;
1207*0fca6ea1SDimitry Andric }
1208*0fca6ea1SDimitry Andric section_iterator Section = IsSTAB ? Obj.section_end() : *IterOrErr;
1209*0fca6ea1SDimitry Andric if (Section == Obj.section_end())
1210*0fca6ea1SDimitry Andric continue;
1211*0fca6ea1SDimitry Andric
1212*0fca6ea1SDimitry Andric // Get the symbol value.
1213*0fca6ea1SDimitry Andric Expected<uint64_t> AddressOrErr = Symbol.getAddress();
1214*0fca6ea1SDimitry Andric if (!AddressOrErr) {
1215*0fca6ea1SDimitry Andric consumeError(AddressOrErr.takeError());
1216*0fca6ea1SDimitry Andric continue;
1217*0fca6ea1SDimitry Andric }
1218*0fca6ea1SDimitry Andric uint64_t Address = *AddressOrErr;
1219*0fca6ea1SDimitry Andric
1220*0fca6ea1SDimitry Andric // Get symbol name.
1221*0fca6ea1SDimitry Andric StringRef Name;
1222*0fca6ea1SDimitry Andric Expected<StringRef> NameOrErr = Symbol.getName();
1223*0fca6ea1SDimitry Andric if (!NameOrErr) {
1224*0fca6ea1SDimitry Andric consumeError(NameOrErr.takeError());
1225*0fca6ea1SDimitry Andric continue;
1226*0fca6ea1SDimitry Andric }
1227*0fca6ea1SDimitry Andric Name = *NameOrErr;
1228*0fca6ea1SDimitry Andric
1229*0fca6ea1SDimitry Andric // Check if the symbol is Comdat.
1230*0fca6ea1SDimitry Andric Expected<uint32_t> FlagsOrErr = Symbol.getFlags();
1231*0fca6ea1SDimitry Andric if (!FlagsOrErr) {
1232*0fca6ea1SDimitry Andric consumeError(FlagsOrErr.takeError());
1233*0fca6ea1SDimitry Andric continue;
1234*0fca6ea1SDimitry Andric }
1235*0fca6ea1SDimitry Andric uint32_t Flags = *FlagsOrErr;
1236*0fca6ea1SDimitry Andric
1237*0fca6ea1SDimitry Andric // Mark the symbol as 'comdat' in any of the following cases:
1238*0fca6ea1SDimitry Andric // - Symbol has the SF_Weak flag or
1239*0fca6ea1SDimitry Andric // - Symbol section index different from the DotTextSectionIndex.
1240*0fca6ea1SDimitry Andric LVSectionIndex SectionIndex = Section->getIndex();
1241*0fca6ea1SDimitry Andric bool IsComdat =
1242*0fca6ea1SDimitry Andric (Flags & SymbolRef::SF_Weak) || (SectionIndex != DotTextSectionIndex);
1243*0fca6ea1SDimitry Andric
1244*0fca6ea1SDimitry Andric // Record the symbol name (linkage) and its loading address.
1245*0fca6ea1SDimitry Andric addToSymbolTable(Name, Address, SectionIndex, IsComdat);
1246*0fca6ea1SDimitry Andric }
1247*0fca6ea1SDimitry Andric }
1248*0fca6ea1SDimitry Andric
sortScopes()1249*0fca6ea1SDimitry Andric void LVDWARFReader::sortScopes() { Root->sort(); }
1250*0fca6ea1SDimitry Andric
print(raw_ostream & OS) const1251*0fca6ea1SDimitry Andric void LVDWARFReader::print(raw_ostream &OS) const {
1252*0fca6ea1SDimitry Andric OS << "LVType\n";
1253*0fca6ea1SDimitry Andric LLVM_DEBUG(dbgs() << "CreateReaders\n");
1254*0fca6ea1SDimitry Andric }
1255