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 &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