15ffd83dbSDimitry Andric //===-- DWARFContext.cpp --------------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric
90b57cec5SDimitry Andric #include "DWARFContext.h"
100b57cec5SDimitry Andric
110b57cec5SDimitry Andric #include "lldb/Core/Section.h"
12bdd1243dSDimitry Andric #include <optional>
130b57cec5SDimitry Andric
140b57cec5SDimitry Andric using namespace lldb;
150b57cec5SDimitry Andric using namespace lldb_private;
16*5f757f3fSDimitry Andric using namespace lldb_private::plugin::dwarf;
170b57cec5SDimitry Andric
LoadSection(SectionList * section_list,SectionType section_type)180b57cec5SDimitry Andric static DWARFDataExtractor LoadSection(SectionList *section_list,
190b57cec5SDimitry Andric SectionType section_type) {
200b57cec5SDimitry Andric if (!section_list)
210b57cec5SDimitry Andric return DWARFDataExtractor();
220b57cec5SDimitry Andric
230b57cec5SDimitry Andric auto section_sp = section_list->FindSectionByType(section_type, true);
240b57cec5SDimitry Andric if (!section_sp)
250b57cec5SDimitry Andric return DWARFDataExtractor();
260b57cec5SDimitry Andric
270b57cec5SDimitry Andric DWARFDataExtractor data;
280b57cec5SDimitry Andric section_sp->GetSectionData(data);
290b57cec5SDimitry Andric return data;
300b57cec5SDimitry Andric }
310b57cec5SDimitry Andric
320b57cec5SDimitry Andric const DWARFDataExtractor &
LoadOrGetSection(std::optional<SectionType> main_section_type,std::optional<SectionType> dwo_section_type,SectionData & data)33bdd1243dSDimitry Andric DWARFContext::LoadOrGetSection(std::optional<SectionType> main_section_type,
34bdd1243dSDimitry Andric std::optional<SectionType> dwo_section_type,
350b57cec5SDimitry Andric SectionData &data) {
360b57cec5SDimitry Andric llvm::call_once(data.flag, [&] {
370b57cec5SDimitry Andric if (dwo_section_type && isDwo())
380b57cec5SDimitry Andric data.data = LoadSection(m_dwo_section_list, *dwo_section_type);
395ffd83dbSDimitry Andric else if (main_section_type)
405ffd83dbSDimitry Andric data.data = LoadSection(m_main_section_list, *main_section_type);
410b57cec5SDimitry Andric });
420b57cec5SDimitry Andric return data.data;
430b57cec5SDimitry Andric }
440b57cec5SDimitry Andric
getOrLoadCuIndexData()455ffd83dbSDimitry Andric const DWARFDataExtractor &DWARFContext::getOrLoadCuIndexData() {
46bdd1243dSDimitry Andric return LoadOrGetSection(std::nullopt, eSectionTypeDWARFDebugCuIndex,
475ffd83dbSDimitry Andric m_data_debug_cu_index);
485ffd83dbSDimitry Andric }
495ffd83dbSDimitry Andric
getOrLoadTuIndexData()505ffd83dbSDimitry Andric const DWARFDataExtractor &DWARFContext::getOrLoadTuIndexData() {
51bdd1243dSDimitry Andric return LoadOrGetSection(std::nullopt, eSectionTypeDWARFDebugTuIndex,
525ffd83dbSDimitry Andric m_data_debug_tu_index);
535ffd83dbSDimitry Andric }
545ffd83dbSDimitry Andric
getOrLoadAbbrevData()550b57cec5SDimitry Andric const DWARFDataExtractor &DWARFContext::getOrLoadAbbrevData() {
560b57cec5SDimitry Andric return LoadOrGetSection(eSectionTypeDWARFDebugAbbrev,
570b57cec5SDimitry Andric eSectionTypeDWARFDebugAbbrevDwo, m_data_debug_abbrev);
580b57cec5SDimitry Andric }
590b57cec5SDimitry Andric
getOrLoadArangesData()600b57cec5SDimitry Andric const DWARFDataExtractor &DWARFContext::getOrLoadArangesData() {
61bdd1243dSDimitry Andric return LoadOrGetSection(eSectionTypeDWARFDebugAranges, std::nullopt,
620b57cec5SDimitry Andric m_data_debug_aranges);
630b57cec5SDimitry Andric }
640b57cec5SDimitry Andric
getOrLoadAddrData()650b57cec5SDimitry Andric const DWARFDataExtractor &DWARFContext::getOrLoadAddrData() {
66bdd1243dSDimitry Andric return LoadOrGetSection(eSectionTypeDWARFDebugAddr, std::nullopt,
670b57cec5SDimitry Andric m_data_debug_addr);
680b57cec5SDimitry Andric }
690b57cec5SDimitry Andric
getOrLoadDebugInfoData()700b57cec5SDimitry Andric const DWARFDataExtractor &DWARFContext::getOrLoadDebugInfoData() {
710b57cec5SDimitry Andric return LoadOrGetSection(eSectionTypeDWARFDebugInfo,
720b57cec5SDimitry Andric eSectionTypeDWARFDebugInfoDwo, m_data_debug_info);
730b57cec5SDimitry Andric }
740b57cec5SDimitry Andric
getOrLoadLineData()750b57cec5SDimitry Andric const DWARFDataExtractor &DWARFContext::getOrLoadLineData() {
76bdd1243dSDimitry Andric return LoadOrGetSection(eSectionTypeDWARFDebugLine, std::nullopt,
770b57cec5SDimitry Andric m_data_debug_line);
780b57cec5SDimitry Andric }
790b57cec5SDimitry Andric
getOrLoadLineStrData()800b57cec5SDimitry Andric const DWARFDataExtractor &DWARFContext::getOrLoadLineStrData() {
81bdd1243dSDimitry Andric return LoadOrGetSection(eSectionTypeDWARFDebugLineStr, std::nullopt,
820b57cec5SDimitry Andric m_data_debug_line_str);
830b57cec5SDimitry Andric }
840b57cec5SDimitry Andric
getOrLoadLocData()85480093f4SDimitry Andric const DWARFDataExtractor &DWARFContext::getOrLoadLocData() {
86480093f4SDimitry Andric return LoadOrGetSection(eSectionTypeDWARFDebugLoc,
87480093f4SDimitry Andric eSectionTypeDWARFDebugLocDwo, m_data_debug_loc);
88480093f4SDimitry Andric }
89480093f4SDimitry Andric
getOrLoadLocListsData()90480093f4SDimitry Andric const DWARFDataExtractor &DWARFContext::getOrLoadLocListsData() {
91480093f4SDimitry Andric return LoadOrGetSection(eSectionTypeDWARFDebugLocLists,
92480093f4SDimitry Andric eSectionTypeDWARFDebugLocListsDwo,
93480093f4SDimitry Andric m_data_debug_loclists);
94480093f4SDimitry Andric }
95480093f4SDimitry Andric
getOrLoadMacroData()960b57cec5SDimitry Andric const DWARFDataExtractor &DWARFContext::getOrLoadMacroData() {
97bdd1243dSDimitry Andric return LoadOrGetSection(eSectionTypeDWARFDebugMacro, std::nullopt,
980b57cec5SDimitry Andric m_data_debug_macro);
990b57cec5SDimitry Andric }
1000b57cec5SDimitry Andric
getOrLoadRangesData()1010b57cec5SDimitry Andric const DWARFDataExtractor &DWARFContext::getOrLoadRangesData() {
102bdd1243dSDimitry Andric return LoadOrGetSection(eSectionTypeDWARFDebugRanges, std::nullopt,
1030b57cec5SDimitry Andric m_data_debug_ranges);
1040b57cec5SDimitry Andric }
1050b57cec5SDimitry Andric
getOrLoadRngListsData()1060b57cec5SDimitry Andric const DWARFDataExtractor &DWARFContext::getOrLoadRngListsData() {
107480093f4SDimitry Andric return LoadOrGetSection(eSectionTypeDWARFDebugRngLists,
108480093f4SDimitry Andric eSectionTypeDWARFDebugRngListsDwo,
1090b57cec5SDimitry Andric m_data_debug_rnglists);
1100b57cec5SDimitry Andric }
1110b57cec5SDimitry Andric
getOrLoadStrData()1120b57cec5SDimitry Andric const DWARFDataExtractor &DWARFContext::getOrLoadStrData() {
1130b57cec5SDimitry Andric return LoadOrGetSection(eSectionTypeDWARFDebugStr,
1140b57cec5SDimitry Andric eSectionTypeDWARFDebugStrDwo, m_data_debug_str);
1150b57cec5SDimitry Andric }
1160b57cec5SDimitry Andric
getOrLoadStrOffsetsData()1170b57cec5SDimitry Andric const DWARFDataExtractor &DWARFContext::getOrLoadStrOffsetsData() {
1180b57cec5SDimitry Andric return LoadOrGetSection(eSectionTypeDWARFDebugStrOffsets,
1190b57cec5SDimitry Andric eSectionTypeDWARFDebugStrOffsetsDwo,
1200b57cec5SDimitry Andric m_data_debug_str_offsets);
1210b57cec5SDimitry Andric }
1220b57cec5SDimitry Andric
getOrLoadDebugTypesData()1230b57cec5SDimitry Andric const DWARFDataExtractor &DWARFContext::getOrLoadDebugTypesData() {
1240b57cec5SDimitry Andric return LoadOrGetSection(eSectionTypeDWARFDebugTypes,
1250b57cec5SDimitry Andric eSectionTypeDWARFDebugTypesDwo, m_data_debug_types);
1260b57cec5SDimitry Andric }
1270b57cec5SDimitry Andric
GetAsLLVM()1280b57cec5SDimitry Andric llvm::DWARFContext &DWARFContext::GetAsLLVM() {
1290b57cec5SDimitry Andric if (!m_llvm_context) {
1300b57cec5SDimitry Andric llvm::StringMap<std::unique_ptr<llvm::MemoryBuffer>> section_map;
1310b57cec5SDimitry Andric uint8_t addr_size = 0;
1325ffd83dbSDimitry Andric auto AddSection = [&](llvm::StringRef name, DWARFDataExtractor data) {
1330b57cec5SDimitry Andric // Set the address size the first time we see it.
1340b57cec5SDimitry Andric if (addr_size == 0)
1355ffd83dbSDimitry Andric addr_size = data.GetAddressByteSize();
1360b57cec5SDimitry Andric
1370b57cec5SDimitry Andric section_map.try_emplace(
1385ffd83dbSDimitry Andric name, llvm::MemoryBuffer::getMemBuffer(toStringRef(data.GetData()),
1395ffd83dbSDimitry Andric name, false));
1400b57cec5SDimitry Andric };
1410b57cec5SDimitry Andric
1425ffd83dbSDimitry Andric AddSection("debug_line_str", getOrLoadLineStrData());
1435ffd83dbSDimitry Andric AddSection("debug_cu_index", getOrLoadCuIndexData());
1445ffd83dbSDimitry Andric AddSection("debug_tu_index", getOrLoadTuIndexData());
145*5f757f3fSDimitry Andric if (isDwo()) {
146*5f757f3fSDimitry Andric AddSection("debug_info.dwo", getOrLoadDebugInfoData());
147*5f757f3fSDimitry Andric AddSection("debug_types.dwo", getOrLoadDebugTypesData());
148*5f757f3fSDimitry Andric }
1490b57cec5SDimitry Andric m_llvm_context = llvm::DWARFContext::create(section_map, addr_size);
1500b57cec5SDimitry Andric }
1510b57cec5SDimitry Andric return *m_llvm_context;
1520b57cec5SDimitry Andric }
153