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