LLDB  mainline
ObjectFileBreakpad.cpp
Go to the documentation of this file.
1 //===-- ObjectFileBreakpad.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 
11 #include "lldb/Core/ModuleSpec.h"
13 #include "lldb/Core/Section.h"
14 
15 using namespace lldb;
16 using namespace lldb_private;
17 using namespace lldb_private::breakpad;
18 
19 namespace {
20 struct Header {
21  ArchSpec arch;
22  UUID uuid;
23  static llvm::Optional<Header> parse(llvm::StringRef text);
24 };
25 } // namespace
26 
27 llvm::Optional<Header> Header::parse(llvm::StringRef text) {
28  llvm::StringRef line;
29  std::tie(line, text) = text.split('\n');
30  auto Module = ModuleRecord::parse(line);
31  if (!Module)
32  return llvm::None;
33 
34  llvm::Triple triple;
35  triple.setArch(Module->Arch);
36  triple.setOS(Module->OS);
37 
38  std::tie(line, text) = text.split('\n');
39 
40  auto Info = InfoRecord::parse(line);
41  UUID uuid = Info && Info->ID ? Info->ID : Module->ID;
42  return Header{ArchSpec(triple), std::move(uuid)};
43 }
44 
45 void ObjectFileBreakpad::Initialize() {
46  PluginManager::RegisterPlugin(GetPluginNameStatic(),
47  GetPluginDescriptionStatic(), CreateInstance,
48  CreateMemoryInstance, GetModuleSpecifications);
49 }
50 
51 void ObjectFileBreakpad::Terminate() {
52  PluginManager::UnregisterPlugin(CreateInstance);
53 }
54 
55 ConstString ObjectFileBreakpad::GetPluginNameStatic() {
56  static ConstString g_name("breakpad");
57  return g_name;
58 }
59 
60 ObjectFile *ObjectFileBreakpad::CreateInstance(
61  const ModuleSP &module_sp, DataBufferSP &data_sp, offset_t data_offset,
62  const FileSpec *file, offset_t file_offset, offset_t length) {
63  if (!data_sp) {
64  data_sp = MapFileData(*file, length, file_offset);
65  if (!data_sp)
66  return nullptr;
67  data_offset = 0;
68  }
69  auto text = toStringRef(data_sp->GetData());
70  llvm::Optional<Header> header = Header::parse(text);
71  if (!header)
72  return nullptr;
73 
74  // Update the data to contain the entire file if it doesn't already
75  if (data_sp->GetByteSize() < length) {
76  data_sp = MapFileData(*file, length, file_offset);
77  if (!data_sp)
78  return nullptr;
79  data_offset = 0;
80  }
81 
82  return new ObjectFileBreakpad(module_sp, data_sp, data_offset, file,
83  file_offset, length, std::move(header->arch),
84  std::move(header->uuid));
85 }
86 
87 ObjectFile *ObjectFileBreakpad::CreateMemoryInstance(
88  const ModuleSP &module_sp, DataBufferSP &data_sp,
89  const ProcessSP &process_sp, addr_t header_addr) {
90  return nullptr;
91 }
92 
93 size_t ObjectFileBreakpad::GetModuleSpecifications(
94  const FileSpec &file, DataBufferSP &data_sp, offset_t data_offset,
95  offset_t file_offset, offset_t length, ModuleSpecList &specs) {
96  auto text = toStringRef(data_sp->GetData());
97  llvm::Optional<Header> header = Header::parse(text);
98  if (!header)
99  return 0;
100  ModuleSpec spec(file, std::move(header->arch));
101  spec.GetUUID() = std::move(header->uuid);
102  specs.Append(spec);
103  return 1;
104 }
105 
106 ObjectFileBreakpad::ObjectFileBreakpad(const ModuleSP &module_sp,
107  DataBufferSP &data_sp,
108  offset_t data_offset,
109  const FileSpec *file, offset_t offset,
110  offset_t length, ArchSpec arch,
111  UUID uuid)
112  : ObjectFile(module_sp, file, offset, length, data_sp, data_offset),
113  m_arch(std::move(arch)), m_uuid(std::move(uuid)) {}
114 
115 bool ObjectFileBreakpad::ParseHeader() {
116  // We already parsed the header during initialization.
117  return true;
118 }
119 
120 Symtab *ObjectFileBreakpad::GetSymtab() {
121  // TODO
122  return nullptr;
123 }
124 
125 void ObjectFileBreakpad::CreateSections(SectionList &unified_section_list) {
126  if (m_sections_up)
127  return;
128  m_sections_up = llvm::make_unique<SectionList>();
129 
130  llvm::Optional<Record::Kind> current_section;
131  offset_t section_start;
132  llvm::StringRef text = toStringRef(m_data.GetData());
133  uint32_t next_section_id = 1;
134  auto maybe_add_section = [&](const uint8_t *end_ptr) {
135  if (!current_section)
136  return; // We have been called before parsing the first line.
137 
138  offset_t end_offset = end_ptr - m_data.GetDataStart();
139  auto section_sp = std::make_shared<Section>(
140  GetModule(), this, next_section_id++,
141  ConstString(toString(*current_section)), eSectionTypeOther,
142  /*file_vm_addr*/ 0, /*vm_size*/ 0, section_start,
143  end_offset - section_start, /*log2align*/ 0, /*flags*/ 0);
144  m_sections_up->AddSection(section_sp);
145  unified_section_list.AddSection(section_sp);
146  };
147  while (!text.empty()) {
148  llvm::StringRef line;
149  std::tie(line, text) = text.split('\n');
150 
151  llvm::Optional<Record::Kind> next_section = Record::classify(line);
152  if (next_section == Record::Line) {
153  // Line records logically belong to the preceding Func record, so we put
154  // them in the same section.
155  next_section = Record::Func;
156  }
157  if (next_section == current_section)
158  continue;
159 
160  // Changing sections, finish off the previous one, if there was any.
161  maybe_add_section(line.bytes_begin());
162  // And start a new one.
163  current_section = next_section;
164  section_start = line.bytes_begin() - m_data.GetDataStart();
165  }
166  // Finally, add the last section.
167  maybe_add_section(m_data.GetDataEnd());
168 }
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
A file utility class.
Definition: FileSpec.h:55
An architecture specification class.
Definition: ArchSpec.h:32
A plug-in interface definition class for object file parsers.
Definition: ObjectFile.h:58
llvm::StringRef toString(Record::Kind K)
uint64_t offset_t
Definition: lldb-types.h:87
A class that describes an executable image and its associated object and symbol files.
Definition: Module.h:109
void Append(const ModuleSpec &spec)
Definition: ModuleSpec.h:333
uint64_t addr_t
Definition: lldb-types.h:83
A uniqued constant string class.
Definition: ConstString.h:38
Definition: SBAddress.h:15
size_t AddSection(const lldb::SectionSP &section_sp)
Definition: Section.cpp:428