1 //===-- DWARFContext.cpp --------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "DWARFContext.h" 10 11 #include "lldb/Core/Section.h" 12 #include <optional> 13 14 using namespace lldb; 15 using namespace lldb_private; 16 using namespace lldb_private::plugin::dwarf; 17 18 static DWARFDataExtractor LoadSection(SectionList *section_list, 19 SectionType section_type) { 20 if (!section_list) 21 return DWARFDataExtractor(); 22 23 auto section_sp = section_list->FindSectionByType(section_type, true); 24 if (!section_sp) 25 return DWARFDataExtractor(); 26 27 DWARFDataExtractor data; 28 section_sp->GetSectionData(data); 29 return data; 30 } 31 32 const DWARFDataExtractor & 33 DWARFContext::LoadOrGetSection(std::optional<SectionType> main_section_type, 34 std::optional<SectionType> dwo_section_type, 35 SectionData &data) { 36 llvm::call_once(data.flag, [&] { 37 if (dwo_section_type && isDwo()) 38 data.data = LoadSection(m_dwo_section_list, *dwo_section_type); 39 else if (main_section_type) 40 data.data = LoadSection(m_main_section_list, *main_section_type); 41 }); 42 return data.data; 43 } 44 45 const DWARFDataExtractor &DWARFContext::getOrLoadCuIndexData() { 46 return LoadOrGetSection(std::nullopt, eSectionTypeDWARFDebugCuIndex, 47 m_data_debug_cu_index); 48 } 49 50 const DWARFDataExtractor &DWARFContext::getOrLoadTuIndexData() { 51 return LoadOrGetSection(std::nullopt, eSectionTypeDWARFDebugTuIndex, 52 m_data_debug_tu_index); 53 } 54 55 const DWARFDataExtractor &DWARFContext::getOrLoadAbbrevData() { 56 return LoadOrGetSection(eSectionTypeDWARFDebugAbbrev, 57 eSectionTypeDWARFDebugAbbrevDwo, m_data_debug_abbrev); 58 } 59 60 const DWARFDataExtractor &DWARFContext::getOrLoadArangesData() { 61 return LoadOrGetSection(eSectionTypeDWARFDebugAranges, std::nullopt, 62 m_data_debug_aranges); 63 } 64 65 const DWARFDataExtractor &DWARFContext::getOrLoadAddrData() { 66 return LoadOrGetSection(eSectionTypeDWARFDebugAddr, std::nullopt, 67 m_data_debug_addr); 68 } 69 70 const DWARFDataExtractor &DWARFContext::getOrLoadDebugInfoData() { 71 return LoadOrGetSection(eSectionTypeDWARFDebugInfo, 72 eSectionTypeDWARFDebugInfoDwo, m_data_debug_info); 73 } 74 75 const DWARFDataExtractor &DWARFContext::getOrLoadLineData() { 76 return LoadOrGetSection(eSectionTypeDWARFDebugLine, std::nullopt, 77 m_data_debug_line); 78 } 79 80 const DWARFDataExtractor &DWARFContext::getOrLoadLineStrData() { 81 return LoadOrGetSection(eSectionTypeDWARFDebugLineStr, std::nullopt, 82 m_data_debug_line_str); 83 } 84 85 const DWARFDataExtractor &DWARFContext::getOrLoadLocData() { 86 return LoadOrGetSection(eSectionTypeDWARFDebugLoc, 87 eSectionTypeDWARFDebugLocDwo, m_data_debug_loc); 88 } 89 90 const DWARFDataExtractor &DWARFContext::getOrLoadLocListsData() { 91 return LoadOrGetSection(eSectionTypeDWARFDebugLocLists, 92 eSectionTypeDWARFDebugLocListsDwo, 93 m_data_debug_loclists); 94 } 95 96 const DWARFDataExtractor &DWARFContext::getOrLoadMacroData() { 97 return LoadOrGetSection(eSectionTypeDWARFDebugMacro, std::nullopt, 98 m_data_debug_macro); 99 } 100 101 const DWARFDataExtractor &DWARFContext::getOrLoadRangesData() { 102 return LoadOrGetSection(eSectionTypeDWARFDebugRanges, std::nullopt, 103 m_data_debug_ranges); 104 } 105 106 const DWARFDataExtractor &DWARFContext::getOrLoadRngListsData() { 107 return LoadOrGetSection(eSectionTypeDWARFDebugRngLists, 108 eSectionTypeDWARFDebugRngListsDwo, 109 m_data_debug_rnglists); 110 } 111 112 const DWARFDataExtractor &DWARFContext::getOrLoadStrData() { 113 return LoadOrGetSection(eSectionTypeDWARFDebugStr, 114 eSectionTypeDWARFDebugStrDwo, m_data_debug_str); 115 } 116 117 const DWARFDataExtractor &DWARFContext::getOrLoadStrOffsetsData() { 118 return LoadOrGetSection(eSectionTypeDWARFDebugStrOffsets, 119 eSectionTypeDWARFDebugStrOffsetsDwo, 120 m_data_debug_str_offsets); 121 } 122 123 const DWARFDataExtractor &DWARFContext::getOrLoadDebugTypesData() { 124 return LoadOrGetSection(eSectionTypeDWARFDebugTypes, 125 eSectionTypeDWARFDebugTypesDwo, m_data_debug_types); 126 } 127 128 llvm::DWARFContext &DWARFContext::GetAsLLVM() { 129 if (!m_llvm_context) { 130 llvm::StringMap<std::unique_ptr<llvm::MemoryBuffer>> section_map; 131 uint8_t addr_size = 0; 132 auto AddSection = [&](llvm::StringRef name, DWARFDataExtractor data) { 133 // Set the address size the first time we see it. 134 if (addr_size == 0) 135 addr_size = data.GetAddressByteSize(); 136 137 section_map.try_emplace( 138 name, llvm::MemoryBuffer::getMemBuffer(toStringRef(data.GetData()), 139 name, false)); 140 }; 141 142 AddSection("debug_line_str", getOrLoadLineStrData()); 143 AddSection("debug_cu_index", getOrLoadCuIndexData()); 144 AddSection("debug_tu_index", getOrLoadTuIndexData()); 145 if (isDwo()) { 146 AddSection("debug_info.dwo", getOrLoadDebugInfoData()); 147 AddSection("debug_types.dwo", getOrLoadDebugTypesData()); 148 } 149 m_llvm_context = llvm::DWARFContext::create(section_map, addr_size); 150 } 151 return *m_llvm_context; 152 } 153