1 #include "llvm/DebugInfo/PDB/Native/SymbolCache.h" 2 3 #include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h" 4 #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" 5 #include "llvm/DebugInfo/CodeView/TypeDeserializer.h" 6 #include "llvm/DebugInfo/CodeView/TypeRecordHelpers.h" 7 #include "llvm/DebugInfo/PDB/Native/DbiStream.h" 8 #include "llvm/DebugInfo/PDB/Native/GlobalsStream.h" 9 #include "llvm/DebugInfo/PDB/Native/ISectionContribVisitor.h" 10 #include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h" 11 #include "llvm/DebugInfo/PDB/Native/NativeEnumGlobals.h" 12 #include "llvm/DebugInfo/PDB/Native/NativeEnumLineNumbers.h" 13 #include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h" 14 #include "llvm/DebugInfo/PDB/Native/NativeFunctionSymbol.h" 15 #include "llvm/DebugInfo/PDB/Native/NativePublicSymbol.h" 16 #include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h" 17 #include "llvm/DebugInfo/PDB/Native/NativeSession.h" 18 #include "llvm/DebugInfo/PDB/Native/NativeTypeArray.h" 19 #include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h" 20 #include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h" 21 #include "llvm/DebugInfo/PDB/Native/NativeTypeFunctionSig.h" 22 #include "llvm/DebugInfo/PDB/Native/NativeTypePointer.h" 23 #include "llvm/DebugInfo/PDB/Native/NativeTypeTypedef.h" 24 #include "llvm/DebugInfo/PDB/Native/NativeTypeUDT.h" 25 #include "llvm/DebugInfo/PDB/Native/NativeTypeVTShape.h" 26 #include "llvm/DebugInfo/PDB/Native/PDBFile.h" 27 #include "llvm/DebugInfo/PDB/Native/PublicsStream.h" 28 #include "llvm/DebugInfo/PDB/Native/SymbolStream.h" 29 #include "llvm/DebugInfo/PDB/Native/TpiStream.h" 30 #include "llvm/DebugInfo/PDB/PDBSymbol.h" 31 #include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h" 32 #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h" 33 34 using namespace llvm; 35 using namespace llvm::codeview; 36 using namespace llvm::pdb; 37 38 // Maps codeview::SimpleTypeKind of a built-in type to the parameters necessary 39 // to instantiate a NativeBuiltinSymbol for that type. 40 static const struct BuiltinTypeEntry { 41 codeview::SimpleTypeKind Kind; 42 PDB_BuiltinType Type; 43 uint32_t Size; 44 } BuiltinTypes[] = { 45 {codeview::SimpleTypeKind::None, PDB_BuiltinType::None, 0}, 46 {codeview::SimpleTypeKind::Void, PDB_BuiltinType::Void, 0}, 47 {codeview::SimpleTypeKind::HResult, PDB_BuiltinType::HResult, 4}, 48 {codeview::SimpleTypeKind::Int16Short, PDB_BuiltinType::Int, 2}, 49 {codeview::SimpleTypeKind::UInt16Short, PDB_BuiltinType::UInt, 2}, 50 {codeview::SimpleTypeKind::Int32, PDB_BuiltinType::Int, 4}, 51 {codeview::SimpleTypeKind::UInt32, PDB_BuiltinType::UInt, 4}, 52 {codeview::SimpleTypeKind::Int32Long, PDB_BuiltinType::Int, 4}, 53 {codeview::SimpleTypeKind::UInt32Long, PDB_BuiltinType::UInt, 4}, 54 {codeview::SimpleTypeKind::Int64Quad, PDB_BuiltinType::Int, 8}, 55 {codeview::SimpleTypeKind::UInt64Quad, PDB_BuiltinType::UInt, 8}, 56 {codeview::SimpleTypeKind::NarrowCharacter, PDB_BuiltinType::Char, 1}, 57 {codeview::SimpleTypeKind::WideCharacter, PDB_BuiltinType::WCharT, 2}, 58 {codeview::SimpleTypeKind::Character16, PDB_BuiltinType::Char16, 2}, 59 {codeview::SimpleTypeKind::Character32, PDB_BuiltinType::Char32, 4}, 60 {codeview::SimpleTypeKind::SignedCharacter, PDB_BuiltinType::Char, 1}, 61 {codeview::SimpleTypeKind::UnsignedCharacter, PDB_BuiltinType::UInt, 1}, 62 {codeview::SimpleTypeKind::Float32, PDB_BuiltinType::Float, 4}, 63 {codeview::SimpleTypeKind::Float64, PDB_BuiltinType::Float, 8}, 64 {codeview::SimpleTypeKind::Float80, PDB_BuiltinType::Float, 10}, 65 {codeview::SimpleTypeKind::Boolean8, PDB_BuiltinType::Bool, 1}, 66 // This table can be grown as necessary, but these are the only types we've 67 // needed so far. 68 }; 69 70 SymbolCache::SymbolCache(NativeSession &Session, DbiStream *Dbi) 71 : Session(Session), Dbi(Dbi), AddrToModuleIndex(IMapAllocator) { 72 // Id 0 is reserved for the invalid symbol. 73 Cache.push_back(nullptr); 74 SourceFiles.push_back(nullptr); 75 76 if (Dbi) 77 Compilands.resize(Dbi->modules().getModuleCount()); 78 } 79 80 std::unique_ptr<IPDBEnumSymbols> 81 SymbolCache::createTypeEnumerator(TypeLeafKind Kind) { 82 return createTypeEnumerator(std::vector<TypeLeafKind>{Kind}); 83 } 84 85 std::unique_ptr<IPDBEnumSymbols> 86 SymbolCache::createTypeEnumerator(std::vector<TypeLeafKind> Kinds) { 87 auto Tpi = Session.getPDBFile().getPDBTpiStream(); 88 if (!Tpi) { 89 consumeError(Tpi.takeError()); 90 return nullptr; 91 } 92 auto &Types = Tpi->typeCollection(); 93 return std::unique_ptr<IPDBEnumSymbols>( 94 new NativeEnumTypes(Session, Types, std::move(Kinds))); 95 } 96 97 std::unique_ptr<IPDBEnumSymbols> 98 SymbolCache::createGlobalsEnumerator(codeview::SymbolKind Kind) { 99 return std::unique_ptr<IPDBEnumSymbols>( 100 new NativeEnumGlobals(Session, {Kind})); 101 } 102 103 SymIndexId SymbolCache::createSimpleType(TypeIndex Index, 104 ModifierOptions Mods) { 105 if (Index.getSimpleMode() != codeview::SimpleTypeMode::Direct) 106 return createSymbol<NativeTypePointer>(Index); 107 108 const auto Kind = Index.getSimpleKind(); 109 const auto It = std::find_if( 110 std::begin(BuiltinTypes), std::end(BuiltinTypes), 111 [Kind](const BuiltinTypeEntry &Builtin) { return Builtin.Kind == Kind; }); 112 if (It == std::end(BuiltinTypes)) 113 return 0; 114 return createSymbol<NativeTypeBuiltin>(Mods, It->Type, It->Size); 115 } 116 117 SymIndexId 118 SymbolCache::createSymbolForModifiedType(codeview::TypeIndex ModifierTI, 119 codeview::CVType CVT) { 120 ModifierRecord Record; 121 if (auto EC = TypeDeserializer::deserializeAs<ModifierRecord>(CVT, Record)) { 122 consumeError(std::move(EC)); 123 return 0; 124 } 125 126 if (Record.ModifiedType.isSimple()) 127 return createSimpleType(Record.ModifiedType, Record.Modifiers); 128 129 // Make sure we create and cache a record for the unmodified type. 130 SymIndexId UnmodifiedId = findSymbolByTypeIndex(Record.ModifiedType); 131 NativeRawSymbol &UnmodifiedNRS = *Cache[UnmodifiedId]; 132 133 switch (UnmodifiedNRS.getSymTag()) { 134 case PDB_SymType::Enum: 135 return createSymbol<NativeTypeEnum>( 136 static_cast<NativeTypeEnum &>(UnmodifiedNRS), std::move(Record)); 137 case PDB_SymType::UDT: 138 return createSymbol<NativeTypeUDT>( 139 static_cast<NativeTypeUDT &>(UnmodifiedNRS), std::move(Record)); 140 default: 141 // No other types can be modified. (LF_POINTER, for example, records 142 // its modifiers a different way. 143 assert(false && "Invalid LF_MODIFIER record"); 144 break; 145 } 146 return 0; 147 } 148 149 SymIndexId SymbolCache::findSymbolByTypeIndex(codeview::TypeIndex Index) { 150 // First see if it's already in our cache. 151 const auto Entry = TypeIndexToSymbolId.find(Index); 152 if (Entry != TypeIndexToSymbolId.end()) 153 return Entry->second; 154 155 // Symbols for built-in types are created on the fly. 156 if (Index.isSimple()) { 157 SymIndexId Result = createSimpleType(Index, ModifierOptions::None); 158 assert(TypeIndexToSymbolId.count(Index) == 0); 159 TypeIndexToSymbolId[Index] = Result; 160 return Result; 161 } 162 163 // We need to instantiate and cache the desired type symbol. 164 auto Tpi = Session.getPDBFile().getPDBTpiStream(); 165 if (!Tpi) { 166 consumeError(Tpi.takeError()); 167 return 0; 168 } 169 codeview::LazyRandomTypeCollection &Types = Tpi->typeCollection(); 170 codeview::CVType CVT = Types.getType(Index); 171 172 if (isUdtForwardRef(CVT)) { 173 Expected<TypeIndex> EFD = Tpi->findFullDeclForForwardRef(Index); 174 175 if (!EFD) 176 consumeError(EFD.takeError()); 177 else if (*EFD != Index) { 178 assert(!isUdtForwardRef(Types.getType(*EFD))); 179 SymIndexId Result = findSymbolByTypeIndex(*EFD); 180 // Record a mapping from ForwardRef -> SymIndex of complete type so that 181 // we'll take the fast path next time. 182 assert(TypeIndexToSymbolId.count(Index) == 0); 183 TypeIndexToSymbolId[Index] = Result; 184 return Result; 185 } 186 } 187 188 // At this point if we still have a forward ref udt it means the full decl was 189 // not in the PDB. We just have to deal with it and use the forward ref. 190 SymIndexId Id = 0; 191 switch (CVT.kind()) { 192 case codeview::LF_ENUM: 193 Id = createSymbolForType<NativeTypeEnum, EnumRecord>(Index, std::move(CVT)); 194 break; 195 case codeview::LF_ARRAY: 196 Id = createSymbolForType<NativeTypeArray, ArrayRecord>(Index, 197 std::move(CVT)); 198 break; 199 case codeview::LF_CLASS: 200 case codeview::LF_STRUCTURE: 201 case codeview::LF_INTERFACE: 202 Id = createSymbolForType<NativeTypeUDT, ClassRecord>(Index, std::move(CVT)); 203 break; 204 case codeview::LF_UNION: 205 Id = createSymbolForType<NativeTypeUDT, UnionRecord>(Index, std::move(CVT)); 206 break; 207 case codeview::LF_POINTER: 208 Id = createSymbolForType<NativeTypePointer, PointerRecord>(Index, 209 std::move(CVT)); 210 break; 211 case codeview::LF_MODIFIER: 212 Id = createSymbolForModifiedType(Index, std::move(CVT)); 213 break; 214 case codeview::LF_PROCEDURE: 215 Id = createSymbolForType<NativeTypeFunctionSig, ProcedureRecord>( 216 Index, std::move(CVT)); 217 break; 218 case codeview::LF_MFUNCTION: 219 Id = createSymbolForType<NativeTypeFunctionSig, MemberFunctionRecord>( 220 Index, std::move(CVT)); 221 break; 222 case codeview::LF_VTSHAPE: 223 Id = createSymbolForType<NativeTypeVTShape, VFTableShapeRecord>( 224 Index, std::move(CVT)); 225 break; 226 default: 227 Id = createSymbolPlaceholder(); 228 break; 229 } 230 if (Id != 0) { 231 assert(TypeIndexToSymbolId.count(Index) == 0); 232 TypeIndexToSymbolId[Index] = Id; 233 } 234 return Id; 235 } 236 237 std::unique_ptr<PDBSymbol> 238 SymbolCache::getSymbolById(SymIndexId SymbolId) const { 239 assert(SymbolId < Cache.size()); 240 241 // Id 0 is reserved. 242 if (SymbolId == 0 || SymbolId >= Cache.size()) 243 return nullptr; 244 245 // Make sure to handle the case where we've inserted a placeholder symbol 246 // for types we don't yet suppport. 247 NativeRawSymbol *NRS = Cache[SymbolId].get(); 248 if (!NRS) 249 return nullptr; 250 251 return PDBSymbol::create(Session, *NRS); 252 } 253 254 NativeRawSymbol &SymbolCache::getNativeSymbolById(SymIndexId SymbolId) const { 255 return *Cache[SymbolId]; 256 } 257 258 uint32_t SymbolCache::getNumCompilands() const { 259 if (!Dbi) 260 return 0; 261 262 return Dbi->modules().getModuleCount(); 263 } 264 265 SymIndexId SymbolCache::getOrCreateGlobalSymbolByOffset(uint32_t Offset) { 266 auto Iter = GlobalOffsetToSymbolId.find(Offset); 267 if (Iter != GlobalOffsetToSymbolId.end()) 268 return Iter->second; 269 270 SymbolStream &SS = cantFail(Session.getPDBFile().getPDBSymbolStream()); 271 CVSymbol CVS = SS.readRecord(Offset); 272 SymIndexId Id = 0; 273 switch (CVS.kind()) { 274 case SymbolKind::S_UDT: { 275 UDTSym US = cantFail(SymbolDeserializer::deserializeAs<UDTSym>(CVS)); 276 Id = createSymbol<NativeTypeTypedef>(std::move(US)); 277 break; 278 } 279 default: 280 Id = createSymbolPlaceholder(); 281 break; 282 } 283 if (Id != 0) { 284 assert(GlobalOffsetToSymbolId.count(Offset) == 0); 285 GlobalOffsetToSymbolId[Offset] = Id; 286 } 287 288 return Id; 289 } 290 291 Expected<ModuleDebugStreamRef> 292 SymbolCache::getModuleDebugStream(uint32_t Index) const { 293 assert(Dbi && "Dbi stream not present"); 294 295 DbiModuleDescriptor Modi = Dbi->modules().getModuleDescriptor(Index); 296 297 uint16_t ModiStream = Modi.getModuleStreamIndex(); 298 if (ModiStream == kInvalidStreamIndex) 299 return make_error<RawError>("Module stream not present"); 300 301 std::unique_ptr<msf::MappedBlockStream> ModStreamData = 302 Session.getPDBFile().createIndexedStream(ModiStream); 303 304 ModuleDebugStreamRef ModS(Modi, std::move(ModStreamData)); 305 if (auto EC = ModS.reload()) 306 return std::move(EC); 307 308 return std::move(ModS); 309 } 310 311 std::unique_ptr<PDBSymbol> 312 SymbolCache::findSymbolBySectOffset(uint32_t Sect, uint32_t Offset, 313 PDB_SymType Type) { 314 if (AddrToModuleIndex.empty()) 315 parseSectionContribs(); 316 317 switch (Type) { 318 case PDB_SymType::Function: 319 return findFunctionSymbolBySectOffset(Sect, Offset); 320 case PDB_SymType::PublicSymbol: 321 return findPublicSymbolBySectOffset(Sect, Offset); 322 case PDB_SymType::None: { 323 // FIXME: Implement for PDB_SymType::Data. 324 if (auto Sym = findFunctionSymbolBySectOffset(Sect, Offset)) 325 return Sym; 326 return nullptr; 327 } 328 default: 329 return nullptr; 330 } 331 } 332 333 std::unique_ptr<PDBSymbol> 334 SymbolCache::findFunctionSymbolBySectOffset(uint32_t Sect, uint32_t Offset) { 335 auto Iter = AddressToFunctionSymId.find({Sect, Offset}); 336 if (Iter != AddressToFunctionSymId.end()) 337 return getSymbolById(Iter->second); 338 339 if (!Dbi) 340 return nullptr; 341 342 auto Modi = getModuleIndexForAddr(Session.getVAFromSectOffset(Sect, Offset)); 343 if (!Modi) 344 return nullptr; 345 346 auto ExpectedModS = getModuleDebugStream(*Modi); 347 if (!ExpectedModS) { 348 consumeError(ExpectedModS.takeError()); 349 return nullptr; 350 } 351 CVSymbolArray Syms = ExpectedModS->getSymbolArray(); 352 353 // Search for the symbol in this module. 354 for (auto I = Syms.begin(), E = Syms.end(); I != E; ++I) { 355 if (I->kind() != S_LPROC32 && I->kind() != S_GPROC32) 356 continue; 357 auto PS = cantFail(SymbolDeserializer::deserializeAs<ProcSym>(*I)); 358 if (Sect == PS.Segment && Offset >= PS.CodeOffset && 359 Offset < PS.CodeOffset + PS.CodeSize) { 360 SymIndexId Id = createSymbol<NativeFunctionSymbol>(PS); 361 AddressToFunctionSymId.insert({{Sect, Offset}, Id}); 362 return getSymbolById(Id); 363 } 364 365 // Jump to the end of this ProcSym. 366 I = Syms.at(PS.End); 367 } 368 return nullptr; 369 } 370 371 std::unique_ptr<PDBSymbol> 372 SymbolCache::findPublicSymbolBySectOffset(uint32_t Sect, uint32_t Offset) { 373 auto Iter = AddressToPublicSymId.find({Sect, Offset}); 374 if (Iter != AddressToPublicSymId.end()) 375 return getSymbolById(Iter->second); 376 377 auto Publics = Session.getPDBFile().getPDBPublicsStream(); 378 if (!Publics) 379 return nullptr; 380 381 auto ExpectedSyms = Session.getPDBFile().getPDBSymbolStream(); 382 if (!ExpectedSyms) 383 return nullptr; 384 BinaryStreamRef SymStream = 385 ExpectedSyms->getSymbolArray().getUnderlyingStream(); 386 387 // Use binary search to find the first public symbol with an address greater 388 // than or equal to Sect, Offset. 389 auto AddrMap = Publics->getAddressMap(); 390 auto First = AddrMap.begin(); 391 auto It = AddrMap.begin(); 392 size_t Count = AddrMap.size(); 393 size_t Half; 394 while (Count > 0) { 395 It = First; 396 Half = Count / 2; 397 It += Half; 398 Expected<CVSymbol> Sym = readSymbolFromStream(SymStream, *It); 399 if (!Sym) { 400 consumeError(Sym.takeError()); 401 return nullptr; 402 } 403 404 auto PS = 405 cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(Sym.get())); 406 if (PS.Segment < Sect || (PS.Segment == Sect && PS.Offset <= Offset)) { 407 First = ++It; 408 Count -= Half + 1; 409 } else 410 Count = Half; 411 } 412 if (It == AddrMap.begin()) 413 return nullptr; 414 --It; 415 416 Expected<CVSymbol> Sym = readSymbolFromStream(SymStream, *It); 417 if (!Sym) { 418 consumeError(Sym.takeError()); 419 return nullptr; 420 } 421 auto PS = cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(Sym.get())); 422 SymIndexId Id = createSymbol<NativePublicSymbol>(PS); 423 AddressToPublicSymId.insert({{Sect, Offset}, Id}); 424 return getSymbolById(Id); 425 } 426 427 std::vector<SymbolCache::LineTableEntry> 428 SymbolCache::findLineTable(uint16_t Modi) const { 429 // Check if this module has already been added. 430 auto LineTableIter = LineTable.find(Modi); 431 if (LineTableIter != LineTable.end()) 432 return LineTableIter->second; 433 434 std::vector<LineTableEntry> &ModuleLineTable = LineTable[Modi]; 435 436 // If there is an error or there are no lines, just return the 437 // empty vector. 438 Expected<ModuleDebugStreamRef> ExpectedModS = getModuleDebugStream(Modi); 439 if (!ExpectedModS) { 440 consumeError(ExpectedModS.takeError()); 441 return ModuleLineTable; 442 } 443 444 std::vector<std::vector<LineTableEntry>> EntryList; 445 for (const auto &SS : ExpectedModS->getSubsectionsArray()) { 446 if (SS.kind() != DebugSubsectionKind::Lines) 447 continue; 448 449 DebugLinesSubsectionRef Lines; 450 BinaryStreamReader Reader(SS.getRecordData()); 451 if (auto EC = Lines.initialize(Reader)) { 452 consumeError(std::move(EC)); 453 continue; 454 } 455 456 uint32_t RelocSegment = Lines.header()->RelocSegment; 457 uint32_t RelocOffset = Lines.header()->RelocOffset; 458 for (const LineColumnEntry &Group : Lines) { 459 if (Group.LineNumbers.empty()) 460 continue; 461 462 std::vector<LineTableEntry> Entries; 463 464 // If there are column numbers, then they should be in a parallel stream 465 // to the line numbers. 466 auto ColIt = Group.Columns.begin(); 467 auto ColsEnd = Group.Columns.end(); 468 469 for (const LineNumberEntry &LN : Group.LineNumbers) { 470 uint64_t VA = 471 Session.getVAFromSectOffset(RelocSegment, RelocOffset + LN.Offset); 472 LineInfo Line(LN.Flags); 473 uint32_t ColNum = 0; 474 475 if (Lines.hasColumnInfo() && ColIt != ColsEnd) { 476 ColNum = ColIt->StartColumn; 477 ++ColIt; 478 } 479 Entries.push_back({VA, Line, ColNum, Group.NameIndex, false}); 480 } 481 482 // Add a terminal entry line to mark the end of this subsection. 483 uint64_t VA = Session.getVAFromSectOffset( 484 RelocSegment, RelocOffset + Lines.header()->CodeSize); 485 LineInfo LastLine(Group.LineNumbers.back().Flags); 486 uint32_t ColNum = 487 (Lines.hasColumnInfo()) ? Group.Columns.back().StartColumn : 0; 488 Entries.push_back({VA, LastLine, ColNum, Group.NameIndex, true}); 489 490 EntryList.push_back(Entries); 491 } 492 } 493 494 // Sort EntryList, and add flattened contents to the line table. 495 std::sort(EntryList.begin(), EntryList.end(), 496 [](const std::vector<LineTableEntry> &LHS, 497 const std::vector<LineTableEntry> &RHS) { 498 return LHS[0].Addr < RHS[0].Addr; 499 }); 500 for (size_t I = 0; I < EntryList.size(); ++I) 501 ModuleLineTable.insert(ModuleLineTable.end(), EntryList[I].begin(), 502 EntryList[I].end()); 503 504 return ModuleLineTable; 505 } 506 507 std::unique_ptr<IPDBEnumLineNumbers> 508 SymbolCache::findLineNumbersByVA(uint64_t VA, uint32_t Length) const { 509 Optional<uint16_t> MaybeModi = getModuleIndexForAddr(VA); 510 if (!MaybeModi) 511 return nullptr; 512 uint16_t Modi = *MaybeModi; 513 514 std::vector<LineTableEntry> Lines = findLineTable(Modi); 515 if (Lines.empty()) 516 return nullptr; 517 518 // Find the first line in the line table whose address is not greater than 519 // the one we are searching for. 520 auto LineIter = llvm::partition_point(Lines, [&](const LineTableEntry &E) { 521 return (E.Addr < VA || (E.Addr == VA && E.IsTerminalEntry)); 522 }); 523 524 // Try to back up if we've gone too far. 525 if (LineIter == Lines.end() || LineIter->Addr > VA) { 526 if (LineIter == Lines.begin() || std::prev(LineIter)->IsTerminalEntry) 527 return nullptr; 528 --LineIter; 529 } 530 531 Expected<ModuleDebugStreamRef> ExpectedModS = getModuleDebugStream(Modi); 532 if (!ExpectedModS) { 533 consumeError(ExpectedModS.takeError()); 534 return nullptr; 535 } 536 Expected<DebugChecksumsSubsectionRef> ExpectedChecksums = 537 ExpectedModS->findChecksumsSubsection(); 538 if (!ExpectedChecksums) { 539 consumeError(ExpectedChecksums.takeError()); 540 return nullptr; 541 } 542 543 // Populate a vector of NativeLineNumbers that have addresses in the given 544 // address range. 545 Optional<uint16_t> EndModi = getModuleIndexForAddr(VA + Length); 546 if (!EndModi) 547 return nullptr; 548 std::vector<NativeLineNumber> LineNumbers; 549 while (Modi <= *EndModi) { 550 // If we reached the end of the current module, increment Modi and get the 551 // new line table and checksums array. 552 if (LineIter == Lines.end()) { 553 ++Modi; 554 555 ExpectedModS = getModuleDebugStream(Modi); 556 if (!ExpectedModS) { 557 consumeError(ExpectedModS.takeError()); 558 break; 559 } 560 ExpectedChecksums = ExpectedModS->findChecksumsSubsection(); 561 if (!ExpectedChecksums) { 562 consumeError(ExpectedChecksums.takeError()); 563 break; 564 } 565 566 Lines = findLineTable(Modi); 567 LineIter = Lines.begin(); 568 569 if (Lines.empty()) 570 continue; 571 } 572 573 if (LineIter->IsTerminalEntry) { 574 ++LineIter; 575 continue; 576 } 577 578 // If the line is still within the address range, create a NativeLineNumber 579 // and add to the list. 580 if (LineIter->Addr > VA + Length) 581 break; 582 583 uint32_t LineSect, LineOff; 584 Session.addressForVA(LineIter->Addr, LineSect, LineOff); 585 uint32_t LineLength = std::next(LineIter)->Addr - LineIter->Addr; 586 auto ChecksumIter = 587 ExpectedChecksums->getArray().at(LineIter->FileNameIndex); 588 uint32_t SrcFileId = getOrCreateSourceFile(*ChecksumIter); 589 NativeLineNumber LineNum(Session, LineIter->Line, LineIter->ColumnNumber, 590 LineSect, LineOff, LineLength, SrcFileId); 591 LineNumbers.push_back(LineNum); 592 ++LineIter; 593 } 594 return std::make_unique<NativeEnumLineNumbers>(std::move(LineNumbers)); 595 } 596 597 std::unique_ptr<PDBSymbolCompiland> 598 SymbolCache::getOrCreateCompiland(uint32_t Index) { 599 if (!Dbi) 600 return nullptr; 601 602 if (Index >= Compilands.size()) 603 return nullptr; 604 605 if (Compilands[Index] == 0) { 606 const DbiModuleList &Modules = Dbi->modules(); 607 Compilands[Index] = 608 createSymbol<NativeCompilandSymbol>(Modules.getModuleDescriptor(Index)); 609 } 610 611 return Session.getConcreteSymbolById<PDBSymbolCompiland>(Compilands[Index]); 612 } 613 614 std::unique_ptr<IPDBSourceFile> 615 SymbolCache::getSourceFileById(SymIndexId FileId) const { 616 assert(FileId < SourceFiles.size()); 617 618 // Id 0 is reserved. 619 if (FileId == 0) 620 return nullptr; 621 622 return std::unique_ptr<NativeSourceFile>( 623 new NativeSourceFile(*SourceFiles[FileId].get())); 624 } 625 626 SymIndexId 627 SymbolCache::getOrCreateSourceFile(const FileChecksumEntry &Checksums) const { 628 auto Iter = FileNameOffsetToId.find(Checksums.FileNameOffset); 629 if (Iter != FileNameOffsetToId.end()) 630 return Iter->second; 631 632 SymIndexId Id = SourceFiles.size(); 633 auto SrcFile = std::make_unique<NativeSourceFile>(Session, Id, Checksums); 634 SourceFiles.push_back(std::move(SrcFile)); 635 FileNameOffsetToId[Checksums.FileNameOffset] = Id; 636 return Id; 637 } 638 639 void SymbolCache::parseSectionContribs() { 640 if (!Dbi) 641 return; 642 643 class Visitor : public ISectionContribVisitor { 644 NativeSession &Session; 645 IMap &AddrMap; 646 647 public: 648 Visitor(NativeSession &Session, IMap &AddrMap) 649 : Session(Session), AddrMap(AddrMap) {} 650 void visit(const SectionContrib &C) override { 651 if (C.Size == 0) 652 return; 653 654 uint64_t VA = Session.getVAFromSectOffset(C.ISect, C.Off); 655 uint64_t End = VA + C.Size; 656 657 // Ignore overlapping sections based on the assumption that a valid 658 // PDB file should not have overlaps. 659 if (!AddrMap.overlaps(VA, End)) 660 AddrMap.insert(VA, End, C.Imod); 661 } 662 void visit(const SectionContrib2 &C) override { visit(C.Base); } 663 }; 664 665 Visitor V(Session, AddrToModuleIndex); 666 Dbi->visitSectionContributions(V); 667 } 668 669 Optional<uint16_t> SymbolCache::getModuleIndexForAddr(uint64_t Addr) const { 670 auto Iter = AddrToModuleIndex.find(Addr); 671 if (Iter == AddrToModuleIndex.end()) 672 return None; 673 return Iter.value(); 674 } 675