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::Compiland: { 323 Optional<uint16_t> Modi = 324 getModuleIndexForAddr(Session.getVAFromSectOffset(Sect, Offset)); 325 if (!Modi) 326 return nullptr; 327 return getOrCreateCompiland(*Modi); 328 } 329 case PDB_SymType::None: { 330 // FIXME: Implement for PDB_SymType::Data. The symbolizer calls this but 331 // only uses it to find the symbol length. 332 if (auto Sym = findFunctionSymbolBySectOffset(Sect, Offset)) 333 return Sym; 334 return nullptr; 335 } 336 default: 337 return nullptr; 338 } 339 } 340 341 std::unique_ptr<PDBSymbol> 342 SymbolCache::findFunctionSymbolBySectOffset(uint32_t Sect, uint32_t Offset) { 343 auto Iter = AddressToSymbolId.find({Sect, Offset}); 344 if (Iter != AddressToSymbolId.end()) 345 return getSymbolById(Iter->second); 346 347 if (!Dbi) 348 return nullptr; 349 350 auto Modi = getModuleIndexForAddr(Session.getVAFromSectOffset(Sect, Offset)); 351 if (!Modi) 352 return nullptr; 353 354 auto ExpectedModS = getModuleDebugStream(*Modi); 355 if (!ExpectedModS) { 356 consumeError(ExpectedModS.takeError()); 357 return nullptr; 358 } 359 CVSymbolArray Syms = ExpectedModS->getSymbolArray(); 360 361 // Search for the symbol in this module. 362 for (auto I = Syms.begin(), E = Syms.end(); I != E; ++I) { 363 if (I->kind() != S_LPROC32 && I->kind() != S_GPROC32) 364 continue; 365 auto PS = cantFail(SymbolDeserializer::deserializeAs<ProcSym>(*I)); 366 if (Sect == PS.Segment && Offset >= PS.CodeOffset && 367 Offset < PS.CodeOffset + PS.CodeSize) { 368 // Check if the symbol is already cached. 369 auto Found = AddressToSymbolId.find({PS.Segment, PS.CodeOffset}); 370 if (Found != AddressToSymbolId.end()) 371 return getSymbolById(Found->second); 372 373 // Otherwise, create a new symbol. 374 SymIndexId Id = createSymbol<NativeFunctionSymbol>(PS); 375 AddressToSymbolId.insert({{PS.Segment, PS.CodeOffset}, Id}); 376 return getSymbolById(Id); 377 } 378 379 // Jump to the end of this ProcSym. 380 I = Syms.at(PS.End); 381 } 382 return nullptr; 383 } 384 385 std::unique_ptr<PDBSymbol> 386 SymbolCache::findPublicSymbolBySectOffset(uint32_t Sect, uint32_t Offset) { 387 auto Iter = AddressToPublicSymId.find({Sect, Offset}); 388 if (Iter != AddressToPublicSymId.end()) 389 return getSymbolById(Iter->second); 390 391 auto Publics = Session.getPDBFile().getPDBPublicsStream(); 392 if (!Publics) 393 return nullptr; 394 395 auto ExpectedSyms = Session.getPDBFile().getPDBSymbolStream(); 396 if (!ExpectedSyms) 397 return nullptr; 398 BinaryStreamRef SymStream = 399 ExpectedSyms->getSymbolArray().getUnderlyingStream(); 400 401 // Use binary search to find the first public symbol with an address greater 402 // than or equal to Sect, Offset. 403 auto AddrMap = Publics->getAddressMap(); 404 auto First = AddrMap.begin(); 405 auto It = AddrMap.begin(); 406 size_t Count = AddrMap.size(); 407 size_t Half; 408 while (Count > 0) { 409 It = First; 410 Half = Count / 2; 411 It += Half; 412 Expected<CVSymbol> Sym = readSymbolFromStream(SymStream, *It); 413 if (!Sym) { 414 consumeError(Sym.takeError()); 415 return nullptr; 416 } 417 418 auto PS = 419 cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(Sym.get())); 420 if (PS.Segment < Sect || (PS.Segment == Sect && PS.Offset <= Offset)) { 421 First = ++It; 422 Count -= Half + 1; 423 } else 424 Count = Half; 425 } 426 if (It == AddrMap.begin()) 427 return nullptr; 428 --It; 429 430 Expected<CVSymbol> Sym = readSymbolFromStream(SymStream, *It); 431 if (!Sym) { 432 consumeError(Sym.takeError()); 433 return nullptr; 434 } 435 436 // Check if the symbol is already cached. 437 auto PS = cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(Sym.get())); 438 auto Found = AddressToPublicSymId.find({PS.Segment, PS.Offset}); 439 if (Found != AddressToPublicSymId.end()) 440 return getSymbolById(Found->second); 441 442 // Otherwise, create a new symbol. 443 SymIndexId Id = createSymbol<NativePublicSymbol>(PS); 444 AddressToPublicSymId.insert({{PS.Segment, PS.Offset}, Id}); 445 return getSymbolById(Id); 446 } 447 448 std::vector<SymbolCache::LineTableEntry> 449 SymbolCache::findLineTable(uint16_t Modi) const { 450 // Check if this module has already been added. 451 auto LineTableIter = LineTable.find(Modi); 452 if (LineTableIter != LineTable.end()) 453 return LineTableIter->second; 454 455 std::vector<LineTableEntry> &ModuleLineTable = LineTable[Modi]; 456 457 // If there is an error or there are no lines, just return the 458 // empty vector. 459 Expected<ModuleDebugStreamRef> ExpectedModS = getModuleDebugStream(Modi); 460 if (!ExpectedModS) { 461 consumeError(ExpectedModS.takeError()); 462 return ModuleLineTable; 463 } 464 465 std::vector<std::vector<LineTableEntry>> EntryList; 466 for (const auto &SS : ExpectedModS->getSubsectionsArray()) { 467 if (SS.kind() != DebugSubsectionKind::Lines) 468 continue; 469 470 DebugLinesSubsectionRef Lines; 471 BinaryStreamReader Reader(SS.getRecordData()); 472 if (auto EC = Lines.initialize(Reader)) { 473 consumeError(std::move(EC)); 474 continue; 475 } 476 477 uint32_t RelocSegment = Lines.header()->RelocSegment; 478 uint32_t RelocOffset = Lines.header()->RelocOffset; 479 for (const LineColumnEntry &Group : Lines) { 480 if (Group.LineNumbers.empty()) 481 continue; 482 483 std::vector<LineTableEntry> Entries; 484 485 // If there are column numbers, then they should be in a parallel stream 486 // to the line numbers. 487 auto ColIt = Group.Columns.begin(); 488 auto ColsEnd = Group.Columns.end(); 489 490 for (const LineNumberEntry &LN : Group.LineNumbers) { 491 uint64_t VA = 492 Session.getVAFromSectOffset(RelocSegment, RelocOffset + LN.Offset); 493 LineInfo Line(LN.Flags); 494 uint32_t ColNum = 0; 495 496 if (Lines.hasColumnInfo() && ColIt != ColsEnd) { 497 ColNum = ColIt->StartColumn; 498 ++ColIt; 499 } 500 Entries.push_back({VA, Line, ColNum, Group.NameIndex, false}); 501 } 502 503 // Add a terminal entry line to mark the end of this subsection. 504 uint64_t VA = Session.getVAFromSectOffset( 505 RelocSegment, RelocOffset + Lines.header()->CodeSize); 506 LineInfo LastLine(Group.LineNumbers.back().Flags); 507 uint32_t ColNum = 508 (Lines.hasColumnInfo()) ? Group.Columns.back().StartColumn : 0; 509 Entries.push_back({VA, LastLine, ColNum, Group.NameIndex, true}); 510 511 EntryList.push_back(Entries); 512 } 513 } 514 515 // Sort EntryList, and add flattened contents to the line table. 516 std::sort(EntryList.begin(), EntryList.end(), 517 [](const std::vector<LineTableEntry> &LHS, 518 const std::vector<LineTableEntry> &RHS) { 519 return LHS[0].Addr < RHS[0].Addr; 520 }); 521 for (size_t I = 0; I < EntryList.size(); ++I) 522 ModuleLineTable.insert(ModuleLineTable.end(), EntryList[I].begin(), 523 EntryList[I].end()); 524 525 return ModuleLineTable; 526 } 527 528 std::unique_ptr<IPDBEnumLineNumbers> 529 SymbolCache::findLineNumbersByVA(uint64_t VA, uint32_t Length) const { 530 Optional<uint16_t> MaybeModi = getModuleIndexForAddr(VA); 531 if (!MaybeModi) 532 return nullptr; 533 uint16_t Modi = *MaybeModi; 534 535 std::vector<LineTableEntry> Lines = findLineTable(Modi); 536 if (Lines.empty()) 537 return nullptr; 538 539 // Find the first line in the line table whose address is not greater than 540 // the one we are searching for. 541 auto LineIter = llvm::partition_point(Lines, [&](const LineTableEntry &E) { 542 return (E.Addr < VA || (E.Addr == VA && E.IsTerminalEntry)); 543 }); 544 545 // Try to back up if we've gone too far. 546 if (LineIter == Lines.end() || LineIter->Addr > VA) { 547 if (LineIter == Lines.begin() || std::prev(LineIter)->IsTerminalEntry) 548 return nullptr; 549 --LineIter; 550 } 551 552 Expected<ModuleDebugStreamRef> ExpectedModS = getModuleDebugStream(Modi); 553 if (!ExpectedModS) { 554 consumeError(ExpectedModS.takeError()); 555 return nullptr; 556 } 557 Expected<DebugChecksumsSubsectionRef> ExpectedChecksums = 558 ExpectedModS->findChecksumsSubsection(); 559 if (!ExpectedChecksums) { 560 consumeError(ExpectedChecksums.takeError()); 561 return nullptr; 562 } 563 564 // Populate a vector of NativeLineNumbers that have addresses in the given 565 // address range. 566 Optional<uint16_t> EndModi = getModuleIndexForAddr(VA + Length); 567 if (!EndModi) 568 return nullptr; 569 std::vector<NativeLineNumber> LineNumbers; 570 while (Modi <= *EndModi) { 571 // If we reached the end of the current module, increment Modi and get the 572 // new line table and checksums array. 573 if (LineIter == Lines.end()) { 574 ++Modi; 575 576 ExpectedModS = getModuleDebugStream(Modi); 577 if (!ExpectedModS) { 578 consumeError(ExpectedModS.takeError()); 579 break; 580 } 581 ExpectedChecksums = ExpectedModS->findChecksumsSubsection(); 582 if (!ExpectedChecksums) { 583 consumeError(ExpectedChecksums.takeError()); 584 break; 585 } 586 587 Lines = findLineTable(Modi); 588 LineIter = Lines.begin(); 589 590 if (Lines.empty()) 591 continue; 592 } 593 594 if (LineIter->IsTerminalEntry) { 595 ++LineIter; 596 continue; 597 } 598 599 // If the line is still within the address range, create a NativeLineNumber 600 // and add to the list. 601 if (LineIter->Addr > VA + Length) 602 break; 603 604 uint32_t LineSect, LineOff; 605 Session.addressForVA(LineIter->Addr, LineSect, LineOff); 606 uint32_t LineLength = std::next(LineIter)->Addr - LineIter->Addr; 607 auto ChecksumIter = 608 ExpectedChecksums->getArray().at(LineIter->FileNameIndex); 609 uint32_t SrcFileId = getOrCreateSourceFile(*ChecksumIter); 610 NativeLineNumber LineNum(Session, LineIter->Line, LineIter->ColumnNumber, 611 LineSect, LineOff, LineLength, SrcFileId, Modi); 612 LineNumbers.push_back(LineNum); 613 ++LineIter; 614 } 615 return std::make_unique<NativeEnumLineNumbers>(std::move(LineNumbers)); 616 } 617 618 std::unique_ptr<PDBSymbolCompiland> 619 SymbolCache::getOrCreateCompiland(uint32_t Index) { 620 if (!Dbi) 621 return nullptr; 622 623 if (Index >= Compilands.size()) 624 return nullptr; 625 626 if (Compilands[Index] == 0) { 627 const DbiModuleList &Modules = Dbi->modules(); 628 Compilands[Index] = 629 createSymbol<NativeCompilandSymbol>(Modules.getModuleDescriptor(Index)); 630 } 631 632 return Session.getConcreteSymbolById<PDBSymbolCompiland>(Compilands[Index]); 633 } 634 635 std::unique_ptr<IPDBSourceFile> 636 SymbolCache::getSourceFileById(SymIndexId FileId) const { 637 assert(FileId < SourceFiles.size()); 638 639 // Id 0 is reserved. 640 if (FileId == 0) 641 return nullptr; 642 643 return std::unique_ptr<NativeSourceFile>( 644 new NativeSourceFile(*SourceFiles[FileId].get())); 645 } 646 647 SymIndexId 648 SymbolCache::getOrCreateSourceFile(const FileChecksumEntry &Checksums) const { 649 auto Iter = FileNameOffsetToId.find(Checksums.FileNameOffset); 650 if (Iter != FileNameOffsetToId.end()) 651 return Iter->second; 652 653 SymIndexId Id = SourceFiles.size(); 654 auto SrcFile = std::make_unique<NativeSourceFile>(Session, Id, Checksums); 655 SourceFiles.push_back(std::move(SrcFile)); 656 FileNameOffsetToId[Checksums.FileNameOffset] = Id; 657 return Id; 658 } 659 660 void SymbolCache::parseSectionContribs() { 661 if (!Dbi) 662 return; 663 664 class Visitor : public ISectionContribVisitor { 665 NativeSession &Session; 666 IMap &AddrMap; 667 668 public: 669 Visitor(NativeSession &Session, IMap &AddrMap) 670 : Session(Session), AddrMap(AddrMap) {} 671 void visit(const SectionContrib &C) override { 672 if (C.Size == 0) 673 return; 674 675 uint64_t VA = Session.getVAFromSectOffset(C.ISect, C.Off); 676 uint64_t End = VA + C.Size; 677 678 // Ignore overlapping sections based on the assumption that a valid 679 // PDB file should not have overlaps. 680 if (!AddrMap.overlaps(VA, End)) 681 AddrMap.insert(VA, End, C.Imod); 682 } 683 void visit(const SectionContrib2 &C) override { visit(C.Base); } 684 }; 685 686 Visitor V(Session, AddrToModuleIndex); 687 Dbi->visitSectionContributions(V); 688 } 689 690 Optional<uint16_t> SymbolCache::getModuleIndexForAddr(uint64_t Addr) const { 691 auto Iter = AddrToModuleIndex.find(Addr); 692 if (Iter == AddrToModuleIndex.end()) 693 return None; 694 return Iter.value(); 695 } 696