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