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