xref: /freebsd-src/contrib/llvm-project/llvm/lib/DebugInfo/LogicalView/Readers/LVDWARFReader.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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 
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 
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 
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 
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 
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 
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 
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 
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.
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 
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.
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.
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 
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 
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 
1249*0fca6ea1SDimitry Andric void LVDWARFReader::sortScopes() { Root->sort(); }
1250*0fca6ea1SDimitry Andric 
1251*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