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 =
330 DIE.getDwarfUnit()->getDebugInfoExtractor();
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.
352 if (!CurrentElement)
353 return CurrentScope;
354
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 if (AbbrevDecl)
400 AbbrevDecl->attributes())
401 processOneAttribute(TheDIE, &CurrentEndOffset, AttrSpec);
402 }
403 };
404
405 ProcessAttributes(DIE, DebugInfoData);
406
407 // If the input DIE is for a compile unit, process its attributes in
408 // the case of split DWARF, to override any common attribute values.
409 if (SkeletonDie.isValid()) {
410 DWARFDataExtractor DebugInfoData =
412 LVOffset Offset = InputDIE.getOffset();
413 if (DebugInfoData.isValidOffset(Offset))
414 ProcessAttributes(InputDIE, DebugInfoData);
415 }
416 }
417
418 if (CurrentScope) {
419 if (CurrentScope->getCanHaveRanges()) {
420 // If the scope has ranges, they are already added to the scope.
421 // Add any collected LowPC/HighPC values.
422 bool IsCompileUnit = CurrentScope->getIsCompileUnit();
423 if (FoundLowPC && FoundHighPC) {
424 CurrentScope->addObject(CurrentLowPC, CurrentHighPC);
425 if (!IsCompileUnit) {
426 // If the scope is a function, add it to the public names.
427 if ((options().getAttributePublics() ||
428 options().getPrintAnyLine()) &&
429 CurrentScope->getIsFunction() &&
430 !CurrentScope->getIsInlinedFunction())
431 CompileUnit->addPublicName(CurrentScope, CurrentLowPC,
432 CurrentHighPC);
433 }
434 }
435
436 // Look for scopes with ranges and no linkage name information that
437 // are referencing another scopes via DW_AT_specification. They are
438 // possible candidates for a comdat scope.
439 if (CurrentScope->getHasRanges() &&
441 CurrentScope->getHasReferenceSpecification()) {
442 // Get the linkage name in order to search for a possible comdat.
443 std::optional<DWARFFormValue> LinkageDIE =
444 DIE.findRecursively(dwarf::DW_AT_linkage_name);
445 if (LinkageDIE.has_value()) {
446 StringRef Name(dwarf::toStringRef(LinkageDIE));
447 if (!Name.empty())
449 }
450 }
451
452 // If the current scope is in the 'LinkageNames' table, update its
453 // logical scope. For other scopes, always we will assume the default
454 // ".text" section index.
456 if (CurrentScope->getIsComdat())
457 CompileUnit->setHasComdatScopes();
458
459 // Update section index contained ranges.
460 if (SectionIndex) {
461 if (!CurrentRanges.empty()) {
463 addSectionRange(SectionIndex, CurrentScope, Range.first,
464 Range.second > Range.first
465 ? Range.second - 1 // Make hi-pc exclusive
466 : Range.second);
467 CurrentRanges.clear();
468 }
469 // If the scope is the CU, do not update the ranges set.
470 if (FoundLowPC && FoundHighPC && !IsCompileUnit) {
471 addSectionRange(SectionIndex, CurrentScope, CurrentLowPC,
472 CurrentHighPC > CurrentLowPC
473 ? CurrentHighPC - 1 // Make hi-pc exclusive
474 : CurrentHighPC);
475 }
476 }
477 }
478 // Mark member functions.
479 if (Parent->getIsAggregate())
480 CurrentScope->setIsMember();
481 }
482
483 // Keep track of symbols with locations.
484 if (options().getAttributeAnyLocation() && CurrentSymbol &&
485 CurrentSymbol->getHasLocation())
486 SymbolsWithLocations.push_back(CurrentSymbol);
487
488 // If we have template parameters, mark the parent as template.
489 if (CurrentType && CurrentType->getIsTemplateParam())
490 Parent->setIsTemplate();
491
492 return CurrentScope;
493}
494
495void LVDWARFReader::traverseDieAndChildren(DWARFDie &DIE, LVScope *Parent,
496 DWARFDie &SkeletonDie) {
497 // Process the current DIE.
498 LVScope *Scope = processOneDie(DIE, Parent, SkeletonDie);
499 if (Scope) {
501 LVOffset Upper = CurrentEndOffset;
502 DWARFDie DummyDie;
503 // Traverse the children chain.
504 DWARFDie Child = DIE.getFirstChild();
505 while (Child) {
506 traverseDieAndChildren(Child, Scope, DummyDie);
507 Upper = Child.getOffset();
508 Child = Child.getSibling();
509 }
510 // Calculate contributions to the debug info section.
511 if (options().getPrintSizes() && Upper)
512 CompileUnit->addSize(Scope, Lower, Upper);
513 }
514}
515
516void LVDWARFReader::processLocationGaps() {
517 if (options().getAttributeAnyLocation())
518 for (LVSymbol *Symbol : SymbolsWithLocations)
519 Symbol->fillLocationGaps();
520}
521
522void LVDWARFReader::createLineAndFileRecords(
524 if (!Lines)
525 return;
526
527 // Get the source filenames.
528 if (!Lines->Prologue.FileNames.empty())
529 for (const DWARFDebugLine::FileNameEntry &Entry :
530 Lines->Prologue.FileNames) {
531 std::string Directory;
532 if (Lines->getDirectoryForEntry(Entry, Directory))
533 Directory = transformPath(Directory);
534 if (Directory.empty())
535 Directory = std::string(CompileUnit->getCompilationDirectory());
536 std::string File = transformPath(dwarf::toStringRef(Entry.Name));
537 std::string String;
538 raw_string_ostream(String) << Directory << "/" << File;
539 CompileUnit->addFilename(String);
540 }
541
542 // In DWARF5 the file indexes start at 0;
543 bool IncrementIndex = Lines->Prologue.getVersion() >= 5;
544
545 // Get the source lines if requested by command line option.
546 if (options().getPrintLines() && Lines->Rows.size())
547 for (const DWARFDebugLine::Row &Row : Lines->Rows) {
548 // Here we collect logical debug lines in CULines. Later on,
549 // the 'processLines()' function will move each created logical line
550 // to its enclosing logical scope, using the debug ranges information
551 // and they will be released when its scope parent is deleted.
552 LVLineDebug *Line = createLineDebug();
554 // Consider the case of WebAssembly.
555 Line->setAddress(Row.Address.Address + WasmCodeSectionOffset);
556 Line->setFilename(
557 CompileUnit->getFilename(IncrementIndex ? Row.File + 1 : Row.File));
558 Line->setLineNumber(Row.Line);
559 if (Row.Discriminator)
560 Line->setDiscriminator(Row.Discriminator);
561 if (Row.IsStmt)
562 Line->setIsNewStatement();
563 if (Row.BasicBlock)
564 Line->setIsBasicBlock();
565 if (Row.EndSequence)
566 Line->setIsEndSequence();
567 if (Row.EpilogueBegin)
568 Line->setIsEpilogueBegin();
569 if (Row.PrologueEnd)
570 Line->setIsPrologueEnd();
571 LLVM_DEBUG({
572 dbgs() << "Address: " << hexValue(Line->getAddress())
573 << " Line: " << Line->lineNumberAsString(/*ShowZero=*/true)
574 << "\n";
575 });
576 }
577}
578
581 // The 'prettyPrintRegisterOp' function uses the DWARFUnit to support
582 // DW_OP_regval_type. At this point we are operating on a logical view
583 // item, with no access to the underlying DWARF data used by LLVM.
584 // We do not support DW_OP_regval_type here.
585 if (Opcode == dwarf::DW_OP_regval_type)
586 return {};
587
588 std::string string;
589 raw_string_ostream Stream(string);
590 DIDumpOptions DumpOpts;
591 auto *MCRegInfo = MRI.get();
592 auto GetRegName = [&MCRegInfo](uint64_t DwarfRegNum, bool IsEH) -> StringRef {
593 if (!MCRegInfo)
594 return {};
595 if (std::optional<MCRegister> LLVMRegNum =
596 MCRegInfo->getLLVMRegNum(DwarfRegNum, IsEH))
597 if (const char *RegName = MCRegInfo->getName(*LLVMRegNum))
598 return StringRef(RegName);
599 return {};
600 };
601 DumpOpts.GetNameForDWARFReg = GetRegName;
602 prettyPrintRegisterOp(/*U=*/nullptr, Stream, DumpOpts, Opcode, Operands);
603 return Stream.str();
604}
605
607 LLVM_DEBUG({
608 W.startLine() << "\n";
609 W.printString("File", Obj.getFileName().str());
610 W.printString("Format", FileFormatName);
611 });
612
613 if (Error Err = LVReader::createScopes())
614 return Err;
615
616 // As the DwarfContext object is valid only during the scopes creation,
617 // we need to create our own Target information, to be used during the
618 // logical view printing, in the case of instructions being requested.
619 std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(Obj);
620 if (!DwarfContext)
622 "Could not create DWARF information: %s",
623 getFilename().str().c_str());
624
625 if (Error Err = loadTargetInfo(Obj))
626 return Err;
627
628 // Create a mapping for virtual addresses.
630
631 // Select the correct compile unit range, depending if we are dealing with
632 // a standard or split DWARF object.
634 DwarfContext->getNumCompileUnits() ? DwarfContext->compile_units()
635 : DwarfContext->dwo_compile_units();
636 for (const std::unique_ptr<DWARFUnit> &CU : CompileUnits) {
637
638 // Take into account the address byte size for a correct 'tombstone'
639 // value identification.
641 dwarf::computeTombstoneAddress(CU->getAddressByteSize()));
642
643 // Deduction of index used for the line records.
644 //
645 // For the following test case: test.cpp
646 // void foo(void ParamPtr) { }
647
648 // Both GCC and Clang generate DWARF-5 .debug_line layout.
649
650 // * GCC (GNU C++17 11.3.0) - All DW_AT_decl_file use index 1.
651 //
652 // .debug_info:
653 // format = DWARF32, version = 0x0005
654 // DW_TAG_compile_unit
655 // DW_AT_name ("test.cpp")
656 // DW_TAG_subprogram ("foo")
657 // DW_AT_decl_file (1)
658 // DW_TAG_formal_parameter ("ParamPtr")
659 // DW_AT_decl_file (1)
660 // .debug_line:
661 // Line table prologue: format (DWARF32), version (5)
662 // include_directories[0] = "..."
663 // file_names[0]: name ("test.cpp"), dir_index (0)
664 // file_names[1]: name ("test.cpp"), dir_index (0)
665
666 // * Clang (14.0.6) - All DW_AT_decl_file use index 0.
667 //
668 // .debug_info:
669 // format = DWARF32, version = 0x0005
670 // DW_AT_producer ("clang version 14.0.6")
671 // DW_AT_name ("test.cpp")
672 //
673 // DW_TAG_subprogram ("foo")
674 // DW_AT_decl_file (0)
675 // DW_TAG_formal_parameter ("ParamPtr")
676 // DW_AT_decl_file (0)
677 // .debug_line:
678 // Line table prologue: format (DWARF32), version (5)
679 // include_directories[0] = "..."
680 // file_names[0]: name ("test.cpp"), dir_index (0)
681
682 // From DWARFDebugLine::getFileNameByIndex documentation:
683 // In Dwarf 4, the files are 1-indexed.
684 // In Dwarf 5, the files are 0-indexed.
685 // Additional discussions here:
686 // https://www.mail-archive.com/[email protected]/msg00883.html
687
688 // The DWARF reader is expecting the files are 1-indexed, so using
689 // the .debug_line header information decide if the indexed require
690 // an internal adjustment.
691
692 // For the case of GCC (DWARF5), if the entries[0] and [1] are the
693 // same, do not perform any adjustment.
694 auto DeduceIncrementFileIndex = [&]() -> bool {
695 if (CU->getVersion() < 5)
696 // DWARF-4 or earlier -> Don't increment index.
697 return false;
698
699 if (const DWARFDebugLine::LineTable *LT =
700 CU->getContext().getLineTableForUnit(CU.get())) {
701 // Check if there are at least 2 entries and if they are the same.
702 if (LT->hasFileAtIndex(0) && LT->hasFileAtIndex(1)) {
703 const DWARFDebugLine::FileNameEntry &EntryZero =
704 LT->Prologue.getFileNameEntry(0);
705 const DWARFDebugLine::FileNameEntry &EntryOne =
706 LT->Prologue.getFileNameEntry(1);
707 // Check directory indexes.
708 if (EntryZero.DirIdx != EntryOne.DirIdx)
709 // DWARF-5 -> Increment index.
710 return true;
711 // Check filename.
712 std::string FileZero;
713 std::string FileOne;
715 LT->getFileNameByIndex(
716 0, None, DILineInfoSpecifier::FileLineInfoKind::RawValue,
717 FileZero);
718 LT->getFileNameByIndex(
719 1, None, DILineInfoSpecifier::FileLineInfoKind::RawValue,
720 FileOne);
721 return FileZero != FileOne;
722 }
723 }
724
725 // DWARF-5 -> Increment index.
726 return true;
727 };
728 // The DWARF reader expects the indexes as 1-indexed.
729 IncrementFileIndex = DeduceIncrementFileIndex();
730
731 DWARFDie UnitDie = CU->getUnitDIE();
732 SmallString<16> DWOAlternativeLocation;
733 if (UnitDie) {
734 std::optional<const char *> DWOFileName =
735 CU->getVersion() >= 5
736 ? dwarf::toString(UnitDie.find(dwarf::DW_AT_dwo_name))
737 : dwarf::toString(UnitDie.find(dwarf::DW_AT_GNU_dwo_name));
738 StringRef From(DWOFileName.value_or(""));
739 DWOAlternativeLocation = createAlternativePath(From);
740 }
741
742 // The current CU can be a normal compile unit (standard) or a skeleton
743 // compile unit (split). For both cases, the returned die, will be used
744 // to create the logical scopes.
745 DWARFDie CUDie = CU->getNonSkeletonUnitDIE(
746 /*ExtractUnitDIEOnly=*/false,
747 /*DWOAlternativeLocation=*/DWOAlternativeLocation);
748 if (!CUDie.isValid())
749 continue;
750
751 // The current unit corresponds to the .dwo file. We need to get the
752 // skeleton unit and query for any ranges that will enclose any ranges
753 // in the non-skeleton unit.
754 DWARFDie DummyDie;
755 DWARFDie SkeletonDie =
756 CUDie.getDwarfUnit()->isDWOUnit() ? CU->getUnitDIE(false) : DummyDie;
757 // Disable the ranges processing if we have just a single .dwo object,
758 // as any DW_AT_ranges will access not available range information.
759 RangesDataAvailable =
760 (!CUDie.getDwarfUnit()->isDWOUnit() ||
761 (SkeletonDie.isValid() ? !SkeletonDie.getDwarfUnit()->isDWOUnit()
762 : true));
763
764 traverseDieAndChildren(CUDie, Root, SkeletonDie);
765
766 createLineAndFileRecords(DwarfContext->getLineTableForUnit(CU.get()));
767 if (Error Err = createInstructions())
768 return Err;
769
770 // Process the compilation unit, as there are cases where enclosed
771 // functions have the same ranges values. Insert the compilation unit
772 // ranges at the end, to allow enclosing ranges to be first in the list.
774 addSectionRange(SectionIndex, CompileUnit);
775 LVRange *ScopesWithRanges = getSectionRanges(SectionIndex);
776 ScopesWithRanges->sort();
777
778 processLines(&CULines, SectionIndex);
779 processLocationGaps();
780
781 // These are per compile unit.
782 ScopesWithRanges->clear();
783 SymbolsWithLocations.clear();
784 CULines.clear();
785 }
786
787 return Error::success();
788}
789
790// Get the location information for the associated attribute.
791void LVDWARFReader::processLocationList(dwarf::Attribute Attr,
792 const DWARFFormValue &FormValue,
793 const DWARFDie &Die,
794 uint64_t OffsetOnEntry,
795 bool CallSiteLocation) {
796
797 auto ProcessLocationExpression = [&](const DWARFExpression &Expression) {
800 };
801
802 DWARFUnit *U = Die.getDwarfUnit();
803 DWARFContext &DwarfContext = U->getContext();
804 bool IsLittleEndian = DwarfContext.isLittleEndian();
805 if (FormValue.isFormClass(DWARFFormValue::FC_Block) ||
808 ArrayRef<uint8_t> Expr = *FormValue.getAsBlock();
809 DataExtractor Data(StringRef((const char *)Expr.data(), Expr.size()),
810 IsLittleEndian, 0);
811 DWARFExpression Expression(Data, U->getAddressByteSize(),
812 U->getFormParams().Format);
813
814 // Add location and operation entries.
815 CurrentSymbol->addLocation(Attr, /*LowPC=*/0, /*HighPC=*/-1,
816 /*SectionOffset=*/0, OffsetOnEntry,
817 CallSiteLocation);
818 ProcessLocationExpression(Expression);
819 return;
820 }
821
824 uint64_t Offset = *FormValue.getAsSectionOffset();
825 if (FormValue.getForm() == dwarf::DW_FORM_loclistx) {
826 std::optional<uint64_t> LoclistOffset = U->getLoclistOffset(Offset);
827 if (!LoclistOffset)
828 return;
829 Offset = *LoclistOffset;
830 }
831 uint64_t BaseAddr = 0;
832 if (std::optional<SectionedAddress> BA = U->getBaseAddress())
833 BaseAddr = BA->Address;
834 LVAddress LowPC = 0;
835 LVAddress HighPC = 0;
836
837 auto ProcessLocationEntry = [&](const DWARFLocationEntry &Entry) {
838 if (Entry.Kind == dwarf::DW_LLE_base_address) {
839 BaseAddr = Entry.Value0;
840 return;
841 }
842 if (Entry.Kind == dwarf::DW_LLE_offset_pair) {
843 LowPC = BaseAddr + Entry.Value0;
844 HighPC = BaseAddr + Entry.Value1;
845 DWARFAddressRange Range{LowPC, HighPC, Entry.SectionIndex};
846 if (Range.SectionIndex == SectionedAddress::UndefSection)
847 Range.SectionIndex = Entry.SectionIndex;
849 DWARFDataExtractor Data(Loc.Expr, IsLittleEndian,
850 U->getAddressByteSize());
851 DWARFExpression Expression(Data, U->getAddressByteSize());
852
853 // Store the real upper limit for the address range.
854 if (UpdateHighAddress && HighPC > 0)
855 --HighPC;
856 // Add location and operation entries.
857 CurrentSymbol->addLocation(Attr, LowPC, HighPC, Offset, OffsetOnEntry,
858 CallSiteLocation);
859 ProcessLocationExpression(Expression);
860 }
861 };
862 Error E = U->getLocationTable().visitLocationList(
863 &Offset, [&](const DWARFLocationEntry &E) {
864 ProcessLocationEntry(E);
865 return true;
866 });
867 if (E)
868 consumeError(std::move(E));
869 }
870}
871
872void LVDWARFReader::processLocationMember(dwarf::Attribute Attr,
873 const DWARFFormValue &FormValue,
874 const DWARFDie &Die,
875 uint64_t OffsetOnEntry) {
876 // Check if the value is an integer constant.
878 // Add a record to hold a constant as location.
880 OffsetOnEntry);
881 else
882 // This is a location description, or a reference to one.
883 processLocationList(Attr, FormValue, Die, OffsetOnEntry);
884}
885
886// Update the current element with the reference.
887void LVDWARFReader::updateReference(dwarf::Attribute Attr,
888 const DWARFFormValue &FormValue) {
889 // FIXME: We are assuming that at most one Reference (DW_AT_specification,
890 // DW_AT_abstract_origin, ...) and at most one Type (DW_AT_import, DW_AT_type)
891 // appear in any single DIE, but this may not be true.
893 if (std::optional<uint64_t> Off = FormValue.getAsRelativeReference())
894 Offset = FormValue.getUnit()->getOffset() + *Off;
895 else if (Off = FormValue.getAsDebugInfoReference(); Off)
896 Offset = *Off;
897 else
898 llvm_unreachable("Unsupported reference type");
899
900 // Get target for the given reference, if already created.
901 LVElement *Target = getElementForOffset(
903 /*IsType=*/Attr == dwarf::DW_AT_import || Attr == dwarf::DW_AT_type);
904 // Check if we are dealing with cross CU references.
905 if (FormValue.getForm() == dwarf::DW_FORM_ref_addr) {
906 if (Target) {
907 // The global reference is ready. Mark it as global.
908 Target->setIsGlobalReference();
909 // Remove global reference from the unseen list.
910 removeGlobalOffset(Offset);
911 } else
912 // Record the unseen cross CU reference.
913 addGlobalOffset(Offset);
914 }
915
916 // At this point, 'Target' can be null, in the case of the target element
917 // not being seen. But the correct bit is set, to indicate that the target
918 // is being referenced by (abstract_origin, extension, specification) or
919 // (import, type).
920 // We must differentiate between the kind of reference. This is needed to
921 // complete inlined function instances with dropped abstract references,
922 // in order to facilitate a logical comparison.
923 switch (Attr) {
924 case dwarf::DW_AT_abstract_origin:
925 case dwarf::DW_AT_call_origin:
927 CurrentElement->setHasReferenceAbstract();
928 break;
929 case dwarf::DW_AT_extension:
931 CurrentElement->setHasReferenceExtension();
932 break;
933 case dwarf::DW_AT_specification:
935 CurrentElement->setHasReferenceSpecification();
936 break;
937 case dwarf::DW_AT_import:
938 case dwarf::DW_AT_type:
940 break;
941 default:
942 break;
943 }
944}
945
946// Get an element given the DIE offset.
947LVElement *LVDWARFReader::getElementForOffset(LVOffset Offset,
948 LVElement *Element, bool IsType) {
949 // Update the element and all the references pointing to this element.
950 LVElementEntry &Entry = ElementTable[Offset];
951 if (!Entry.Element) {
952 if (IsType)
953 Entry.Types.insert(Element);
954 else
955 Entry.References.insert(Element);
956 }
957 return Entry.Element;
958}
959
960Error LVDWARFReader::loadTargetInfo(const ObjectFile &Obj) {
961 // Detect the architecture from the object file. We usually don't need OS
962 // info to lookup a target and create register info.
963 Triple TT = Obj.makeTriple();
964
965 // Features to be passed to target/subtarget
967 SubtargetFeatures FeaturesValue;
968 if (!Features) {
969 consumeError(Features.takeError());
970 FeaturesValue = SubtargetFeatures();
971 }
972 FeaturesValue = *Features;
973
974 StringRef CPU;
975 if (auto OptCPU = Obj.tryGetCPUName())
976 CPU = *OptCPU;
977
978 return loadGenericTargetInfo(TT.str(), FeaturesValue.getString(), CPU);
979}
980
981void LVDWARFReader::mapRangeAddress(const ObjectFile &Obj) {
982 for (auto Iter = Obj.symbol_begin(); Iter != Obj.symbol_end(); ++Iter) {
983 const SymbolRef &Symbol = *Iter;
984
985 Expected<SymbolRef::Type> TypeOrErr = Symbol.getType();
986 if (!TypeOrErr) {
987 consumeError(TypeOrErr.takeError());
988 continue;
989 }
990
991 // Process only symbols that represent a function.
992 SymbolRef::Type Type = *TypeOrErr;
994 continue;
995
996 // In the case of a Mach-O STAB symbol, get its section only if
997 // the STAB symbol's section field refers to a valid section index.
998 // Otherwise the symbol may error trying to load a section that
999 // does not exist.
1000 const MachOObjectFile *MachO = dyn_cast<const MachOObjectFile>(&Obj);
1001 bool IsSTAB = false;
1002 if (MachO) {
1003 DataRefImpl SymDRI = Symbol.getRawDataRefImpl();
1004 uint8_t NType =
1005 (MachO->is64Bit() ? MachO->getSymbol64TableEntry(SymDRI).n_type
1006 : MachO->getSymbolTableEntry(SymDRI).n_type);
1007 if (NType & MachO::N_STAB)
1008 IsSTAB = true;
1009 }
1010
1011 Expected<section_iterator> IterOrErr = Symbol.getSection();
1012 if (!IterOrErr) {
1013 consumeError(IterOrErr.takeError());
1014 continue;
1015 }
1016 section_iterator Section = IsSTAB ? Obj.section_end() : *IterOrErr;
1017 if (Section == Obj.section_end())
1018 continue;
1019
1020 // Get the symbol value.
1021 Expected<uint64_t> AddressOrErr = Symbol.getAddress();
1022 if (!AddressOrErr) {
1023 consumeError(AddressOrErr.takeError());
1024 continue;
1025 }
1026 uint64_t Address = *AddressOrErr;
1027
1028 // Get symbol name.
1030 Expected<StringRef> NameOrErr = Symbol.getName();
1031 if (!NameOrErr) {
1032 consumeError(NameOrErr.takeError());
1033 continue;
1034 }
1035 Name = *NameOrErr;
1036
1037 // Check if the symbol is Comdat.
1038 Expected<uint32_t> FlagsOrErr = Symbol.getFlags();
1039 if (!FlagsOrErr) {
1040 consumeError(FlagsOrErr.takeError());
1041 continue;
1042 }
1043 uint32_t Flags = *FlagsOrErr;
1044
1045 // Mark the symbol as 'comdat' in any of the following cases:
1046 // - Symbol has the SF_Weak flag or
1047 // - Symbol section index different from the DotTextSectionIndex.
1048 LVSectionIndex SectionIndex = Section->getIndex();
1049 bool IsComdat =
1050 (Flags & SymbolRef::SF_Weak) || (SectionIndex != DotTextSectionIndex);
1051
1052 // Record the symbol name (linkage) and its loading address.
1053 addToSymbolTable(Name, Address, SectionIndex, IsComdat);
1054 }
1055}
1056
1058
1060 OS << "LVType\n";
1061 LLVM_DEBUG(dbgs() << "CreateReaders\n");
1062}
BlockVerifier::State From
#define RegName(no)
mir Rename Register Operands
raw_pwrite_stream & OS
#define LLVM_DEBUG(...)
Definition: Debug.h:119
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:147
const T * data() const
Definition: ArrayRef.h:144
A structured debug information entry.
Definition: DIE.h:828
unsigned getOffset() const
Get the compile/type unit relative offset of this DIE.
Definition: DIE.h:866
dwarf::Tag getTag() const
Definition: DIE.h:864
DWARFContext This data structure is the top level entity that deals with dwarf debug information pars...
Definition: DWARFContext.h:49
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 DWARFDataExtractor (typically for an in-memory copy of an object-file section) plus a relocation ma...
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:250
DWARFUnit * getDwarfUnit() const
Definition: DWARFDie.h:55
LLVM_ABI DWARFDie getSibling() const
Get the sibling of this DIE object.
Definition: DWARFDie.cpp:661
const DWARFAbbreviationDeclaration * getAbbreviationDeclarationPtr() const
Get the abbreviation declaration for this DIE.
Definition: DWARFDie.h:60
bool isValid() const
Definition: DWARFDie.h:52
This class represents an Operation in the Expression.
ArrayRef< uint64_t > getRawOperands() const
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
Definition: DWARFUnit.cpp:209
uint64_t getOffset() const
Definition: DWARFUnit.h:325
bool isDWOUnit() const
Definition: DWARFUnit.h:322
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.
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:414
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:233
Manages the enabling and disabling of subtarget specific features.
LLVM_ABI 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:47
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: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
virtual void setReference(LVElement *Element)
Definition: LVElement.h:231
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 setType(LVElement *Element=nullptr)
Definition: LVElement.h:315
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
virtual size_t getLinkageNameIndex() const
Definition: LVElement.h:238
void setOffset(LVOffset DieOffset)
Definition: LVObject.h:240
void setLineNumber(uint32_t Number)
Definition: LVObject.h:274
void setTag(dwarf::Tag Tag)
Definition: LVObject.h:232
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 FileFormatName
Definition: LVReader.h:146
std::string createAlternativePath(StringRef From)
Definition: LVReader.h:181
LVElement * CurrentElement
Definition: LVReader.h:134
LVElement * createElement(dwarf::Tag Tag)
Definition: LVReader.cpp:219
StringRef getFilename() const
Definition: LVReader.h:263
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:116
void addObject(LVLocation *Location)
Definition: LVScope.cpp:155
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:231
virtual section_iterator section_end() const =0
virtual Expected< SubtargetFeatures > getFeatures() const =0
Triple makeTriple() const
Create a triple from the data in this object file.
Definition: ObjectFile.cpp:110
virtual std::optional< StringRef > tryGetCPUName() const
Definition: ObjectFile.h:345
This is a value type class that represents a single symbol in the list of symbols in the object file.
Definition: ObjectFile.h:170
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:53
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:662
std::string & str()
Returns the string's reference.
Definition: raw_ostream.h:680
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ Entry
Definition: COFF.h:862
@ N_STAB
Definition: MachO.h:307
Attribute
Attributes.
Definition: Dwarf.h:124
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
SourceLanguage
Definition: Dwarf.h:214
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:1222
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
constexpr unsigned int DWARF_CHAR_BIT
Definition: LVElement.h:73
LLVM_ABI std::string transformPath(StringRef Path)
Definition: LVSupport.cpp:31
constexpr bool UpdateHighAddress
std::pair< LVAddress, LVAddress > LVAddressRange
Definition: LVRange.h:24
LVOptions & options()
Definition: LVOptions.h:448
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:1305
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:126
const char * toString(DWARFSectionKind Kind)
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
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:215
static LLVM_ABI bool mayHaveLocationList(dwarf::Attribute Attr)
Identify DWARF attributes that may contain a pointer to a location list.
Definition: DWARFDie.cpp:737
static LLVM_ABI bool mayHaveLocationExpr(dwarf::Attribute Attr)
Identifies DWARF attributes that may contain a reference to a DWARF expression.
Definition: DWARFDie.cpp:754
Standard .debug_line state machine structure.
A single location within a location list.
Definition: DWARFDebugLoc.h:31
Represents a single DWARF expression, whose value is location-dependent.
uint8_t n_type
Definition: MachO.h:1011
A source language supported by any of the debug info representations.
static const uint64_t UndefSection
Definition: ObjectFile.h:148