1 //===-- SymbolFilePDB.cpp ---------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "SymbolFilePDB.h" 11 12 #include "clang/Lex/Lexer.h" 13 14 #include "lldb/Core/Module.h" 15 #include "lldb/Core/PluginManager.h" 16 #include "lldb/Symbol/ClangASTContext.h" 17 #include "lldb/Symbol/CompileUnit.h" 18 #include "lldb/Symbol/LineTable.h" 19 #include "lldb/Symbol/ObjectFile.h" 20 #include "lldb/Symbol/SymbolContext.h" 21 #include "lldb/Symbol/TypeMap.h" 22 23 #include "llvm/DebugInfo/PDB/GenericError.h" 24 #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" 25 #include "llvm/DebugInfo/PDB/IPDBLineNumber.h" 26 #include "llvm/DebugInfo/PDB/IPDBSourceFile.h" 27 #include "llvm/DebugInfo/PDB/PDBSymbol.h" 28 #include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h" 29 #include "llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h" 30 #include "llvm/DebugInfo/PDB/PDBSymbolExe.h" 31 #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h" 32 #include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h" 33 #include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h" 34 #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h" 35 #include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h" 36 #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" 37 38 #include "Plugins/SymbolFile/PDB/PDBASTParser.h" 39 40 #include <regex> 41 42 using namespace lldb_private; 43 using namespace llvm::pdb; 44 45 namespace { 46 lldb::LanguageType TranslateLanguage(PDB_Lang lang) { 47 switch (lang) { 48 case PDB_Lang::Cpp: 49 return lldb::LanguageType::eLanguageTypeC_plus_plus; 50 case PDB_Lang::C: 51 return lldb::LanguageType::eLanguageTypeC; 52 default: 53 return lldb::LanguageType::eLanguageTypeUnknown; 54 } 55 } 56 57 bool ShouldAddLine(uint32_t requested_line, uint32_t actual_line, 58 uint32_t addr_length) { 59 return ((requested_line == 0 || actual_line == requested_line) && 60 addr_length > 0); 61 } 62 } 63 64 void SymbolFilePDB::Initialize() { 65 PluginManager::RegisterPlugin(GetPluginNameStatic(), 66 GetPluginDescriptionStatic(), CreateInstance, 67 DebuggerInitialize); 68 } 69 70 void SymbolFilePDB::Terminate() { 71 PluginManager::UnregisterPlugin(CreateInstance); 72 } 73 74 void SymbolFilePDB::DebuggerInitialize(lldb_private::Debugger &debugger) {} 75 76 lldb_private::ConstString SymbolFilePDB::GetPluginNameStatic() { 77 static ConstString g_name("pdb"); 78 return g_name; 79 } 80 81 const char *SymbolFilePDB::GetPluginDescriptionStatic() { 82 return "Microsoft PDB debug symbol file reader."; 83 } 84 85 lldb_private::SymbolFile * 86 SymbolFilePDB::CreateInstance(lldb_private::ObjectFile *obj_file) { 87 return new SymbolFilePDB(obj_file); 88 } 89 90 SymbolFilePDB::SymbolFilePDB(lldb_private::ObjectFile *object_file) 91 : SymbolFile(object_file), m_cached_compile_unit_count(0) {} 92 93 SymbolFilePDB::~SymbolFilePDB() {} 94 95 uint32_t SymbolFilePDB::CalculateAbilities() { 96 if (!m_session_up) { 97 // Lazily load and match the PDB file, but only do this once. 98 std::string exePath = m_obj_file->GetFileSpec().GetPath(); 99 auto error = loadDataForEXE(PDB_ReaderType::DIA, llvm::StringRef(exePath), 100 m_session_up); 101 if (error) { 102 llvm::consumeError(std::move(error)); 103 return 0; 104 } 105 } 106 return CompileUnits | LineTables; 107 } 108 109 void SymbolFilePDB::InitializeObject() { 110 lldb::addr_t obj_load_address = m_obj_file->GetFileOffset(); 111 m_session_up->setLoadAddress(obj_load_address); 112 113 TypeSystem *type_system = 114 GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); 115 ClangASTContext *clang_type_system = 116 llvm::dyn_cast_or_null<ClangASTContext>(type_system); 117 m_tu_decl_ctx_up = llvm::make_unique<CompilerDeclContext>( 118 type_system, clang_type_system->GetTranslationUnitDecl()); 119 } 120 121 uint32_t SymbolFilePDB::GetNumCompileUnits() { 122 if (m_cached_compile_unit_count == 0) { 123 auto global = m_session_up->getGlobalScope(); 124 auto compilands = global->findAllChildren<PDBSymbolCompiland>(); 125 m_cached_compile_unit_count = compilands->getChildCount(); 126 127 // The linker can inject an additional "dummy" compilation unit into the 128 // PDB. 129 // Ignore this special compile unit for our purposes, if it is there. It is 130 // always the last one. 131 auto last_cu = compilands->getChildAtIndex(m_cached_compile_unit_count - 1); 132 std::string name = last_cu->getName(); 133 if (name == "* Linker *") 134 --m_cached_compile_unit_count; 135 } 136 return m_cached_compile_unit_count; 137 } 138 139 lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitAtIndex(uint32_t index) { 140 auto global = m_session_up->getGlobalScope(); 141 auto compilands = global->findAllChildren<PDBSymbolCompiland>(); 142 auto cu = compilands->getChildAtIndex(index); 143 144 uint32_t id = cu->getSymIndexId(); 145 146 return ParseCompileUnitForSymIndex(id); 147 } 148 149 lldb::LanguageType 150 SymbolFilePDB::ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) { 151 // What fields should I expect to be filled out on the SymbolContext? Is it 152 // safe to assume that `sc.comp_unit` is valid? 153 if (!sc.comp_unit) 154 return lldb::eLanguageTypeUnknown; 155 156 auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>( 157 sc.comp_unit->GetID()); 158 if (!cu) 159 return lldb::eLanguageTypeUnknown; 160 auto details = cu->findOneChild<PDBSymbolCompilandDetails>(); 161 if (!details) 162 return lldb::eLanguageTypeUnknown; 163 return TranslateLanguage(details->getLanguage()); 164 } 165 166 size_t SymbolFilePDB::ParseCompileUnitFunctions( 167 const lldb_private::SymbolContext &sc) { 168 // TODO: Implement this 169 return size_t(); 170 } 171 172 bool SymbolFilePDB::ParseCompileUnitLineTable( 173 const lldb_private::SymbolContext &sc) { 174 return ParseCompileUnitLineTable(sc, 0); 175 } 176 177 bool SymbolFilePDB::ParseCompileUnitDebugMacros( 178 const lldb_private::SymbolContext &sc) { 179 // PDB doesn't contain information about macros 180 return false; 181 } 182 183 bool SymbolFilePDB::ParseCompileUnitSupportFiles( 184 const lldb_private::SymbolContext &sc, 185 lldb_private::FileSpecList &support_files) { 186 if (!sc.comp_unit) 187 return false; 188 189 // In theory this is unnecessary work for us, because all of this information 190 // is easily 191 // (and quickly) accessible from DebugInfoPDB, so caching it a second time 192 // seems like a waste. 193 // Unfortunately, there's no good way around this short of a moderate 194 // refactor, since SymbolVendor 195 // depends on being able to cache this list. 196 auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>( 197 sc.comp_unit->GetID()); 198 if (!cu) 199 return false; 200 auto files = m_session_up->getSourceFilesForCompiland(*cu); 201 if (!files || files->getChildCount() == 0) 202 return false; 203 204 while (auto file = files->getNext()) { 205 FileSpec spec(file->getFileName(), false); 206 support_files.Append(spec); 207 } 208 return true; 209 } 210 211 bool SymbolFilePDB::ParseImportedModules( 212 const lldb_private::SymbolContext &sc, 213 std::vector<lldb_private::ConstString> &imported_modules) { 214 // PDB does not yet support module debug info 215 return false; 216 } 217 218 size_t 219 SymbolFilePDB::ParseFunctionBlocks(const lldb_private::SymbolContext &sc) { 220 // TODO: Implement this 221 return size_t(); 222 } 223 224 size_t SymbolFilePDB::ParseTypes(const lldb_private::SymbolContext &sc) { 225 // TODO: Implement this 226 return size_t(); 227 } 228 229 size_t 230 SymbolFilePDB::ParseVariablesForContext(const lldb_private::SymbolContext &sc) { 231 // TODO: Implement this 232 return size_t(); 233 } 234 235 lldb_private::Type *SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) { 236 auto find_result = m_types.find(type_uid); 237 if (find_result != m_types.end()) 238 return find_result->second.get(); 239 240 TypeSystem *type_system = 241 GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); 242 ClangASTContext *clang_type_system = 243 llvm::dyn_cast_or_null<ClangASTContext>(type_system); 244 if (!clang_type_system) 245 return nullptr; 246 PDBASTParser *pdb = 247 llvm::dyn_cast<PDBASTParser>(clang_type_system->GetPDBParser()); 248 if (!pdb) 249 return nullptr; 250 251 auto pdb_type = m_session_up->getSymbolById(type_uid); 252 if (pdb_type == nullptr) 253 return nullptr; 254 255 lldb::TypeSP result = pdb->CreateLLDBTypeFromPDBType(*pdb_type); 256 m_types.insert(std::make_pair(type_uid, result)); 257 return result.get(); 258 } 259 260 bool SymbolFilePDB::CompleteType(lldb_private::CompilerType &compiler_type) { 261 // TODO: Implement this 262 return false; 263 } 264 265 lldb_private::CompilerDecl SymbolFilePDB::GetDeclForUID(lldb::user_id_t uid) { 266 return lldb_private::CompilerDecl(); 267 } 268 269 lldb_private::CompilerDeclContext 270 SymbolFilePDB::GetDeclContextForUID(lldb::user_id_t uid) { 271 // PDB always uses the translation unit decl context for everything. We can 272 // improve this later 273 // but it's not easy because PDB doesn't provide a high enough level of type 274 // fidelity in this area. 275 return *m_tu_decl_ctx_up; 276 } 277 278 lldb_private::CompilerDeclContext 279 SymbolFilePDB::GetDeclContextContainingUID(lldb::user_id_t uid) { 280 return *m_tu_decl_ctx_up; 281 } 282 283 void SymbolFilePDB::ParseDeclsForContext( 284 lldb_private::CompilerDeclContext decl_ctx) {} 285 286 uint32_t 287 SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr, 288 uint32_t resolve_scope, 289 lldb_private::SymbolContext &sc) { 290 return uint32_t(); 291 } 292 293 uint32_t SymbolFilePDB::ResolveSymbolContext( 294 const lldb_private::FileSpec &file_spec, uint32_t line, bool check_inlines, 295 uint32_t resolve_scope, lldb_private::SymbolContextList &sc_list) { 296 if (resolve_scope & lldb::eSymbolContextCompUnit) { 297 // Locate all compilation units with line numbers referencing the specified 298 // file. For example, if 299 // `file_spec` is <vector>, then this should return all source files and 300 // header files that reference 301 // <vector>, either directly or indirectly. 302 auto compilands = m_session_up->findCompilandsForSourceFile( 303 file_spec.GetPath(), PDB_NameSearchFlags::NS_CaseInsensitive); 304 305 // For each one, either find get its previously parsed data, or parse it 306 // afresh and add it to 307 // the symbol context list. 308 while (auto compiland = compilands->getNext()) { 309 // If we're not checking inlines, then don't add line information for this 310 // file unless the FileSpec 311 // matches. 312 if (!check_inlines) { 313 // `getSourceFileName` returns the basename of the original source file 314 // used to generate this compiland. 315 // It does not return the full path. Currently the only way to get that 316 // is to do a basename lookup to 317 // get the IPDBSourceFile, but this is ambiguous in the case of two 318 // source files with the same name 319 // contributing to the same compiland. This is a moderately extreme 320 // edge case, so we consider this ok 321 // for now, although we need to find a long term solution. 322 std::string source_file = compiland->getSourceFileName(); 323 auto pdb_file = m_session_up->findOneSourceFile( 324 compiland.get(), source_file, 325 PDB_NameSearchFlags::NS_CaseInsensitive); 326 source_file = pdb_file->getFileName(); 327 FileSpec this_spec(source_file, false, FileSpec::ePathSyntaxWindows); 328 if (!file_spec.FileEquals(this_spec)) 329 continue; 330 } 331 332 SymbolContext sc; 333 auto cu = ParseCompileUnitForSymIndex(compiland->getSymIndexId()); 334 sc.comp_unit = cu.get(); 335 sc.module_sp = cu->GetModule(); 336 sc_list.Append(sc); 337 338 // If we were asked to resolve line entries, add all entries to the line 339 // table that match the requested 340 // line (or all lines if `line` == 0) 341 if (resolve_scope & lldb::eSymbolContextLineEntry) 342 ParseCompileUnitLineTable(sc, line); 343 } 344 } 345 return sc_list.GetSize(); 346 } 347 348 uint32_t SymbolFilePDB::FindGlobalVariables( 349 const lldb_private::ConstString &name, 350 const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append, 351 uint32_t max_matches, lldb_private::VariableList &variables) { 352 return uint32_t(); 353 } 354 355 uint32_t 356 SymbolFilePDB::FindGlobalVariables(const lldb_private::RegularExpression ®ex, 357 bool append, uint32_t max_matches, 358 lldb_private::VariableList &variables) { 359 return uint32_t(); 360 } 361 362 uint32_t SymbolFilePDB::FindFunctions( 363 const lldb_private::ConstString &name, 364 const lldb_private::CompilerDeclContext *parent_decl_ctx, 365 uint32_t name_type_mask, bool include_inlines, bool append, 366 lldb_private::SymbolContextList &sc_list) { 367 return uint32_t(); 368 } 369 370 uint32_t 371 SymbolFilePDB::FindFunctions(const lldb_private::RegularExpression ®ex, 372 bool include_inlines, bool append, 373 lldb_private::SymbolContextList &sc_list) { 374 return uint32_t(); 375 } 376 377 void SymbolFilePDB::GetMangledNamesForFunction( 378 const std::string &scope_qualified_name, 379 std::vector<lldb_private::ConstString> &mangled_names) {} 380 381 uint32_t SymbolFilePDB::FindTypes( 382 const lldb_private::SymbolContext &sc, 383 const lldb_private::ConstString &name, 384 const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append, 385 uint32_t max_matches, 386 llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, 387 lldb_private::TypeMap &types) { 388 if (!append) 389 types.Clear(); 390 if (!name) 391 return 0; 392 393 searched_symbol_files.clear(); 394 searched_symbol_files.insert(this); 395 396 std::string name_str = name.AsCString(); 397 398 // If this might be a regex, we have to return EVERY symbol and process them 399 // one by one, which is going 400 // to destroy performance on large PDB files. So try really hard not to use a 401 // regex match. 402 if (name_str.find_first_of("[]?*.-+\\") != std::string::npos) 403 FindTypesByRegex(name_str, max_matches, types); 404 else 405 FindTypesByName(name_str, max_matches, types); 406 return types.GetSize(); 407 } 408 409 void SymbolFilePDB::FindTypesByRegex(const std::string ®ex, 410 uint32_t max_matches, 411 lldb_private::TypeMap &types) { 412 // When searching by regex, we need to go out of our way to limit the search 413 // space as much as possible, since 414 // the way this is implemented is by searching EVERYTHING in the PDB and 415 // manually doing a regex compare. PDB 416 // library isn't optimized for regex searches or searches across multiple 417 // symbol types at the same time, so the 418 // best we can do is to search enums, then typedefs, then classes one by one, 419 // and do a regex compare against all 420 // of them. 421 PDB_SymType tags_to_search[] = {PDB_SymType::Enum, PDB_SymType::Typedef, 422 PDB_SymType::UDT}; 423 auto global = m_session_up->getGlobalScope(); 424 std::unique_ptr<IPDBEnumSymbols> results; 425 426 std::regex re(regex); 427 428 uint32_t matches = 0; 429 430 for (auto tag : tags_to_search) { 431 results = global->findAllChildren(tag); 432 while (auto result = results->getNext()) { 433 if (max_matches > 0 && matches >= max_matches) 434 break; 435 436 std::string type_name; 437 if (auto enum_type = llvm::dyn_cast<PDBSymbolTypeEnum>(result.get())) 438 type_name = enum_type->getName(); 439 else if (auto typedef_type = 440 llvm::dyn_cast<PDBSymbolTypeTypedef>(result.get())) 441 type_name = typedef_type->getName(); 442 else if (auto class_type = llvm::dyn_cast<PDBSymbolTypeUDT>(result.get())) 443 type_name = class_type->getName(); 444 else { 445 // We're only looking for types that have names. Skip symbols, as well 446 // as 447 // unnamed types such as arrays, pointers, etc. 448 continue; 449 } 450 451 if (!std::regex_match(type_name, re)) 452 continue; 453 454 // This should cause the type to get cached and stored in the `m_types` 455 // lookup. 456 if (!ResolveTypeUID(result->getSymIndexId())) 457 continue; 458 459 auto iter = m_types.find(result->getSymIndexId()); 460 if (iter == m_types.end()) 461 continue; 462 types.Insert(iter->second); 463 ++matches; 464 } 465 } 466 } 467 468 void SymbolFilePDB::FindTypesByName(const std::string &name, 469 uint32_t max_matches, 470 lldb_private::TypeMap &types) { 471 auto global = m_session_up->getGlobalScope(); 472 std::unique_ptr<IPDBEnumSymbols> results; 473 results = global->findChildren(PDB_SymType::None, name.c_str(), 474 PDB_NameSearchFlags::NS_Default); 475 476 uint32_t matches = 0; 477 478 while (auto result = results->getNext()) { 479 if (max_matches > 0 && matches >= max_matches) 480 break; 481 switch (result->getSymTag()) { 482 case PDB_SymType::Enum: 483 case PDB_SymType::UDT: 484 case PDB_SymType::Typedef: 485 break; 486 default: 487 // We're only looking for types that have names. Skip symbols, as well as 488 // unnamed types such as arrays, pointers, etc. 489 continue; 490 } 491 492 // This should cause the type to get cached and stored in the `m_types` 493 // lookup. 494 if (!ResolveTypeUID(result->getSymIndexId())) 495 continue; 496 497 auto iter = m_types.find(result->getSymIndexId()); 498 if (iter == m_types.end()) 499 continue; 500 types.Insert(iter->second); 501 ++matches; 502 } 503 } 504 505 size_t SymbolFilePDB::FindTypes( 506 const std::vector<lldb_private::CompilerContext> &contexts, bool append, 507 lldb_private::TypeMap &types) { 508 return 0; 509 } 510 511 lldb_private::TypeList *SymbolFilePDB::GetTypeList() { return nullptr; } 512 513 size_t SymbolFilePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope, 514 uint32_t type_mask, 515 lldb_private::TypeList &type_list) { 516 return size_t(); 517 } 518 519 lldb_private::TypeSystem * 520 SymbolFilePDB::GetTypeSystemForLanguage(lldb::LanguageType language) { 521 auto type_system = 522 m_obj_file->GetModule()->GetTypeSystemForLanguage(language); 523 if (type_system) 524 type_system->SetSymbolFile(this); 525 return type_system; 526 } 527 528 lldb_private::CompilerDeclContext SymbolFilePDB::FindNamespace( 529 const lldb_private::SymbolContext &sc, 530 const lldb_private::ConstString &name, 531 const lldb_private::CompilerDeclContext *parent_decl_ctx) { 532 return lldb_private::CompilerDeclContext(); 533 } 534 535 lldb_private::ConstString SymbolFilePDB::GetPluginName() { 536 static ConstString g_name("pdb"); 537 return g_name; 538 } 539 540 uint32_t SymbolFilePDB::GetPluginVersion() { return 1; } 541 542 IPDBSession &SymbolFilePDB::GetPDBSession() { return *m_session_up; } 543 544 const IPDBSession &SymbolFilePDB::GetPDBSession() const { 545 return *m_session_up; 546 } 547 548 lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitForSymIndex(uint32_t id) { 549 auto found_cu = m_comp_units.find(id); 550 if (found_cu != m_comp_units.end()) 551 return found_cu->second; 552 553 auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(id); 554 555 // `getSourceFileName` returns the basename of the original source file used 556 // to generate this compiland. It does 557 // not return the full path. Currently the only way to get that is to do a 558 // basename lookup to get the 559 // IPDBSourceFile, but this is ambiguous in the case of two source files with 560 // the same name contributing to the 561 // same compiland. This is a moderately extreme edge case, so we consider this 562 // ok for now, although we need to find 563 // a long term solution. 564 auto file = 565 m_session_up->findOneSourceFile(cu.get(), cu->getSourceFileName(), 566 PDB_NameSearchFlags::NS_CaseInsensitive); 567 std::string path = file->getFileName(); 568 569 lldb::LanguageType lang; 570 auto details = cu->findOneChild<PDBSymbolCompilandDetails>(); 571 if (!details) 572 lang = lldb::eLanguageTypeC_plus_plus; 573 else 574 lang = TranslateLanguage(details->getLanguage()); 575 576 // Don't support optimized code for now, DebugInfoPDB does not return this 577 // information. 578 LazyBool optimized = eLazyBoolNo; 579 auto result = std::make_shared<CompileUnit>( 580 m_obj_file->GetModule(), nullptr, path.c_str(), id, lang, optimized); 581 m_comp_units.insert(std::make_pair(id, result)); 582 return result; 583 } 584 585 bool SymbolFilePDB::ParseCompileUnitLineTable( 586 const lldb_private::SymbolContext &sc, uint32_t match_line) { 587 auto global = m_session_up->getGlobalScope(); 588 auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>( 589 sc.comp_unit->GetID()); 590 591 // LineEntry needs the *index* of the file into the list of support files 592 // returned by 593 // ParseCompileUnitSupportFiles. But the underlying SDK gives us a globally 594 // unique 595 // idenfitifier in the namespace of the PDB. So, we have to do a mapping so 596 // that we 597 // can hand out indices. 598 llvm::DenseMap<uint32_t, uint32_t> index_map; 599 BuildSupportFileIdToSupportFileIndexMap(*cu, index_map); 600 auto line_table = llvm::make_unique<LineTable>(sc.comp_unit); 601 602 // Find contributions to `cu` from all source and header files. 603 std::string path = sc.comp_unit->GetPath(); 604 auto files = m_session_up->getSourceFilesForCompiland(*cu); 605 606 // For each source and header file, create a LineSequence for contributions to 607 // the cu 608 // from that file, and add the sequence. 609 while (auto file = files->getNext()) { 610 std::unique_ptr<LineSequence> sequence( 611 line_table->CreateLineSequenceContainer()); 612 auto lines = m_session_up->findLineNumbers(*cu, *file); 613 int entry_count = lines->getChildCount(); 614 615 uint64_t prev_addr; 616 uint32_t prev_length; 617 uint32_t prev_line; 618 uint32_t prev_source_idx; 619 620 for (int i = 0; i < entry_count; ++i) { 621 auto line = lines->getChildAtIndex(i); 622 623 uint64_t lno = line->getLineNumber(); 624 uint64_t addr = line->getVirtualAddress(); 625 uint32_t length = line->getLength(); 626 uint32_t source_id = line->getSourceFileId(); 627 uint32_t col = line->getColumnNumber(); 628 uint32_t source_idx = index_map[source_id]; 629 630 // There was a gap between the current entry and the previous entry if the 631 // addresses don't perfectly line 632 // up. 633 bool is_gap = (i > 0) && (prev_addr + prev_length < addr); 634 635 // Before inserting the current entry, insert a terminal entry at the end 636 // of the previous entry's address 637 // range if the current entry resulted in a gap from the previous entry. 638 if (is_gap && ShouldAddLine(match_line, prev_line, prev_length)) { 639 line_table->AppendLineEntryToSequence( 640 sequence.get(), prev_addr + prev_length, prev_line, 0, 641 prev_source_idx, false, false, false, false, true); 642 } 643 644 if (ShouldAddLine(match_line, lno, length)) { 645 bool is_statement = line->isStatement(); 646 bool is_prologue = false; 647 bool is_epilogue = false; 648 auto func = 649 m_session_up->findSymbolByAddress(addr, PDB_SymType::Function); 650 if (func) { 651 auto prologue = func->findOneChild<PDBSymbolFuncDebugStart>(); 652 is_prologue = (addr == prologue->getVirtualAddress()); 653 654 auto epilogue = func->findOneChild<PDBSymbolFuncDebugEnd>(); 655 is_epilogue = (addr == epilogue->getVirtualAddress()); 656 } 657 658 line_table->AppendLineEntryToSequence(sequence.get(), addr, lno, col, 659 source_idx, is_statement, false, 660 is_prologue, is_epilogue, false); 661 } 662 663 prev_addr = addr; 664 prev_length = length; 665 prev_line = lno; 666 prev_source_idx = source_idx; 667 } 668 669 if (entry_count > 0 && ShouldAddLine(match_line, prev_line, prev_length)) { 670 // The end is always a terminal entry, so insert it regardless. 671 line_table->AppendLineEntryToSequence( 672 sequence.get(), prev_addr + prev_length, prev_line, 0, 673 prev_source_idx, false, false, false, false, true); 674 } 675 676 line_table->InsertSequence(sequence.release()); 677 } 678 679 sc.comp_unit->SetLineTable(line_table.release()); 680 return true; 681 } 682 683 void SymbolFilePDB::BuildSupportFileIdToSupportFileIndexMap( 684 const PDBSymbolCompiland &cu, 685 llvm::DenseMap<uint32_t, uint32_t> &index_map) const { 686 // This is a hack, but we need to convert the source id into an index into the 687 // support 688 // files array. We don't want to do path comparisons to avoid basename / full 689 // path 690 // issues that may or may not even be a problem, so we use the globally unique 691 // source 692 // file identifiers. Ideally we could use the global identifiers everywhere, 693 // but LineEntry 694 // currently assumes indices. 695 auto source_files = m_session_up->getSourceFilesForCompiland(cu); 696 int index = 0; 697 698 while (auto file = source_files->getNext()) { 699 uint32_t source_id = file->getUniqueId(); 700 index_map[source_id] = index++; 701 } 702 } 703