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())
140 switch (AttrSpec.
Attr) {
143 case dwarf::DW_AT_low_pc:
144 case dwarf::DW_AT_high_pc:
145 case dwarf::DW_AT_ranges:
146 if (
InUnit.getGlobalData().getOptions().UpdateIndexTablesOnly)
153 case dwarf::DW_AT_rnglists_base:
158 return !
InUnit.getGlobalData().getOptions().UpdateIndexTablesOnly;
159 case dwarf::DW_AT_loclists_base:
164 return !
InUnit.getGlobalData().getOptions().UpdateIndexTablesOnly;
165 case dwarf::DW_AT_location:
166 case dwarf::DW_AT_frame_base:
167 if (
InUnit.getGlobalData().getOptions().UpdateIndexTablesOnly)
187 InUnit.warn(
"cann't read string attribute.");
192 InUnit.getGlobalData().getStringPool().insert(*String).first;
195 if (AttrSpec.
Attr == dwarf::DW_AT_name)
197 else if (AttrSpec.
Attr == dwarf::DW_AT_MIPS_linkage_name ||
198 AttrSpec.
Attr == dwarf::DW_AT_linkage_name)
199 AttrInfo.MangledName = StringInPool;
201 if (AttrSpec.
Form == dwarf::DW_FORM_line_strp) {
211 .addStringPlaceholderAttribute(AttrSpec.
Attr, dwarf::DW_FORM_line_strp)
226 .addStringPlaceholderAttribute(AttrSpec.
Attr, dwarf::DW_FORM_strp)
231 .addIndexedStringAttribute(AttrSpec.
Attr, dwarf::DW_FORM_strx,
232 OutUnit->getDebugStrIndex(StringInPool))
239 if (AttrSpec.
Attr == dwarf::DW_AT_sibling)
242 std::optional<UnitEntryPairTy> RefDiePair =
244 if (!RefDiePair || !RefDiePair->DieEntry) {
252 RefDiePair->CU->getDIEInfo(RefDiePair->DieEntry);
254 RefTypeName = RefDiePair->CU->getDieTypeEntry(RefDiePair->DieEntry);
262 if (RefDiePair->DieEntry->getTag() == dwarf::DW_TAG_module &&
263 AttrSpec.
Attr == dwarf::DW_AT_import && !
OutUnit.isTypeUnit() &&
266 if (RefDiePair->CU->getModulePath(RefDiePair->DieEntry, Path)) {
268 InUnit.getGlobalData().getModulePool().getOrCreate(Path);
273 RefDiePair->CU->getDIEIndex(RefDiePair->DieEntry), Anchor},
276 .addScalarAttribute(AttrSpec.
Attr, dwarf::DW_FORM_ref_addr, 0xBADDEF)
282 assert(RefTypeName &&
"Type name for referenced DIE is not set");
284 "Type name for DIE is not set");
291 .addScalarAttribute(AttrSpec.
Attr, dwarf::DW_FORM_ref4, 0xBADDEF)
300 .addScalarAttribute(AttrSpec.
Attr, dwarf::DW_FORM_ref_addr, 0xBADDEF)
305 uint64_t OutDieOffset = RefDiePair->CU->getDieOutOffset(RefDiePair->DieEntry);
308 bool IsLocal =
OutUnit->getUniqueID() == RefDiePair->CU->getUniqueID();
311 dwarf::Form NewForm = IsLocal ? dwarf::DW_FORM_ref4 : dwarf::DW_FORM_ref_addr;
315 if (IsLocal && (OutDieOffset != 0))
316 return Generator.addScalarAttribute(AttrSpec.
Attr, NewForm, OutDieOffset)
324 RefDiePair->CU->getDIEIndex(RefDiePair->DieEntry)},
326 return Generator.addScalarAttribute(AttrSpec.
Attr, NewForm, 0xBADDEF).second;
336 switch (AttrSpec.
Attr) {
337 case dwarf::DW_AT_macro_info: {
340 InUnit.getContainingFile().Dwarf->getDebugMacinfo();
346 &
OutUnit->getOrCreateSectionDescriptor(
351 case dwarf::DW_AT_macros: {
354 InUnit.getContainingFile().Dwarf->getDebugMacro();
360 &
OutUnit->getOrCreateSectionDescriptor(
365 case dwarf::DW_AT_stmt_list: {
371 case dwarf::DW_AT_str_offsets_base: {
374 &
OutUnit->getOrCreateSectionDescriptor(
381 AttrInfo.HasStringOffsetBaseAttr =
true;
383 .addScalarAttribute(AttrSpec.
Attr, AttrSpec.
Form,
384 OutUnit->getDebugStrOffsetsHeaderSize())
387 case dwarf::DW_AT_decl_file: {
394 if (std::optional<std::pair<StringRef, StringRef>> DirAndFilename =
395 InUnit.getDirAndFilenameFromLineTable(Val))
401 .insert(DirAndFilename->first)
405 .insert(DirAndFilename->second)
416 if (AttrSpec.
Attr == dwarf::DW_AT_const_value &&
421 if (
InUnit.getGlobalData().getOptions().UpdateIndexTablesOnly) {
423 Value = *OptionalValue;
425 Value = *OptionalValue;
427 Value = *OptionalValue;
429 InUnit.warn(
"unsupported scalar attribute form. Dropping attribute.",
434 if (AttrSpec.
Attr == dwarf::DW_AT_declaration &&
Value)
437 if (AttrSpec.
Form == dwarf::DW_FORM_loclistx)
446 if (AttrSpec.
Form == dwarf::DW_FORM_rnglistx) {
455 std::optional<uint64_t>
Offset =
456 InUnit.getOrigUnit().getRnglistOffset(*Index);
463 ResultingForm = dwarf::DW_FORM_sec_offset;
464 }
else if (AttrSpec.
Form == dwarf::DW_FORM_loclistx) {
473 std::optional<uint64_t>
Offset =
474 InUnit.getOrigUnit().getLoclistOffset(*Index);
481 ResultingForm = dwarf::DW_FORM_sec_offset;
482 }
else if (AttrSpec.
Attr == dwarf::DW_AT_high_pc &&
487 std::optional<uint64_t> LowPC =
OutUnit.getAsCompileUnit()->getLowPc();
491 Value =
OutUnit.getAsCompileUnit()->getHighPc() - *LowPC;
492 }
else if (AttrSpec.
Form == dwarf::DW_FORM_sec_offset)
494 else if (AttrSpec.
Form == dwarf::DW_FORM_sdata)
497 Value = *OptionalValue;
499 InUnit.warn(
"unsupported scalar attribute form. Dropping attribute.",
504 if (AttrSpec.
Attr == dwarf::DW_AT_ranges ||
505 AttrSpec.
Attr == dwarf::DW_AT_start_scope) {
515 InUnit.getOrigUnit().getVersion())) {
516 int64_t AddrAdjustmentValue = 0;
525 }
else if (AttrSpec.
Attr == dwarf::DW_AT_addr_base) {
536 .addScalarAttribute(AttrSpec.
Attr, AttrSpec.
Form,
537 OutUnit->getDebugAddrHeaderSize())
539 }
else if (AttrSpec.
Attr == dwarf::DW_AT_declaration &&
Value)
549 if (AttrSpec.
Attr == dwarf::DW_AT_LLVM_stmt_sequence &&
555 if (AttrSpec.
Attr == dwarf::DW_AT_high_pc &&
566 if (AttrSpec.
Attr == dwarf::DW_AT_LLVM_stmt_sequence) {
572 OutUnit.getAsCompileUnit()->noteStmtSeqListAttribute(&Result.first,
Value);
580 return Result.second;
587 switch (
Op.getCode()) {
588 case dwarf::DW_OP_addr:
589 case dwarf::DW_OP_addrx:
590 case dwarf::DW_OP_constx:
618 InUnit.getFormParams().Format);
634 if ((ResultForm == dwarf::DW_FORM_block1 && Bytes.
size() > UINT8_MAX) ||
635 (ResultForm == dwarf::DW_FORM_block2 && Bytes.
size() > UINT16_MAX) ||
636 (ResultForm == dwarf::DW_FORM_block4 && Bytes.
size() > UINT32_MAX))
637 ResultForm = dwarf::DW_FORM_block;
639 size_t FinalAttributeSize;
640 if (AttrSpec.
Form == dwarf::DW_FORM_exprloc)
642 Generator.addLocationAttribute(AttrSpec.
Attr, ResultForm, Bytes).second;
645 Generator.addBlockAttribute(AttrSpec.
Attr, ResultForm, Bytes).second;
648 for (
size_t Idx = NumberOfPatchesAtStart; Idx <
PatchesOffsets.size();
658 InUnit.getGlobalData().getOptions().UpdateIndexTablesOnly;
660 return FinalAttributeSize;
666 if (AttrSpec.
Attr == dwarf::DW_AT_low_pc)
669 if (
InUnit.getGlobalData().getOptions().UpdateIndexTablesOnly)
689 std::optional<DWARFFormValue> AddrAttribute =
694 std::optional<uint64_t> Addr = AddrAttribute->getAsAddress();
696 InUnit.warn(
"cann't read address attribute value.");
701 AttrSpec.
Attr == dwarf::DW_AT_low_pc) {
702 if (std::optional<uint64_t> LowPC =
OutUnit.getAsCompileUnit()->getLowPc())
706 }
else if (
InputDieEntry->getTag() == dwarf::DW_TAG_compile_unit &&
707 AttrSpec.
Attr == dwarf::DW_AT_high_pc) {
708 if (uint64_t HighPc =
OutUnit.getAsCompileUnit()->getHighPc())
713 if (AttrSpec.
Attr == dwarf::DW_AT_high_pc)
721 if (AttrSpec.
Form == dwarf::DW_FORM_addr) {
727 .addScalarAttribute(AttrSpec.
Attr, dwarf::Form::DW_FORM_addrx,
728 OutUnit.getAsCompileUnit()->getDebugAddrIndex(*Addr))
735 std::optional<uint64_t> LowPC =
739 uint64_t Constrained =
740 InUnit.getContainingFile().Addresses->constrainCodeRangeHighPC(
742 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.