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