1 //===-- SymbolFileNativePDB.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 "SymbolFileNativePDB.h"
10
11 #include "clang/AST/Attr.h"
12 #include "clang/AST/CharUnits.h"
13 #include "clang/AST/Decl.h"
14 #include "clang/AST/DeclCXX.h"
15 #include "clang/AST/Type.h"
16
17 #include "Plugins/ExpressionParser/Clang/ClangUtil.h"
18 #include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h"
19 #include "Plugins/ObjectFile/PDB/ObjectFilePDB.h"
20 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
21 #include "lldb/Core/Module.h"
22 #include "lldb/Core/PluginManager.h"
23 #include "lldb/Core/StreamBuffer.h"
24 #include "lldb/Core/StreamFile.h"
25 #include "lldb/Symbol/CompileUnit.h"
26 #include "lldb/Symbol/LineTable.h"
27 #include "lldb/Symbol/ObjectFile.h"
28 #include "lldb/Symbol/SymbolContext.h"
29 #include "lldb/Symbol/SymbolVendor.h"
30 #include "lldb/Symbol/Variable.h"
31 #include "lldb/Symbol/VariableList.h"
32 #include "lldb/Utility/LLDBLog.h"
33 #include "lldb/Utility/Log.h"
34
35 #include "llvm/DebugInfo/CodeView/CVRecord.h"
36 #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
37 #include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
38 #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
39 #include "llvm/DebugInfo/CodeView/RecordName.h"
40 #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
41 #include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h"
42 #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
43 #include "llvm/DebugInfo/PDB/Native/DbiStream.h"
44 #include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
45 #include "llvm/DebugInfo/PDB/Native/InfoStream.h"
46 #include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
47 #include "llvm/DebugInfo/PDB/Native/NativeSession.h"
48 #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
49 #include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
50 #include "llvm/DebugInfo/PDB/Native/TpiStream.h"
51 #include "llvm/DebugInfo/PDB/PDB.h"
52 #include "llvm/DebugInfo/PDB/PDBTypes.h"
53 #include "llvm/Demangle/MicrosoftDemangle.h"
54 #include "llvm/Object/COFF.h"
55 #include "llvm/Support/Allocator.h"
56 #include "llvm/Support/BinaryStreamReader.h"
57 #include "llvm/Support/Error.h"
58 #include "llvm/Support/ErrorOr.h"
59 #include "llvm/Support/MemoryBuffer.h"
60
61 #include "DWARFLocationExpression.h"
62 #include "PdbAstBuilder.h"
63 #include "PdbSymUid.h"
64 #include "PdbUtil.h"
65 #include "UdtRecordCompleter.h"
66
67 using namespace lldb;
68 using namespace lldb_private;
69 using namespace npdb;
70 using namespace llvm::codeview;
71 using namespace llvm::pdb;
72
73 char SymbolFileNativePDB::ID;
74
TranslateLanguage(PDB_Lang lang)75 static lldb::LanguageType TranslateLanguage(PDB_Lang lang) {
76 switch (lang) {
77 case PDB_Lang::Cpp:
78 return lldb::LanguageType::eLanguageTypeC_plus_plus;
79 case PDB_Lang::C:
80 return lldb::LanguageType::eLanguageTypeC;
81 case PDB_Lang::Swift:
82 return lldb::LanguageType::eLanguageTypeSwift;
83 case PDB_Lang::Rust:
84 return lldb::LanguageType::eLanguageTypeRust;
85 default:
86 return lldb::LanguageType::eLanguageTypeUnknown;
87 }
88 }
89
90 static std::unique_ptr<PDBFile>
loadMatchingPDBFile(std::string exe_path,llvm::BumpPtrAllocator & allocator)91 loadMatchingPDBFile(std::string exe_path, llvm::BumpPtrAllocator &allocator) {
92 // Try to find a matching PDB for an EXE.
93 using namespace llvm::object;
94 auto expected_binary = createBinary(exe_path);
95
96 // If the file isn't a PE/COFF executable, fail.
97 if (!expected_binary) {
98 llvm::consumeError(expected_binary.takeError());
99 return nullptr;
100 }
101 OwningBinary<Binary> binary = std::move(*expected_binary);
102
103 // TODO: Avoid opening the PE/COFF binary twice by reading this information
104 // directly from the lldb_private::ObjectFile.
105 auto *obj = llvm::dyn_cast<llvm::object::COFFObjectFile>(binary.getBinary());
106 if (!obj)
107 return nullptr;
108 const llvm::codeview::DebugInfo *pdb_info = nullptr;
109
110 // If it doesn't have a debug directory, fail.
111 llvm::StringRef pdb_file;
112 if (llvm::Error e = obj->getDebugPDBInfo(pdb_info, pdb_file)) {
113 consumeError(std::move(e));
114 return nullptr;
115 }
116
117 // If the file doesn't exist, perhaps the path specified at build time
118 // doesn't match the PDB's current location, so check the location of the
119 // executable.
120 if (!FileSystem::Instance().Exists(pdb_file)) {
121 const auto exe_dir = FileSpec(exe_path).CopyByRemovingLastPathComponent();
122 const auto pdb_name = FileSpec(pdb_file).GetFilename().GetCString();
123 pdb_file = exe_dir.CopyByAppendingPathComponent(pdb_name).GetCString();
124 }
125
126 // If the file is not a PDB or if it doesn't have a matching GUID, fail.
127 auto pdb = ObjectFilePDB::loadPDBFile(std::string(pdb_file), allocator);
128 if (!pdb)
129 return nullptr;
130
131 auto expected_info = pdb->getPDBInfoStream();
132 if (!expected_info) {
133 llvm::consumeError(expected_info.takeError());
134 return nullptr;
135 }
136 llvm::codeview::GUID guid;
137 memcpy(&guid, pdb_info->PDB70.Signature, 16);
138
139 if (expected_info->getGuid() != guid)
140 return nullptr;
141 return pdb;
142 }
143
IsFunctionPrologue(const CompilandIndexItem & cci,lldb::addr_t addr)144 static bool IsFunctionPrologue(const CompilandIndexItem &cci,
145 lldb::addr_t addr) {
146 // FIXME: Implement this.
147 return false;
148 }
149
IsFunctionEpilogue(const CompilandIndexItem & cci,lldb::addr_t addr)150 static bool IsFunctionEpilogue(const CompilandIndexItem &cci,
151 lldb::addr_t addr) {
152 // FIXME: Implement this.
153 return false;
154 }
155
GetSimpleTypeName(SimpleTypeKind kind)156 static llvm::StringRef GetSimpleTypeName(SimpleTypeKind kind) {
157 switch (kind) {
158 case SimpleTypeKind::Boolean128:
159 case SimpleTypeKind::Boolean16:
160 case SimpleTypeKind::Boolean32:
161 case SimpleTypeKind::Boolean64:
162 case SimpleTypeKind::Boolean8:
163 return "bool";
164 case SimpleTypeKind::Byte:
165 case SimpleTypeKind::UnsignedCharacter:
166 return "unsigned char";
167 case SimpleTypeKind::NarrowCharacter:
168 return "char";
169 case SimpleTypeKind::SignedCharacter:
170 case SimpleTypeKind::SByte:
171 return "signed char";
172 case SimpleTypeKind::Character16:
173 return "char16_t";
174 case SimpleTypeKind::Character32:
175 return "char32_t";
176 case SimpleTypeKind::Character8:
177 return "char8_t";
178 case SimpleTypeKind::Complex80:
179 case SimpleTypeKind::Complex64:
180 case SimpleTypeKind::Complex32:
181 return "complex";
182 case SimpleTypeKind::Float128:
183 case SimpleTypeKind::Float80:
184 return "long double";
185 case SimpleTypeKind::Float64:
186 return "double";
187 case SimpleTypeKind::Float32:
188 return "float";
189 case SimpleTypeKind::Float16:
190 return "single";
191 case SimpleTypeKind::Int128:
192 return "__int128";
193 case SimpleTypeKind::Int64:
194 case SimpleTypeKind::Int64Quad:
195 return "int64_t";
196 case SimpleTypeKind::Int32:
197 return "int";
198 case SimpleTypeKind::Int16:
199 return "short";
200 case SimpleTypeKind::UInt128:
201 return "unsigned __int128";
202 case SimpleTypeKind::UInt64:
203 case SimpleTypeKind::UInt64Quad:
204 return "uint64_t";
205 case SimpleTypeKind::HResult:
206 return "HRESULT";
207 case SimpleTypeKind::UInt32:
208 return "unsigned";
209 case SimpleTypeKind::UInt16:
210 case SimpleTypeKind::UInt16Short:
211 return "unsigned short";
212 case SimpleTypeKind::Int32Long:
213 return "long";
214 case SimpleTypeKind::UInt32Long:
215 return "unsigned long";
216 case SimpleTypeKind::Void:
217 return "void";
218 case SimpleTypeKind::WideCharacter:
219 return "wchar_t";
220 default:
221 return "";
222 }
223 }
224
IsClassRecord(TypeLeafKind kind)225 static bool IsClassRecord(TypeLeafKind kind) {
226 switch (kind) {
227 case LF_STRUCTURE:
228 case LF_CLASS:
229 case LF_INTERFACE:
230 return true;
231 default:
232 return false;
233 }
234 }
235
Initialize()236 void SymbolFileNativePDB::Initialize() {
237 PluginManager::RegisterPlugin(GetPluginNameStatic(),
238 GetPluginDescriptionStatic(), CreateInstance,
239 DebuggerInitialize);
240 }
241
Terminate()242 void SymbolFileNativePDB::Terminate() {
243 PluginManager::UnregisterPlugin(CreateInstance);
244 }
245
DebuggerInitialize(Debugger & debugger)246 void SymbolFileNativePDB::DebuggerInitialize(Debugger &debugger) {}
247
GetPluginDescriptionStatic()248 llvm::StringRef SymbolFileNativePDB::GetPluginDescriptionStatic() {
249 return "Microsoft PDB debug symbol cross-platform file reader.";
250 }
251
CreateInstance(ObjectFileSP objfile_sp)252 SymbolFile *SymbolFileNativePDB::CreateInstance(ObjectFileSP objfile_sp) {
253 return new SymbolFileNativePDB(std::move(objfile_sp));
254 }
255
SymbolFileNativePDB(ObjectFileSP objfile_sp)256 SymbolFileNativePDB::SymbolFileNativePDB(ObjectFileSP objfile_sp)
257 : SymbolFileCommon(std::move(objfile_sp)) {}
258
259 SymbolFileNativePDB::~SymbolFileNativePDB() = default;
260
CalculateAbilities()261 uint32_t SymbolFileNativePDB::CalculateAbilities() {
262 uint32_t abilities = 0;
263 if (!m_objfile_sp)
264 return 0;
265
266 if (!m_index) {
267 // Lazily load and match the PDB file, but only do this once.
268 PDBFile *pdb_file;
269 if (auto *pdb = llvm::dyn_cast<ObjectFilePDB>(m_objfile_sp.get())) {
270 pdb_file = &pdb->GetPDBFile();
271 } else {
272 m_file_up = loadMatchingPDBFile(m_objfile_sp->GetFileSpec().GetPath(),
273 m_allocator);
274 pdb_file = m_file_up.get();
275 }
276
277 if (!pdb_file)
278 return 0;
279
280 auto expected_index = PdbIndex::create(pdb_file);
281 if (!expected_index) {
282 llvm::consumeError(expected_index.takeError());
283 return 0;
284 }
285 m_index = std::move(*expected_index);
286 }
287 if (!m_index)
288 return 0;
289
290 // We don't especially have to be precise here. We only distinguish between
291 // stripped and not stripped.
292 abilities = kAllAbilities;
293
294 if (m_index->dbi().isStripped())
295 abilities &= ~(Blocks | LocalVariables);
296 return abilities;
297 }
298
InitializeObject()299 void SymbolFileNativePDB::InitializeObject() {
300 m_obj_load_address = m_objfile_sp->GetModule()
301 ->GetObjectFile()
302 ->GetBaseAddress()
303 .GetFileAddress();
304 m_index->SetLoadAddress(m_obj_load_address);
305 m_index->ParseSectionContribs();
306
307 auto ts_or_err = m_objfile_sp->GetModule()->GetTypeSystemForLanguage(
308 lldb::eLanguageTypeC_plus_plus);
309 if (auto err = ts_or_err.takeError()) {
310 LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err),
311 "Failed to initialize");
312 } else {
313 ts_or_err->SetSymbolFile(this);
314 auto *clang = llvm::cast_or_null<TypeSystemClang>(&ts_or_err.get());
315 lldbassert(clang);
316 m_ast = std::make_unique<PdbAstBuilder>(*m_objfile_sp, *m_index, *clang);
317 }
318 }
319
CalculateNumCompileUnits()320 uint32_t SymbolFileNativePDB::CalculateNumCompileUnits() {
321 const DbiModuleList &modules = m_index->dbi().modules();
322 uint32_t count = modules.getModuleCount();
323 if (count == 0)
324 return count;
325
326 // The linker can inject an additional "dummy" compilation unit into the
327 // PDB. Ignore this special compile unit for our purposes, if it is there.
328 // It is always the last one.
329 DbiModuleDescriptor last = modules.getModuleDescriptor(count - 1);
330 if (last.getModuleName() == "* Linker *")
331 --count;
332 return count;
333 }
334
CreateBlock(PdbCompilandSymId block_id)335 Block &SymbolFileNativePDB::CreateBlock(PdbCompilandSymId block_id) {
336 CompilandIndexItem *cii = m_index->compilands().GetCompiland(block_id.modi);
337 CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(block_id.offset);
338 CompUnitSP comp_unit = GetOrCreateCompileUnit(*cii);
339 lldb::user_id_t opaque_block_uid = toOpaqueUid(block_id);
340 BlockSP child_block = std::make_shared<Block>(opaque_block_uid);
341
342 switch (sym.kind()) {
343 case S_GPROC32:
344 case S_LPROC32: {
345 // This is a function. It must be global. Creating the Function entry
346 // for it automatically creates a block for it.
347 FunctionSP func = GetOrCreateFunction(block_id, *comp_unit);
348 Block &block = func->GetBlock(false);
349 if (block.GetNumRanges() == 0)
350 block.AddRange(Block::Range(0, func->GetAddressRange().GetByteSize()));
351 return block;
352 }
353 case S_BLOCK32: {
354 // This is a block. Its parent is either a function or another block. In
355 // either case, its parent can be viewed as a block (e.g. a function
356 // contains 1 big block. So just get the parent block and add this block
357 // to it.
358 BlockSym block(static_cast<SymbolRecordKind>(sym.kind()));
359 cantFail(SymbolDeserializer::deserializeAs<BlockSym>(sym, block));
360 lldbassert(block.Parent != 0);
361 PdbCompilandSymId parent_id(block_id.modi, block.Parent);
362 Block &parent_block = GetOrCreateBlock(parent_id);
363 parent_block.AddChild(child_block);
364 m_ast->GetOrCreateBlockDecl(block_id);
365 m_blocks.insert({opaque_block_uid, child_block});
366 break;
367 }
368 case S_INLINESITE: {
369 // This ensures line table is parsed first so we have inline sites info.
370 comp_unit->GetLineTable();
371
372 std::shared_ptr<InlineSite> inline_site = m_inline_sites[opaque_block_uid];
373 Block &parent_block = GetOrCreateBlock(inline_site->parent_id);
374 parent_block.AddChild(child_block);
375 m_ast->GetOrCreateInlinedFunctionDecl(block_id);
376 // Copy ranges from InlineSite to Block.
377 for (size_t i = 0; i < inline_site->ranges.GetSize(); ++i) {
378 auto *entry = inline_site->ranges.GetEntryAtIndex(i);
379 child_block->AddRange(
380 Block::Range(entry->GetRangeBase(), entry->GetByteSize()));
381 }
382 child_block->FinalizeRanges();
383
384 // Get the inlined function callsite info.
385 Declaration &decl = inline_site->inline_function_info->GetDeclaration();
386 Declaration &callsite = inline_site->inline_function_info->GetCallSite();
387 child_block->SetInlinedFunctionInfo(
388 inline_site->inline_function_info->GetName().GetCString(), nullptr,
389 &decl, &callsite);
390 m_blocks.insert({opaque_block_uid, child_block});
391 break;
392 }
393 default:
394 lldbassert(false && "Symbol is not a block!");
395 }
396
397 return *child_block;
398 }
399
CreateFunction(PdbCompilandSymId func_id,CompileUnit & comp_unit)400 lldb::FunctionSP SymbolFileNativePDB::CreateFunction(PdbCompilandSymId func_id,
401 CompileUnit &comp_unit) {
402 const CompilandIndexItem *cci =
403 m_index->compilands().GetCompiland(func_id.modi);
404 lldbassert(cci);
405 CVSymbol sym_record = cci->m_debug_stream.readSymbolAtOffset(func_id.offset);
406
407 lldbassert(sym_record.kind() == S_LPROC32 || sym_record.kind() == S_GPROC32);
408 SegmentOffsetLength sol = GetSegmentOffsetAndLength(sym_record);
409
410 auto file_vm_addr =
411 m_index->MakeVirtualAddress(sol.so.segment, sol.so.offset);
412 if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0)
413 return nullptr;
414
415 AddressRange func_range(file_vm_addr, sol.length,
416 comp_unit.GetModule()->GetSectionList());
417 if (!func_range.GetBaseAddress().IsValid())
418 return nullptr;
419
420 ProcSym proc(static_cast<SymbolRecordKind>(sym_record.kind()));
421 cantFail(SymbolDeserializer::deserializeAs<ProcSym>(sym_record, proc));
422 if (proc.FunctionType == TypeIndex::None())
423 return nullptr;
424 TypeSP func_type = GetOrCreateType(proc.FunctionType);
425 if (!func_type)
426 return nullptr;
427
428 PdbTypeSymId sig_id(proc.FunctionType, false);
429 Mangled mangled(proc.Name);
430 FunctionSP func_sp = std::make_shared<Function>(
431 &comp_unit, toOpaqueUid(func_id), toOpaqueUid(sig_id), mangled,
432 func_type.get(), func_range);
433
434 comp_unit.AddFunction(func_sp);
435
436 m_ast->GetOrCreateFunctionDecl(func_id);
437
438 return func_sp;
439 }
440
441 CompUnitSP
CreateCompileUnit(const CompilandIndexItem & cci)442 SymbolFileNativePDB::CreateCompileUnit(const CompilandIndexItem &cci) {
443 lldb::LanguageType lang =
444 cci.m_compile_opts ? TranslateLanguage(cci.m_compile_opts->getLanguage())
445 : lldb::eLanguageTypeUnknown;
446
447 LazyBool optimized = eLazyBoolNo;
448 if (cci.m_compile_opts && cci.m_compile_opts->hasOptimizations())
449 optimized = eLazyBoolYes;
450
451 llvm::SmallString<64> source_file_name =
452 m_index->compilands().GetMainSourceFile(cci);
453 FileSpec fs(llvm::sys::path::convert_to_slash(
454 source_file_name, llvm::sys::path::Style::windows_backslash));
455
456 CompUnitSP cu_sp =
457 std::make_shared<CompileUnit>(m_objfile_sp->GetModule(), nullptr, fs,
458 toOpaqueUid(cci.m_id), lang, optimized);
459
460 SetCompileUnitAtIndex(cci.m_id.modi, cu_sp);
461 return cu_sp;
462 }
463
CreateModifierType(PdbTypeSymId type_id,const ModifierRecord & mr,CompilerType ct)464 lldb::TypeSP SymbolFileNativePDB::CreateModifierType(PdbTypeSymId type_id,
465 const ModifierRecord &mr,
466 CompilerType ct) {
467 TpiStream &stream = m_index->tpi();
468
469 std::string name;
470 if (mr.ModifiedType.isSimple())
471 name = std::string(GetSimpleTypeName(mr.ModifiedType.getSimpleKind()));
472 else
473 name = computeTypeName(stream.typeCollection(), mr.ModifiedType);
474 Declaration decl;
475 lldb::TypeSP modified_type = GetOrCreateType(mr.ModifiedType);
476
477 return std::make_shared<Type>(toOpaqueUid(type_id), this, ConstString(name),
478 modified_type->GetByteSize(nullptr), nullptr,
479 LLDB_INVALID_UID, Type::eEncodingIsUID, decl,
480 ct, Type::ResolveState::Full);
481 }
482
483 lldb::TypeSP
CreatePointerType(PdbTypeSymId type_id,const llvm::codeview::PointerRecord & pr,CompilerType ct)484 SymbolFileNativePDB::CreatePointerType(PdbTypeSymId type_id,
485 const llvm::codeview::PointerRecord &pr,
486 CompilerType ct) {
487 TypeSP pointee = GetOrCreateType(pr.ReferentType);
488 if (!pointee)
489 return nullptr;
490
491 if (pr.isPointerToMember()) {
492 MemberPointerInfo mpi = pr.getMemberInfo();
493 GetOrCreateType(mpi.ContainingType);
494 }
495
496 Declaration decl;
497 return std::make_shared<Type>(toOpaqueUid(type_id), this, ConstString(),
498 pr.getSize(), nullptr, LLDB_INVALID_UID,
499 Type::eEncodingIsUID, decl, ct,
500 Type::ResolveState::Full);
501 }
502
CreateSimpleType(TypeIndex ti,CompilerType ct)503 lldb::TypeSP SymbolFileNativePDB::CreateSimpleType(TypeIndex ti,
504 CompilerType ct) {
505 uint64_t uid = toOpaqueUid(PdbTypeSymId(ti, false));
506 if (ti == TypeIndex::NullptrT()) {
507 Declaration decl;
508 return std::make_shared<Type>(
509 uid, this, ConstString("std::nullptr_t"), 0, nullptr, LLDB_INVALID_UID,
510 Type::eEncodingIsUID, decl, ct, Type::ResolveState::Full);
511 }
512
513 if (ti.getSimpleMode() != SimpleTypeMode::Direct) {
514 TypeSP direct_sp = GetOrCreateType(ti.makeDirect());
515 uint32_t pointer_size = 0;
516 switch (ti.getSimpleMode()) {
517 case SimpleTypeMode::FarPointer32:
518 case SimpleTypeMode::NearPointer32:
519 pointer_size = 4;
520 break;
521 case SimpleTypeMode::NearPointer64:
522 pointer_size = 8;
523 break;
524 default:
525 // 128-bit and 16-bit pointers unsupported.
526 return nullptr;
527 }
528 Declaration decl;
529 return std::make_shared<Type>(
530 uid, this, ConstString(), pointer_size, nullptr, LLDB_INVALID_UID,
531 Type::eEncodingIsUID, decl, ct, Type::ResolveState::Full);
532 }
533
534 if (ti.getSimpleKind() == SimpleTypeKind::NotTranslated)
535 return nullptr;
536
537 size_t size = GetTypeSizeForSimpleKind(ti.getSimpleKind());
538 llvm::StringRef type_name = GetSimpleTypeName(ti.getSimpleKind());
539
540 Declaration decl;
541 return std::make_shared<Type>(uid, this, ConstString(type_name), size,
542 nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID,
543 decl, ct, Type::ResolveState::Full);
544 }
545
GetUnqualifiedTypeName(const TagRecord & record)546 static std::string GetUnqualifiedTypeName(const TagRecord &record) {
547 if (!record.hasUniqueName()) {
548 MSVCUndecoratedNameParser parser(record.Name);
549 llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers();
550
551 return std::string(specs.back().GetBaseName());
552 }
553
554 llvm::ms_demangle::Demangler demangler;
555 StringView sv(record.UniqueName.begin(), record.UniqueName.size());
556 llvm::ms_demangle::TagTypeNode *ttn = demangler.parseTagUniqueName(sv);
557 if (demangler.Error)
558 return std::string(record.Name);
559
560 llvm::ms_demangle::IdentifierNode *idn =
561 ttn->QualifiedName->getUnqualifiedIdentifier();
562 return idn->toString();
563 }
564
565 lldb::TypeSP
CreateClassStructUnion(PdbTypeSymId type_id,const TagRecord & record,size_t size,CompilerType ct)566 SymbolFileNativePDB::CreateClassStructUnion(PdbTypeSymId type_id,
567 const TagRecord &record,
568 size_t size, CompilerType ct) {
569
570 std::string uname = GetUnqualifiedTypeName(record);
571
572 // FIXME: Search IPI stream for LF_UDT_MOD_SRC_LINE.
573 Declaration decl;
574 return std::make_shared<Type>(toOpaqueUid(type_id), this, ConstString(uname),
575 size, nullptr, LLDB_INVALID_UID,
576 Type::eEncodingIsUID, decl, ct,
577 Type::ResolveState::Forward);
578 }
579
CreateTagType(PdbTypeSymId type_id,const ClassRecord & cr,CompilerType ct)580 lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbTypeSymId type_id,
581 const ClassRecord &cr,
582 CompilerType ct) {
583 return CreateClassStructUnion(type_id, cr, cr.getSize(), ct);
584 }
585
CreateTagType(PdbTypeSymId type_id,const UnionRecord & ur,CompilerType ct)586 lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbTypeSymId type_id,
587 const UnionRecord &ur,
588 CompilerType ct) {
589 return CreateClassStructUnion(type_id, ur, ur.getSize(), ct);
590 }
591
CreateTagType(PdbTypeSymId type_id,const EnumRecord & er,CompilerType ct)592 lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbTypeSymId type_id,
593 const EnumRecord &er,
594 CompilerType ct) {
595 std::string uname = GetUnqualifiedTypeName(er);
596
597 Declaration decl;
598 TypeSP underlying_type = GetOrCreateType(er.UnderlyingType);
599
600 return std::make_shared<lldb_private::Type>(
601 toOpaqueUid(type_id), this, ConstString(uname),
602 underlying_type->GetByteSize(nullptr), nullptr, LLDB_INVALID_UID,
603 lldb_private::Type::eEncodingIsUID, decl, ct,
604 lldb_private::Type::ResolveState::Forward);
605 }
606
CreateArrayType(PdbTypeSymId type_id,const ArrayRecord & ar,CompilerType ct)607 TypeSP SymbolFileNativePDB::CreateArrayType(PdbTypeSymId type_id,
608 const ArrayRecord &ar,
609 CompilerType ct) {
610 TypeSP element_type = GetOrCreateType(ar.ElementType);
611
612 Declaration decl;
613 TypeSP array_sp = std::make_shared<lldb_private::Type>(
614 toOpaqueUid(type_id), this, ConstString(), ar.Size, nullptr,
615 LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl, ct,
616 lldb_private::Type::ResolveState::Full);
617 array_sp->SetEncodingType(element_type.get());
618 return array_sp;
619 }
620
621
CreateFunctionType(PdbTypeSymId type_id,const MemberFunctionRecord & mfr,CompilerType ct)622 TypeSP SymbolFileNativePDB::CreateFunctionType(PdbTypeSymId type_id,
623 const MemberFunctionRecord &mfr,
624 CompilerType ct) {
625 Declaration decl;
626 return std::make_shared<lldb_private::Type>(
627 toOpaqueUid(type_id), this, ConstString(), 0, nullptr, LLDB_INVALID_UID,
628 lldb_private::Type::eEncodingIsUID, decl, ct,
629 lldb_private::Type::ResolveState::Full);
630 }
631
CreateProcedureType(PdbTypeSymId type_id,const ProcedureRecord & pr,CompilerType ct)632 TypeSP SymbolFileNativePDB::CreateProcedureType(PdbTypeSymId type_id,
633 const ProcedureRecord &pr,
634 CompilerType ct) {
635 Declaration decl;
636 return std::make_shared<lldb_private::Type>(
637 toOpaqueUid(type_id), this, ConstString(), 0, nullptr, LLDB_INVALID_UID,
638 lldb_private::Type::eEncodingIsUID, decl, ct,
639 lldb_private::Type::ResolveState::Full);
640 }
641
CreateType(PdbTypeSymId type_id,CompilerType ct)642 TypeSP SymbolFileNativePDB::CreateType(PdbTypeSymId type_id, CompilerType ct) {
643 if (type_id.index.isSimple())
644 return CreateSimpleType(type_id.index, ct);
645
646 TpiStream &stream = type_id.is_ipi ? m_index->ipi() : m_index->tpi();
647 CVType cvt = stream.getType(type_id.index);
648
649 if (cvt.kind() == LF_MODIFIER) {
650 ModifierRecord modifier;
651 llvm::cantFail(
652 TypeDeserializer::deserializeAs<ModifierRecord>(cvt, modifier));
653 return CreateModifierType(type_id, modifier, ct);
654 }
655
656 if (cvt.kind() == LF_POINTER) {
657 PointerRecord pointer;
658 llvm::cantFail(
659 TypeDeserializer::deserializeAs<PointerRecord>(cvt, pointer));
660 return CreatePointerType(type_id, pointer, ct);
661 }
662
663 if (IsClassRecord(cvt.kind())) {
664 ClassRecord cr;
665 llvm::cantFail(TypeDeserializer::deserializeAs<ClassRecord>(cvt, cr));
666 return CreateTagType(type_id, cr, ct);
667 }
668
669 if (cvt.kind() == LF_ENUM) {
670 EnumRecord er;
671 llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er));
672 return CreateTagType(type_id, er, ct);
673 }
674
675 if (cvt.kind() == LF_UNION) {
676 UnionRecord ur;
677 llvm::cantFail(TypeDeserializer::deserializeAs<UnionRecord>(cvt, ur));
678 return CreateTagType(type_id, ur, ct);
679 }
680
681 if (cvt.kind() == LF_ARRAY) {
682 ArrayRecord ar;
683 llvm::cantFail(TypeDeserializer::deserializeAs<ArrayRecord>(cvt, ar));
684 return CreateArrayType(type_id, ar, ct);
685 }
686
687 if (cvt.kind() == LF_PROCEDURE) {
688 ProcedureRecord pr;
689 llvm::cantFail(TypeDeserializer::deserializeAs<ProcedureRecord>(cvt, pr));
690 return CreateProcedureType(type_id, pr, ct);
691 }
692 if (cvt.kind() == LF_MFUNCTION) {
693 MemberFunctionRecord mfr;
694 llvm::cantFail(TypeDeserializer::deserializeAs<MemberFunctionRecord>(cvt, mfr));
695 return CreateFunctionType(type_id, mfr, ct);
696 }
697
698 return nullptr;
699 }
700
CreateAndCacheType(PdbTypeSymId type_id)701 TypeSP SymbolFileNativePDB::CreateAndCacheType(PdbTypeSymId type_id) {
702 // If they search for a UDT which is a forward ref, try and resolve the full
703 // decl and just map the forward ref uid to the full decl record.
704 llvm::Optional<PdbTypeSymId> full_decl_uid;
705 if (IsForwardRefUdt(type_id, m_index->tpi())) {
706 auto expected_full_ti =
707 m_index->tpi().findFullDeclForForwardRef(type_id.index);
708 if (!expected_full_ti)
709 llvm::consumeError(expected_full_ti.takeError());
710 else if (*expected_full_ti != type_id.index) {
711 full_decl_uid = PdbTypeSymId(*expected_full_ti, false);
712
713 // It's possible that a lookup would occur for the full decl causing it
714 // to be cached, then a second lookup would occur for the forward decl.
715 // We don't want to create a second full decl, so make sure the full
716 // decl hasn't already been cached.
717 auto full_iter = m_types.find(toOpaqueUid(*full_decl_uid));
718 if (full_iter != m_types.end()) {
719 TypeSP result = full_iter->second;
720 // Map the forward decl to the TypeSP for the full decl so we can take
721 // the fast path next time.
722 m_types[toOpaqueUid(type_id)] = result;
723 return result;
724 }
725 }
726 }
727
728 PdbTypeSymId best_decl_id = full_decl_uid ? *full_decl_uid : type_id;
729
730 clang::QualType qt = m_ast->GetOrCreateType(best_decl_id);
731 if (qt.isNull())
732 return nullptr;
733
734 TypeSP result = CreateType(best_decl_id, m_ast->ToCompilerType(qt));
735 if (!result)
736 return nullptr;
737
738 uint64_t best_uid = toOpaqueUid(best_decl_id);
739 m_types[best_uid] = result;
740 // If we had both a forward decl and a full decl, make both point to the new
741 // type.
742 if (full_decl_uid)
743 m_types[toOpaqueUid(type_id)] = result;
744
745 return result;
746 }
747
GetOrCreateType(PdbTypeSymId type_id)748 TypeSP SymbolFileNativePDB::GetOrCreateType(PdbTypeSymId type_id) {
749 // We can't use try_emplace / overwrite here because the process of creating
750 // a type could create nested types, which could invalidate iterators. So
751 // we have to do a 2-phase lookup / insert.
752 auto iter = m_types.find(toOpaqueUid(type_id));
753 if (iter != m_types.end())
754 return iter->second;
755
756 TypeSP type = CreateAndCacheType(type_id);
757 if (type)
758 GetTypeList().Insert(type);
759 return type;
760 }
761
CreateGlobalVariable(PdbGlobalSymId var_id)762 VariableSP SymbolFileNativePDB::CreateGlobalVariable(PdbGlobalSymId var_id) {
763 CVSymbol sym = m_index->symrecords().readRecord(var_id.offset);
764 if (sym.kind() == S_CONSTANT)
765 return CreateConstantSymbol(var_id, sym);
766
767 lldb::ValueType scope = eValueTypeInvalid;
768 TypeIndex ti;
769 llvm::StringRef name;
770 lldb::addr_t addr = 0;
771 uint16_t section = 0;
772 uint32_t offset = 0;
773 bool is_external = false;
774 switch (sym.kind()) {
775 case S_GDATA32:
776 is_external = true;
777 LLVM_FALLTHROUGH;
778 case S_LDATA32: {
779 DataSym ds(sym.kind());
780 llvm::cantFail(SymbolDeserializer::deserializeAs<DataSym>(sym, ds));
781 ti = ds.Type;
782 scope = (sym.kind() == S_GDATA32) ? eValueTypeVariableGlobal
783 : eValueTypeVariableStatic;
784 name = ds.Name;
785 section = ds.Segment;
786 offset = ds.DataOffset;
787 addr = m_index->MakeVirtualAddress(ds.Segment, ds.DataOffset);
788 break;
789 }
790 case S_GTHREAD32:
791 is_external = true;
792 LLVM_FALLTHROUGH;
793 case S_LTHREAD32: {
794 ThreadLocalDataSym tlds(sym.kind());
795 llvm::cantFail(
796 SymbolDeserializer::deserializeAs<ThreadLocalDataSym>(sym, tlds));
797 ti = tlds.Type;
798 name = tlds.Name;
799 section = tlds.Segment;
800 offset = tlds.DataOffset;
801 addr = m_index->MakeVirtualAddress(tlds.Segment, tlds.DataOffset);
802 scope = eValueTypeVariableThreadLocal;
803 break;
804 }
805 default:
806 llvm_unreachable("unreachable!");
807 }
808
809 CompUnitSP comp_unit;
810 llvm::Optional<uint16_t> modi = m_index->GetModuleIndexForVa(addr);
811 if (!modi) {
812 return nullptr;
813 }
814
815 CompilandIndexItem &cci = m_index->compilands().GetOrCreateCompiland(*modi);
816 comp_unit = GetOrCreateCompileUnit(cci);
817
818 Declaration decl;
819 PdbTypeSymId tid(ti, false);
820 SymbolFileTypeSP type_sp =
821 std::make_shared<SymbolFileType>(*this, toOpaqueUid(tid));
822 Variable::RangeList ranges;
823
824 m_ast->GetOrCreateVariableDecl(var_id);
825
826 ModuleSP module_sp = GetObjectFile()->GetModule();
827 DWARFExpressionList location(
828 module_sp, MakeGlobalLocationExpression(section, offset, module_sp),
829 nullptr);
830
831 std::string global_name("::");
832 global_name += name;
833 bool artificial = false;
834 bool location_is_constant_data = false;
835 bool static_member = false;
836 VariableSP var_sp = std::make_shared<Variable>(
837 toOpaqueUid(var_id), name.str().c_str(), global_name.c_str(), type_sp,
838 scope, comp_unit.get(), ranges, &decl, location, is_external, artificial,
839 location_is_constant_data, static_member);
840
841 return var_sp;
842 }
843
844 lldb::VariableSP
CreateConstantSymbol(PdbGlobalSymId var_id,const CVSymbol & cvs)845 SymbolFileNativePDB::CreateConstantSymbol(PdbGlobalSymId var_id,
846 const CVSymbol &cvs) {
847 TpiStream &tpi = m_index->tpi();
848 ConstantSym constant(cvs.kind());
849
850 llvm::cantFail(SymbolDeserializer::deserializeAs<ConstantSym>(cvs, constant));
851 std::string global_name("::");
852 global_name += constant.Name;
853 PdbTypeSymId tid(constant.Type, false);
854 SymbolFileTypeSP type_sp =
855 std::make_shared<SymbolFileType>(*this, toOpaqueUid(tid));
856
857 Declaration decl;
858 Variable::RangeList ranges;
859 ModuleSP module = GetObjectFile()->GetModule();
860 DWARFExpressionList location(module,
861 MakeConstantLocationExpression(
862 constant.Type, tpi, constant.Value, module),
863 nullptr);
864
865 bool external = false;
866 bool artificial = false;
867 bool location_is_constant_data = true;
868 bool static_member = false;
869 VariableSP var_sp = std::make_shared<Variable>(
870 toOpaqueUid(var_id), constant.Name.str().c_str(), global_name.c_str(),
871 type_sp, eValueTypeVariableGlobal, module.get(), ranges, &decl, location,
872 external, artificial, location_is_constant_data, static_member);
873 return var_sp;
874 }
875
876 VariableSP
GetOrCreateGlobalVariable(PdbGlobalSymId var_id)877 SymbolFileNativePDB::GetOrCreateGlobalVariable(PdbGlobalSymId var_id) {
878 auto emplace_result = m_global_vars.try_emplace(toOpaqueUid(var_id), nullptr);
879 if (emplace_result.second) {
880 if (VariableSP var_sp = CreateGlobalVariable(var_id))
881 emplace_result.first->second = var_sp;
882 else
883 return nullptr;
884 }
885
886 return emplace_result.first->second;
887 }
888
GetOrCreateType(TypeIndex ti)889 lldb::TypeSP SymbolFileNativePDB::GetOrCreateType(TypeIndex ti) {
890 return GetOrCreateType(PdbTypeSymId(ti, false));
891 }
892
GetOrCreateFunction(PdbCompilandSymId func_id,CompileUnit & comp_unit)893 FunctionSP SymbolFileNativePDB::GetOrCreateFunction(PdbCompilandSymId func_id,
894 CompileUnit &comp_unit) {
895 auto emplace_result = m_functions.try_emplace(toOpaqueUid(func_id), nullptr);
896 if (emplace_result.second)
897 emplace_result.first->second = CreateFunction(func_id, comp_unit);
898
899 return emplace_result.first->second;
900 }
901
902 CompUnitSP
GetOrCreateCompileUnit(const CompilandIndexItem & cci)903 SymbolFileNativePDB::GetOrCreateCompileUnit(const CompilandIndexItem &cci) {
904
905 auto emplace_result =
906 m_compilands.try_emplace(toOpaqueUid(cci.m_id), nullptr);
907 if (emplace_result.second)
908 emplace_result.first->second = CreateCompileUnit(cci);
909
910 lldbassert(emplace_result.first->second);
911 return emplace_result.first->second;
912 }
913
GetOrCreateBlock(PdbCompilandSymId block_id)914 Block &SymbolFileNativePDB::GetOrCreateBlock(PdbCompilandSymId block_id) {
915 auto iter = m_blocks.find(toOpaqueUid(block_id));
916 if (iter != m_blocks.end())
917 return *iter->second;
918
919 return CreateBlock(block_id);
920 }
921
ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx)922 void SymbolFileNativePDB::ParseDeclsForContext(
923 lldb_private::CompilerDeclContext decl_ctx) {
924 clang::DeclContext *context = m_ast->FromCompilerDeclContext(decl_ctx);
925 if (!context)
926 return;
927 m_ast->ParseDeclsForContext(*context);
928 }
929
ParseCompileUnitAtIndex(uint32_t index)930 lldb::CompUnitSP SymbolFileNativePDB::ParseCompileUnitAtIndex(uint32_t index) {
931 if (index >= GetNumCompileUnits())
932 return CompUnitSP();
933 lldbassert(index < UINT16_MAX);
934 if (index >= UINT16_MAX)
935 return nullptr;
936
937 CompilandIndexItem &item = m_index->compilands().GetOrCreateCompiland(index);
938
939 return GetOrCreateCompileUnit(item);
940 }
941
ParseLanguage(CompileUnit & comp_unit)942 lldb::LanguageType SymbolFileNativePDB::ParseLanguage(CompileUnit &comp_unit) {
943 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
944 PdbSymUid uid(comp_unit.GetID());
945 lldbassert(uid.kind() == PdbSymUidKind::Compiland);
946
947 CompilandIndexItem *item =
948 m_index->compilands().GetCompiland(uid.asCompiland().modi);
949 lldbassert(item);
950 if (!item->m_compile_opts)
951 return lldb::eLanguageTypeUnknown;
952
953 return TranslateLanguage(item->m_compile_opts->getLanguage());
954 }
955
AddSymbols(Symtab & symtab)956 void SymbolFileNativePDB::AddSymbols(Symtab &symtab) {}
957
ParseFunctions(CompileUnit & comp_unit)958 size_t SymbolFileNativePDB::ParseFunctions(CompileUnit &comp_unit) {
959 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
960 PdbSymUid uid{comp_unit.GetID()};
961 lldbassert(uid.kind() == PdbSymUidKind::Compiland);
962 uint16_t modi = uid.asCompiland().modi;
963 CompilandIndexItem &cii = m_index->compilands().GetOrCreateCompiland(modi);
964
965 size_t count = comp_unit.GetNumFunctions();
966 const CVSymbolArray &syms = cii.m_debug_stream.getSymbolArray();
967 for (auto iter = syms.begin(); iter != syms.end(); ++iter) {
968 if (iter->kind() != S_LPROC32 && iter->kind() != S_GPROC32)
969 continue;
970
971 PdbCompilandSymId sym_id{modi, iter.offset()};
972
973 FunctionSP func = GetOrCreateFunction(sym_id, comp_unit);
974 }
975
976 size_t new_count = comp_unit.GetNumFunctions();
977 lldbassert(new_count >= count);
978 return new_count - count;
979 }
980
NeedsResolvedCompileUnit(uint32_t resolve_scope)981 static bool NeedsResolvedCompileUnit(uint32_t resolve_scope) {
982 // If any of these flags are set, we need to resolve the compile unit.
983 uint32_t flags = eSymbolContextCompUnit;
984 flags |= eSymbolContextVariable;
985 flags |= eSymbolContextFunction;
986 flags |= eSymbolContextBlock;
987 flags |= eSymbolContextLineEntry;
988 return (resolve_scope & flags) != 0;
989 }
990
ResolveSymbolContext(const Address & addr,SymbolContextItem resolve_scope,SymbolContext & sc)991 uint32_t SymbolFileNativePDB::ResolveSymbolContext(
992 const Address &addr, SymbolContextItem resolve_scope, SymbolContext &sc) {
993 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
994 uint32_t resolved_flags = 0;
995 lldb::addr_t file_addr = addr.GetFileAddress();
996
997 if (NeedsResolvedCompileUnit(resolve_scope)) {
998 llvm::Optional<uint16_t> modi = m_index->GetModuleIndexForVa(file_addr);
999 if (!modi)
1000 return 0;
1001 CompUnitSP cu_sp = GetCompileUnitAtIndex(*modi);
1002 if (!cu_sp)
1003 return 0;
1004
1005 sc.comp_unit = cu_sp.get();
1006 resolved_flags |= eSymbolContextCompUnit;
1007 }
1008
1009 if (resolve_scope & eSymbolContextFunction ||
1010 resolve_scope & eSymbolContextBlock) {
1011 lldbassert(sc.comp_unit);
1012 std::vector<SymbolAndUid> matches = m_index->FindSymbolsByVa(file_addr);
1013 // Search the matches in reverse. This way if there are multiple matches
1014 // (for example we are 3 levels deep in a nested scope) it will find the
1015 // innermost one first.
1016 for (const auto &match : llvm::reverse(matches)) {
1017 if (match.uid.kind() != PdbSymUidKind::CompilandSym)
1018 continue;
1019
1020 PdbCompilandSymId csid = match.uid.asCompilandSym();
1021 CVSymbol cvs = m_index->ReadSymbolRecord(csid);
1022 PDB_SymType type = CVSymToPDBSym(cvs.kind());
1023 if (type != PDB_SymType::Function && type != PDB_SymType::Block)
1024 continue;
1025 if (type == PDB_SymType::Function) {
1026 sc.function = GetOrCreateFunction(csid, *sc.comp_unit).get();
1027 Block &block = sc.function->GetBlock(true);
1028 addr_t func_base =
1029 sc.function->GetAddressRange().GetBaseAddress().GetFileAddress();
1030 addr_t offset = file_addr - func_base;
1031 sc.block = block.FindInnermostBlockByOffset(offset);
1032 }
1033
1034 if (type == PDB_SymType::Block) {
1035 sc.block = &GetOrCreateBlock(csid);
1036 sc.function = sc.block->CalculateSymbolContextFunction();
1037 }
1038 if (sc.function)
1039 resolved_flags |= eSymbolContextFunction;
1040 if (sc.block)
1041 resolved_flags |= eSymbolContextBlock;
1042 break;
1043 }
1044 }
1045
1046 if (resolve_scope & eSymbolContextLineEntry) {
1047 lldbassert(sc.comp_unit);
1048 if (auto *line_table = sc.comp_unit->GetLineTable()) {
1049 if (line_table->FindLineEntryByAddress(addr, sc.line_entry))
1050 resolved_flags |= eSymbolContextLineEntry;
1051 }
1052 }
1053
1054 return resolved_flags;
1055 }
1056
ResolveSymbolContext(const SourceLocationSpec & src_location_spec,lldb::SymbolContextItem resolve_scope,SymbolContextList & sc_list)1057 uint32_t SymbolFileNativePDB::ResolveSymbolContext(
1058 const SourceLocationSpec &src_location_spec,
1059 lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
1060 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1061 const uint32_t prev_size = sc_list.GetSize();
1062 if (resolve_scope & eSymbolContextCompUnit) {
1063 for (uint32_t cu_idx = 0, num_cus = GetNumCompileUnits(); cu_idx < num_cus;
1064 ++cu_idx) {
1065 CompileUnit *cu = ParseCompileUnitAtIndex(cu_idx).get();
1066 if (!cu)
1067 continue;
1068
1069 bool file_spec_matches_cu_file_spec = FileSpec::Match(
1070 src_location_spec.GetFileSpec(), cu->GetPrimaryFile());
1071 if (file_spec_matches_cu_file_spec) {
1072 cu->ResolveSymbolContext(src_location_spec, resolve_scope, sc_list);
1073 break;
1074 }
1075 }
1076 }
1077 return sc_list.GetSize() - prev_size;
1078 }
1079
ParseLineTable(CompileUnit & comp_unit)1080 bool SymbolFileNativePDB::ParseLineTable(CompileUnit &comp_unit) {
1081 // Unfortunately LLDB is set up to parse the entire compile unit line table
1082 // all at once, even if all it really needs is line info for a specific
1083 // function. In the future it would be nice if it could set the sc.m_function
1084 // member, and we could only get the line info for the function in question.
1085 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1086 PdbSymUid cu_id(comp_unit.GetID());
1087 lldbassert(cu_id.kind() == PdbSymUidKind::Compiland);
1088 uint16_t modi = cu_id.asCompiland().modi;
1089 CompilandIndexItem *cii = m_index->compilands().GetCompiland(modi);
1090 lldbassert(cii);
1091
1092 // Parse DEBUG_S_LINES subsections first, then parse all S_INLINESITE records
1093 // in this CU. Add line entries into the set first so that if there are line
1094 // entries with same addres, the later is always more accurate than the
1095 // former.
1096 std::set<LineTable::Entry, LineTableEntryComparator> line_set;
1097
1098 // This is basically a copy of the .debug$S subsections from all original COFF
1099 // object files merged together with address relocations applied. We are
1100 // looking for all DEBUG_S_LINES subsections.
1101 for (const DebugSubsectionRecord &dssr :
1102 cii->m_debug_stream.getSubsectionsArray()) {
1103 if (dssr.kind() != DebugSubsectionKind::Lines)
1104 continue;
1105
1106 DebugLinesSubsectionRef lines;
1107 llvm::BinaryStreamReader reader(dssr.getRecordData());
1108 if (auto EC = lines.initialize(reader)) {
1109 llvm::consumeError(std::move(EC));
1110 return false;
1111 }
1112
1113 const LineFragmentHeader *lfh = lines.header();
1114 uint64_t virtual_addr =
1115 m_index->MakeVirtualAddress(lfh->RelocSegment, lfh->RelocOffset);
1116 if (virtual_addr == LLDB_INVALID_ADDRESS)
1117 continue;
1118
1119 for (const LineColumnEntry &group : lines) {
1120 llvm::Expected<uint32_t> file_index_or_err =
1121 GetFileIndex(*cii, group.NameIndex);
1122 if (!file_index_or_err)
1123 continue;
1124 uint32_t file_index = file_index_or_err.get();
1125 lldbassert(!group.LineNumbers.empty());
1126 CompilandIndexItem::GlobalLineTable::Entry line_entry(
1127 LLDB_INVALID_ADDRESS, 0);
1128 for (const LineNumberEntry &entry : group.LineNumbers) {
1129 LineInfo cur_info(entry.Flags);
1130
1131 if (cur_info.isAlwaysStepInto() || cur_info.isNeverStepInto())
1132 continue;
1133
1134 uint64_t addr = virtual_addr + entry.Offset;
1135
1136 bool is_statement = cur_info.isStatement();
1137 bool is_prologue = IsFunctionPrologue(*cii, addr);
1138 bool is_epilogue = IsFunctionEpilogue(*cii, addr);
1139
1140 uint32_t lno = cur_info.getStartLine();
1141
1142 LineTable::Entry new_entry(addr, lno, 0, file_index, is_statement, false,
1143 is_prologue, is_epilogue, false);
1144 // Terminal entry has lower precedence than new entry.
1145 auto iter = line_set.find(new_entry);
1146 if (iter != line_set.end() && iter->is_terminal_entry)
1147 line_set.erase(iter);
1148 line_set.insert(new_entry);
1149
1150 if (line_entry.GetRangeBase() != LLDB_INVALID_ADDRESS) {
1151 line_entry.SetRangeEnd(addr);
1152 cii->m_global_line_table.Append(line_entry);
1153 }
1154 line_entry.SetRangeBase(addr);
1155 line_entry.data = {file_index, lno};
1156 }
1157 LineInfo last_line(group.LineNumbers.back().Flags);
1158 line_set.emplace(virtual_addr + lfh->CodeSize, last_line.getEndLine(), 0,
1159 file_index, false, false, false, false, true);
1160
1161 if (line_entry.GetRangeBase() != LLDB_INVALID_ADDRESS) {
1162 line_entry.SetRangeEnd(virtual_addr + lfh->CodeSize);
1163 cii->m_global_line_table.Append(line_entry);
1164 }
1165 }
1166 }
1167
1168 cii->m_global_line_table.Sort();
1169
1170 // Parse all S_INLINESITE in this CU.
1171 const CVSymbolArray &syms = cii->m_debug_stream.getSymbolArray();
1172 for (auto iter = syms.begin(); iter != syms.end();) {
1173 if (iter->kind() != S_LPROC32 && iter->kind() != S_GPROC32) {
1174 ++iter;
1175 continue;
1176 }
1177
1178 uint32_t record_offset = iter.offset();
1179 CVSymbol func_record =
1180 cii->m_debug_stream.readSymbolAtOffset(record_offset);
1181 SegmentOffsetLength sol = GetSegmentOffsetAndLength(func_record);
1182 addr_t file_vm_addr =
1183 m_index->MakeVirtualAddress(sol.so.segment, sol.so.offset);
1184 if (file_vm_addr == LLDB_INVALID_ADDRESS)
1185 continue;
1186
1187 AddressRange func_range(file_vm_addr, sol.length,
1188 comp_unit.GetModule()->GetSectionList());
1189 Address func_base = func_range.GetBaseAddress();
1190 PdbCompilandSymId func_id{modi, record_offset};
1191
1192 // Iterate all S_INLINESITEs in the function.
1193 auto parse_inline_sites = [&](SymbolKind kind, PdbCompilandSymId id) {
1194 if (kind != S_INLINESITE)
1195 return false;
1196
1197 ParseInlineSite(id, func_base);
1198
1199 for (const auto &line_entry :
1200 m_inline_sites[toOpaqueUid(id)]->line_entries) {
1201 // If line_entry is not terminal entry, remove previous line entry at
1202 // the same address and insert new one. Terminal entry inside an inline
1203 // site might not be terminal entry for its parent.
1204 if (!line_entry.is_terminal_entry)
1205 line_set.erase(line_entry);
1206 line_set.insert(line_entry);
1207 }
1208 // No longer useful after adding to line_set.
1209 m_inline_sites[toOpaqueUid(id)]->line_entries.clear();
1210 return true;
1211 };
1212 ParseSymbolArrayInScope(func_id, parse_inline_sites);
1213 // Jump to the end of the function record.
1214 iter = syms.at(getScopeEndOffset(func_record));
1215 }
1216
1217 cii->m_global_line_table.Clear();
1218
1219 // Add line entries in line_set to line_table.
1220 auto line_table = std::make_unique<LineTable>(&comp_unit);
1221 std::unique_ptr<LineSequence> sequence(
1222 line_table->CreateLineSequenceContainer());
1223 for (const auto &line_entry : line_set) {
1224 line_table->AppendLineEntryToSequence(
1225 sequence.get(), line_entry.file_addr, line_entry.line,
1226 line_entry.column, line_entry.file_idx,
1227 line_entry.is_start_of_statement, line_entry.is_start_of_basic_block,
1228 line_entry.is_prologue_end, line_entry.is_epilogue_begin,
1229 line_entry.is_terminal_entry);
1230 }
1231 line_table->InsertSequence(sequence.get());
1232
1233 if (line_table->GetSize() == 0)
1234 return false;
1235
1236 comp_unit.SetLineTable(line_table.release());
1237 return true;
1238 }
1239
ParseDebugMacros(CompileUnit & comp_unit)1240 bool SymbolFileNativePDB::ParseDebugMacros(CompileUnit &comp_unit) {
1241 // PDB doesn't contain information about macros
1242 return false;
1243 }
1244
1245 llvm::Expected<uint32_t>
GetFileIndex(const CompilandIndexItem & cii,uint32_t file_id)1246 SymbolFileNativePDB::GetFileIndex(const CompilandIndexItem &cii,
1247 uint32_t file_id) {
1248 const auto &checksums = cii.m_strings.checksums().getArray();
1249 const auto &strings = cii.m_strings.strings();
1250 // Indices in this structure are actually offsets of records in the
1251 // DEBUG_S_FILECHECKSUMS subsection. Those entries then have an index
1252 // into the global PDB string table.
1253 auto iter = checksums.at(file_id);
1254 if (iter == checksums.end())
1255 return llvm::make_error<RawError>(raw_error_code::no_entry);
1256
1257 llvm::Expected<llvm::StringRef> efn = strings.getString(iter->FileNameOffset);
1258 if (!efn) {
1259 return efn.takeError();
1260 }
1261
1262 // LLDB wants the index of the file in the list of support files.
1263 auto fn_iter = llvm::find(cii.m_file_list, *efn);
1264 if (fn_iter != cii.m_file_list.end())
1265 return std::distance(cii.m_file_list.begin(), fn_iter);
1266 return llvm::make_error<RawError>(raw_error_code::no_entry);
1267 }
1268
ParseSupportFiles(CompileUnit & comp_unit,FileSpecList & support_files)1269 bool SymbolFileNativePDB::ParseSupportFiles(CompileUnit &comp_unit,
1270 FileSpecList &support_files) {
1271 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1272 PdbSymUid cu_id(comp_unit.GetID());
1273 lldbassert(cu_id.kind() == PdbSymUidKind::Compiland);
1274 CompilandIndexItem *cci =
1275 m_index->compilands().GetCompiland(cu_id.asCompiland().modi);
1276 lldbassert(cci);
1277
1278 for (llvm::StringRef f : cci->m_file_list) {
1279 FileSpec::Style style =
1280 f.startswith("/") ? FileSpec::Style::posix : FileSpec::Style::windows;
1281 FileSpec spec(f, style);
1282 support_files.Append(spec);
1283 }
1284 return true;
1285 }
1286
ParseImportedModules(const SymbolContext & sc,std::vector<SourceModule> & imported_modules)1287 bool SymbolFileNativePDB::ParseImportedModules(
1288 const SymbolContext &sc, std::vector<SourceModule> &imported_modules) {
1289 // PDB does not yet support module debug info
1290 return false;
1291 }
1292
ParseInlineSite(PdbCompilandSymId id,Address func_addr)1293 void SymbolFileNativePDB::ParseInlineSite(PdbCompilandSymId id,
1294 Address func_addr) {
1295 lldb::user_id_t opaque_uid = toOpaqueUid(id);
1296 if (m_inline_sites.find(opaque_uid) != m_inline_sites.end())
1297 return;
1298
1299 addr_t func_base = func_addr.GetFileAddress();
1300 CompilandIndexItem *cii = m_index->compilands().GetCompiland(id.modi);
1301 CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(id.offset);
1302 CompUnitSP comp_unit = GetOrCreateCompileUnit(*cii);
1303
1304 InlineSiteSym inline_site(static_cast<SymbolRecordKind>(sym.kind()));
1305 cantFail(SymbolDeserializer::deserializeAs<InlineSiteSym>(sym, inline_site));
1306 PdbCompilandSymId parent_id(id.modi, inline_site.Parent);
1307
1308 std::shared_ptr<InlineSite> inline_site_sp =
1309 std::make_shared<InlineSite>(parent_id);
1310
1311 // Get the inlined function declaration info.
1312 auto iter = cii->m_inline_map.find(inline_site.Inlinee);
1313 if (iter == cii->m_inline_map.end())
1314 return;
1315 InlineeSourceLine inlinee_line = iter->second;
1316
1317 const FileSpecList &files = comp_unit->GetSupportFiles();
1318 FileSpec decl_file;
1319 llvm::Expected<uint32_t> file_index_or_err =
1320 GetFileIndex(*cii, inlinee_line.Header->FileID);
1321 if (!file_index_or_err)
1322 return;
1323 uint32_t file_offset = file_index_or_err.get();
1324 decl_file = files.GetFileSpecAtIndex(file_offset);
1325 uint32_t decl_line = inlinee_line.Header->SourceLineNum;
1326 std::unique_ptr<Declaration> decl_up =
1327 std::make_unique<Declaration>(decl_file, decl_line);
1328
1329 // Parse range and line info.
1330 uint32_t code_offset = 0;
1331 int32_t line_offset = 0;
1332 llvm::Optional<uint32_t> code_offset_base;
1333 llvm::Optional<uint32_t> code_offset_end;
1334 llvm::Optional<int32_t> cur_line_offset;
1335 llvm::Optional<int32_t> next_line_offset;
1336 llvm::Optional<uint32_t> next_file_offset;
1337
1338 bool is_terminal_entry = false;
1339 bool is_start_of_statement = true;
1340 // The first instruction is the prologue end.
1341 bool is_prologue_end = true;
1342
1343 auto update_code_offset = [&](uint32_t code_delta) {
1344 if (!code_offset_base)
1345 code_offset_base = code_offset;
1346 else if (!code_offset_end)
1347 code_offset_end = *code_offset_base + code_delta;
1348 };
1349 auto update_line_offset = [&](int32_t line_delta) {
1350 line_offset += line_delta;
1351 if (!code_offset_base || !cur_line_offset)
1352 cur_line_offset = line_offset;
1353 else
1354 next_line_offset = line_offset;
1355 ;
1356 };
1357 auto update_file_offset = [&](uint32_t offset) {
1358 if (!code_offset_base)
1359 file_offset = offset;
1360 else
1361 next_file_offset = offset;
1362 };
1363
1364 for (auto &annot : inline_site.annotations()) {
1365 switch (annot.OpCode) {
1366 case BinaryAnnotationsOpCode::CodeOffset:
1367 case BinaryAnnotationsOpCode::ChangeCodeOffset:
1368 case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:
1369 code_offset += annot.U1;
1370 update_code_offset(annot.U1);
1371 break;
1372 case BinaryAnnotationsOpCode::ChangeLineOffset:
1373 update_line_offset(annot.S1);
1374 break;
1375 case BinaryAnnotationsOpCode::ChangeCodeLength:
1376 update_code_offset(annot.U1);
1377 code_offset += annot.U1;
1378 is_terminal_entry = true;
1379 break;
1380 case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset:
1381 code_offset += annot.U1;
1382 update_code_offset(annot.U1);
1383 update_line_offset(annot.S1);
1384 break;
1385 case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset:
1386 code_offset += annot.U2;
1387 update_code_offset(annot.U2);
1388 update_code_offset(annot.U1);
1389 code_offset += annot.U1;
1390 is_terminal_entry = true;
1391 break;
1392 case BinaryAnnotationsOpCode::ChangeFile:
1393 update_file_offset(annot.U1);
1394 break;
1395 default:
1396 break;
1397 }
1398
1399 // Add range if current range is finished.
1400 if (code_offset_base && code_offset_end && cur_line_offset) {
1401 inline_site_sp->ranges.Append(RangeSourceLineVector::Entry(
1402 *code_offset_base, *code_offset_end - *code_offset_base,
1403 decl_line + *cur_line_offset));
1404 // Set base, end, file offset and line offset for next range.
1405 if (next_file_offset)
1406 file_offset = *next_file_offset;
1407 if (next_line_offset) {
1408 cur_line_offset = next_line_offset;
1409 next_line_offset = llvm::None;
1410 }
1411 code_offset_base = is_terminal_entry ? llvm::None : code_offset_end;
1412 code_offset_end = next_file_offset = llvm::None;
1413 }
1414 if (code_offset_base && cur_line_offset) {
1415 if (is_terminal_entry) {
1416 LineTable::Entry line_entry(
1417 func_base + *code_offset_base, decl_line + *cur_line_offset, 0,
1418 file_offset, false, false, false, false, true);
1419 inline_site_sp->line_entries.push_back(line_entry);
1420 } else {
1421 LineTable::Entry line_entry(func_base + *code_offset_base,
1422 decl_line + *cur_line_offset, 0,
1423 file_offset, is_start_of_statement, false,
1424 is_prologue_end, false, false);
1425 inline_site_sp->line_entries.push_back(line_entry);
1426 is_prologue_end = false;
1427 is_start_of_statement = false;
1428 }
1429 }
1430 if (is_terminal_entry)
1431 is_start_of_statement = true;
1432 is_terminal_entry = false;
1433 }
1434
1435 inline_site_sp->ranges.Sort();
1436
1437 // Get the inlined function callsite info.
1438 std::unique_ptr<Declaration> callsite_up;
1439 if (!inline_site_sp->ranges.IsEmpty()) {
1440 auto *entry = inline_site_sp->ranges.GetEntryAtIndex(0);
1441 addr_t base_offset = entry->GetRangeBase();
1442 if (cii->m_debug_stream.readSymbolAtOffset(parent_id.offset).kind() ==
1443 S_INLINESITE) {
1444 // Its parent is another inline site, lookup parent site's range vector
1445 // for callsite line.
1446 ParseInlineSite(parent_id, func_base);
1447 std::shared_ptr<InlineSite> parent_site =
1448 m_inline_sites[toOpaqueUid(parent_id)];
1449 FileSpec &parent_decl_file =
1450 parent_site->inline_function_info->GetDeclaration().GetFile();
1451 if (auto *parent_entry =
1452 parent_site->ranges.FindEntryThatContains(base_offset)) {
1453 callsite_up =
1454 std::make_unique<Declaration>(parent_decl_file, parent_entry->data);
1455 }
1456 } else {
1457 // Its parent is a function, lookup global line table for callsite.
1458 if (auto *entry = cii->m_global_line_table.FindEntryThatContains(
1459 func_base + base_offset)) {
1460 const FileSpec &callsite_file =
1461 files.GetFileSpecAtIndex(entry->data.first);
1462 callsite_up =
1463 std::make_unique<Declaration>(callsite_file, entry->data.second);
1464 }
1465 }
1466 }
1467
1468 // Get the inlined function name.
1469 CVType inlinee_cvt = m_index->ipi().getType(inline_site.Inlinee);
1470 std::string inlinee_name;
1471 if (inlinee_cvt.kind() == LF_MFUNC_ID) {
1472 MemberFuncIdRecord mfr;
1473 cantFail(
1474 TypeDeserializer::deserializeAs<MemberFuncIdRecord>(inlinee_cvt, mfr));
1475 LazyRandomTypeCollection &types = m_index->tpi().typeCollection();
1476 inlinee_name.append(std::string(types.getTypeName(mfr.ClassType)));
1477 inlinee_name.append("::");
1478 inlinee_name.append(mfr.getName().str());
1479 } else if (inlinee_cvt.kind() == LF_FUNC_ID) {
1480 FuncIdRecord fir;
1481 cantFail(TypeDeserializer::deserializeAs<FuncIdRecord>(inlinee_cvt, fir));
1482 TypeIndex parent_idx = fir.getParentScope();
1483 if (!parent_idx.isNoneType()) {
1484 LazyRandomTypeCollection &ids = m_index->ipi().typeCollection();
1485 inlinee_name.append(std::string(ids.getTypeName(parent_idx)));
1486 inlinee_name.append("::");
1487 }
1488 inlinee_name.append(fir.getName().str());
1489 }
1490 inline_site_sp->inline_function_info = std::make_shared<InlineFunctionInfo>(
1491 inlinee_name.c_str(), llvm::StringRef(), decl_up.get(),
1492 callsite_up.get());
1493
1494 m_inline_sites[opaque_uid] = inline_site_sp;
1495 }
1496
ParseBlocksRecursive(Function & func)1497 size_t SymbolFileNativePDB::ParseBlocksRecursive(Function &func) {
1498 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1499 PdbCompilandSymId func_id = PdbSymUid(func.GetID()).asCompilandSym();
1500 // After we iterate through inline sites inside the function, we already get
1501 // all the info needed, removing from the map to save memory.
1502 std::set<uint64_t> remove_uids;
1503 auto parse_blocks = [&](SymbolKind kind, PdbCompilandSymId id) {
1504 if (kind == S_GPROC32 || kind == S_LPROC32 || kind == S_BLOCK32 ||
1505 kind == S_INLINESITE) {
1506 GetOrCreateBlock(id);
1507 if (kind == S_INLINESITE)
1508 remove_uids.insert(toOpaqueUid(id));
1509 return true;
1510 }
1511 return false;
1512 };
1513 size_t count = ParseSymbolArrayInScope(func_id, parse_blocks);
1514 for (uint64_t uid : remove_uids) {
1515 m_inline_sites.erase(uid);
1516 }
1517 return count;
1518 }
1519
ParseSymbolArrayInScope(PdbCompilandSymId parent_id,llvm::function_ref<bool (SymbolKind,PdbCompilandSymId)> fn)1520 size_t SymbolFileNativePDB::ParseSymbolArrayInScope(
1521 PdbCompilandSymId parent_id,
1522 llvm::function_ref<bool(SymbolKind, PdbCompilandSymId)> fn) {
1523 CompilandIndexItem *cii = m_index->compilands().GetCompiland(parent_id.modi);
1524 CVSymbolArray syms =
1525 cii->m_debug_stream.getSymbolArrayForScope(parent_id.offset);
1526
1527 size_t count = 1;
1528 for (auto iter = syms.begin(); iter != syms.end(); ++iter) {
1529 PdbCompilandSymId child_id(parent_id.modi, iter.offset());
1530 if (fn(iter->kind(), child_id))
1531 ++count;
1532 }
1533
1534 return count;
1535 }
1536
DumpClangAST(Stream & s)1537 void SymbolFileNativePDB::DumpClangAST(Stream &s) { m_ast->Dump(s); }
1538
FindGlobalVariables(ConstString name,const CompilerDeclContext & parent_decl_ctx,uint32_t max_matches,VariableList & variables)1539 void SymbolFileNativePDB::FindGlobalVariables(
1540 ConstString name, const CompilerDeclContext &parent_decl_ctx,
1541 uint32_t max_matches, VariableList &variables) {
1542 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1543 using SymbolAndOffset = std::pair<uint32_t, llvm::codeview::CVSymbol>;
1544
1545 std::vector<SymbolAndOffset> results = m_index->globals().findRecordsByName(
1546 name.GetStringRef(), m_index->symrecords());
1547 for (const SymbolAndOffset &result : results) {
1548 switch (result.second.kind()) {
1549 case SymbolKind::S_GDATA32:
1550 case SymbolKind::S_LDATA32:
1551 case SymbolKind::S_GTHREAD32:
1552 case SymbolKind::S_LTHREAD32:
1553 case SymbolKind::S_CONSTANT: {
1554 PdbGlobalSymId global(result.first, false);
1555 if (VariableSP var = GetOrCreateGlobalVariable(global))
1556 variables.AddVariable(var);
1557 break;
1558 }
1559 default:
1560 continue;
1561 }
1562 }
1563 }
1564
FindFunctions(ConstString name,const CompilerDeclContext & parent_decl_ctx,FunctionNameType name_type_mask,bool include_inlines,SymbolContextList & sc_list)1565 void SymbolFileNativePDB::FindFunctions(
1566 ConstString name, const CompilerDeclContext &parent_decl_ctx,
1567 FunctionNameType name_type_mask, bool include_inlines,
1568 SymbolContextList &sc_list) {
1569 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1570 // For now we only support lookup by method name or full name.
1571 if (!(name_type_mask & eFunctionNameTypeFull ||
1572 name_type_mask & eFunctionNameTypeMethod))
1573 return;
1574
1575 using SymbolAndOffset = std::pair<uint32_t, llvm::codeview::CVSymbol>;
1576
1577 std::vector<SymbolAndOffset> matches = m_index->globals().findRecordsByName(
1578 name.GetStringRef(), m_index->symrecords());
1579 for (const SymbolAndOffset &match : matches) {
1580 if (match.second.kind() != S_PROCREF && match.second.kind() != S_LPROCREF)
1581 continue;
1582 ProcRefSym proc(match.second.kind());
1583 cantFail(SymbolDeserializer::deserializeAs<ProcRefSym>(match.second, proc));
1584
1585 if (!IsValidRecord(proc))
1586 continue;
1587
1588 CompilandIndexItem &cci =
1589 m_index->compilands().GetOrCreateCompiland(proc.modi());
1590 SymbolContext sc;
1591
1592 sc.comp_unit = GetOrCreateCompileUnit(cci).get();
1593 PdbCompilandSymId func_id(proc.modi(), proc.SymOffset);
1594 sc.function = GetOrCreateFunction(func_id, *sc.comp_unit).get();
1595
1596 sc_list.Append(sc);
1597 }
1598 }
1599
FindFunctions(const RegularExpression & regex,bool include_inlines,SymbolContextList & sc_list)1600 void SymbolFileNativePDB::FindFunctions(const RegularExpression ®ex,
1601 bool include_inlines,
1602 SymbolContextList &sc_list) {}
1603
FindTypes(ConstString name,const CompilerDeclContext & parent_decl_ctx,uint32_t max_matches,llvm::DenseSet<SymbolFile * > & searched_symbol_files,TypeMap & types)1604 void SymbolFileNativePDB::FindTypes(
1605 ConstString name, const CompilerDeclContext &parent_decl_ctx,
1606 uint32_t max_matches, llvm::DenseSet<SymbolFile *> &searched_symbol_files,
1607 TypeMap &types) {
1608 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1609 if (!name)
1610 return;
1611
1612 searched_symbol_files.clear();
1613 searched_symbol_files.insert(this);
1614
1615 // There is an assumption 'name' is not a regex
1616 FindTypesByName(name.GetStringRef(), max_matches, types);
1617 }
1618
FindTypes(llvm::ArrayRef<CompilerContext> pattern,LanguageSet languages,llvm::DenseSet<SymbolFile * > & searched_symbol_files,TypeMap & types)1619 void SymbolFileNativePDB::FindTypes(
1620 llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
1621 llvm::DenseSet<SymbolFile *> &searched_symbol_files, TypeMap &types) {}
1622
FindTypesByName(llvm::StringRef name,uint32_t max_matches,TypeMap & types)1623 void SymbolFileNativePDB::FindTypesByName(llvm::StringRef name,
1624 uint32_t max_matches,
1625 TypeMap &types) {
1626
1627 std::vector<TypeIndex> matches = m_index->tpi().findRecordsByName(name);
1628 if (max_matches > 0 && max_matches < matches.size())
1629 matches.resize(max_matches);
1630
1631 for (TypeIndex ti : matches) {
1632 TypeSP type = GetOrCreateType(ti);
1633 if (!type)
1634 continue;
1635
1636 types.Insert(type);
1637 }
1638 }
1639
ParseTypes(CompileUnit & comp_unit)1640 size_t SymbolFileNativePDB::ParseTypes(CompileUnit &comp_unit) {
1641 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1642 // Only do the full type scan the first time.
1643 if (m_done_full_type_scan)
1644 return 0;
1645
1646 const size_t old_count = GetTypeList().GetSize();
1647 LazyRandomTypeCollection &types = m_index->tpi().typeCollection();
1648
1649 // First process the entire TPI stream.
1650 for (auto ti = types.getFirst(); ti; ti = types.getNext(*ti)) {
1651 TypeSP type = GetOrCreateType(*ti);
1652 if (type)
1653 (void)type->GetFullCompilerType();
1654 }
1655
1656 // Next look for S_UDT records in the globals stream.
1657 for (const uint32_t gid : m_index->globals().getGlobalsTable()) {
1658 PdbGlobalSymId global{gid, false};
1659 CVSymbol sym = m_index->ReadSymbolRecord(global);
1660 if (sym.kind() != S_UDT)
1661 continue;
1662
1663 UDTSym udt = llvm::cantFail(SymbolDeserializer::deserializeAs<UDTSym>(sym));
1664 bool is_typedef = true;
1665 if (IsTagRecord(PdbTypeSymId{udt.Type, false}, m_index->tpi())) {
1666 CVType cvt = m_index->tpi().getType(udt.Type);
1667 llvm::StringRef name = CVTagRecord::create(cvt).name();
1668 if (name == udt.Name)
1669 is_typedef = false;
1670 }
1671
1672 if (is_typedef)
1673 GetOrCreateTypedef(global);
1674 }
1675
1676 const size_t new_count = GetTypeList().GetSize();
1677
1678 m_done_full_type_scan = true;
1679
1680 return new_count - old_count;
1681 }
1682
1683 size_t
ParseVariablesForCompileUnit(CompileUnit & comp_unit,VariableList & variables)1684 SymbolFileNativePDB::ParseVariablesForCompileUnit(CompileUnit &comp_unit,
1685 VariableList &variables) {
1686 PdbSymUid sym_uid(comp_unit.GetID());
1687 lldbassert(sym_uid.kind() == PdbSymUidKind::Compiland);
1688 return 0;
1689 }
1690
CreateLocalVariable(PdbCompilandSymId scope_id,PdbCompilandSymId var_id,bool is_param)1691 VariableSP SymbolFileNativePDB::CreateLocalVariable(PdbCompilandSymId scope_id,
1692 PdbCompilandSymId var_id,
1693 bool is_param) {
1694 ModuleSP module = GetObjectFile()->GetModule();
1695 Block &block = GetOrCreateBlock(scope_id);
1696 // Get function block.
1697 Block *func_block = █
1698 while (func_block->GetParent()) {
1699 func_block = func_block->GetParent();
1700 }
1701 Address addr;
1702 func_block->GetStartAddress(addr);
1703 VariableInfo var_info =
1704 GetVariableLocationInfo(*m_index, var_id, *func_block, module);
1705 if (!var_info.location || !var_info.ranges)
1706 return nullptr;
1707
1708 CompilandIndexItem *cii = m_index->compilands().GetCompiland(var_id.modi);
1709 CompUnitSP comp_unit_sp = GetOrCreateCompileUnit(*cii);
1710 TypeSP type_sp = GetOrCreateType(var_info.type);
1711 std::string name = var_info.name.str();
1712 Declaration decl;
1713 SymbolFileTypeSP sftype =
1714 std::make_shared<SymbolFileType>(*this, type_sp->GetID());
1715
1716 is_param |= var_info.is_param;
1717 ValueType var_scope =
1718 is_param ? eValueTypeVariableArgument : eValueTypeVariableLocal;
1719 bool external = false;
1720 bool artificial = false;
1721 bool location_is_constant_data = false;
1722 bool static_member = false;
1723 DWARFExpressionList locaiton_list = DWARFExpressionList(
1724 module, *var_info.location, nullptr);
1725 VariableSP var_sp = std::make_shared<Variable>(
1726 toOpaqueUid(var_id), name.c_str(), name.c_str(), sftype, var_scope,
1727 &block, *var_info.ranges, &decl, locaiton_list, external, artificial,
1728 location_is_constant_data, static_member);
1729 if (!is_param)
1730 m_ast->GetOrCreateVariableDecl(scope_id, var_id);
1731
1732 m_local_variables[toOpaqueUid(var_id)] = var_sp;
1733 return var_sp;
1734 }
1735
GetOrCreateLocalVariable(PdbCompilandSymId scope_id,PdbCompilandSymId var_id,bool is_param)1736 VariableSP SymbolFileNativePDB::GetOrCreateLocalVariable(
1737 PdbCompilandSymId scope_id, PdbCompilandSymId var_id, bool is_param) {
1738 auto iter = m_local_variables.find(toOpaqueUid(var_id));
1739 if (iter != m_local_variables.end())
1740 return iter->second;
1741
1742 return CreateLocalVariable(scope_id, var_id, is_param);
1743 }
1744
CreateTypedef(PdbGlobalSymId id)1745 TypeSP SymbolFileNativePDB::CreateTypedef(PdbGlobalSymId id) {
1746 CVSymbol sym = m_index->ReadSymbolRecord(id);
1747 lldbassert(sym.kind() == SymbolKind::S_UDT);
1748
1749 UDTSym udt = llvm::cantFail(SymbolDeserializer::deserializeAs<UDTSym>(sym));
1750
1751 TypeSP target_type = GetOrCreateType(udt.Type);
1752
1753 (void)m_ast->GetOrCreateTypedefDecl(id);
1754
1755 Declaration decl;
1756 return std::make_shared<lldb_private::Type>(
1757 toOpaqueUid(id), this, ConstString(udt.Name),
1758 target_type->GetByteSize(nullptr), nullptr, target_type->GetID(),
1759 lldb_private::Type::eEncodingIsTypedefUID, decl,
1760 target_type->GetForwardCompilerType(),
1761 lldb_private::Type::ResolveState::Forward);
1762 }
1763
GetOrCreateTypedef(PdbGlobalSymId id)1764 TypeSP SymbolFileNativePDB::GetOrCreateTypedef(PdbGlobalSymId id) {
1765 auto iter = m_types.find(toOpaqueUid(id));
1766 if (iter != m_types.end())
1767 return iter->second;
1768
1769 return CreateTypedef(id);
1770 }
1771
ParseVariablesForBlock(PdbCompilandSymId block_id)1772 size_t SymbolFileNativePDB::ParseVariablesForBlock(PdbCompilandSymId block_id) {
1773 Block &block = GetOrCreateBlock(block_id);
1774
1775 size_t count = 0;
1776
1777 CompilandIndexItem *cii = m_index->compilands().GetCompiland(block_id.modi);
1778 CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(block_id.offset);
1779 uint32_t params_remaining = 0;
1780 switch (sym.kind()) {
1781 case S_GPROC32:
1782 case S_LPROC32: {
1783 ProcSym proc(static_cast<SymbolRecordKind>(sym.kind()));
1784 cantFail(SymbolDeserializer::deserializeAs<ProcSym>(sym, proc));
1785 CVType signature = m_index->tpi().getType(proc.FunctionType);
1786 ProcedureRecord sig;
1787 cantFail(TypeDeserializer::deserializeAs<ProcedureRecord>(signature, sig));
1788 params_remaining = sig.getParameterCount();
1789 break;
1790 }
1791 case S_BLOCK32:
1792 break;
1793 case S_INLINESITE:
1794 break;
1795 default:
1796 lldbassert(false && "Symbol is not a block!");
1797 return 0;
1798 }
1799
1800 VariableListSP variables = block.GetBlockVariableList(false);
1801 if (!variables) {
1802 variables = std::make_shared<VariableList>();
1803 block.SetVariableList(variables);
1804 }
1805
1806 CVSymbolArray syms = limitSymbolArrayToScope(
1807 cii->m_debug_stream.getSymbolArray(), block_id.offset);
1808
1809 // Skip the first record since it's a PROC32 or BLOCK32, and there's
1810 // no point examining it since we know it's not a local variable.
1811 syms.drop_front();
1812 auto iter = syms.begin();
1813 auto end = syms.end();
1814
1815 while (iter != end) {
1816 uint32_t record_offset = iter.offset();
1817 CVSymbol variable_cvs = *iter;
1818 PdbCompilandSymId child_sym_id(block_id.modi, record_offset);
1819 ++iter;
1820
1821 // If this is a block or inline site, recurse into its children and then
1822 // skip it.
1823 if (variable_cvs.kind() == S_BLOCK32 ||
1824 variable_cvs.kind() == S_INLINESITE) {
1825 uint32_t block_end = getScopeEndOffset(variable_cvs);
1826 count += ParseVariablesForBlock(child_sym_id);
1827 iter = syms.at(block_end);
1828 continue;
1829 }
1830
1831 bool is_param = params_remaining > 0;
1832 VariableSP variable;
1833 switch (variable_cvs.kind()) {
1834 case S_REGREL32:
1835 case S_REGISTER:
1836 case S_LOCAL:
1837 variable = GetOrCreateLocalVariable(block_id, child_sym_id, is_param);
1838 if (is_param)
1839 --params_remaining;
1840 if (variable)
1841 variables->AddVariableIfUnique(variable);
1842 break;
1843 default:
1844 break;
1845 }
1846 }
1847
1848 // Pass false for set_children, since we call this recursively so that the
1849 // children will call this for themselves.
1850 block.SetDidParseVariables(true, false);
1851
1852 return count;
1853 }
1854
ParseVariablesForContext(const SymbolContext & sc)1855 size_t SymbolFileNativePDB::ParseVariablesForContext(const SymbolContext &sc) {
1856 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1857 lldbassert(sc.function || sc.comp_unit);
1858
1859 VariableListSP variables;
1860 if (sc.block) {
1861 PdbSymUid block_id(sc.block->GetID());
1862
1863 size_t count = ParseVariablesForBlock(block_id.asCompilandSym());
1864 return count;
1865 }
1866
1867 if (sc.function) {
1868 PdbSymUid block_id(sc.function->GetID());
1869
1870 size_t count = ParseVariablesForBlock(block_id.asCompilandSym());
1871 return count;
1872 }
1873
1874 if (sc.comp_unit) {
1875 variables = sc.comp_unit->GetVariableList(false);
1876 if (!variables) {
1877 variables = std::make_shared<VariableList>();
1878 sc.comp_unit->SetVariableList(variables);
1879 }
1880 return ParseVariablesForCompileUnit(*sc.comp_unit, *variables);
1881 }
1882
1883 llvm_unreachable("Unreachable!");
1884 }
1885
GetDeclForUID(lldb::user_id_t uid)1886 CompilerDecl SymbolFileNativePDB::GetDeclForUID(lldb::user_id_t uid) {
1887 if (auto decl = m_ast->GetOrCreateDeclForUid(uid))
1888 return *decl;
1889 else
1890 return CompilerDecl();
1891 }
1892
1893 CompilerDeclContext
GetDeclContextForUID(lldb::user_id_t uid)1894 SymbolFileNativePDB::GetDeclContextForUID(lldb::user_id_t uid) {
1895 clang::DeclContext *context =
1896 m_ast->GetOrCreateDeclContextForUid(PdbSymUid(uid));
1897 if (!context)
1898 return {};
1899
1900 return m_ast->ToCompilerDeclContext(*context);
1901 }
1902
1903 CompilerDeclContext
GetDeclContextContainingUID(lldb::user_id_t uid)1904 SymbolFileNativePDB::GetDeclContextContainingUID(lldb::user_id_t uid) {
1905 clang::DeclContext *context = m_ast->GetParentDeclContext(PdbSymUid(uid));
1906 return m_ast->ToCompilerDeclContext(*context);
1907 }
1908
ResolveTypeUID(lldb::user_id_t type_uid)1909 Type *SymbolFileNativePDB::ResolveTypeUID(lldb::user_id_t type_uid) {
1910 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1911 auto iter = m_types.find(type_uid);
1912 // lldb should not be passing us non-sensical type uids. the only way it
1913 // could have a type uid in the first place is if we handed it out, in which
1914 // case we should know about the type. However, that doesn't mean we've
1915 // instantiated it yet. We can vend out a UID for a future type. So if the
1916 // type doesn't exist, let's instantiate it now.
1917 if (iter != m_types.end())
1918 return &*iter->second;
1919
1920 PdbSymUid uid(type_uid);
1921 lldbassert(uid.kind() == PdbSymUidKind::Type);
1922 PdbTypeSymId type_id = uid.asTypeSym();
1923 if (type_id.index.isNoneType())
1924 return nullptr;
1925
1926 TypeSP type_sp = CreateAndCacheType(type_id);
1927 return &*type_sp;
1928 }
1929
1930 llvm::Optional<SymbolFile::ArrayInfo>
GetDynamicArrayInfoForUID(lldb::user_id_t type_uid,const lldb_private::ExecutionContext * exe_ctx)1931 SymbolFileNativePDB::GetDynamicArrayInfoForUID(
1932 lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) {
1933 return llvm::None;
1934 }
1935
1936
CompleteType(CompilerType & compiler_type)1937 bool SymbolFileNativePDB::CompleteType(CompilerType &compiler_type) {
1938 clang::QualType qt =
1939 clang::QualType::getFromOpaquePtr(compiler_type.GetOpaqueQualType());
1940
1941 return m_ast->CompleteType(qt);
1942 }
1943
GetTypes(lldb_private::SymbolContextScope * sc_scope,TypeClass type_mask,lldb_private::TypeList & type_list)1944 void SymbolFileNativePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope,
1945 TypeClass type_mask,
1946 lldb_private::TypeList &type_list) {}
1947
1948 CompilerDeclContext
FindNamespace(ConstString name,const CompilerDeclContext & parent_decl_ctx)1949 SymbolFileNativePDB::FindNamespace(ConstString name,
1950 const CompilerDeclContext &parent_decl_ctx) {
1951 return {};
1952 }
1953
1954 llvm::Expected<TypeSystem &>
GetTypeSystemForLanguage(lldb::LanguageType language)1955 SymbolFileNativePDB::GetTypeSystemForLanguage(lldb::LanguageType language) {
1956 auto type_system_or_err =
1957 m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language);
1958 if (type_system_or_err) {
1959 type_system_or_err->SetSymbolFile(this);
1960 }
1961 return type_system_or_err;
1962 }
1963
GetDebugInfoSize()1964 uint64_t SymbolFileNativePDB::GetDebugInfoSize() {
1965 // PDB files are a separate file that contains all debug info.
1966 return m_index->pdb().getFileSize();
1967 }
1968