26 :
InUnit.getOrigUnit().getNextUnitOffset();
36 InUnit.getContaingFile().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);
257 assert(RefTypeName &&
"Type name for referenced DIE is not set");
259 "Type name for DIE is not set");
266 .addScalarAttribute(AttrSpec.
Attr, dwarf::DW_FORM_ref4, 0xBADDEF)
275 .addScalarAttribute(AttrSpec.
Attr, dwarf::DW_FORM_ref_addr, 0xBADDEF)
280 uint64_t OutDieOffset = RefDiePair->CU->getDieOutOffset(RefDiePair->DieEntry);
283 bool IsLocal =
OutUnit->getUniqueID() == RefDiePair->CU->getUniqueID();
286 dwarf::Form NewForm = IsLocal ? dwarf::DW_FORM_ref4 : dwarf::DW_FORM_ref_addr;
290 if (IsLocal && (OutDieOffset != 0))
291 return Generator.addScalarAttribute(AttrSpec.
Attr, NewForm, OutDieOffset)
299 RefDiePair->CU->getDIEIndex(RefDiePair->DieEntry)},
301 return Generator.addScalarAttribute(AttrSpec.
Attr, NewForm, 0xBADDEF).second;
311 switch (AttrSpec.
Attr) {
312 case dwarf::DW_AT_macro_info: {
315 InUnit.getContaingFile().Dwarf->getDebugMacinfo();
321 &
OutUnit->getOrCreateSectionDescriptor(
326 case dwarf::DW_AT_macros: {
329 InUnit.getContaingFile().Dwarf->getDebugMacro();
335 &
OutUnit->getOrCreateSectionDescriptor(
340 case dwarf::DW_AT_stmt_list: {
346 case dwarf::DW_AT_str_offsets_base: {
349 &
OutUnit->getOrCreateSectionDescriptor(
356 AttrInfo.HasStringOffsetBaseAttr =
true;
358 .addScalarAttribute(AttrSpec.
Attr, AttrSpec.
Form,
359 OutUnit->getDebugStrOffsetsHeaderSize())
362 case dwarf::DW_AT_decl_file: {
369 if (std::optional<std::pair<StringRef, StringRef>> DirAndFilename =
370 InUnit.getDirAndFilenameFromLineTable(Val))
376 .insert(DirAndFilename->first)
380 .insert(DirAndFilename->second)
391 if (AttrSpec.
Attr == dwarf::DW_AT_const_value &&
396 if (
InUnit.getGlobalData().getOptions().UpdateIndexTablesOnly) {
398 Value = *OptionalValue;
400 Value = *OptionalValue;
402 Value = *OptionalValue;
404 InUnit.warn(
"unsupported scalar attribute form. Dropping attribute.",
409 if (AttrSpec.
Attr == dwarf::DW_AT_declaration &&
Value)
412 if (AttrSpec.
Form == dwarf::DW_FORM_loclistx)
421 if (AttrSpec.
Form == dwarf::DW_FORM_rnglistx) {
430 std::optional<uint64_t>
Offset =
431 InUnit.getOrigUnit().getRnglistOffset(*Index);
438 ResultingForm = dwarf::DW_FORM_sec_offset;
439 }
else if (AttrSpec.
Form == dwarf::DW_FORM_loclistx) {
448 std::optional<uint64_t>
Offset =
449 InUnit.getOrigUnit().getLoclistOffset(*Index);
456 ResultingForm = dwarf::DW_FORM_sec_offset;
457 }
else if (AttrSpec.
Attr == dwarf::DW_AT_high_pc &&
462 std::optional<uint64_t> LowPC =
OutUnit.getAsCompileUnit()->getLowPc();
466 Value =
OutUnit.getAsCompileUnit()->getHighPc() - *LowPC;
467 }
else if (AttrSpec.
Form == dwarf::DW_FORM_sec_offset)
469 else if (AttrSpec.
Form == dwarf::DW_FORM_sdata)
472 Value = *OptionalValue;
474 InUnit.warn(
"unsupported scalar attribute form. Dropping attribute.",
479 if (AttrSpec.
Attr == dwarf::DW_AT_ranges ||
480 AttrSpec.
Attr == dwarf::DW_AT_start_scope) {
490 InUnit.getOrigUnit().getVersion())) {
491 int64_t AddrAdjustmentValue = 0;
500 }
else if (AttrSpec.
Attr == dwarf::DW_AT_addr_base) {
511 .addScalarAttribute(AttrSpec.
Attr, AttrSpec.
Form,
512 OutUnit->getDebugAddrHeaderSize())
514 }
else if (AttrSpec.
Attr == dwarf::DW_AT_declaration &&
Value)
538 InUnit.getOrigUnit().isLittleEndian(),
539 InUnit.getOrigUnit().getAddressByteSize());
541 InUnit.getFormParams().Format);
551 if ((ResultForm == dwarf::DW_FORM_block1 && Bytes.
size() > UINT8_MAX) ||
552 (ResultForm == dwarf::DW_FORM_block2 && Bytes.
size() > UINT16_MAX) ||
553 (ResultForm == dwarf::DW_FORM_block4 && Bytes.
size() > UINT32_MAX))
554 ResultForm = dwarf::DW_FORM_block;
556 size_t FinalAttributeSize;
557 if (AttrSpec.
Form == dwarf::DW_FORM_exprloc)
559 Generator.addLocationAttribute(AttrSpec.
Attr, ResultForm, Bytes).second;
562 Generator.addBlockAttribute(AttrSpec.
Attr, ResultForm, Bytes).second;
565 for (
size_t Idx = NumberOfPatchesAtStart; Idx <
PatchesOffsets.size();
575 InUnit.getGlobalData().getOptions().UpdateIndexTablesOnly;
577 return FinalAttributeSize;
583 if (AttrSpec.
Attr == dwarf::DW_AT_low_pc)
586 if (
InUnit.getGlobalData().getOptions().UpdateIndexTablesOnly)
606 std::optional<DWARFFormValue> AddrAttribute =
611 std::optional<uint64_t> Addr = AddrAttribute->getAsAddress();
613 InUnit.warn(
"cann't read address attribute value.");
618 AttrSpec.
Attr == dwarf::DW_AT_low_pc) {
619 if (std::optional<uint64_t> LowPC =
OutUnit.getAsCompileUnit()->getLowPc())
623 }
else if (
InputDieEntry->getTag() == dwarf::DW_TAG_compile_unit &&
624 AttrSpec.
Attr == dwarf::DW_AT_high_pc) {
636 if (AttrSpec.
Form == dwarf::DW_FORM_addr) {
642 .addScalarAttribute(AttrSpec.
Attr, dwarf::Form::DW_FORM_addrx,
643 OutUnit.getAsCompileUnit()->getDebugAddrIndex(*Addr))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
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.
StringRef - Represent a constant reference to a string, i.e.
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.
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< std::nullopt_t > StringEntry
StringEntry keeps data of the string: the length, external offset and a string body which is placed r...
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.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
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 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.