LLVM 22.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
23#include "llvm/Object/MachO.h"
25
26using namespace llvm;
27using namespace llvm::object;
28using namespace llvm::logicalview;
29
30#define DEBUG_TYPE "DWARFReader"
31
32void LVDWARFReader::processOneAttribute(const DWARFDie &Die,
33 LVOffset *OffsetPtr,
34 const AttributeSpec &AttrSpec) {
35 uint64_t OffsetOnEntry = *OffsetPtr;
36 DWARFUnit *U = Die.getDwarfUnit();
37 const DWARFFormValue &FormValue =
38 DWARFFormValue::createFromUnit(AttrSpec.Form, U, OffsetPtr);
39
40 // We are processing .debug_info section, implicit_const attribute
41 // values are not really stored here, but in .debug_abbrev section.
42 auto GetAsUnsignedConstant = [&]() -> int64_t {
43 if (AttrSpec.isImplicitConst())
44 return AttrSpec.getImplicitConstValue();
45 if (std::optional<uint64_t> Val = FormValue.getAsUnsignedConstant())
46 return *Val;
47 return 0;
48 };
49
50 auto GetFlag = [](const DWARFFormValue &FormValue) -> bool {
51 return FormValue.isFormClass(DWARFFormValue::FC_Flag);
52 };
53
54 auto GetBoundValue = [&AttrSpec](const DWARFFormValue &FormValue) -> int64_t {
55 switch (FormValue.getForm()) {
56 case dwarf::DW_FORM_ref_addr:
57 case dwarf::DW_FORM_ref1:
58 case dwarf::DW_FORM_ref2:
59 case dwarf::DW_FORM_ref4:
60 case dwarf::DW_FORM_ref8:
61 case dwarf::DW_FORM_ref_udata:
62 case dwarf::DW_FORM_ref_sig8:
63 return *FormValue.getAsReferenceUVal();
64 case dwarf::DW_FORM_data1:
65 case dwarf::DW_FORM_flag:
66 case dwarf::DW_FORM_data2:
67 case dwarf::DW_FORM_data4:
68 case dwarf::DW_FORM_data8:
69 case dwarf::DW_FORM_udata:
70 case dwarf::DW_FORM_ref_sup4:
71 case dwarf::DW_FORM_ref_sup8:
72 return *FormValue.getAsUnsignedConstant();
73 case dwarf::DW_FORM_sdata:
74 return *FormValue.getAsSignedConstant();
75 case dwarf::DW_FORM_implicit_const:
76 return AttrSpec.getImplicitConstValue();
77 default:
78 return 0;
79 }
80 };
81
83 dbgs() << " " << hexValue(OffsetOnEntry)
84 << formatv(" {0}", AttrSpec.Attr) << "\n";
85 });
86
87 switch (AttrSpec.Attr) {
88 case dwarf::DW_AT_accessibility:
89 CurrentElement->setAccessibilityCode(GetAsUnsignedConstant());
90 break;
91 case dwarf::DW_AT_artificial:
92 CurrentElement->setIsArtificial();
93 break;
94 case dwarf::DW_AT_bit_size:
95 CurrentElement->setBitSize(GetAsUnsignedConstant());
96 break;
97 case dwarf::DW_AT_byte_size:
98 CurrentElement->setBitSize(GetAsUnsignedConstant() * DWARF_CHAR_BIT);
99 break;
100 case dwarf::DW_AT_call_file:
101 CurrentElement->setCallFilenameIndex(IncrementFileIndex
102 ? GetAsUnsignedConstant() + 1
103 : GetAsUnsignedConstant());
104 break;
105 case dwarf::DW_AT_call_line:
106 CurrentElement->setCallLineNumber(GetAsUnsignedConstant());
107 break;
108 case dwarf::DW_AT_comp_dir:
109 CompileUnit->setCompilationDirectory(dwarf::toStringRef(FormValue));
110 break;
111 case dwarf::DW_AT_const_value:
112 if (FormValue.isFormClass(DWARFFormValue::FC_Block)) {
113 ArrayRef<uint8_t> Expr = *FormValue.getAsBlock();
114 // Store the expression as a hexadecimal string.
116 llvm::toHex(llvm::toStringRef(Expr), /*LowerCase=*/true));
117 } else if (FormValue.isFormClass(DWARFFormValue::FC_Constant)) {
118 // In the case of negative values, generate the string representation
119 // for a positive value prefixed with the negative sign.
120 if (FormValue.getForm() == dwarf::DW_FORM_sdata) {
121 std::stringstream Stream;
122 int64_t Value = *FormValue.getAsSignedConstant();
123 if (Value < 0) {
124 Stream << "-";
125 Value = std::abs(Value);
126 }
127 Stream << hexString(Value, 2);
128 CurrentElement->setValue(Stream.str());
129 } else
130 CurrentElement->setValue(hexString(GetAsUnsignedConstant(), 2));
131 } else
133 break;
134 case dwarf::DW_AT_count:
135 CurrentElement->setCount(GetAsUnsignedConstant());
136 break;
137 case dwarf::DW_AT_decl_line:
138 CurrentElement->setLineNumber(GetAsUnsignedConstant());
139 break;
140 case dwarf::DW_AT_decl_file:
141 CurrentElement->setFilenameIndex(IncrementFileIndex
142 ? GetAsUnsignedConstant() + 1
143 : GetAsUnsignedConstant());
144 break;
145 case dwarf::DW_AT_enum_class:
146 if (GetFlag(FormValue))
147 CurrentElement->setIsEnumClass();
148 break;
149 case dwarf::DW_AT_external:
150 if (GetFlag(FormValue))
151 CurrentElement->setIsExternal();
152 break;
153 case dwarf::DW_AT_GNU_discriminator:
154 CurrentElement->setDiscriminator(GetAsUnsignedConstant());
155 break;
156 case dwarf::DW_AT_inline:
157 CurrentElement->setInlineCode(GetAsUnsignedConstant());
158 break;
159 case dwarf::DW_AT_lower_bound:
160 CurrentElement->setLowerBound(GetBoundValue(FormValue));
161 break;
162 case dwarf::DW_AT_name:
164 break;
165 case dwarf::DW_AT_GNU_template_name:
167 break;
168 case dwarf::DW_AT_linkage_name:
169 case dwarf::DW_AT_MIPS_linkage_name:
171 break;
172 case dwarf::DW_AT_producer:
173 if (options().getAttributeProducer())
175 break;
176 case dwarf::DW_AT_language:
177 if (options().getAttributeLanguage())
179 static_cast<llvm::dwarf::SourceLanguage>(GetAsUnsignedConstant())});
180 break;
181 case dwarf::DW_AT_upper_bound:
182 CurrentElement->setUpperBound(GetBoundValue(FormValue));
183 break;
184 case dwarf::DW_AT_virtuality:
185 CurrentElement->setVirtualityCode(GetAsUnsignedConstant());
186 break;
187
188 case dwarf::DW_AT_abstract_origin:
189 case dwarf::DW_AT_call_origin:
190 case dwarf::DW_AT_extension:
191 case dwarf::DW_AT_import:
192 case dwarf::DW_AT_specification:
193 case dwarf::DW_AT_type:
194 updateReference(AttrSpec.Attr, FormValue);
195 break;
196
197 case dwarf::DW_AT_low_pc:
198 if (options().getGeneralCollectRanges()) {
199 FoundLowPC = true;
200 // For toolchains that support the removal of unused code, the linker
201 // marks functions that have been removed, by setting the value for the
202 // low_pc to the max address.
203 if (std::optional<uint64_t> Value = FormValue.getAsAddress()) {
204 CurrentLowPC = *Value;
205 } else {
206 uint64_t UValue = FormValue.getRawUValue();
207 if (U->getAddrOffsetSectionItem(UValue)) {
208 CurrentLowPC = *FormValue.getAsAddress();
209 } else {
210 FoundLowPC = false;
211 // We are dealing with an index into the .debug_addr section.
212 LLVM_DEBUG({
213 dbgs() << format("indexed (%8.8x) address = ", (uint32_t)UValue);
214 });
215 }
216 }
217 if (FoundLowPC) {
218 if (CurrentLowPC == getTombstoneAddress())
219 CurrentElement->setIsDiscarded();
220 else
221 // Consider the case of WebAssembly.
222 CurrentLowPC += WasmCodeSectionOffset;
224 setCUBaseAddress(CurrentLowPC);
225 }
226 }
227 break;
228
229 case dwarf::DW_AT_high_pc:
230 if (options().getGeneralCollectRanges()) {
231 FoundHighPC = true;
232 if (std::optional<uint64_t> Address = FormValue.getAsAddress())
233 // High PC is an address.
234 CurrentHighPC = *Address;
235 if (std::optional<uint64_t> Offset = FormValue.getAsUnsignedConstant())
236 // High PC is an offset from LowPC.
237 // Don't add the WebAssembly offset if we have seen a DW_AT_low_pc, as
238 // the CurrentLowPC has already that offset added. Basically, use the
239 // original DW_AT_loc_pc value.
240 CurrentHighPC =
241 (FoundLowPC ? CurrentLowPC - WasmCodeSectionOffset : CurrentLowPC) +
242 *Offset;
243 // Store the real upper limit for the address range.
244 if (UpdateHighAddress && CurrentHighPC > 0)
245 --CurrentHighPC;
246 // Consider the case of WebAssembly.
247 CurrentHighPC += WasmCodeSectionOffset;
249 setCUHighAddress(CurrentHighPC);
250 }
251 break;
252
253 case dwarf::DW_AT_ranges:
254 if (RangesDataAvailable && options().getGeneralCollectRanges()) {
255 auto GetRanges = [](const DWARFFormValue &FormValue,
257 if (FormValue.getForm() == dwarf::DW_FORM_rnglistx)
258 return U->findRnglistFromIndex(*FormValue.getAsSectionOffset());
259 return U->findRnglistFromOffset(*FormValue.getAsSectionOffset());
260 };
262 GetRanges(FormValue, U);
263 if (!RangesOrError) {
264 LLVM_DEBUG({
265 std::string TheError(toString(RangesOrError.takeError()));
266 dbgs() << format("error decoding address ranges = ",
267 TheError.c_str());
268 });
269 consumeError(RangesOrError.takeError());
270 break;
271 }
272 // The address ranges are absolute. There is no need to add any addend.
273 DWARFAddressRangesVector Ranges = RangesOrError.get();
275 // This seems to be a tombstone for empty ranges.
276 if ((Range.LowPC == Range.HighPC) ||
277 (Range.LowPC == getTombstoneAddress()))
278 continue;
279 // Store the real upper limit for the address range.
280 if (UpdateHighAddress && Range.HighPC > 0)
281 --Range.HighPC;
282 // Consider the case of WebAssembly.
285 // Add the pair of addresses.
286 CurrentScope->addObject(Range.LowPC, Range.HighPC);
287 // If the scope is the CU, do not update the ranges set.
289 CurrentRanges.emplace_back(Range.LowPC, Range.HighPC);
290 }
291 }
292 break;
293
294 // Get the location list for the symbol.
295 case dwarf::DW_AT_data_member_location:
296 if (options().getAttributeAnyLocation())
297 processLocationMember(AttrSpec.Attr, FormValue, Die, OffsetOnEntry);
298 break;
299
300 // Get the location list for the symbol.
301 case dwarf::DW_AT_location:
302 case dwarf::DW_AT_string_length:
303 case dwarf::DW_AT_use_location:
304 if (options().getAttributeAnyLocation() && CurrentSymbol)
305 processLocationList(AttrSpec.Attr, FormValue, Die, OffsetOnEntry);
306 break;
307
308 case dwarf::DW_AT_call_data_value:
309 case dwarf::DW_AT_call_value:
310 case dwarf::DW_AT_GNU_call_site_data_value:
311 case dwarf::DW_AT_GNU_call_site_value:
312 if (options().getAttributeAnyLocation() && CurrentSymbol)
313 processLocationList(AttrSpec.Attr, FormValue, Die, OffsetOnEntry,
314 /*CallSiteLocation=*/true);
315 break;
316
317 default:
318 break;
319 }
320}
321
322LVScope *LVDWARFReader::processOneDie(const DWARFDie &InputDIE, LVScope *Parent,
323 DWARFDie &SkeletonDie) {
324 // If the input DIE corresponds to the compile unit, it can be:
325 // a) Simple DWARF: a standard DIE. Ignore the skeleton DIE (is empty).
326 // b) Split DWARF: the DIE for the split DWARF. The skeleton is the DIE
327 // for the skeleton DWARF. Process both DIEs.
328 const DWARFDie &DIE = SkeletonDie.isValid() ? SkeletonDie : InputDIE;
329 DWARFDataExtractor DebugInfoData =
331 LVOffset Offset = DIE.getOffset();
332
333 // Reset values for the current DIE.
334 CurrentLowPC = 0;
335 CurrentHighPC = 0;
337 CurrentEndOffset = 0;
338 FoundLowPC = false;
339 FoundHighPC = false;
340
341 // Process supported attributes.
342 if (DebugInfoData.isValidOffset(Offset)) {
343
344 LLVM_DEBUG({
345 dbgs() << "DIE: " << hexValue(Offset) << formatv(" {0}", DIE.getTag())
346 << "\n";
347 });
348
349 // Create the logical view element for the current DIE.
350 dwarf::Tag Tag = DIE.getTag();
352 if (!CurrentElement)
353 return CurrentScope;
354
355 CurrentElement->setTag(Tag);
356 CurrentElement->setOffset(Offset);
357
358 if (options().getAttributeAnySource() && CurrentElement->isCompileUnit())
360 static_cast<LVScopeCompileUnit *>(CurrentElement));
361
362 // Insert the newly created element into the element symbol table. If the
363 // element is in the list, it means there are previously created elements
364 // referencing this element.
365 auto [It, Inserted] = ElementTable.try_emplace(Offset, CurrentElement);
366 if (!Inserted) {
367 // There are previous references to this element. We need to update the
368 // element and all the references pointing to this element.
369 LVElementEntry &Reference = ElementTable[Offset];
370 Reference.Element = CurrentElement;
371 // Traverse the element set and update the elements (backtracking).
372 for (LVElement *Target : Reference.References)
373 Target->setReference(CurrentElement);
374 for (LVElement *Target : Reference.Types)
375 Target->setType(CurrentElement);
376 // Clear the pending elements.
377 Reference.References.clear();
378 Reference.Types.clear();
379 }
380
381 // Add the current element to its parent as there are attributes
382 // (locations) that require the scope level.
383 if (CurrentScope)
384 Parent->addElement(CurrentScope);
385 else if (CurrentSymbol)
386 Parent->addElement(CurrentSymbol);
387 else if (CurrentType)
388 Parent->addElement(CurrentType);
389
390 // Process the attributes for the given DIE.
391 auto ProcessAttributes = [&](const DWARFDie &TheDIE,
392 DWARFDataExtractor &DebugData) {
393 CurrentEndOffset = Offset;
394 uint32_t abbrCode = DebugData.getULEB128(&CurrentEndOffset);
395 if (abbrCode) {
396 if (const DWARFAbbreviationDeclaration *AbbrevDecl =
398 for (const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec :
399 AbbrevDecl->attributes())
400 processOneAttribute(TheDIE, &CurrentEndOffset, AttrSpec);
401 }
402 };
403
404 ProcessAttributes(DIE, DebugInfoData);
405
406 // If the input DIE is for a compile unit, process its attributes in
407 // the case of split DWARF, to override any common attribute values.
408 if (SkeletonDie.isValid()) {
409 DWARFDataExtractor DebugInfoData =
411 LVOffset Offset = InputDIE.getOffset();
412 if (DebugInfoData.isValidOffset(Offset))
413 ProcessAttributes(InputDIE, DebugInfoData);
414 }
415 }
416
417 if (CurrentScope) {
418 if (CurrentScope->getCanHaveRanges()) {
419 // If the scope has ranges, they are already added to the scope.
420 // Add any collected LowPC/HighPC values.
421 bool IsCompileUnit = CurrentScope->getIsCompileUnit();
422 if (FoundLowPC && FoundHighPC) {
423 CurrentScope->addObject(CurrentLowPC, CurrentHighPC);
424 if (!IsCompileUnit) {
425 // If the scope is a function, add it to the public names.
426 if ((options().getAttributePublics() ||
427 options().getPrintAnyLine()) &&
428 CurrentScope->getIsFunction() &&
429 !CurrentScope->getIsInlinedFunction())
430 CompileUnit->addPublicName(CurrentScope, CurrentLowPC,
431 CurrentHighPC);
432 }
433 }
434
435 // Look for scopes with ranges and no linkage name information that
436 // are referencing another scopes via DW_AT_specification. They are
437 // possible candidates for a comdat scope.
438 if (CurrentScope->getHasRanges() &&
439 !CurrentScope->getLinkageNameIndex() &&
440 CurrentScope->getHasReferenceSpecification()) {
441 // Get the linkage name in order to search for a possible comdat.
442 std::optional<DWARFFormValue> LinkageDIE =
443 DIE.findRecursively(dwarf::DW_AT_linkage_name);
444 if (LinkageDIE.has_value()) {
445 StringRef Name(dwarf::toStringRef(LinkageDIE));
446 if (!Name.empty())
447 CurrentScope->setLinkageName(Name);
448 }
449 }
450
451 // If the current scope is in the 'LinkageNames' table, update its
452 // logical scope. For other scopes, always we will assume the default
453 // ".text" section index.
455 if (CurrentScope->getIsComdat())
456 CompileUnit->setHasComdatScopes();
457
458 // Update section index contained ranges.
459 if (SectionIndex) {
460 if (!CurrentRanges.empty()) {
462 addSectionRange(SectionIndex, CurrentScope, Range.first,
463 Range.second > Range.first
464 ? Range.second - 1 // Make hi-pc exclusive
465 : Range.second);
466 CurrentRanges.clear();
467 }
468 // If the scope is the CU, do not update the ranges set.
469 if (FoundLowPC && FoundHighPC && !IsCompileUnit) {
470 addSectionRange(SectionIndex, CurrentScope, CurrentLowPC,
471 CurrentHighPC > CurrentLowPC
472 ? CurrentHighPC - 1 // Make hi-pc exclusive
473 : CurrentHighPC);
474 }
475 }
476 }
477 // Mark member functions.
478 if (Parent->getIsAggregate())
479 CurrentScope->setIsMember();
480 }
481
482 // Keep track of symbols with locations.
483 if (options().getAttributeAnyLocation() && CurrentSymbol &&
484 CurrentSymbol->getHasLocation())
485 SymbolsWithLocations.push_back(CurrentSymbol);
486
487 // If we have template parameters, mark the parent as template.
488 if (CurrentType && CurrentType->getIsTemplateParam())
489 Parent->setIsTemplate();
490
491 return CurrentScope;
492}
493
494void LVDWARFReader::traverseDieAndChildren(DWARFDie &DIE, LVScope *Parent,
495 DWARFDie &SkeletonDie) {
496 // Process the current DIE.
497 LVScope *Scope = processOneDie(DIE, Parent, SkeletonDie);
498 if (Scope) {
499 LVOffset Lower = DIE.getOffset();
500 LVOffset Upper = CurrentEndOffset;
501 DWARFDie DummyDie;
502 // Traverse the children chain.
503 DWARFDie Child = DIE.getFirstChild();
504 while (Child) {
505 traverseDieAndChildren(Child, Scope, DummyDie);
506 Upper = Child.getOffset();
507 Child = Child.getSibling();
508 }
509 // Calculate contributions to the debug info section.
510 if (options().getPrintSizes() && Upper)
511 CompileUnit->addSize(Scope, Lower, Upper);
512 }
513}
514
515void LVDWARFReader::processLocationGaps() {
516 if (options().getAttributeAnyLocation())
517 for (LVSymbol *Symbol : SymbolsWithLocations)
518 Symbol->fillLocationGaps();
519}
520
521void LVDWARFReader::createLineAndFileRecords(
522 const DWARFDebugLine::LineTable *Lines) {
523 if (!Lines)
524 return;
525
526 // Get the source filenames.
527 if (!Lines->Prologue.FileNames.empty())
528 for (const DWARFDebugLine::FileNameEntry &Entry :
529 Lines->Prologue.FileNames) {
530 std::string Directory;
531 if (Lines->getDirectoryForEntry(Entry, Directory))
532 Directory = transformPath(Directory);
533 if (Directory.empty())
534 Directory = std::string(CompileUnit->getCompilationDirectory());
535 std::string File = transformPath(dwarf::toStringRef(Entry.Name));
536 std::string String;
537 raw_string_ostream(String) << Directory << "/" << File;
538 CompileUnit->addFilename(String);
539 }
540
541 // In DWARF5 the file indexes start at 0;
542 bool IncrementIndex = Lines->Prologue.getVersion() >= 5;
543
544 // Get the source lines if requested by command line option.
545 if (options().getPrintLines() && Lines->Rows.size())
546 for (const DWARFDebugLine::Row &Row : Lines->Rows) {
547 // Here we collect logical debug lines in CULines. Later on,
548 // the 'processLines()' function will move each created logical line
549 // to its enclosing logical scope, using the debug ranges information
550 // and they will be released when its scope parent is deleted.
551 LVLineDebug *Line = createLineDebug();
552 CULines.push_back(Line);
553 // Consider the case of WebAssembly.
554 Line->setAddress(Row.Address.Address + WasmCodeSectionOffset);
555 Line->setFilename(
556 CompileUnit->getFilename(IncrementIndex ? Row.File + 1 : Row.File));
557 Line->setLineNumber(Row.Line);
558 if (Row.Discriminator)
559 Line->setDiscriminator(Row.Discriminator);
560 if (Row.IsStmt)
561 Line->setIsNewStatement();
562 if (Row.BasicBlock)
563 Line->setIsBasicBlock();
564 if (Row.EndSequence)
565 Line->setIsEndSequence();
566 if (Row.EpilogueBegin)
567 Line->setIsEpilogueBegin();
568 if (Row.PrologueEnd)
569 Line->setIsPrologueEnd();
570 LLVM_DEBUG({
571 dbgs() << "Address: " << hexValue(Line->getAddress())
572 << " Line: " << Line->lineNumberAsString(/*ShowZero=*/true)
573 << "\n";
574 });
575 }
576}
577
579 ArrayRef<uint64_t> Operands) {
580 // The 'prettyPrintRegisterOp' function uses the DWARFUnit to support
581 // DW_OP_regval_type. At this point we are operating on a logical view
582 // item, with no access to the underlying DWARF data used by LLVM.
583 // We do not support DW_OP_regval_type here.
584 if (Opcode == dwarf::DW_OP_regval_type)
585 return {};
586
587 std::string string;
588 raw_string_ostream Stream(string);
589 DIDumpOptions DumpOpts;
590 auto *MCRegInfo = MRI.get();
591 auto GetRegName = [&MCRegInfo](uint64_t DwarfRegNum, bool IsEH) -> StringRef {
592 if (!MCRegInfo)
593 return {};
594 if (std::optional<MCRegister> LLVMRegNum =
595 MCRegInfo->getLLVMRegNum(DwarfRegNum, IsEH))
596 if (const char *RegName = MCRegInfo->getName(*LLVMRegNum))
597 return StringRef(RegName);
598 return {};
599 };
600 DumpOpts.GetNameForDWARFReg = GetRegName;
601 prettyPrintRegisterOp(/*U=*/nullptr, Stream, DumpOpts, Opcode, Operands);
602 return Stream.str();
603}
604
606 LLVM_DEBUG({
607 W.startLine() << "\n";
608 W.printString("File", Obj.getFileName().str());
609 W.printString("Format", FileFormatName);
610 });
611
612 if (Error Err = LVReader::createScopes())
613 return Err;
614
615 // As the DwarfContext object is valid only during the scopes creation,
616 // we need to create our own Target information, to be used during the
617 // logical view printing, in the case of instructions being requested.
618 std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(Obj);
619 if (!DwarfContext)
621 "Could not create DWARF information: %s",
622 getFilename().str().c_str());
623
624 if (Error Err = loadTargetInfo(Obj))
625 return Err;
626
627 // Create a mapping for virtual addresses.
629
630 // Select the correct compile unit range, depending if we are dealing with
631 // a standard or split DWARF object.
633 DwarfContext->getNumCompileUnits() ? DwarfContext->compile_units()
634 : DwarfContext->dwo_compile_units();
635 for (const std::unique_ptr<DWARFUnit> &CU : CompileUnits) {
636
637 // Take into account the address byte size for a correct 'tombstone'
638 // value identification.
640 dwarf::computeTombstoneAddress(CU->getAddressByteSize()));
641
642 // Deduction of index used for the line records.
643 //
644 // For the following test case: test.cpp
645 // void foo(void ParamPtr) { }
646
647 // Both GCC and Clang generate DWARF-5 .debug_line layout.
648
649 // * GCC (GNU C++17 11.3.0) - All DW_AT_decl_file use index 1.
650 //
651 // .debug_info:
652 // format = DWARF32, version = 0x0005
653 // DW_TAG_compile_unit
654 // DW_AT_name ("test.cpp")
655 // DW_TAG_subprogram ("foo")
656 // DW_AT_decl_file (1)
657 // DW_TAG_formal_parameter ("ParamPtr")
658 // DW_AT_decl_file (1)
659 // .debug_line:
660 // Line table prologue: format (DWARF32), version (5)
661 // include_directories[0] = "..."
662 // file_names[0]: name ("test.cpp"), dir_index (0)
663 // file_names[1]: name ("test.cpp"), dir_index (0)
664
665 // * Clang (14.0.6) - All DW_AT_decl_file use index 0.
666 //
667 // .debug_info:
668 // format = DWARF32, version = 0x0005
669 // DW_AT_producer ("clang version 14.0.6")
670 // DW_AT_name ("test.cpp")
671 //
672 // DW_TAG_subprogram ("foo")
673 // DW_AT_decl_file (0)
674 // DW_TAG_formal_parameter ("ParamPtr")
675 // DW_AT_decl_file (0)
676 // .debug_line:
677 // Line table prologue: format (DWARF32), version (5)
678 // include_directories[0] = "..."
679 // file_names[0]: name ("test.cpp"), dir_index (0)
680
681 // From DWARFDebugLine::getFileNameByIndex documentation:
682 // In Dwarf 4, the files are 1-indexed.
683 // In Dwarf 5, the files are 0-indexed.
684 // Additional discussions here:
685 // https://www.mail-archive.com/dwarf-discuss@lists.dwarfstd.org/msg00883.html
686
687 // The DWARF reader is expecting the files are 1-indexed, so using
688 // the .debug_line header information decide if the indexed require
689 // an internal adjustment.
690
691 // For the case of GCC (DWARF5), if the entries[0] and [1] are the
692 // same, do not perform any adjustment.
693 auto DeduceIncrementFileIndex = [&]() -> bool {
694 if (CU->getVersion() < 5)
695 // DWARF-4 or earlier -> Don't increment index.
696 return false;
697
698 if (const DWARFDebugLine::LineTable *LT =
699 CU->getContext().getLineTableForUnit(CU.get())) {
700 // Check if there are at least 2 entries and if they are the same.
701 if (LT->hasFileAtIndex(0) && LT->hasFileAtIndex(1)) {
702 const DWARFDebugLine::FileNameEntry &EntryZero =
703 LT->Prologue.getFileNameEntry(0);
704 const DWARFDebugLine::FileNameEntry &EntryOne =
705 LT->Prologue.getFileNameEntry(1);
706 // Check directory indexes.
707 if (EntryZero.DirIdx != EntryOne.DirIdx)
708 // DWARF-5 -> Increment index.
709 return true;
710 // Check filename.
711 std::string FileZero;
712 std::string FileOne;
714 LT->getFileNameByIndex(
716 FileZero);
717 LT->getFileNameByIndex(
719 FileOne);
720 return FileZero != FileOne;
721 }
722 }
723
724 // DWARF-5 -> Increment index.
725 return true;
726 };
727 // The DWARF reader expects the indexes as 1-indexed.
728 IncrementFileIndex = DeduceIncrementFileIndex();
729
730 DWARFDie UnitDie = CU->getUnitDIE();
731 SmallString<16> DWOAlternativeLocation;
732 if (UnitDie) {
733 std::optional<const char *> DWOFileName =
734 CU->getVersion() >= 5
735 ? dwarf::toString(UnitDie.find(dwarf::DW_AT_dwo_name))
736 : dwarf::toString(UnitDie.find(dwarf::DW_AT_GNU_dwo_name));
737 StringRef From(DWOFileName.value_or(""));
738 DWOAlternativeLocation = createAlternativePath(From);
739 }
740
741 // The current CU can be a normal compile unit (standard) or a skeleton
742 // compile unit (split). For both cases, the returned die, will be used
743 // to create the logical scopes.
744 DWARFDie CUDie = CU->getNonSkeletonUnitDIE(
745 /*ExtractUnitDIEOnly=*/false,
746 /*DWOAlternativeLocation=*/DWOAlternativeLocation);
747 if (!CUDie.isValid())
748 continue;
749
750 // The current unit corresponds to the .dwo file. We need to get the
751 // skeleton unit and query for any ranges that will enclose any ranges
752 // in the non-skeleton unit.
753 DWARFDie DummyDie;
754 DWARFDie SkeletonDie =
755 CUDie.getDwarfUnit()->isDWOUnit() ? CU->getUnitDIE(false) : DummyDie;
756 // Disable the ranges processing if we have just a single .dwo object,
757 // as any DW_AT_ranges will access not available range information.
758 RangesDataAvailable =
759 (!CUDie.getDwarfUnit()->isDWOUnit() ||
760 (SkeletonDie.isValid() ? !SkeletonDie.getDwarfUnit()->isDWOUnit()
761 : true));
762
763 traverseDieAndChildren(CUDie, Root, SkeletonDie);
764
765 createLineAndFileRecords(DwarfContext->getLineTableForUnit(CU.get()));
766 if (Error Err = createInstructions())
767 return Err;
768
769 // Process the compilation unit, as there are cases where enclosed
770 // functions have the same ranges values. Insert the compilation unit
771 // ranges at the end, to allow enclosing ranges to be first in the list.
773 addSectionRange(SectionIndex, CompileUnit);
774 LVRange *ScopesWithRanges = getSectionRanges(SectionIndex);
775 ScopesWithRanges->sort();
776
777 processLines(&CULines, SectionIndex);
778 processLocationGaps();
779
780 // These are per compile unit.
781 ScopesWithRanges->clear();
782 SymbolsWithLocations.clear();
783 CULines.clear();
784 }
785
786 return Error::success();
787}
788
789// Get the location information for the associated attribute.
790void LVDWARFReader::processLocationList(dwarf::Attribute Attr,
791 const DWARFFormValue &FormValue,
792 const DWARFDie &Die,
793 uint64_t OffsetOnEntry,
794 bool CallSiteLocation) {
795
796 auto ProcessLocationExpression = [&](const DWARFExpression &Expression) {
798 CurrentSymbol->addLocationOperands(Op.getCode(), Op.getRawOperands());
799 };
800
801 DWARFUnit *U = Die.getDwarfUnit();
802 DWARFContext &DwarfContext = U->getContext();
803 bool IsLittleEndian = DwarfContext.isLittleEndian();
804 if (FormValue.isFormClass(DWARFFormValue::FC_Block) ||
807 ArrayRef<uint8_t> Expr = *FormValue.getAsBlock();
808 DataExtractor Data(StringRef((const char *)Expr.data(), Expr.size()),
809 IsLittleEndian, 0);
810 DWARFExpression Expression(Data, U->getAddressByteSize(),
811 U->getFormParams().Format);
812
813 // Add location and operation entries.
814 CurrentSymbol->addLocation(Attr, /*LowPC=*/0, /*HighPC=*/-1,
815 /*SectionOffset=*/0, OffsetOnEntry,
816 CallSiteLocation);
817 ProcessLocationExpression(Expression);
818 return;
819 }
820
823 uint64_t Offset = *FormValue.getAsSectionOffset();
824 if (FormValue.getForm() == dwarf::DW_FORM_loclistx) {
825 std::optional<uint64_t> LoclistOffset = U->getLoclistOffset(Offset);
826 if (!LoclistOffset)
827 return;
828 Offset = *LoclistOffset;
829 }
830 uint64_t BaseAddr = 0;
831 if (std::optional<SectionedAddress> BA = U->getBaseAddress())
832 BaseAddr = BA->Address;
833 LVAddress LowPC = 0;
834 LVAddress HighPC = 0;
835
836 auto ProcessLocationEntry = [&](const DWARFLocationEntry &Entry) {
837 if (Entry.Kind == dwarf::DW_LLE_base_address) {
838 BaseAddr = Entry.Value0;
839 return;
840 }
841 if (Entry.Kind == dwarf::DW_LLE_offset_pair) {
842 LowPC = BaseAddr + Entry.Value0;
843 HighPC = BaseAddr + Entry.Value1;
844 DWARFAddressRange Range{LowPC, HighPC, Entry.SectionIndex};
845 if (Range.SectionIndex == SectionedAddress::UndefSection)
846 Range.SectionIndex = Entry.SectionIndex;
847 DWARFLocationExpression Loc{Range, Entry.Loc};
848 DWARFDataExtractor Data(Loc.Expr, IsLittleEndian,
849 U->getAddressByteSize());
850 DWARFExpression Expression(Data, U->getAddressByteSize());
851
852 // Store the real upper limit for the address range.
853 if (UpdateHighAddress && HighPC > 0)
854 --HighPC;
855 // Add location and operation entries.
856 CurrentSymbol->addLocation(Attr, LowPC, HighPC, Offset, OffsetOnEntry,
857 CallSiteLocation);
858 ProcessLocationExpression(Expression);
859 }
860 };
861 Error E = U->getLocationTable().visitLocationList(
862 &Offset, [&](const DWARFLocationEntry &E) {
863 ProcessLocationEntry(E);
864 return true;
865 });
866 if (E)
867 consumeError(std::move(E));
868 }
869}
870
871void LVDWARFReader::processLocationMember(dwarf::Attribute Attr,
872 const DWARFFormValue &FormValue,
873 const DWARFDie &Die,
874 uint64_t OffsetOnEntry) {
875 // Check if the value is an integer constant.
877 // Add a record to hold a constant as location.
878 CurrentSymbol->addLocationConstant(Attr, *FormValue.getAsUnsignedConstant(),
879 OffsetOnEntry);
880 else
881 // This is a location description, or a reference to one.
882 processLocationList(Attr, FormValue, Die, OffsetOnEntry);
883}
884
885// Update the current element with the reference.
886void LVDWARFReader::updateReference(dwarf::Attribute Attr,
887 const DWARFFormValue &FormValue) {
888 // FIXME: We are assuming that at most one Reference (DW_AT_specification,
889 // DW_AT_abstract_origin, ...) and at most one Type (DW_AT_import, DW_AT_type)
890 // appear in any single DIE, but this may not be true.
891 uint64_t Offset;
892 if (std::optional<uint64_t> Off = FormValue.getAsRelativeReference())
893 Offset = FormValue.getUnit()->getOffset() + *Off;
894 else if (Off = FormValue.getAsDebugInfoReference(); Off)
895 Offset = *Off;
896 else
897 llvm_unreachable("Unsupported reference type");
898
899 // Get target for the given reference, if already created.
900 LVElement *Target = getElementForOffset(
902 /*IsType=*/Attr == dwarf::DW_AT_import || Attr == dwarf::DW_AT_type);
903 // Check if we are dealing with cross CU references.
904 if (FormValue.getForm() == dwarf::DW_FORM_ref_addr) {
905 if (Target) {
906 // The global reference is ready. Mark it as global.
907 Target->setIsGlobalReference();
908 // Remove global reference from the unseen list.
909 removeGlobalOffset(Offset);
910 } else
911 // Record the unseen cross CU reference.
912 addGlobalOffset(Offset);
913 }
914
915 // At this point, 'Target' can be null, in the case of the target element
916 // not being seen. But the correct bit is set, to indicate that the target
917 // is being referenced by (abstract_origin, extension, specification) or
918 // (import, type).
919 // We must differentiate between the kind of reference. This is needed to
920 // complete inlined function instances with dropped abstract references,
921 // in order to facilitate a logical comparison.
922 switch (Attr) {
923 case dwarf::DW_AT_abstract_origin:
924 case dwarf::DW_AT_call_origin:
925 CurrentElement->setReference(Target);
926 CurrentElement->setHasReferenceAbstract();
927 break;
928 case dwarf::DW_AT_extension:
929 CurrentElement->setReference(Target);
930 CurrentElement->setHasReferenceExtension();
931 break;
932 case dwarf::DW_AT_specification:
933 CurrentElement->setReference(Target);
934 CurrentElement->setHasReferenceSpecification();
935 break;
936 case dwarf::DW_AT_import:
937 case dwarf::DW_AT_type:
938 CurrentElement->setType(Target);
939 break;
940 default:
941 break;
942 }
943}
944
945// Get an element given the DIE offset.
946LVElement *LVDWARFReader::getElementForOffset(LVOffset Offset,
947 LVElement *Element, bool IsType) {
948 // Update the element and all the references pointing to this element.
949 LVElementEntry &Entry = ElementTable[Offset];
950 if (!Entry.Element) {
951 if (IsType)
952 Entry.Types.insert(Element);
953 else
954 Entry.References.insert(Element);
955 }
956 return Entry.Element;
957}
958
959Error LVDWARFReader::loadTargetInfo(const ObjectFile &Obj) {
960 // Detect the architecture from the object file. We usually don't need OS
961 // info to lookup a target and create register info.
962 Triple TT = Obj.makeTriple();
963
964 // Features to be passed to target/subtarget
965 Expected<SubtargetFeatures> Features = Obj.getFeatures();
966 SubtargetFeatures FeaturesValue;
967 if (!Features) {
968 consumeError(Features.takeError());
969 FeaturesValue = SubtargetFeatures();
970 }
971 FeaturesValue = *Features;
972
973 StringRef CPU;
974 if (auto OptCPU = Obj.tryGetCPUName())
975 CPU = *OptCPU;
976
977 return loadGenericTargetInfo(TT.str(), FeaturesValue.getString(), CPU);
978}
979
980void LVDWARFReader::mapRangeAddress(const ObjectFile &Obj) {
981 for (auto Iter = Obj.symbol_begin(); Iter != Obj.symbol_end(); ++Iter) {
982 const SymbolRef &Symbol = *Iter;
983
984 Expected<SymbolRef::Type> TypeOrErr = Symbol.getType();
985 if (!TypeOrErr) {
986 consumeError(TypeOrErr.takeError());
987 continue;
988 }
989
990 // Process only symbols that represent a function.
991 SymbolRef::Type Type = *TypeOrErr;
993 continue;
994
995 // In the case of a Mach-O STAB symbol, get its section only if
996 // the STAB symbol's section field refers to a valid section index.
997 // Otherwise the symbol may error trying to load a section that
998 // does not exist.
999 const MachOObjectFile *MachO = dyn_cast<const MachOObjectFile>(&Obj);
1000 bool IsSTAB = false;
1001 if (MachO) {
1002 DataRefImpl SymDRI = Symbol.getRawDataRefImpl();
1003 uint8_t NType =
1004 (MachO->is64Bit() ? MachO->getSymbol64TableEntry(SymDRI).n_type
1005 : MachO->getSymbolTableEntry(SymDRI).n_type);
1006 if (NType & MachO::N_STAB)
1007 IsSTAB = true;
1008 }
1009
1010 Expected<section_iterator> IterOrErr = Symbol.getSection();
1011 if (!IterOrErr) {
1012 consumeError(IterOrErr.takeError());
1013 continue;
1014 }
1015 section_iterator Section = IsSTAB ? Obj.section_end() : *IterOrErr;
1016 if (Section == Obj.section_end())
1017 continue;
1018
1019 // Get the symbol value.
1020 Expected<uint64_t> AddressOrErr = Symbol.getAddress();
1021 if (!AddressOrErr) {
1022 consumeError(AddressOrErr.takeError());
1023 continue;
1024 }
1025 uint64_t Address = *AddressOrErr;
1026
1027 // Get symbol name.
1028 StringRef Name;
1029 Expected<StringRef> NameOrErr = Symbol.getName();
1030 if (!NameOrErr) {
1031 consumeError(NameOrErr.takeError());
1032 continue;
1033 }
1034 Name = *NameOrErr;
1035
1036 // Check if the symbol is Comdat.
1037 Expected<uint32_t> FlagsOrErr = Symbol.getFlags();
1038 if (!FlagsOrErr) {
1039 consumeError(FlagsOrErr.takeError());
1040 continue;
1041 }
1042 uint32_t Flags = *FlagsOrErr;
1043
1044 // Mark the symbol as 'comdat' in any of the following cases:
1045 // - Symbol has the SF_Weak flag or
1046 // - Symbol section index different from the DotTextSectionIndex.
1047 LVSectionIndex SectionIndex = Section->getIndex();
1048 bool IsComdat =
1049 (Flags & SymbolRef::SF_Weak) || (SectionIndex != DotTextSectionIndex);
1050
1051 // Record the symbol name (linkage) and its loading address.
1052 addToSymbolTable(Name, Address, SectionIndex, IsComdat);
1053 }
1054}
1055
1057
1059 OS << "LVType\n";
1060 LLVM_DEBUG(dbgs() << "CreateReaders\n");
1061}
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define RegName(no)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
#define LLVM_DEBUG(...)
Definition Debug.h:114
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
size - Get the array size.
Definition ArrayRef.h:142
const T * data() const
Definition ArrayRef.h:139
DWARFContext This data structure is the top level entity that deals with dwarf debug information pars...
DWARFUnitVector::compile_unit_range compile_unit_range
bool isLittleEndian() const
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)
Utility class that carries the DWARF compile/type unit and the debug info entry in an object.
Definition DWARFDie.h:43
uint64_t getOffset() const
Get the absolute offset into the debug info or types section.
Definition DWARFDie.h:68
LLVM_ABI std::optional< DWARFFormValue > find(dwarf::Attribute Attr) const
Extract the specified attribute from this DIE.
Definition DWARFDie.cpp:317
DWARFUnit * getDwarfUnit() const
Definition DWARFDie.h:55
LLVM_ABI DWARFDie getSibling() const
Get the sibling of this DIE object.
Definition DWARFDie.cpp:730
LLVM_ABI std::optional< DWARFFormValue > findRecursively(ArrayRef< dwarf::Attribute > Attrs) const
Extract the first value of any attribute in Attrs from this DIE and recurse into any DW_AT_specificat...
Definition DWARFDie.cpp:341
const DWARFAbbreviationDeclaration * getAbbreviationDeclarationPtr() const
Get the abbreviation declaration for this DIE.
Definition DWARFDie.h:60
LLVM_ABI DWARFDie getFirstChild() const
Get the first child of this DIE object.
Definition DWARFDie.cpp:742
dwarf::Tag getTag() const
Definition DWARFDie.h:73
bool isValid() const
Definition DWARFDie.h:52
This class represents an Operation in the Expression.
LLVM_ABI std::optional< ArrayRef< uint8_t > > getAsBlock() const
LLVM_ABI std::optional< uint64_t > getAsSectionOffset() const
LLVM_ABI bool isFormClass(FormClass FC) const
LLVM_ABI std::optional< uint64_t > getAsReferenceUVal() const
LLVM_ABI std::optional< int64_t > getAsSignedConstant() const
LLVM_ABI std::optional< uint64_t > getAsAddress() const
LLVM_ABI std::optional< uint64_t > getAsRelativeReference() const
getAsFoo functions below return the extracted value as Foo if only DWARFFormValue has form class is s...
LLVM_ABI std::optional< uint64_t > getAsDebugInfoReference() const
LLVM_ABI std::optional< uint64_t > getAsUnsignedConstant() const
static LLVM_ABI 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
uint64_t getOffset() const
Definition DWARFUnit.h:328
bool isDWOUnit() const
Definition DWARFUnit.h:325
bool isValidOffset(uint64_t offset) const
Test the validity of offset.
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
Tagged union holding either a T or a Error.
Definition Error.h:485
Error takeError()
Take ownership of the stored error.
Definition Error.h:612
reference get()
Returns a reference to the stored T value.
Definition Error.h:582
Class representing an expression and its matching format.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
LLVM_ABI std::string getString() const
Returns features as a string.
LLVM Value Representation.
Definition Value.h:75
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
Error loadGenericTargetInfo(StringRef TheTriple, StringRef TheFeatures, StringRef TheCPU)
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
LVAddress getTombstoneAddress() const
void setCUHighAddress(LVAddress Address)
void setTombstoneAddress(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:260
virtual void setCallLineNumber(uint32_t Number)
Definition LVElement.h:241
virtual void setBitSize(uint32_t Size)
Definition LVElement.h:257
virtual void setLinkageName(StringRef LinkageName)
Definition LVElement.h:236
virtual void setProducer(StringRef ProducerName)
Definition LVElement.h:223
virtual void setUpperBound(int64_t Value)
Definition LVElement.h:264
virtual void setDiscriminator(uint32_t Value)
Definition LVElement.h:270
virtual void setLowerBound(int64_t Value)
Definition LVElement.h:262
virtual void setValue(StringRef Value)
Definition LVElement.h:274
void setInlineCode(uint32_t Code)
Definition LVElement.h:292
void setName(StringRef ElementName) override
Definition LVElement.cpp:95
virtual bool isCompileUnit() const
Definition LVElement.h:228
void setAccessibilityCode(uint32_t Access)
Definition LVElement.h:279
void setVirtualityCode(uint32_t Virtuality)
Definition LVElement.h:297
void setFilenameIndex(size_t Index)
Definition LVElement.h:245
virtual void setSourceLanguage(LVSourceLanguage SL)
Definition LVElement.h:226
virtual void setCallFilenameIndex(size_t Index)
Definition LVElement.h:243
void setLineNumber(uint32_t Number)
Definition LVObject.h:275
LVRange * getSectionRanges(LVSectionIndex SectionIndex)
Definition LVReader.cpp:208
void addCompileUnitOffset(LVOffset Offset, LVScopeCompileUnit *CompileUnit)
Definition LVReader.h:160
std::vector< LVAddressRange > CurrentRanges
Definition LVReader.h:142
std::string createAlternativePath(StringRef From)
Definition LVReader.h:181
LVElement * createElement(dwarf::Tag Tag)
Definition LVReader.cpp:219
StringRef getFilename() const
Definition LVReader.h:263
LVScopeCompileUnit * CompileUnit
Definition LVReader.h:149
LVSectionIndex DotTextSectionIndex
Definition LVReader.h:152
void addSectionRange(LVSectionIndex SectionIndex, LVScope *Scope)
Definition LVReader.cpp:197
virtual Error createScopes()
Definition LVReader.h:167
void addElement(LVElement *Element)
Definition LVScope.cpp:122
void addObject(LVLocation *Location)
Definition LVScope.cpp:161
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
MachO::nlist getSymbolTableEntry(DataRefImpl DRI) const
MachO::nlist_64 getSymbol64TableEntry(DataRefImpl DRI) const
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
A raw_ostream that writes to an std::string.
std::string & str()
Returns the string's reference.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ Entry
Definition COFF.h:862
Attribute
Attributes.
Definition Dwarf.h:125
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.
uint64_t computeTombstoneAddress(uint8_t AddressByteSize)
Definition Dwarf.h:1242
FormattedNumber hexValue(uint64_t N, unsigned Width=HEX_WIDTH, bool Upper=false)
Definition LVSupport.h:123
std::string hexString(uint64_t Value, size_t Width=HEX_WIDTH)
Definition LVSupport.h:129
uint64_t LVOffset
Definition LVObject.h:39
constexpr unsigned int DWARF_CHAR_BIT
Definition LVElement.h:73
LLVM_ABI std::string transformPath(StringRef Path)
Definition LVSupport.cpp:31
std::pair< LVAddress, LVAddress > LVAddressRange
Definition LVRange.h:24
constexpr bool UpdateHighAddress
uint8_t LVSmall
Definition LVObject.h:42
uint64_t LVSectionIndex
Definition LVObject.h:35
DWARFAbbreviationDeclaration::AttributeSpec AttributeSpec
uint64_t LVAddress
Definition LVObject.h:36
LVOptions & options()
Definition LVOptions.h:448
content_iterator< SectionRef > section_iterator
Definition ObjectFile.h:49
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:532
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
SmallVectorImpl< T >::const_pointer c_str(SmallVectorImpl< T > &str)
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition Error.h:1305
@ invalid_argument
Definition Errc.h:56
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition Format.h:129
FunctionAddr VTableAddr uintptr_t uintptr_t Data
Definition InstrProf.h:189
DWARFExpression::Operation Op
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
void toHex(ArrayRef< uint8_t > Input, bool LowerCase, SmallVectorImpl< char > &Output)
Convert buffer Input to its hexadecimal representation. The returned string is double the size of Inp...
LLVM_ABI bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS, DIDumpOptions DumpOpts, uint8_t Opcode, ArrayRef< uint64_t > Operands)
Pretty print a register opcode and operands.
void consumeError(Error Err)
Consume a Error without doing anything.
Definition Error.h:1083
StringRef toStringRef(bool B)
Construct a string ref from a boolean.
std::vector< DWARFAddressRange > DWARFAddressRangesVector
DWARFAddressRangesVector - represents a set of absolute address ranges.
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:217
static LLVM_ABI bool mayHaveLocationList(dwarf::Attribute Attr)
Identify DWARF attributes that may contain a pointer to a location list.
Definition DWARFDie.cpp:806
static LLVM_ABI bool mayHaveLocationExpr(dwarf::Attribute Attr)
Identifies DWARF attributes that may contain a reference to a DWARF expression.
Definition DWARFDie.cpp:823
SmallVector< uint8_t, 4 > Expr
The expression itself.
static const uint64_t UndefSection
Definition ObjectFile.h:148
A source language supported by any of the debug info representations.