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