1*1db9f3b2SDimitry Andric //===- DIEAttributeCloner.h -------------------------------------*- C++ -*-===// 2*1db9f3b2SDimitry Andric // 3*1db9f3b2SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*1db9f3b2SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*1db9f3b2SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*1db9f3b2SDimitry Andric // 7*1db9f3b2SDimitry Andric //===----------------------------------------------------------------------===// 8*1db9f3b2SDimitry Andric 9*1db9f3b2SDimitry Andric #ifndef LLVM_LIB_DWARFLINKER_PARALLEL_DIEATTRIBUTECLONER_H 10*1db9f3b2SDimitry Andric #define LLVM_LIB_DWARFLINKER_PARALLEL_DIEATTRIBUTECLONER_H 11*1db9f3b2SDimitry Andric 12*1db9f3b2SDimitry Andric #include "ArrayList.h" 13*1db9f3b2SDimitry Andric #include "DIEGenerator.h" 14*1db9f3b2SDimitry Andric #include "DWARFLinkerCompileUnit.h" 15*1db9f3b2SDimitry Andric #include "DWARFLinkerGlobalData.h" 16*1db9f3b2SDimitry Andric #include "DWARFLinkerTypeUnit.h" 17*1db9f3b2SDimitry Andric 18*1db9f3b2SDimitry Andric namespace llvm { 19*1db9f3b2SDimitry Andric namespace dwarf_linker { 20*1db9f3b2SDimitry Andric namespace parallel { 21*1db9f3b2SDimitry Andric 22*1db9f3b2SDimitry Andric /// Information gathered and exchanged between the various 23*1db9f3b2SDimitry Andric /// clone*Attr helpers about the attributes of a particular DIE. 24*1db9f3b2SDimitry Andric struct AttributesInfo { 25*1db9f3b2SDimitry Andric /// Short Name. 26*1db9f3b2SDimitry Andric StringEntry *Name = nullptr; 27*1db9f3b2SDimitry Andric 28*1db9f3b2SDimitry Andric /// Mangled Name. 29*1db9f3b2SDimitry Andric StringEntry *MangledName = nullptr; 30*1db9f3b2SDimitry Andric 31*1db9f3b2SDimitry Andric /// Does the DIE have an address pointing to live code section? 32*1db9f3b2SDimitry Andric bool HasLiveAddress = false; 33*1db9f3b2SDimitry Andric 34*1db9f3b2SDimitry Andric /// Is this DIE only a declaration? 35*1db9f3b2SDimitry Andric bool IsDeclaration = false; 36*1db9f3b2SDimitry Andric 37*1db9f3b2SDimitry Andric /// Does the DIE have a ranges attribute? 38*1db9f3b2SDimitry Andric bool HasRanges = false; 39*1db9f3b2SDimitry Andric 40*1db9f3b2SDimitry Andric /// Does the DIE have a string offset attribute? 41*1db9f3b2SDimitry Andric bool HasStringOffsetBaseAttr = false; 42*1db9f3b2SDimitry Andric }; 43*1db9f3b2SDimitry Andric 44*1db9f3b2SDimitry Andric /// This class creates clones of input DIE attributes. 45*1db9f3b2SDimitry Andric /// It enumerates attributes of input DIE, creates clone for each 46*1db9f3b2SDimitry Andric /// attribute, adds cloned attribute to the output DIE. 47*1db9f3b2SDimitry Andric class DIEAttributeCloner { 48*1db9f3b2SDimitry Andric public: DIEAttributeCloner(DIE * OutDIE,CompileUnit & InUnit,CompileUnit * OutUnit,const DWARFDebugInfoEntry * InputDieEntry,DIEGenerator & Generator,std::optional<int64_t> FuncAddressAdjustment,std::optional<int64_t> VarAddressAdjustment,bool HasLocationExpressionAddress)49*1db9f3b2SDimitry Andric DIEAttributeCloner(DIE *OutDIE, CompileUnit &InUnit, CompileUnit *OutUnit, 50*1db9f3b2SDimitry Andric const DWARFDebugInfoEntry *InputDieEntry, 51*1db9f3b2SDimitry Andric DIEGenerator &Generator, 52*1db9f3b2SDimitry Andric std::optional<int64_t> FuncAddressAdjustment, 53*1db9f3b2SDimitry Andric std::optional<int64_t> VarAddressAdjustment, 54*1db9f3b2SDimitry Andric bool HasLocationExpressionAddress) 55*1db9f3b2SDimitry Andric : DIEAttributeCloner(OutDIE, InUnit, 56*1db9f3b2SDimitry Andric CompileUnit::OutputUnitVariantPtr(OutUnit), 57*1db9f3b2SDimitry Andric InputDieEntry, Generator, FuncAddressAdjustment, 58*1db9f3b2SDimitry Andric VarAddressAdjustment, HasLocationExpressionAddress) { 59*1db9f3b2SDimitry Andric } 60*1db9f3b2SDimitry Andric DIEAttributeCloner(DIE * OutDIE,CompileUnit & InUnit,TypeUnit * OutUnit,const DWARFDebugInfoEntry * InputDieEntry,DIEGenerator & Generator,std::optional<int64_t> FuncAddressAdjustment,std::optional<int64_t> VarAddressAdjustment,bool HasLocationExpressionAddress)61*1db9f3b2SDimitry Andric DIEAttributeCloner(DIE *OutDIE, CompileUnit &InUnit, TypeUnit *OutUnit, 62*1db9f3b2SDimitry Andric const DWARFDebugInfoEntry *InputDieEntry, 63*1db9f3b2SDimitry Andric DIEGenerator &Generator, 64*1db9f3b2SDimitry Andric std::optional<int64_t> FuncAddressAdjustment, 65*1db9f3b2SDimitry Andric std::optional<int64_t> VarAddressAdjustment, 66*1db9f3b2SDimitry Andric bool HasLocationExpressionAddress) 67*1db9f3b2SDimitry Andric : DIEAttributeCloner(OutDIE, InUnit, 68*1db9f3b2SDimitry Andric CompileUnit::OutputUnitVariantPtr(OutUnit), 69*1db9f3b2SDimitry Andric InputDieEntry, Generator, FuncAddressAdjustment, 70*1db9f3b2SDimitry Andric VarAddressAdjustment, HasLocationExpressionAddress) { 71*1db9f3b2SDimitry Andric } 72*1db9f3b2SDimitry Andric 73*1db9f3b2SDimitry Andric /// Clone attributes of input DIE. 74*1db9f3b2SDimitry Andric void clone(); 75*1db9f3b2SDimitry Andric 76*1db9f3b2SDimitry Andric /// Create abbreviations for the output DIE after all attributes are cloned. 77*1db9f3b2SDimitry Andric unsigned finalizeAbbreviations(bool HasChildrenToClone); 78*1db9f3b2SDimitry Andric 79*1db9f3b2SDimitry Andric /// Cannot be used concurrently. 80*1db9f3b2SDimitry Andric AttributesInfo AttrInfo; 81*1db9f3b2SDimitry Andric getOutOffset()82*1db9f3b2SDimitry Andric unsigned getOutOffset() { return AttrOutOffset; } 83*1db9f3b2SDimitry Andric 84*1db9f3b2SDimitry Andric protected: DIEAttributeCloner(DIE * OutDIE,CompileUnit & InUnit,CompileUnit::OutputUnitVariantPtr OutUnit,const DWARFDebugInfoEntry * InputDieEntry,DIEGenerator & Generator,std::optional<int64_t> FuncAddressAdjustment,std::optional<int64_t> VarAddressAdjustment,bool HasLocationExpressionAddress)85*1db9f3b2SDimitry Andric DIEAttributeCloner(DIE *OutDIE, CompileUnit &InUnit, 86*1db9f3b2SDimitry Andric CompileUnit::OutputUnitVariantPtr OutUnit, 87*1db9f3b2SDimitry Andric const DWARFDebugInfoEntry *InputDieEntry, 88*1db9f3b2SDimitry Andric DIEGenerator &Generator, 89*1db9f3b2SDimitry Andric std::optional<int64_t> FuncAddressAdjustment, 90*1db9f3b2SDimitry Andric std::optional<int64_t> VarAddressAdjustment, 91*1db9f3b2SDimitry Andric bool HasLocationExpressionAddress) 92*1db9f3b2SDimitry Andric : OutDIE(OutDIE), InUnit(InUnit), OutUnit(OutUnit), 93*1db9f3b2SDimitry Andric DebugInfoOutputSection( 94*1db9f3b2SDimitry Andric OutUnit->getSectionDescriptor(DebugSectionKind::DebugInfo)), 95*1db9f3b2SDimitry Andric InputDieEntry(InputDieEntry), Generator(Generator), 96*1db9f3b2SDimitry Andric FuncAddressAdjustment(FuncAddressAdjustment), 97*1db9f3b2SDimitry Andric VarAddressAdjustment(VarAddressAdjustment), 98*1db9f3b2SDimitry Andric HasLocationExpressionAddress(HasLocationExpressionAddress) { 99*1db9f3b2SDimitry Andric InputDIEIdx = InUnit.getDIEIndex(InputDieEntry); 100*1db9f3b2SDimitry Andric 101*1db9f3b2SDimitry Andric // Use DW_FORM_strp form for string attributes for DWARF version less than 5 102*1db9f3b2SDimitry Andric // or if output unit is type unit and we need to produce deterministic 103*1db9f3b2SDimitry Andric // result. (We can not generate deterministic results for debug_str_offsets 104*1db9f3b2SDimitry Andric // section when attributes are cloned parallelly). 105*1db9f3b2SDimitry Andric Use_DW_FORM_strp = 106*1db9f3b2SDimitry Andric (InUnit.getVersion() < 5) || 107*1db9f3b2SDimitry Andric (OutUnit.isTypeUnit() && 108*1db9f3b2SDimitry Andric ((InUnit.getGlobalData().getOptions().Threads != 1) && 109*1db9f3b2SDimitry Andric !InUnit.getGlobalData().getOptions().AllowNonDeterministicOutput)); 110*1db9f3b2SDimitry Andric } 111*1db9f3b2SDimitry Andric 112*1db9f3b2SDimitry Andric /// Clone string attribute. 113*1db9f3b2SDimitry Andric size_t 114*1db9f3b2SDimitry Andric cloneStringAttr(const DWARFFormValue &Val, 115*1db9f3b2SDimitry Andric const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec); 116*1db9f3b2SDimitry Andric 117*1db9f3b2SDimitry Andric /// Clone attribute referencing another DIE. 118*1db9f3b2SDimitry Andric size_t 119*1db9f3b2SDimitry Andric cloneDieRefAttr(const DWARFFormValue &Val, 120*1db9f3b2SDimitry Andric const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec); 121*1db9f3b2SDimitry Andric 122*1db9f3b2SDimitry Andric /// Clone scalar attribute. 123*1db9f3b2SDimitry Andric size_t 124*1db9f3b2SDimitry Andric cloneScalarAttr(const DWARFFormValue &Val, 125*1db9f3b2SDimitry Andric const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec); 126*1db9f3b2SDimitry Andric 127*1db9f3b2SDimitry Andric /// Clone block or exprloc attribute. 128*1db9f3b2SDimitry Andric size_t 129*1db9f3b2SDimitry Andric cloneBlockAttr(const DWARFFormValue &Val, 130*1db9f3b2SDimitry Andric const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec); 131*1db9f3b2SDimitry Andric 132*1db9f3b2SDimitry Andric /// Clone address attribute. 133*1db9f3b2SDimitry Andric size_t 134*1db9f3b2SDimitry Andric cloneAddressAttr(const DWARFFormValue &Val, 135*1db9f3b2SDimitry Andric const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec); 136*1db9f3b2SDimitry Andric 137*1db9f3b2SDimitry Andric /// Returns true if attribute should be skipped. 138*1db9f3b2SDimitry Andric bool 139*1db9f3b2SDimitry Andric shouldSkipAttribute(DWARFAbbreviationDeclaration::AttributeSpec AttrSpec); 140*1db9f3b2SDimitry Andric 141*1db9f3b2SDimitry Andric /// Output DIE. 142*1db9f3b2SDimitry Andric DIE *OutDIE = nullptr; 143*1db9f3b2SDimitry Andric 144*1db9f3b2SDimitry Andric /// Input compilation unit. 145*1db9f3b2SDimitry Andric CompileUnit &InUnit; 146*1db9f3b2SDimitry Andric 147*1db9f3b2SDimitry Andric /// Output unit(either "plain" compilation unit, either artificial type unit). 148*1db9f3b2SDimitry Andric CompileUnit::OutputUnitVariantPtr OutUnit; 149*1db9f3b2SDimitry Andric 150*1db9f3b2SDimitry Andric /// .debug_info section descriptor. 151*1db9f3b2SDimitry Andric SectionDescriptor &DebugInfoOutputSection; 152*1db9f3b2SDimitry Andric 153*1db9f3b2SDimitry Andric /// Input DIE entry. 154*1db9f3b2SDimitry Andric const DWARFDebugInfoEntry *InputDieEntry = nullptr; 155*1db9f3b2SDimitry Andric 156*1db9f3b2SDimitry Andric /// Input DIE index. 157*1db9f3b2SDimitry Andric uint32_t InputDIEIdx = 0; 158*1db9f3b2SDimitry Andric 159*1db9f3b2SDimitry Andric /// Output DIE generator. 160*1db9f3b2SDimitry Andric DIEGenerator &Generator; 161*1db9f3b2SDimitry Andric 162*1db9f3b2SDimitry Andric /// Relocation adjustment for the function address ranges. 163*1db9f3b2SDimitry Andric std::optional<int64_t> FuncAddressAdjustment; 164*1db9f3b2SDimitry Andric 165*1db9f3b2SDimitry Andric /// Relocation adjustment for the variable locations. 166*1db9f3b2SDimitry Andric std::optional<int64_t> VarAddressAdjustment; 167*1db9f3b2SDimitry Andric 168*1db9f3b2SDimitry Andric /// Indicates whether InputDieEntry has an location attribute 169*1db9f3b2SDimitry Andric /// containg address expression. 170*1db9f3b2SDimitry Andric bool HasLocationExpressionAddress = false; 171*1db9f3b2SDimitry Andric 172*1db9f3b2SDimitry Andric /// Output offset after all attributes. 173*1db9f3b2SDimitry Andric unsigned AttrOutOffset = 0; 174*1db9f3b2SDimitry Andric 175*1db9f3b2SDimitry Andric /// Patches for the cloned attributes. 176*1db9f3b2SDimitry Andric OffsetsPtrVector PatchesOffsets; 177*1db9f3b2SDimitry Andric 178*1db9f3b2SDimitry Andric /// This flag forces using DW_FORM_strp for string attributes. 179*1db9f3b2SDimitry Andric bool Use_DW_FORM_strp = false; 180*1db9f3b2SDimitry Andric }; 181*1db9f3b2SDimitry Andric 182*1db9f3b2SDimitry Andric } // end of namespace parallel 183*1db9f3b2SDimitry Andric } // end of namespace dwarf_linker 184*1db9f3b2SDimitry Andric } // end of namespace llvm 185*1db9f3b2SDimitry Andric 186*1db9f3b2SDimitry Andric #endif // LLVM_LIB_DWARFLINKER_PARALLEL_DIEATTRIBUTECLONER_H 187