xref: /freebsd-src/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp (revision 2d4e511ca269f1908d27f4e5779c53475527391d)
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 
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 &
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 
43 const DWARFDataExtractor &DWARFContext::getOrLoadAbbrevData() {
44   return LoadOrGetSection(eSectionTypeDWARFDebugAbbrev,
45                           eSectionTypeDWARFDebugAbbrevDwo, m_data_debug_abbrev);
46 }
47 
48 const DWARFDataExtractor &DWARFContext::getOrLoadArangesData() {
49   return LoadOrGetSection(eSectionTypeDWARFDebugAranges, llvm::None,
50                           m_data_debug_aranges);
51 }
52 
53 const DWARFDataExtractor &DWARFContext::getOrLoadAddrData() {
54   return LoadOrGetSection(eSectionTypeDWARFDebugAddr, llvm::None,
55                           m_data_debug_addr);
56 }
57 
58 const DWARFDataExtractor &DWARFContext::getOrLoadDebugInfoData() {
59   return LoadOrGetSection(eSectionTypeDWARFDebugInfo,
60                           eSectionTypeDWARFDebugInfoDwo, m_data_debug_info);
61 }
62 
63 const DWARFDataExtractor &DWARFContext::getOrLoadLineData() {
64   return LoadOrGetSection(eSectionTypeDWARFDebugLine, llvm::None,
65                           m_data_debug_line);
66 }
67 
68 const DWARFDataExtractor &DWARFContext::getOrLoadLineStrData() {
69   return LoadOrGetSection(eSectionTypeDWARFDebugLineStr, llvm::None,
70                           m_data_debug_line_str);
71 }
72 
73 const DWARFDataExtractor &DWARFContext::getOrLoadMacroData() {
74   return LoadOrGetSection(eSectionTypeDWARFDebugMacro, llvm::None,
75                           m_data_debug_macro);
76 }
77 
78 const DWARFDataExtractor &DWARFContext::getOrLoadRangesData() {
79   return LoadOrGetSection(eSectionTypeDWARFDebugRanges, llvm::None,
80                           m_data_debug_ranges);
81 }
82 
83 const DWARFDataExtractor &DWARFContext::getOrLoadRngListsData() {
84   return LoadOrGetSection(eSectionTypeDWARFDebugRngLists, llvm::None,
85                           m_data_debug_rnglists);
86 }
87 
88 const DWARFDataExtractor &DWARFContext::getOrLoadStrData() {
89   return LoadOrGetSection(eSectionTypeDWARFDebugStr,
90                           eSectionTypeDWARFDebugStrDwo, m_data_debug_str);
91 }
92 
93 const DWARFDataExtractor &DWARFContext::getOrLoadStrOffsetsData() {
94   return LoadOrGetSection(eSectionTypeDWARFDebugStrOffsets,
95                           eSectionTypeDWARFDebugStrOffsetsDwo,
96                           m_data_debug_str_offsets);
97 }
98 
99 const DWARFDataExtractor &DWARFContext::getOrLoadDebugTypesData() {
100   return LoadOrGetSection(eSectionTypeDWARFDebugTypes,
101                           eSectionTypeDWARFDebugTypesDwo, m_data_debug_types);
102 }
103 
104 llvm::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 &section) {
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 &section : *m_main_section_list)
127         AddSection(*section);
128     }
129 
130     if (m_dwo_section_list) {
131       for (auto &section : *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