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