LLDB mainline
ObjectFilePDB.cpp
Go to the documentation of this file.
1//===-- ObjectFilePDB.cpp -------------------------------------------------===//
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 "ObjectFilePDB.h"
10#include "lldb/Core/Module.h"
13#include "lldb/Core/Section.h"
15#include "llvm/BinaryFormat/Magic.h"
16#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
17#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
18#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
19#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
20#include "llvm/DebugInfo/PDB/PDB.h"
21#include "llvm/Support/BinaryByteStream.h"
22
23using namespace lldb;
24using namespace lldb_private;
25using namespace llvm::pdb;
26using namespace llvm::codeview;
27
29
30static UUID GetPDBUUID(InfoStream &IS, DbiStream &DS) {
31 UUID::CvRecordPdb70 debug_info;
32 memcpy(&debug_info.Uuid, IS.getGuid().Guid, sizeof(debug_info.Uuid));
33 debug_info.Age = DS.getAge();
34 return UUID(debug_info);
35}
36
38
44
48
50 auto dbi_stream = m_file_up->getPDBDbiStream();
51 if (!dbi_stream) {
52 llvm::consumeError(dbi_stream.takeError());
53 return ArchSpec();
54 }
55
56 PDB_Machine machine = dbi_stream->getMachineType();
57 switch (machine) {
58 default:
59 break;
60 case PDB_Machine::Amd64:
61 case PDB_Machine::x86:
62 case PDB_Machine::PowerPC:
63 case PDB_Machine::PowerPCFP:
64 case PDB_Machine::Arm:
65 case PDB_Machine::ArmNT:
66 case PDB_Machine::Thumb:
67 case PDB_Machine::Arm64:
68 ArchSpec arch;
69 arch.SetArchitecture(eArchTypeCOFF, static_cast<int>(machine),
71 return arch;
72 }
73 return ArchSpec();
74}
75
78 if (!m_file_up)
79 return false;
80 auto info_stream = m_file_up->getPDBInfoStream();
81 if (!info_stream) {
82 llvm::consumeError(info_stream.takeError());
83 return false;
84 }
85 auto dbi_stream = m_file_up->getPDBDbiStream();
86 if (!dbi_stream) {
87 llvm::consumeError(dbi_stream.takeError());
88 return false;
89 }
90 m_uuid = GetPDBUUID(*info_stream, *dbi_stream);
91 return true;
92}
93
95 DataExtractorSP extractor_sp,
96 offset_t data_offset,
97 const FileSpec *file,
98 offset_t file_offset,
99 offset_t length) {
100 auto objfile_up = std::make_unique<ObjectFilePDB>(
101 module_sp, extractor_sp, data_offset, file, file_offset, length);
102 if (!objfile_up->initPDBFile())
103 return nullptr;
104 return objfile_up.release();
105}
106
108 WritableDataBufferSP data_sp,
109 const ProcessSP &process_sp,
110 addr_t header_addr) {
111 return nullptr;
112}
113
115 const FileSpec &file, DataBufferSP &data_sp, offset_t data_offset,
116 offset_t file_offset, offset_t length, ModuleSpecList &specs) {
117 const size_t initial_count = specs.GetSize();
118 ModuleSpec module_spec(file);
119 llvm::BumpPtrAllocator allocator;
120 std::unique_ptr<PDBFile> pdb_file = loadPDBFile(file.GetPath(), allocator);
121 if (!pdb_file)
122 return initial_count;
123
124 auto info_stream = pdb_file->getPDBInfoStream();
125 if (!info_stream) {
126 llvm::consumeError(info_stream.takeError());
127 return initial_count;
128 }
129 auto dbi_stream = pdb_file->getPDBDbiStream();
130 if (!dbi_stream) {
131 llvm::consumeError(dbi_stream.takeError());
132 return initial_count;
133 }
134
135 lldb_private::UUID &uuid = module_spec.GetUUID();
136 uuid = GetPDBUUID(*info_stream, *dbi_stream);
137
138 ArchSpec &module_arch = module_spec.GetArchitecture();
139 switch (dbi_stream->getMachineType()) {
140 case PDB_Machine::Amd64:
141 module_arch.SetTriple("x86_64-pc-windows");
142 specs.Append(module_spec);
143 break;
144 case PDB_Machine::x86:
145 module_arch.SetTriple("i386-pc-windows");
146 specs.Append(module_spec);
147 break;
148 case PDB_Machine::ArmNT:
149 module_arch.SetTriple("armv7-pc-windows");
150 specs.Append(module_spec);
151 break;
152 case PDB_Machine::Arm64:
153 module_arch.SetTriple("aarch64-pc-windows");
154 specs.Append(module_spec);
155 break;
156 default:
157 break;
158 }
159
160 return specs.GetSize() - initial_count;
161}
162
164 DataExtractorSP &extractor_sp,
165 offset_t data_offset, const FileSpec *file,
166 offset_t offset, offset_t length)
167 : ObjectFile(module_sp, file, offset, length, extractor_sp, data_offset) {}
168
169std::unique_ptr<PDBFile>
170ObjectFilePDB::loadPDBFile(std::string PdbPath,
171 llvm::BumpPtrAllocator &Allocator) {
172 llvm::file_magic magic;
173 auto ec = llvm::identify_magic(PdbPath, magic);
174 if (ec || magic != llvm::file_magic::pdb)
175 return nullptr;
176 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> ErrorOrBuffer =
177 llvm::MemoryBuffer::getFile(PdbPath, /*IsText=*/false,
178 /*RequiresNullTerminator=*/false);
179 if (!ErrorOrBuffer)
180 return nullptr;
181 std::unique_ptr<llvm::MemoryBuffer> Buffer = std::move(*ErrorOrBuffer);
182
183 llvm::StringRef Path = Buffer->getBufferIdentifier();
184 auto Stream = std::make_unique<llvm::MemoryBufferByteStream>(
185 std::move(Buffer), llvm::endianness::little);
186
187 auto File = std::make_unique<PDBFile>(Path, std::move(Stream), Allocator);
188 if (auto EC = File->parseFileHeaders()) {
189 llvm::consumeError(std::move(EC));
190 return nullptr;
191 }
192 if (auto EC = File->parseStreamData()) {
193 llvm::consumeError(std::move(EC));
194 return nullptr;
195 }
196
197 return File;
198}
static UUID GetPDBUUID(InfoStream &IS, DbiStream &DS)
#define LLDB_PLUGIN_DEFINE(PluginName)
An architecture specification class.
Definition ArchSpec.h:31
bool SetTriple(const llvm::Triple &triple)
Architecture triple setter.
Definition ArchSpec.cpp:741
bool SetArchitecture(ArchitectureType arch_type, uint32_t cpu, uint32_t sub, uint32_t os=0)
Change the architecture object type, CPU type and OS type.
Definition ArchSpec.cpp:845
A file utility class.
Definition FileSpec.h:57
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition FileSpec.cpp:374
An abstract base class for files.
Definition File.h:36
void Append(const ModuleSpec &spec)
Definition ModuleSpec.h:326
ArchSpec & GetArchitecture()
Definition ModuleSpec.h:91
static ObjectFile * CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataExtractorSP extractor_sp, lldb::offset_t data_offset, const FileSpec *file, lldb::offset_t file_offset, lldb::offset_t length)
static const char * GetPluginDescriptionStatic()
static std::unique_ptr< llvm::pdb::PDBFile > loadPDBFile(std::string PdbPath, llvm::BumpPtrAllocator &Allocator)
static size_t GetModuleSpecifications(const FileSpec &file, lldb::DataBufferSP &data_sp, lldb::offset_t data_offset, lldb::offset_t file_offset, lldb::offset_t length, ModuleSpecList &specs)
std::unique_ptr< llvm::pdb::PDBFile > m_file_up
static ObjectFile * CreateMemoryInstance(const lldb::ModuleSP &module_sp, lldb::WritableDataBufferSP data_sp, const lldb::ProcessSP &process_sp, lldb::addr_t header_addr)
ObjectFilePDB(const lldb::ModuleSP &module_sp, lldb::DataExtractorSP &extractor_sp, lldb::offset_t data_offset, const FileSpec *file, lldb::offset_t offset, lldb::offset_t length)
llvm::BumpPtrAllocator m_allocator
static llvm::StringRef GetPluginNameStatic()
ArchSpec GetArchitecture() override
Get the ArchSpec for this object file.
ObjectFile(const lldb::ModuleSP &module_sp, const FileSpec *file_spec_ptr, lldb::offset_t file_offset, lldb::offset_t length, lldb::DataExtractorSP extractor_sp, lldb::offset_t data_offset)
Construct with a parent module, offset, and header data.
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
A stream class that can stream formatted output to a file.
Definition Stream.h:28
Represents UUID's of various sizes.
Definition UUID.h:27
#define LLDB_INVALID_CPUTYPE
A class that represents a running process on the host machine.
uint64_t offset_t
Definition lldb-types.h:85
std::shared_ptr< lldb_private::Process > ProcessSP
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
uint64_t addr_t
Definition lldb-types.h:80
std::shared_ptr< lldb_private::DataExtractor > DataExtractorSP
std::shared_ptr< lldb_private::Module > ModuleSP
struct lldb_private::UUID::CvRecordPdb70::@270014123013057306020052025020177330273131255133 Uuid
llvm::support::ulittle32_t Age
Definition UUID.h:47