1//===-- LVDWARFReader.cpp -------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This implements the LVDWARFReader class.
10// It supports ELF, Mach-O and Wasm binary formats.
11//
12//===----------------------------------------------------------------------===//
13
14#include "llvm/DebugInfo/LogicalView/Readers/LVDWARFReader.h"
15#include "llvm/DebugInfo/DIContext.h"
16#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
17#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
18#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
19#include "llvm/DebugInfo/LogicalView/Core/LVLine.h"
20#include "llvm/DebugInfo/LogicalView/Core/LVScope.h"
21#include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h"
22#include "llvm/DebugInfo/LogicalView/Core/LVType.h"
23#include "llvm/Object/MachO.h"
24#include "llvm/Support/FormatVariadic.h"
25
26using namespace llvm;
27using namespace llvm::object;
28using namespace llvm::logicalview;
29
30#define DEBUG_TYPE "DWARFReader"
31
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(F: AttrSpec.Form, Unit: 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(FC: 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
82 LLVM_DEBUG({
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(V: FormValue));
110 break;
111 case dwarf::DW_AT_const_value:
112 if (FormValue.isFormClass(FC: DWARFFormValue::FC_Block)) {
113 ArrayRef<uint8_t> Expr = *FormValue.getAsBlock();
114 // Store the expression as a hexadecimal string.
115 CurrentElement->setValue(
116 llvm::toHex(Input: llvm::toStringRef(Input: Expr), /*LowerCase=*/true));
117 } else if (FormValue.isFormClass(FC: 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(i: Value);
126 }
127 Stream << hexString(Value, Width: 2);
128 CurrentElement->setValue(Stream.str());
129 } else
130 CurrentElement->setValue(hexString(Value: GetAsUnsignedConstant(), Width: 2));
131 } else
132 CurrentElement->setValue(dwarf::toStringRef(V: FormValue));
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:
163 CurrentElement->setName(dwarf::toStringRef(V: FormValue));
164 break;
165 case dwarf::DW_AT_GNU_template_name:
166 CurrentElement->setValue(dwarf::toStringRef(V: FormValue));
167 break;
168 case dwarf::DW_AT_linkage_name:
169 case dwarf::DW_AT_MIPS_linkage_name:
170 CurrentElement->setLinkageName(dwarf::toStringRef(V: FormValue));
171 break;
172 case dwarf::DW_AT_producer:
173 if (options().getAttributeProducer())
174 CurrentElement->setProducer(dwarf::toStringRef(V: FormValue));
175 break;
176 case dwarf::DW_AT_language:
177 if (options().getAttributeLanguage())
178 CurrentElement->setSourceLanguage(LVSourceLanguage{
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(Attr: 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(Index: 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;
223 if (CurrentElement->isCompileUnit())
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;
248 if (CurrentElement->isCompileUnit())
249 setCUHighAddress(CurrentHighPC);
250 }
251 break;
252
253 case dwarf::DW_AT_ranges:
254 if (RangesDataAvailable && options().getGeneralCollectRanges()) {
255 auto GetRanges = [](const DWARFFormValue &FormValue,
256 DWARFUnit *U) -> Expected<DWARFAddressRangesVector> {
257 if (FormValue.getForm() == dwarf::DW_FORM_rnglistx)
258 return U->findRnglistFromIndex(Index: *FormValue.getAsSectionOffset());
259 return U->findRnglistFromOffset(Offset: *FormValue.getAsSectionOffset());
260 };
261 Expected<DWARFAddressRangesVector> RangesOrError =
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(Err: RangesOrError.takeError());
270 break;
271 }
272 // The address ranges are absolute. There is no need to add any addend.
273 DWARFAddressRangesVector Ranges = RangesOrError.get();
274 for (DWARFAddressRange &Range : Ranges) {
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.
283 Range.LowPC += WasmCodeSectionOffset;
284 Range.HighPC += WasmCodeSectionOffset;
285 // Add the pair of addresses.
286 CurrentScope->addObject(LowerAddress: Range.LowPC, UpperAddress: Range.HighPC);
287 // If the scope is the CU, do not update the ranges set.
288 if (!CurrentElement->isCompileUnit())
289 CurrentRanges.emplace_back(args&: Range.LowPC, args&: 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(Attr: 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(Attr: 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(Attr: 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();
331 LVOffset Offset = DIE.getOffset();
332
333 // Reset values for the current DIE.
334 CurrentLowPC = 0;
335 CurrentHighPC = 0;
336 CurrentOffset = Offset;
337 CurrentEndOffset = 0;
338 FoundLowPC = false;
339 FoundHighPC = false;
340
341 // Process supported attributes.
342 if (DebugInfoData.isValidOffset(offset: 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();
351 CurrentElement = createElement(Tag);
352 if (!CurrentElement)
353 return CurrentScope;
354
355 CurrentElement->setTag(Tag);
356 CurrentElement->setOffset(Offset);
357
358 if (options().getAttributeAnySource() && CurrentElement->isCompileUnit())
359 addCompileUnitOffset(Offset,
360 CompileUnit: 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(k: Offset, args&: 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(Scope: CurrentScope);
385 else if (CurrentSymbol)
386 Parent->addElement(Symbol: CurrentSymbol);
387 else if (CurrentType)
388 Parent->addElement(Type: 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(offset_ptr: &CurrentEndOffset);
395 if (abbrCode) {
396 if (const DWARFAbbreviationDeclaration *AbbrevDecl =
397 TheDIE.getAbbreviationDeclarationPtr())
398 for (const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec :
399 AbbrevDecl->attributes())
400 processOneAttribute(Die: TheDIE, OffsetPtr: &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 =
410 InputDIE.getDwarfUnit()->getDebugInfoExtractor();
411 LVOffset Offset = InputDIE.getOffset();
412 if (DebugInfoData.isValidOffset(offset: 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(LowerAddress: CurrentLowPC, UpperAddress: 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(Scope: CurrentScope, LowPC: CurrentLowPC,
431 HighPC: 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(Attrs: dwarf::DW_AT_linkage_name);
444 if (LinkageDIE.has_value()) {
445 StringRef Name(dwarf::toStringRef(V: 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.
454 LVSectionIndex SectionIndex = updateSymbolTable(Function: CurrentScope);
455 if (CurrentScope->getIsComdat())
456 CompileUnit->setHasComdatScopes();
457
458 // Update section index contained ranges.
459 if (SectionIndex) {
460 if (!CurrentRanges.empty()) {
461 for (LVAddressRange &Range : CurrentRanges)
462 addSectionRange(SectionIndex, Scope: CurrentScope, LowerAddress: Range.first,
463 UpperAddress: 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, Scope: CurrentScope, LowerAddress: CurrentLowPC,
471 UpperAddress: 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(Elt: 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(InputDIE: 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(DIE&: Child, Parent: Scope, SkeletonDie&: 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(Path: Directory);
533 if (Directory.empty())
534 Directory = std::string(CompileUnit->getCompilationDirectory());
535 std::string File = transformPath(Path: dwarf::toStringRef(V: Entry.Name));
536 std::string String;
537 raw_string_ostream(String) << Directory << "/" << File;
538 CompileUnit->addFilename(Name: 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(Elt: Line);
553 // Consider the case of WebAssembly.
554 Line->setAddress(Row.Address.Address + WasmCodeSectionOffset);
555 Line->setFilename(
556 CompileUnit->getFilename(Index: 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
578std::string LVDWARFReader::getRegisterName(LVSmall Opcode,
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(RegNum: DwarfRegNum, isEH: IsEH))
596 if (const char *RegName = MCRegInfo->getName(RegNo: *LLVMRegNum))
597 return StringRef(RegName);
598 return {};
599 };
600 DumpOpts.GetNameForDWARFReg = GetRegName;
601 prettyPrintRegisterOp(/*U=*/nullptr, OS&: Stream, DumpOpts, Opcode, Operands);
602 return Stream.str();
603}
604
605Error LVDWARFReader::createScopes() {
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)
620 return createStringError(EC: errc::invalid_argument,
621 Fmt: "Could not create DWARF information: %s",
622 Vals: getFilename().str().c_str());
623
624 if (Error Err = loadTargetInfo(Obj))
625 return Err;
626
627 // Create a mapping for virtual addresses.
628 mapVirtualAddress(Obj);
629
630 // Select the correct compile unit range, depending if we are dealing with
631 // a standard or split DWARF object.
632 DWARFContext::compile_unit_range CompileUnits =
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.
639 setTombstoneAddress(
640 dwarf::computeTombstoneAddress(AddressByteSize: 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(U: CU.get())) {
700 // Check if there are at least 2 entries and if they are the same.
701 if (LT->hasFileAtIndex(FileIndex: 0) && LT->hasFileAtIndex(FileIndex: 1)) {
702 const DWARFDebugLine::FileNameEntry &EntryZero =
703 LT->Prologue.getFileNameEntry(Index: 0);
704 const DWARFDebugLine::FileNameEntry &EntryOne =
705 LT->Prologue.getFileNameEntry(Index: 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;
713 StringRef None;
714 LT->getFileNameByIndex(
715 FileIndex: 0, CompDir: None, Kind: DILineInfoSpecifier::FileLineInfoKind::RawValue,
716 Result&: FileZero);
717 LT->getFileNameByIndex(
718 FileIndex: 1, CompDir: None, Kind: DILineInfoSpecifier::FileLineInfoKind::RawValue,
719 Result&: 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(V: UnitDie.find(Attr: dwarf::DW_AT_dwo_name))
736 : dwarf::toString(V: UnitDie.find(Attr: dwarf::DW_AT_GNU_dwo_name));
737 StringRef From(DWOFileName.value_or(u: ""));
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(ExtractUnitDIEOnly: 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(DIE&: CUDie, Parent: Root, SkeletonDie);
764
765 createLineAndFileRecords(Lines: DwarfContext->getLineTableForUnit(U: 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.
772 LVSectionIndex SectionIndex = getSectionIndex(Scope: CompileUnit);
773 addSectionRange(SectionIndex, Scope: CompileUnit);
774 LVRange *ScopesWithRanges = getSectionRanges(SectionIndex);
775 ScopesWithRanges->sort();
776
777 processLines(DebugLines: &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) {
797 for (const DWARFExpression::Operation &Op : Expression)
798 CurrentSymbol->addLocationOperands(Opcode: Op.getCode(), Operands: Op.getRawOperands());
799 };
800
801 DWARFUnit *U = Die.getDwarfUnit();
802 DWARFContext &DwarfContext = U->getContext();
803 bool IsLittleEndian = DwarfContext.isLittleEndian();
804 if (FormValue.isFormClass(FC: DWARFFormValue::FC_Block) ||
805 (DWARFAttribute::mayHaveLocationExpr(Attr) &&
806 FormValue.isFormClass(FC: DWARFFormValue::FC_Exprloc))) {
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, LocDescOffset: OffsetOnEntry,
816 CallSiteLocation);
817 ProcessLocationExpression(Expression);
818 return;
819 }
820
821 if (DWARFAttribute::mayHaveLocationList(Attr) &&
822 FormValue.isFormClass(FC: DWARFFormValue::FC_SectionOffset)) {
823 uint64_t Offset = *FormValue.getAsSectionOffset();
824 if (FormValue.getForm() == dwarf::DW_FORM_loclistx) {
825 std::optional<uint64_t> LoclistOffset = U->getLoclistOffset(Index: 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: Range, .Expr: 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, SectionOffset: Offset, LocDescOffset: OffsetOnEntry,
857 CallSiteLocation);
858 ProcessLocationExpression(Expression);
859 }
860 };
861 Error E = U->getLocationTable().visitLocationList(
862 Offset: &Offset, Callback: [&](const DWARFLocationEntry &E) {
863 ProcessLocationEntry(E);
864 return true;
865 });
866 if (E)
867 consumeError(Err: 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.
876 if (FormValue.isFormClass(FC: DWARFFormValue::FC_Constant))
877 // Add a record to hold a constant as location.
878 CurrentSymbol->addLocationConstant(Attr, Constant: *FormValue.getAsUnsignedConstant(),
879 LocDescOffset: 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(
901 offset: Offset, Element: CurrentElement,
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(x: Element);
953 else
954 Entry.References.insert(x: 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(Err: 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(TheTriple: TT.str(), TheFeatures: FeaturesValue.getString(), TheCPU: 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(Err: TypeOrErr.takeError());
987 continue;
988 }
989
990 // Process only symbols that represent a function.
991 SymbolRef::Type Type = *TypeOrErr;
992 if (Type != SymbolRef::ST_Function)
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>(Val: &Obj);
1000 bool IsSTAB = false;
1001 if (MachO) {
1002 DataRefImpl SymDRI = Symbol.getRawDataRefImpl();
1003 uint8_t NType =
1004 (MachO->is64Bit() ? MachO->getSymbol64TableEntry(DRI: SymDRI).n_type
1005 : MachO->getSymbolTableEntry(DRI: 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(Err: 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(Err: 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(Err: 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(Err: 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
1056void LVDWARFReader::sortScopes() { Root->sort(); }
1057
1058void LVDWARFReader::print(raw_ostream &OS) const {
1059 OS << "LVType\n";
1060 LLVM_DEBUG(dbgs() << "CreateReaders\n");
1061}
1062