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