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