1dda28197Spatrick //===-- DWARFContext.cpp --------------------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick
9061da546Spatrick #include "DWARFContext.h"
10061da546Spatrick
11061da546Spatrick #include "lldb/Core/Section.h"
12*f6aab3d8Srobert #include <optional>
13061da546Spatrick
14061da546Spatrick using namespace lldb;
15061da546Spatrick using namespace lldb_private;
16061da546Spatrick
LoadSection(SectionList * section_list,SectionType section_type)17061da546Spatrick static DWARFDataExtractor LoadSection(SectionList *section_list,
18061da546Spatrick SectionType section_type) {
19061da546Spatrick if (!section_list)
20061da546Spatrick return DWARFDataExtractor();
21061da546Spatrick
22061da546Spatrick auto section_sp = section_list->FindSectionByType(section_type, true);
23061da546Spatrick if (!section_sp)
24061da546Spatrick return DWARFDataExtractor();
25061da546Spatrick
26061da546Spatrick DWARFDataExtractor data;
27061da546Spatrick section_sp->GetSectionData(data);
28061da546Spatrick return data;
29061da546Spatrick }
30061da546Spatrick
31061da546Spatrick const DWARFDataExtractor &
LoadOrGetSection(std::optional<SectionType> main_section_type,std::optional<SectionType> dwo_section_type,SectionData & data)32*f6aab3d8Srobert DWARFContext::LoadOrGetSection(std::optional<SectionType> main_section_type,
33*f6aab3d8Srobert std::optional<SectionType> dwo_section_type,
34061da546Spatrick SectionData &data) {
35061da546Spatrick llvm::call_once(data.flag, [&] {
36061da546Spatrick if (dwo_section_type && isDwo())
37061da546Spatrick data.data = LoadSection(m_dwo_section_list, *dwo_section_type);
38dda28197Spatrick else if (main_section_type)
39dda28197Spatrick data.data = LoadSection(m_main_section_list, *main_section_type);
40061da546Spatrick });
41061da546Spatrick return data.data;
42061da546Spatrick }
43061da546Spatrick
getOrLoadCuIndexData()44dda28197Spatrick const DWARFDataExtractor &DWARFContext::getOrLoadCuIndexData() {
45*f6aab3d8Srobert return LoadOrGetSection(std::nullopt, eSectionTypeDWARFDebugCuIndex,
46dda28197Spatrick m_data_debug_cu_index);
47dda28197Spatrick }
48dda28197Spatrick
getOrLoadTuIndexData()49dda28197Spatrick const DWARFDataExtractor &DWARFContext::getOrLoadTuIndexData() {
50*f6aab3d8Srobert return LoadOrGetSection(std::nullopt, eSectionTypeDWARFDebugTuIndex,
51dda28197Spatrick m_data_debug_tu_index);
52dda28197Spatrick }
53dda28197Spatrick
getOrLoadAbbrevData()54061da546Spatrick const DWARFDataExtractor &DWARFContext::getOrLoadAbbrevData() {
55061da546Spatrick return LoadOrGetSection(eSectionTypeDWARFDebugAbbrev,
56061da546Spatrick eSectionTypeDWARFDebugAbbrevDwo, m_data_debug_abbrev);
57061da546Spatrick }
58061da546Spatrick
getOrLoadArangesData()59061da546Spatrick const DWARFDataExtractor &DWARFContext::getOrLoadArangesData() {
60*f6aab3d8Srobert return LoadOrGetSection(eSectionTypeDWARFDebugAranges, std::nullopt,
61061da546Spatrick m_data_debug_aranges);
62061da546Spatrick }
63061da546Spatrick
getOrLoadAddrData()64061da546Spatrick const DWARFDataExtractor &DWARFContext::getOrLoadAddrData() {
65*f6aab3d8Srobert return LoadOrGetSection(eSectionTypeDWARFDebugAddr, std::nullopt,
66061da546Spatrick m_data_debug_addr);
67061da546Spatrick }
68061da546Spatrick
getOrLoadDebugInfoData()69061da546Spatrick const DWARFDataExtractor &DWARFContext::getOrLoadDebugInfoData() {
70061da546Spatrick return LoadOrGetSection(eSectionTypeDWARFDebugInfo,
71061da546Spatrick eSectionTypeDWARFDebugInfoDwo, m_data_debug_info);
72061da546Spatrick }
73061da546Spatrick
getOrLoadLineData()74061da546Spatrick const DWARFDataExtractor &DWARFContext::getOrLoadLineData() {
75*f6aab3d8Srobert return LoadOrGetSection(eSectionTypeDWARFDebugLine, std::nullopt,
76061da546Spatrick m_data_debug_line);
77061da546Spatrick }
78061da546Spatrick
getOrLoadLineStrData()79061da546Spatrick const DWARFDataExtractor &DWARFContext::getOrLoadLineStrData() {
80*f6aab3d8Srobert return LoadOrGetSection(eSectionTypeDWARFDebugLineStr, std::nullopt,
81061da546Spatrick m_data_debug_line_str);
82061da546Spatrick }
83061da546Spatrick
getOrLoadLocData()84061da546Spatrick const DWARFDataExtractor &DWARFContext::getOrLoadLocData() {
85061da546Spatrick return LoadOrGetSection(eSectionTypeDWARFDebugLoc,
86061da546Spatrick eSectionTypeDWARFDebugLocDwo, m_data_debug_loc);
87061da546Spatrick }
88061da546Spatrick
getOrLoadLocListsData()89061da546Spatrick const DWARFDataExtractor &DWARFContext::getOrLoadLocListsData() {
90061da546Spatrick return LoadOrGetSection(eSectionTypeDWARFDebugLocLists,
91061da546Spatrick eSectionTypeDWARFDebugLocListsDwo,
92061da546Spatrick m_data_debug_loclists);
93061da546Spatrick }
94061da546Spatrick
getOrLoadMacroData()95061da546Spatrick const DWARFDataExtractor &DWARFContext::getOrLoadMacroData() {
96*f6aab3d8Srobert return LoadOrGetSection(eSectionTypeDWARFDebugMacro, std::nullopt,
97061da546Spatrick m_data_debug_macro);
98061da546Spatrick }
99061da546Spatrick
getOrLoadRangesData()100061da546Spatrick const DWARFDataExtractor &DWARFContext::getOrLoadRangesData() {
101*f6aab3d8Srobert return LoadOrGetSection(eSectionTypeDWARFDebugRanges, std::nullopt,
102061da546Spatrick m_data_debug_ranges);
103061da546Spatrick }
104061da546Spatrick
getOrLoadRngListsData()105061da546Spatrick const DWARFDataExtractor &DWARFContext::getOrLoadRngListsData() {
106061da546Spatrick return LoadOrGetSection(eSectionTypeDWARFDebugRngLists,
107061da546Spatrick eSectionTypeDWARFDebugRngListsDwo,
108061da546Spatrick m_data_debug_rnglists);
109061da546Spatrick }
110061da546Spatrick
getOrLoadStrData()111061da546Spatrick const DWARFDataExtractor &DWARFContext::getOrLoadStrData() {
112061da546Spatrick return LoadOrGetSection(eSectionTypeDWARFDebugStr,
113061da546Spatrick eSectionTypeDWARFDebugStrDwo, m_data_debug_str);
114061da546Spatrick }
115061da546Spatrick
getOrLoadStrOffsetsData()116061da546Spatrick const DWARFDataExtractor &DWARFContext::getOrLoadStrOffsetsData() {
117061da546Spatrick return LoadOrGetSection(eSectionTypeDWARFDebugStrOffsets,
118061da546Spatrick eSectionTypeDWARFDebugStrOffsetsDwo,
119061da546Spatrick m_data_debug_str_offsets);
120061da546Spatrick }
121061da546Spatrick
getOrLoadDebugTypesData()122061da546Spatrick const DWARFDataExtractor &DWARFContext::getOrLoadDebugTypesData() {
123061da546Spatrick return LoadOrGetSection(eSectionTypeDWARFDebugTypes,
124061da546Spatrick eSectionTypeDWARFDebugTypesDwo, m_data_debug_types);
125061da546Spatrick }
126061da546Spatrick
GetAsLLVM()127061da546Spatrick llvm::DWARFContext &DWARFContext::GetAsLLVM() {
128061da546Spatrick if (!m_llvm_context) {
129061da546Spatrick llvm::StringMap<std::unique_ptr<llvm::MemoryBuffer>> section_map;
130061da546Spatrick uint8_t addr_size = 0;
131dda28197Spatrick auto AddSection = [&](llvm::StringRef name, DWARFDataExtractor data) {
132061da546Spatrick // Set the address size the first time we see it.
133061da546Spatrick if (addr_size == 0)
134dda28197Spatrick addr_size = data.GetAddressByteSize();
135061da546Spatrick
136061da546Spatrick section_map.try_emplace(
137dda28197Spatrick name, llvm::MemoryBuffer::getMemBuffer(toStringRef(data.GetData()),
138dda28197Spatrick name, false));
139061da546Spatrick };
140061da546Spatrick
141dda28197Spatrick AddSection("debug_line_str", getOrLoadLineStrData());
142dda28197Spatrick AddSection("debug_cu_index", getOrLoadCuIndexData());
143dda28197Spatrick AddSection("debug_tu_index", getOrLoadTuIndexData());
144061da546Spatrick
145061da546Spatrick m_llvm_context = llvm::DWARFContext::create(section_map, addr_size);
146061da546Spatrick }
147061da546Spatrick return *m_llvm_context;
148061da546Spatrick }
149