26 :
InUnit.getOrigUnit().getNextUnitOffset();
36 InUnit.getContainingFile().Addresses->applyValidRelocs(DIECopy,
Offset,
37 Data.isLittleEndian());
43 const auto *Abbrev =
InputDieEntry->getAbbreviationDeclarationPtr();
48 for (
const auto &AttrSpec : Abbrev->attributes()) {
61 switch (AttrSpec.Form) {
62 case dwarf::DW_FORM_strp:
63 case dwarf::DW_FORM_line_strp:
64 case dwarf::DW_FORM_string:
65 case dwarf::DW_FORM_strx:
66 case dwarf::DW_FORM_strx1:
67 case dwarf::DW_FORM_strx2:
68 case dwarf::DW_FORM_strx3:
69 case dwarf::DW_FORM_strx4:
72 case dwarf::DW_FORM_ref_addr:
73 case dwarf::DW_FORM_ref1:
74 case dwarf::DW_FORM_ref2:
75 case dwarf::DW_FORM_ref4:
76 case dwarf::DW_FORM_ref8:
77 case dwarf::DW_FORM_ref_udata:
80 case dwarf::DW_FORM_data1:
81 case dwarf::DW_FORM_data2:
82 case dwarf::DW_FORM_data4:
83 case dwarf::DW_FORM_data8:
84 case dwarf::DW_FORM_udata:
85 case dwarf::DW_FORM_sdata:
86 case dwarf::DW_FORM_sec_offset:
87 case dwarf::DW_FORM_flag:
88 case dwarf::DW_FORM_flag_present:
89 case dwarf::DW_FORM_rnglistx:
90 case dwarf::DW_FORM_loclistx:
91 case dwarf::DW_FORM_implicit_const:
94 case dwarf::DW_FORM_block:
95 case dwarf::DW_FORM_block1:
96 case dwarf::DW_FORM_block2:
97 case dwarf::DW_FORM_block4:
98 case dwarf::DW_FORM_exprloc:
101 case dwarf::DW_FORM_addr:
102 case dwarf::DW_FORM_addrx:
103 case dwarf::DW_FORM_addrx1:
104 case dwarf::DW_FORM_addrx2:
105 case dwarf::DW_FORM_addrx3:
106 case dwarf::DW_FORM_addrx4:
110 InUnit.warn(
"unsupported attribute form " +
112 " in DieAttributeCloner::clone(). Dropping.",
124 &
OutUnit->getOrCreateSectionDescriptor(
131 .addScalarAttribute(dwarf::DW_AT_str_offsets_base,
132 dwarf::DW_FORM_sec_offset,
133 OutUnit->getDebugStrOffsetsHeaderSize())
141 !
InUnit.getGlobalData().getOptions().UpdateIndexTablesOnly) {
150 .addScalarAttribute(dwarf::DW_AT_addr_base,
151 dwarf::DW_FORM_sec_offset,
152 OutUnit->getDebugAddrHeaderSize())
159 switch (AttrSpec.
Attr) {
162 case dwarf::DW_AT_low_pc:
163 case dwarf::DW_AT_high_pc:
164 case dwarf::DW_AT_ranges:
165 if (
InUnit.getGlobalData().getOptions().UpdateIndexTablesOnly)
172 case dwarf::DW_AT_rnglists_base:
177 return !
InUnit.getGlobalData().getOptions().UpdateIndexTablesOnly;
178 case dwarf::DW_AT_loclists_base:
183 return !
InUnit.getGlobalData().getOptions().UpdateIndexTablesOnly;
184 case dwarf::DW_AT_location:
185 case dwarf::DW_AT_frame_base:
186 if (
InUnit.getGlobalData().getOptions().UpdateIndexTablesOnly)
206 InUnit.warn(
"cann't read string attribute.");
211 InUnit.getGlobalData().getStringPool().insert(*String).first;
214 if (AttrSpec.
Attr == dwarf::DW_AT_name)
216 else if (AttrSpec.
Attr == dwarf::DW_AT_MIPS_linkage_name ||
217 AttrSpec.
Attr == dwarf::DW_AT_linkage_name)
218 AttrInfo.MangledName = StringInPool;
220 if (AttrSpec.
Form == dwarf::DW_FORM_line_strp) {
230 .addStringPlaceholderAttribute(AttrSpec.
Attr, dwarf::DW_FORM_line_strp)
245 .addStringPlaceholderAttribute(AttrSpec.
Attr, dwarf::DW_FORM_strp)
250 .addIndexedStringAttribute(AttrSpec.
Attr, dwarf::DW_FORM_strx,
251 OutUnit->getDebugStrIndex(StringInPool))
258 if (AttrSpec.
Attr == dwarf::DW_AT_sibling)
261 std::optional<UnitEntryPairTy> RefDiePair =
263 if (!RefDiePair || !RefDiePair->DieEntry) {
271 RefDiePair->CU->getDIEInfo(RefDiePair->DieEntry);
273 RefTypeName = RefDiePair->CU->getDieTypeEntry(RefDiePair->DieEntry);
281 if (RefDiePair->DieEntry->getTag() == dwarf::DW_TAG_module &&
282 AttrSpec.
Attr == dwarf::DW_AT_import && !
OutUnit.isTypeUnit() &&
285 if (RefDiePair->CU->getModulePath(RefDiePair->DieEntry, Path)) {
287 InUnit.getGlobalData().getModulePool().getOrCreate(Path);
292 RefDiePair->CU->getDIEIndex(RefDiePair->DieEntry), Anchor},
295 .addScalarAttribute(AttrSpec.
Attr, dwarf::DW_FORM_ref_addr, 0xBADDEF)
301 assert(RefTypeName &&
"Type name for referenced DIE is not set");
303 "Type name for DIE is not set");
310 .addScalarAttribute(AttrSpec.
Attr, dwarf::DW_FORM_ref4, 0xBADDEF)
319 .addScalarAttribute(AttrSpec.
Attr, dwarf::DW_FORM_ref_addr, 0xBADDEF)
324 uint64_t OutDieOffset = RefDiePair->CU->getDieOutOffset(RefDiePair->DieEntry);
327 bool IsLocal =
OutUnit->getUniqueID() == RefDiePair->CU->getUniqueID();
330 dwarf::Form NewForm = IsLocal ? dwarf::DW_FORM_ref4 : dwarf::DW_FORM_ref_addr;
334 if (IsLocal && (OutDieOffset != 0))
335 return Generator.addScalarAttribute(AttrSpec.
Attr, NewForm, OutDieOffset)
343 RefDiePair->CU->getDIEIndex(RefDiePair->DieEntry)},
345 return Generator.addScalarAttribute(AttrSpec.
Attr, NewForm, 0xBADDEF).second;
355 switch (AttrSpec.
Attr) {
356 case dwarf::DW_AT_macro_info: {
359 InUnit.getContainingFile().Dwarf->getDebugMacinfo();
365 &
OutUnit->getOrCreateSectionDescriptor(
370 case dwarf::DW_AT_macros: {
373 InUnit.getContainingFile().Dwarf->getDebugMacro();
379 &
OutUnit->getOrCreateSectionDescriptor(
384 case dwarf::DW_AT_stmt_list: {
390 case dwarf::DW_AT_str_offsets_base: {
393 &
OutUnit->getOrCreateSectionDescriptor(
400 AttrInfo.HasStringOffsetBaseAttr =
true;
402 .addScalarAttribute(AttrSpec.
Attr, AttrSpec.
Form,
403 OutUnit->getDebugStrOffsetsHeaderSize())
406 case dwarf::DW_AT_decl_file: {
413 if (std::optional<std::pair<StringRef, StringRef>> DirAndFilename =
414 InUnit.getDirAndFilenameFromLineTable(Val))
420 .insert(DirAndFilename->first)
424 .insert(DirAndFilename->second)
435 if (AttrSpec.
Attr == dwarf::DW_AT_const_value &&
440 if (
InUnit.getGlobalData().getOptions().UpdateIndexTablesOnly) {
442 Value = *OptionalValue;
444 Value = *OptionalValue;
446 Value = *OptionalValue;
448 InUnit.warn(
"unsupported scalar attribute form. Dropping attribute.",
453 if (AttrSpec.
Attr == dwarf::DW_AT_declaration &&
Value)
456 if (AttrSpec.
Form == dwarf::DW_FORM_loclistx)
465 if (AttrSpec.
Form == dwarf::DW_FORM_rnglistx) {
474 std::optional<uint64_t>
Offset =
475 InUnit.getOrigUnit().getRnglistOffset(*Index);
482 ResultingForm = dwarf::DW_FORM_sec_offset;
483 }
else if (AttrSpec.
Form == dwarf::DW_FORM_loclistx) {
492 std::optional<uint64_t>
Offset =
493 InUnit.getOrigUnit().getLoclistOffset(*Index);
500 ResultingForm = dwarf::DW_FORM_sec_offset;
501 }
else if (AttrSpec.
Attr == dwarf::DW_AT_high_pc &&
506 std::optional<uint64_t> LowPC =
OutUnit.getAsCompileUnit()->getLowPc();
510 Value =
OutUnit.getAsCompileUnit()->getHighPc() - *LowPC;
511 }
else if (AttrSpec.
Form == dwarf::DW_FORM_sec_offset)
513 else if (AttrSpec.
Form == dwarf::DW_FORM_sdata)
516 Value = *OptionalValue;
518 InUnit.warn(
"unsupported scalar attribute form. Dropping attribute.",
523 if (AttrSpec.
Attr == dwarf::DW_AT_ranges ||
524 AttrSpec.
Attr == dwarf::DW_AT_start_scope) {
534 InUnit.getOrigUnit().getVersion())) {
535 int64_t AddrAdjustmentValue = 0;
544 }
else if (AttrSpec.
Attr == dwarf::DW_AT_addr_base) {
556 .addScalarAttribute(AttrSpec.
Attr, AttrSpec.
Form,
557 OutUnit->getDebugAddrHeaderSize())
559 }
else if (AttrSpec.
Attr == dwarf::DW_AT_declaration &&
Value)
569 if (AttrSpec.
Attr == dwarf::DW_AT_LLVM_stmt_sequence &&
575 if (AttrSpec.
Attr == dwarf::DW_AT_high_pc &&
586 if (AttrSpec.
Attr == dwarf::DW_AT_LLVM_stmt_sequence) {
592 OutUnit.getAsCompileUnit()->noteStmtSeqListAttribute(&Result.first,
Value);
600 return Result.second;
607 switch (
Op.getCode()) {
608 case dwarf::DW_OP_addr:
609 case dwarf::DW_OP_addrx:
610 case dwarf::DW_OP_constx:
638 InUnit.getFormParams().Format);
654 if ((ResultForm == dwarf::DW_FORM_block1 && Bytes.
size() > UINT8_MAX) ||
655 (ResultForm == dwarf::DW_FORM_block2 && Bytes.
size() > UINT16_MAX) ||
656 (ResultForm == dwarf::DW_FORM_block4 && Bytes.
size() > UINT32_MAX))
657 ResultForm = dwarf::DW_FORM_block;
659 size_t FinalAttributeSize;
660 if (AttrSpec.
Form == dwarf::DW_FORM_exprloc)
662 Generator.addLocationAttribute(AttrSpec.
Attr, ResultForm, Bytes).second;
665 Generator.addBlockAttribute(AttrSpec.
Attr, ResultForm, Bytes).second;
668 for (
size_t Idx = NumberOfPatchesAtStart; Idx <
PatchesOffsets.size();
678 InUnit.getGlobalData().getOptions().UpdateIndexTablesOnly;
680 return FinalAttributeSize;
686 if (AttrSpec.
Attr == dwarf::DW_AT_low_pc)
689 if (
InUnit.getGlobalData().getOptions().UpdateIndexTablesOnly)
709 std::optional<DWARFFormValue> AddrAttribute =
714 std::optional<uint64_t> Addr = AddrAttribute->getAsAddress();
716 InUnit.warn(
"cann't read address attribute value.");
721 AttrSpec.
Attr == dwarf::DW_AT_low_pc) {
722 if (std::optional<uint64_t> LowPC =
OutUnit.getAsCompileUnit()->getLowPc())
726 }
else if (
InputDieEntry->getTag() == dwarf::DW_TAG_compile_unit &&
727 AttrSpec.
Attr == dwarf::DW_AT_high_pc) {
728 if (uint64_t HighPc =
OutUnit.getAsCompileUnit()->getHighPc())
733 if (AttrSpec.
Attr == dwarf::DW_AT_high_pc)
741 if (AttrSpec.
Form == dwarf::DW_FORM_addr) {
747 .addScalarAttribute(AttrSpec.
Attr, dwarf::Form::DW_FORM_addrx,
748 OutUnit.getAsCompileUnit()->getDebugAddrIndex(*Addr))
755 std::optional<uint64_t> LowPC =
759 uint64_t Constrained =
760 InUnit.getContainingFile().Addresses->constrainCodeRangeHighPC(
762 return IsLength ? Constrained - *LowPC : Constrained;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool expressionDependsOnOriginUnit(const DWARFExpression &Expr)
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
This class represents an Operation in the Expression.
Encoding
Size and signedness of expression operations' operands.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
LLVM Value Representation.
size_t cloneBlockAttr(const DWARFFormValue &Val, const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec)
Clone block or exprloc attribute.
AttributesInfo AttrInfo
Cannot be used concurrently.
CompileUnit & InUnit
Input compilation unit.
bool HasLocationExpressionAddress
Indicates whether InputDieEntry has an location attribute containg address expression.
SectionDescriptor & DebugInfoOutputSection
.debug_info section descriptor.
unsigned finalizeAbbreviations(bool HasChildrenToClone)
Create abbreviations for the output DIE after all attributes are cloned.
unsigned AttrOutOffset
Output offset after all attributes.
DIEGenerator & Generator
Output DIE generator.
size_t cloneScalarAttr(const DWARFFormValue &Val, const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec)
Clone scalar attribute.
OffsetsPtrVector PatchesOffsets
Patches for the cloned attributes.
void clone()
Clone attributes of input DIE.
size_t cloneDieRefAttr(const DWARFFormValue &Val, const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec)
Clone attribute referencing another DIE.
bool shouldSkipAttribute(DWARFAbbreviationDeclaration::AttributeSpec AttrSpec)
Returns true if attribute should be skipped.
size_t cloneStringAttr(const DWARFFormValue &Val, const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec)
Clone string attribute.
const DWARFDebugInfoEntry * InputDieEntry
Input DIE entry.
std::optional< int64_t > FuncAddressAdjustment
Relocation adjustment for the function address ranges.
CompileUnit::OutputUnitVariantPtr OutUnit
Output unit(either "plain" compilation unit, either artificial type unit).
size_t cloneAddressAttr(const DWARFFormValue &Val, const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec)
Clone address attribute.
uint32_t InputDIEIdx
Input DIE index.
std::optional< int64_t > VarAddressAdjustment
Relocation adjustment for the variable locations.
uint64_t constrainHighPC(uint64_t HighPC, bool IsLength)
Returns the input DIE's DW_AT_high_pc value HighPC, constrained so the code range it ends stays clear...
bool Use_DW_FORM_strp
This flag forces using DW_FORM_strp for string attributes.
LLVM_ABI StringRef FormEncodingString(unsigned Encoding)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
StringMapEntry< std::atomic< TypeEntryBody * > > TypeEntry
StringMapEntry< EmptyStringSetTag > StringEntry
StringEntry keeps data of the string: the length, external offset and a string body which is placed r...
std::optional< uint64_t > toAddress(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an address.
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
LLVM_ABI bool doesFormBelongToClass(dwarf::Form Form, DWARFFormValue::FormClass FC, uint16_t DwarfVersion)
Check whether specified Form belongs to the FC class.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI unsigned getULEB128Size(uint64_t Value)
Utility function to get the size of the ULEB128-encoded value.
DWARFExpression::Operation Op
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
static LLVM_ABI bool mayHaveLocationList(dwarf::Attribute Attr)
Identify DWARF attributes that may contain a pointer to a location list.
static LLVM_ABI bool mayHaveLocationExpr(dwarf::Attribute Attr)
Identifies DWARF attributes that may contain a reference to a DWARF expression.
Information gathered about source DIEs.
bool needToPlaceInTypeTable() const
This structure is used to update a DW_AT_import reference to a DW_TAG_module.
This structure is used to update reference to the DIE.
This structure is used to update reference to the type DIE.
This structure is used to update strings offsets into .debug_line_str.
This structure is used to update location list offset into .debug_loc/.debug_loclists.
This structure is used to update range list offset into .debug_ranges/.debug_rnglists.
This structure is used to update strings offsets into .debug_str.
This structure is used to update reference to the type DIE.
Where the DW_TAG_module DIE describing a clang module ended up in the output.