1343181Sdim//===-- PdbUtil.cpp ---------------------------------------------*- C++ -*-===// 2343181Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6343181Sdim// 7343181Sdim//===----------------------------------------------------------------------===// 8343181Sdim 9343181Sdim#include "PdbUtil.h" 10343181Sdim 11343181Sdim#include "DWARFLocationExpression.h" 12343181Sdim#include "PdbIndex.h" 13343181Sdim#include "PdbSymUid.h" 14343181Sdim 15343181Sdim#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" 16343181Sdim#include "llvm/DebugInfo/CodeView/TypeDeserializer.h" 17353358Sdim#include "llvm/DebugInfo/PDB/Native/DbiStream.h" 18343181Sdim#include "llvm/DebugInfo/PDB/Native/TpiStream.h" 19343181Sdim 20343181Sdim#include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h" 21353358Sdim#include "lldb/Symbol/Block.h" 22343181Sdim#include "lldb/Utility/LLDBAssert.h" 23343181Sdim#include "lldb/lldb-enumerations.h" 24343181Sdim 25343181Sdimusing namespace lldb_private; 26343181Sdimusing namespace lldb_private::npdb; 27343181Sdimusing namespace llvm::codeview; 28343181Sdimusing namespace llvm::pdb; 29343181Sdim 30343181Sdimstatic Variable::RangeList 31343181SdimMakeRangeList(const PdbIndex &index, const LocalVariableAddrRange &range, 32343181Sdim llvm::ArrayRef<LocalVariableAddrGap> gaps) { 33343181Sdim lldb::addr_t start = 34343181Sdim index.MakeVirtualAddress(range.ISectStart, range.OffsetStart); 35343181Sdim lldb::addr_t end = start + range.Range; 36343181Sdim 37343181Sdim Variable::RangeList result; 38343181Sdim while (!gaps.empty()) { 39343181Sdim const LocalVariableAddrGap &gap = gaps.front(); 40343181Sdim 41343181Sdim lldb::addr_t size = gap.GapStartOffset - start; 42343181Sdim result.Append(start, size); 43343181Sdim start += gap.Range; 44343181Sdim gaps = gaps.drop_front(); 45343181Sdim } 46343181Sdim 47353358Sdim result.Append(start, end - start); 48343181Sdim return result; 49343181Sdim} 50343181Sdim 51343181SdimCVTagRecord CVTagRecord::create(CVType type) { 52343181Sdim assert(IsTagRecord(type) && "type is not a tag record!"); 53343181Sdim switch (type.kind()) { 54343181Sdim case LF_CLASS: 55343181Sdim case LF_STRUCTURE: 56343181Sdim case LF_INTERFACE: { 57343181Sdim ClassRecord cr; 58343181Sdim llvm::cantFail(TypeDeserializer::deserializeAs<ClassRecord>(type, cr)); 59343181Sdim return CVTagRecord(std::move(cr)); 60343181Sdim } 61343181Sdim case LF_UNION: { 62343181Sdim UnionRecord ur; 63343181Sdim llvm::cantFail(TypeDeserializer::deserializeAs<UnionRecord>(type, ur)); 64343181Sdim return CVTagRecord(std::move(ur)); 65343181Sdim } 66343181Sdim case LF_ENUM: { 67343181Sdim EnumRecord er; 68343181Sdim llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(type, er)); 69343181Sdim return CVTagRecord(std::move(er)); 70343181Sdim } 71343181Sdim default: 72343181Sdim llvm_unreachable("Unreachable!"); 73343181Sdim } 74343181Sdim} 75343181Sdim 76343181SdimCVTagRecord::CVTagRecord(ClassRecord &&c) 77343181Sdim : cvclass(std::move(c)), 78343181Sdim m_kind(cvclass.Kind == TypeRecordKind::Struct ? Struct : Class) {} 79343181SdimCVTagRecord::CVTagRecord(UnionRecord &&u) 80343181Sdim : cvunion(std::move(u)), m_kind(Union) {} 81343181SdimCVTagRecord::CVTagRecord(EnumRecord &&e) : cvenum(std::move(e)), m_kind(Enum) {} 82343181Sdim 83343181SdimPDB_SymType lldb_private::npdb::CVSymToPDBSym(SymbolKind kind) { 84343181Sdim switch (kind) { 85343181Sdim case S_COMPILE3: 86343181Sdim case S_OBJNAME: 87343181Sdim return PDB_SymType::CompilandDetails; 88343181Sdim case S_ENVBLOCK: 89343181Sdim return PDB_SymType::CompilandEnv; 90343181Sdim case S_THUNK32: 91343181Sdim case S_TRAMPOLINE: 92343181Sdim return PDB_SymType::Thunk; 93343181Sdim case S_COFFGROUP: 94343181Sdim return PDB_SymType::CoffGroup; 95343181Sdim case S_EXPORT: 96343181Sdim return PDB_SymType::Export; 97343181Sdim case S_LPROC32: 98343181Sdim case S_GPROC32: 99343181Sdim case S_LPROC32_DPC: 100343181Sdim return PDB_SymType::Function; 101343181Sdim case S_PUB32: 102343181Sdim return PDB_SymType::PublicSymbol; 103343181Sdim case S_INLINESITE: 104343181Sdim return PDB_SymType::InlineSite; 105343181Sdim case S_LOCAL: 106343181Sdim case S_BPREL32: 107343181Sdim case S_REGREL32: 108343181Sdim case S_MANCONSTANT: 109343181Sdim case S_CONSTANT: 110343181Sdim case S_LDATA32: 111343181Sdim case S_GDATA32: 112343181Sdim case S_LMANDATA: 113343181Sdim case S_GMANDATA: 114343181Sdim case S_LTHREAD32: 115343181Sdim case S_GTHREAD32: 116343181Sdim return PDB_SymType::Data; 117343181Sdim case S_BLOCK32: 118343181Sdim return PDB_SymType::Block; 119343181Sdim case S_LABEL32: 120343181Sdim return PDB_SymType::Label; 121343181Sdim case S_CALLSITEINFO: 122343181Sdim return PDB_SymType::CallSite; 123343181Sdim case S_HEAPALLOCSITE: 124343181Sdim return PDB_SymType::HeapAllocationSite; 125343181Sdim case S_CALLEES: 126343181Sdim return PDB_SymType::Callee; 127343181Sdim case S_CALLERS: 128343181Sdim return PDB_SymType::Caller; 129343181Sdim default: 130343181Sdim lldbassert(false && "Invalid symbol record kind!"); 131343181Sdim } 132343181Sdim return PDB_SymType::None; 133343181Sdim} 134343181Sdim 135343181SdimPDB_SymType lldb_private::npdb::CVTypeToPDBType(TypeLeafKind kind) { 136343181Sdim switch (kind) { 137343181Sdim case LF_ARRAY: 138343181Sdim return PDB_SymType::ArrayType; 139343181Sdim case LF_ARGLIST: 140343181Sdim return PDB_SymType::FunctionSig; 141343181Sdim case LF_BCLASS: 142343181Sdim return PDB_SymType::BaseClass; 143343181Sdim case LF_BINTERFACE: 144343181Sdim return PDB_SymType::BaseInterface; 145343181Sdim case LF_CLASS: 146343181Sdim case LF_STRUCTURE: 147343181Sdim case LF_INTERFACE: 148343181Sdim case LF_UNION: 149343181Sdim return PDB_SymType::UDT; 150343181Sdim case LF_POINTER: 151343181Sdim return PDB_SymType::PointerType; 152343181Sdim case LF_ENUM: 153343181Sdim return PDB_SymType::Enum; 154343181Sdim case LF_PROCEDURE: 155343181Sdim return PDB_SymType::FunctionSig; 156343181Sdim case LF_BITFIELD: 157343181Sdim return PDB_SymType::BuiltinType; 158343181Sdim default: 159343181Sdim lldbassert(false && "Invalid type record kind!"); 160343181Sdim } 161343181Sdim return PDB_SymType::None; 162343181Sdim} 163343181Sdim 164343181Sdimbool lldb_private::npdb::SymbolHasAddress(const CVSymbol &sym) { 165343181Sdim switch (sym.kind()) { 166343181Sdim case S_GPROC32: 167343181Sdim case S_LPROC32: 168343181Sdim case S_GPROC32_ID: 169343181Sdim case S_LPROC32_ID: 170343181Sdim case S_LPROC32_DPC: 171343181Sdim case S_LPROC32_DPC_ID: 172343181Sdim case S_THUNK32: 173343181Sdim case S_TRAMPOLINE: 174343181Sdim case S_COFFGROUP: 175343181Sdim case S_BLOCK32: 176343181Sdim case S_LABEL32: 177343181Sdim case S_CALLSITEINFO: 178343181Sdim case S_HEAPALLOCSITE: 179343181Sdim case S_LDATA32: 180343181Sdim case S_GDATA32: 181343181Sdim case S_LMANDATA: 182343181Sdim case S_GMANDATA: 183343181Sdim case S_LTHREAD32: 184343181Sdim case S_GTHREAD32: 185343181Sdim return true; 186343181Sdim default: 187343181Sdim return false; 188343181Sdim } 189343181Sdim} 190343181Sdim 191343181Sdimbool lldb_private::npdb::SymbolIsCode(const CVSymbol &sym) { 192343181Sdim switch (sym.kind()) { 193343181Sdim case S_GPROC32: 194343181Sdim case S_LPROC32: 195343181Sdim case S_GPROC32_ID: 196343181Sdim case S_LPROC32_ID: 197343181Sdim case S_LPROC32_DPC: 198343181Sdim case S_LPROC32_DPC_ID: 199343181Sdim case S_THUNK32: 200343181Sdim case S_TRAMPOLINE: 201343181Sdim case S_COFFGROUP: 202343181Sdim case S_BLOCK32: 203343181Sdim return true; 204343181Sdim default: 205343181Sdim return false; 206343181Sdim } 207343181Sdim} 208343181Sdim 209343181Sdimtemplate <typename RecordT> RecordT createRecord(const CVSymbol &sym) { 210343181Sdim RecordT record(static_cast<SymbolRecordKind>(sym.kind())); 211343181Sdim cantFail(SymbolDeserializer::deserializeAs<RecordT>(sym, record)); 212343181Sdim return record; 213343181Sdim} 214343181Sdim 215343181Sdimtemplate <typename RecordT> 216343181Sdimstatic SegmentOffset GetSegmentAndOffset(const CVSymbol &sym) { 217343181Sdim RecordT record = createRecord<RecordT>(sym); 218343181Sdim return {record.Segment, record.CodeOffset}; 219343181Sdim} 220343181Sdim 221343181Sdimtemplate <> 222343181SdimSegmentOffset GetSegmentAndOffset<TrampolineSym>(const CVSymbol &sym) { 223343181Sdim TrampolineSym record = createRecord<TrampolineSym>(sym); 224343181Sdim return {record.ThunkSection, record.ThunkOffset}; 225343181Sdim} 226343181Sdim 227343181Sdimtemplate <> SegmentOffset GetSegmentAndOffset<Thunk32Sym>(const CVSymbol &sym) { 228343181Sdim Thunk32Sym record = createRecord<Thunk32Sym>(sym); 229343181Sdim return {record.Segment, record.Offset}; 230343181Sdim} 231343181Sdim 232343181Sdimtemplate <> 233343181SdimSegmentOffset GetSegmentAndOffset<CoffGroupSym>(const CVSymbol &sym) { 234343181Sdim CoffGroupSym record = createRecord<CoffGroupSym>(sym); 235343181Sdim return {record.Segment, record.Offset}; 236343181Sdim} 237343181Sdim 238343181Sdimtemplate <> SegmentOffset GetSegmentAndOffset<DataSym>(const CVSymbol &sym) { 239343181Sdim DataSym record = createRecord<DataSym>(sym); 240343181Sdim return {record.Segment, record.DataOffset}; 241343181Sdim} 242343181Sdim 243343181Sdimtemplate <> 244343181SdimSegmentOffset GetSegmentAndOffset<ThreadLocalDataSym>(const CVSymbol &sym) { 245343181Sdim ThreadLocalDataSym record = createRecord<ThreadLocalDataSym>(sym); 246343181Sdim return {record.Segment, record.DataOffset}; 247343181Sdim} 248343181Sdim 249343181SdimSegmentOffset lldb_private::npdb::GetSegmentAndOffset(const CVSymbol &sym) { 250343181Sdim switch (sym.kind()) { 251343181Sdim case S_GPROC32: 252343181Sdim case S_LPROC32: 253343181Sdim case S_GPROC32_ID: 254343181Sdim case S_LPROC32_ID: 255343181Sdim case S_LPROC32_DPC: 256343181Sdim case S_LPROC32_DPC_ID: 257343181Sdim return ::GetSegmentAndOffset<ProcSym>(sym); 258343181Sdim case S_THUNK32: 259343181Sdim return ::GetSegmentAndOffset<Thunk32Sym>(sym); 260343181Sdim break; 261343181Sdim case S_TRAMPOLINE: 262343181Sdim return ::GetSegmentAndOffset<TrampolineSym>(sym); 263343181Sdim break; 264343181Sdim case S_COFFGROUP: 265343181Sdim return ::GetSegmentAndOffset<CoffGroupSym>(sym); 266343181Sdim break; 267343181Sdim case S_BLOCK32: 268343181Sdim return ::GetSegmentAndOffset<BlockSym>(sym); 269343181Sdim break; 270343181Sdim case S_LABEL32: 271343181Sdim return ::GetSegmentAndOffset<LabelSym>(sym); 272343181Sdim break; 273343181Sdim case S_CALLSITEINFO: 274343181Sdim return ::GetSegmentAndOffset<CallSiteInfoSym>(sym); 275343181Sdim break; 276343181Sdim case S_HEAPALLOCSITE: 277343181Sdim return ::GetSegmentAndOffset<HeapAllocationSiteSym>(sym); 278343181Sdim break; 279343181Sdim case S_LDATA32: 280343181Sdim case S_GDATA32: 281343181Sdim case S_LMANDATA: 282343181Sdim case S_GMANDATA: 283343181Sdim return ::GetSegmentAndOffset<DataSym>(sym); 284343181Sdim break; 285343181Sdim case S_LTHREAD32: 286343181Sdim case S_GTHREAD32: 287343181Sdim return ::GetSegmentAndOffset<ThreadLocalDataSym>(sym); 288343181Sdim break; 289343181Sdim default: 290343181Sdim lldbassert(false && "Record does not have a segment/offset!"); 291343181Sdim } 292343181Sdim return {0, 0}; 293343181Sdim} 294343181Sdim 295343181Sdimtemplate <typename RecordT> 296343181SdimSegmentOffsetLength GetSegmentOffsetAndLength(const CVSymbol &sym) { 297343181Sdim RecordT record = createRecord<RecordT>(sym); 298343181Sdim return {record.Segment, record.CodeOffset, record.CodeSize}; 299343181Sdim} 300343181Sdim 301343181Sdimtemplate <> 302343181SdimSegmentOffsetLength 303343181SdimGetSegmentOffsetAndLength<TrampolineSym>(const CVSymbol &sym) { 304343181Sdim TrampolineSym record = createRecord<TrampolineSym>(sym); 305343181Sdim return {record.ThunkSection, record.ThunkOffset, record.Size}; 306343181Sdim} 307343181Sdim 308343181Sdimtemplate <> 309343181SdimSegmentOffsetLength GetSegmentOffsetAndLength<Thunk32Sym>(const CVSymbol &sym) { 310343181Sdim Thunk32Sym record = createRecord<Thunk32Sym>(sym); 311343181Sdim return SegmentOffsetLength{record.Segment, record.Offset, record.Length}; 312343181Sdim} 313343181Sdim 314343181Sdimtemplate <> 315343181SdimSegmentOffsetLength 316343181SdimGetSegmentOffsetAndLength<CoffGroupSym>(const CVSymbol &sym) { 317343181Sdim CoffGroupSym record = createRecord<CoffGroupSym>(sym); 318343181Sdim return SegmentOffsetLength{record.Segment, record.Offset, record.Size}; 319343181Sdim} 320343181Sdim 321343181SdimSegmentOffsetLength 322343181Sdimlldb_private::npdb::GetSegmentOffsetAndLength(const CVSymbol &sym) { 323343181Sdim switch (sym.kind()) { 324343181Sdim case S_GPROC32: 325343181Sdim case S_LPROC32: 326343181Sdim case S_GPROC32_ID: 327343181Sdim case S_LPROC32_ID: 328343181Sdim case S_LPROC32_DPC: 329343181Sdim case S_LPROC32_DPC_ID: 330343181Sdim return ::GetSegmentOffsetAndLength<ProcSym>(sym); 331343181Sdim case S_THUNK32: 332343181Sdim return ::GetSegmentOffsetAndLength<Thunk32Sym>(sym); 333343181Sdim break; 334343181Sdim case S_TRAMPOLINE: 335343181Sdim return ::GetSegmentOffsetAndLength<TrampolineSym>(sym); 336343181Sdim break; 337343181Sdim case S_COFFGROUP: 338343181Sdim return ::GetSegmentOffsetAndLength<CoffGroupSym>(sym); 339343181Sdim break; 340343181Sdim case S_BLOCK32: 341343181Sdim return ::GetSegmentOffsetAndLength<BlockSym>(sym); 342343181Sdim break; 343343181Sdim default: 344343181Sdim lldbassert(false && "Record does not have a segment/offset/length triple!"); 345343181Sdim } 346343181Sdim return {0, 0, 0}; 347343181Sdim} 348343181Sdim 349343181Sdimbool lldb_private::npdb::IsForwardRefUdt(CVType cvt) { 350343181Sdim ClassRecord cr; 351343181Sdim UnionRecord ur; 352343181Sdim EnumRecord er; 353343181Sdim switch (cvt.kind()) { 354343181Sdim case LF_CLASS: 355343181Sdim case LF_STRUCTURE: 356343181Sdim case LF_INTERFACE: 357343181Sdim llvm::cantFail(TypeDeserializer::deserializeAs<ClassRecord>(cvt, cr)); 358343181Sdim return cr.isForwardRef(); 359343181Sdim case LF_UNION: 360343181Sdim llvm::cantFail(TypeDeserializer::deserializeAs<UnionRecord>(cvt, ur)); 361343181Sdim return ur.isForwardRef(); 362343181Sdim case LF_ENUM: 363343181Sdim llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er)); 364343181Sdim return er.isForwardRef(); 365343181Sdim default: 366343181Sdim return false; 367343181Sdim } 368343181Sdim} 369343181Sdim 370343181Sdimbool lldb_private::npdb::IsTagRecord(llvm::codeview::CVType cvt) { 371343181Sdim switch (cvt.kind()) { 372343181Sdim case LF_CLASS: 373343181Sdim case LF_STRUCTURE: 374343181Sdim case LF_UNION: 375343181Sdim case LF_ENUM: 376343181Sdim return true; 377343181Sdim default: 378343181Sdim return false; 379343181Sdim } 380343181Sdim} 381343181Sdim 382343181Sdimbool lldb_private::npdb::IsClassStructUnion(llvm::codeview::CVType cvt) { 383343181Sdim switch (cvt.kind()) { 384343181Sdim case LF_CLASS: 385343181Sdim case LF_STRUCTURE: 386343181Sdim case LF_UNION: 387343181Sdim return true; 388343181Sdim default: 389343181Sdim return false; 390343181Sdim } 391343181Sdim} 392343181Sdim 393343181Sdimbool lldb_private::npdb::IsForwardRefUdt(const PdbTypeSymId &id, 394343181Sdim TpiStream &tpi) { 395343181Sdim if (id.is_ipi || id.index.isSimple()) 396343181Sdim return false; 397343181Sdim return IsForwardRefUdt(tpi.getType(id.index)); 398343181Sdim} 399343181Sdim 400343181Sdimbool lldb_private::npdb::IsTagRecord(const PdbTypeSymId &id, TpiStream &tpi) { 401343181Sdim if (id.is_ipi || id.index.isSimple()) 402343181Sdim return false; 403343181Sdim return IsTagRecord(tpi.getType(id.index)); 404343181Sdim} 405343181Sdim 406343181Sdimlldb::AccessType 407343181Sdimlldb_private::npdb::TranslateMemberAccess(MemberAccess access) { 408343181Sdim switch (access) { 409343181Sdim case MemberAccess::Private: 410343181Sdim return lldb::eAccessPrivate; 411343181Sdim case MemberAccess::Protected: 412343181Sdim return lldb::eAccessProtected; 413343181Sdim case MemberAccess::Public: 414343181Sdim return lldb::eAccessPublic; 415343181Sdim case MemberAccess::None: 416343181Sdim return lldb::eAccessNone; 417343181Sdim } 418343181Sdim llvm_unreachable("unreachable"); 419343181Sdim} 420343181Sdim 421343181SdimTypeIndex lldb_private::npdb::GetFieldListIndex(CVType cvt) { 422343181Sdim switch (cvt.kind()) { 423343181Sdim case LF_CLASS: 424343181Sdim case LF_STRUCTURE: 425343181Sdim case LF_INTERFACE: { 426343181Sdim ClassRecord cr; 427343181Sdim cantFail(TypeDeserializer::deserializeAs<ClassRecord>(cvt, cr)); 428343181Sdim return cr.FieldList; 429343181Sdim } 430343181Sdim case LF_UNION: { 431343181Sdim UnionRecord ur; 432343181Sdim cantFail(TypeDeserializer::deserializeAs<UnionRecord>(cvt, ur)); 433343181Sdim return ur.FieldList; 434343181Sdim } 435343181Sdim case LF_ENUM: { 436343181Sdim EnumRecord er; 437343181Sdim cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er)); 438343181Sdim return er.FieldList; 439343181Sdim } 440343181Sdim default: 441343181Sdim llvm_unreachable("Unreachable!"); 442343181Sdim } 443343181Sdim} 444343181Sdim 445343181SdimTypeIndex lldb_private::npdb::LookThroughModifierRecord(CVType modifier) { 446343181Sdim lldbassert(modifier.kind() == LF_MODIFIER); 447343181Sdim ModifierRecord mr; 448343181Sdim llvm::cantFail(TypeDeserializer::deserializeAs<ModifierRecord>(modifier, mr)); 449343181Sdim return mr.ModifiedType; 450343181Sdim} 451343181Sdim 452343181Sdimllvm::StringRef lldb_private::npdb::DropNameScope(llvm::StringRef name) { 453343181Sdim return MSVCUndecoratedNameParser::DropScope(name); 454343181Sdim} 455343181Sdim 456343181SdimVariableInfo lldb_private::npdb::GetVariableNameInfo(CVSymbol sym) { 457343181Sdim VariableInfo result; 458343181Sdim 459343181Sdim if (sym.kind() == S_REGREL32) { 460343181Sdim RegRelativeSym reg(SymbolRecordKind::RegRelativeSym); 461343181Sdim cantFail(SymbolDeserializer::deserializeAs<RegRelativeSym>(sym, reg)); 462343181Sdim result.type = reg.Type; 463343181Sdim result.name = reg.Name; 464343181Sdim return result; 465343181Sdim } 466343181Sdim 467343181Sdim if (sym.kind() == S_REGISTER) { 468343181Sdim RegisterSym reg(SymbolRecordKind::RegisterSym); 469343181Sdim cantFail(SymbolDeserializer::deserializeAs<RegisterSym>(sym, reg)); 470343181Sdim result.type = reg.Index; 471343181Sdim result.name = reg.Name; 472343181Sdim return result; 473343181Sdim } 474343181Sdim 475343181Sdim if (sym.kind() == S_LOCAL) { 476343181Sdim LocalSym local(SymbolRecordKind::LocalSym); 477343181Sdim cantFail(SymbolDeserializer::deserializeAs<LocalSym>(sym, local)); 478343181Sdim result.type = local.Type; 479343181Sdim result.name = local.Name; 480343181Sdim return result; 481343181Sdim } 482343181Sdim 483343181Sdim if (sym.kind() == S_GDATA32 || sym.kind() == S_LDATA32) { 484343181Sdim DataSym data(SymbolRecordKind::DataSym); 485343181Sdim cantFail(SymbolDeserializer::deserializeAs<DataSym>(sym, data)); 486343181Sdim result.type = data.Type; 487343181Sdim result.name = data.Name; 488343181Sdim return result; 489343181Sdim } 490343181Sdim 491343181Sdim if (sym.kind() == S_GTHREAD32 || sym.kind() == S_LTHREAD32) { 492343181Sdim ThreadLocalDataSym data(SymbolRecordKind::ThreadLocalDataSym); 493343181Sdim cantFail(SymbolDeserializer::deserializeAs<ThreadLocalDataSym>(sym, data)); 494343181Sdim result.type = data.Type; 495343181Sdim result.name = data.Name; 496343181Sdim return result; 497343181Sdim } 498343181Sdim 499343181Sdim if (sym.kind() == S_CONSTANT) { 500343181Sdim ConstantSym constant(SymbolRecordKind::ConstantSym); 501343181Sdim cantFail(SymbolDeserializer::deserializeAs<ConstantSym>(sym, constant)); 502343181Sdim result.type = constant.Type; 503343181Sdim result.name = constant.Name; 504343181Sdim return result; 505343181Sdim } 506343181Sdim 507343181Sdim lldbassert(false && "Invalid variable record kind!"); 508343181Sdim return {}; 509343181Sdim} 510343181Sdim 511353358Sdimstatic llvm::FixedStreamArray<FrameData>::Iterator 512353358SdimGetCorrespondingFrameData(lldb::addr_t load_addr, 513353358Sdim const DebugFrameDataSubsectionRef &fpo_data, 514353358Sdim const Variable::RangeList &ranges) { 515353358Sdim lldbassert(!ranges.IsEmpty()); 516353358Sdim 517353358Sdim // assume that all variable ranges correspond to one frame data 518353358Sdim using RangeListEntry = Variable::RangeList::Entry; 519353358Sdim const RangeListEntry &range = ranges.GetEntryRef(0); 520353358Sdim 521353358Sdim auto it = fpo_data.begin(); 522353358Sdim 523353358Sdim // start by searching first frame data range containing variable range 524353358Sdim for (; it != fpo_data.end(); ++it) { 525353358Sdim RangeListEntry fd_range(load_addr + it->RvaStart, it->CodeSize); 526353358Sdim 527353358Sdim if (fd_range.Contains(range)) { 528353358Sdim break; 529353358Sdim } 530353358Sdim } 531353358Sdim 532353358Sdim // then first most nested entry that still contains variable range 533353358Sdim auto found = it; 534353358Sdim for (; it != fpo_data.end(); ++it) { 535353358Sdim RangeListEntry fd_range(load_addr + it->RvaStart, it->CodeSize); 536353358Sdim 537353358Sdim if (!fd_range.Contains(range)) { 538353358Sdim break; 539353358Sdim } 540353358Sdim found = it; 541353358Sdim } 542353358Sdim 543353358Sdim return found; 544353358Sdim} 545353358Sdim 546353358Sdimstatic bool GetFrameDataProgram(PdbIndex &index, 547353358Sdim const Variable::RangeList &ranges, 548353358Sdim llvm::StringRef &out_program) { 549353358Sdim const DebugFrameDataSubsectionRef &new_fpo_data = 550353358Sdim index.dbi().getNewFpoRecords(); 551353358Sdim 552353358Sdim auto frame_data_it = 553353358Sdim GetCorrespondingFrameData(index.GetLoadAddress(), new_fpo_data, ranges); 554353358Sdim if (frame_data_it == new_fpo_data.end()) 555353358Sdim return false; 556353358Sdim 557353358Sdim PDBStringTable &strings = cantFail(index.pdb().getStringTable()); 558353358Sdim out_program = cantFail(strings.getStringForID(frame_data_it->FrameFunc)); 559353358Sdim return true; 560353358Sdim} 561353358Sdim 562353358Sdimstatic RegisterId GetBaseFrameRegister(PdbIndex &index, 563353358Sdim PdbCompilandSymId frame_proc_id, 564353358Sdim bool is_parameter) { 565353358Sdim CVSymbol frame_proc_cvs = index.ReadSymbolRecord(frame_proc_id); 566353358Sdim lldbassert(frame_proc_cvs.kind() == S_FRAMEPROC); 567353358Sdim 568353358Sdim FrameProcSym frame_proc(SymbolRecordKind::FrameProcSym); 569353358Sdim cantFail(SymbolDeserializer::deserializeAs<FrameProcSym>(frame_proc_cvs, 570353358Sdim frame_proc)); 571353358Sdim 572353358Sdim CPUType cpu_type = index.compilands() 573353358Sdim .GetCompiland(frame_proc_id.modi) 574353358Sdim ->m_compile_opts->Machine; 575353358Sdim 576353358Sdim return is_parameter ? frame_proc.getParamFramePtrReg(cpu_type) 577353358Sdim : frame_proc.getLocalFramePtrReg(cpu_type); 578353358Sdim} 579353358Sdim 580343181SdimVariableInfo lldb_private::npdb::GetVariableLocationInfo( 581353358Sdim PdbIndex &index, PdbCompilandSymId var_id, Block &block, 582353358Sdim lldb::ModuleSP module) { 583343181Sdim 584343181Sdim CVSymbol sym = index.ReadSymbolRecord(var_id); 585343181Sdim 586343181Sdim VariableInfo result = GetVariableNameInfo(sym); 587343181Sdim 588343181Sdim if (sym.kind() == S_REGREL32) { 589343181Sdim RegRelativeSym reg(SymbolRecordKind::RegRelativeSym); 590343181Sdim cantFail(SymbolDeserializer::deserializeAs<RegRelativeSym>(sym, reg)); 591343181Sdim result.location = 592343181Sdim MakeRegRelLocationExpression(reg.Register, reg.Offset, module); 593343181Sdim result.ranges.emplace(); 594343181Sdim return result; 595343181Sdim } 596343181Sdim 597343181Sdim if (sym.kind() == S_REGISTER) { 598343181Sdim RegisterSym reg(SymbolRecordKind::RegisterSym); 599343181Sdim cantFail(SymbolDeserializer::deserializeAs<RegisterSym>(sym, reg)); 600343181Sdim result.location = MakeEnregisteredLocationExpression(reg.Register, module); 601343181Sdim result.ranges.emplace(); 602343181Sdim return result; 603343181Sdim } 604343181Sdim 605343181Sdim if (sym.kind() == S_LOCAL) { 606343181Sdim LocalSym local(SymbolRecordKind::LocalSym); 607343181Sdim cantFail(SymbolDeserializer::deserializeAs<LocalSym>(sym, local)); 608343181Sdim 609343181Sdim PdbCompilandSymId loc_specifier_id(var_id.modi, 610343181Sdim var_id.offset + sym.RecordData.size()); 611343181Sdim CVSymbol loc_specifier_cvs = index.ReadSymbolRecord(loc_specifier_id); 612343181Sdim if (loc_specifier_cvs.kind() == S_DEFRANGE_FRAMEPOINTER_REL) { 613343181Sdim DefRangeFramePointerRelSym loc( 614343181Sdim SymbolRecordKind::DefRangeFramePointerRelSym); 615343181Sdim cantFail(SymbolDeserializer::deserializeAs<DefRangeFramePointerRelSym>( 616343181Sdim loc_specifier_cvs, loc)); 617353358Sdim 618353358Sdim Variable::RangeList ranges = MakeRangeList(index, loc.Range, loc.Gaps); 619353358Sdim 620353358Sdim // TODO: may be better to pass function scope and not lookup it every 621353358Sdim // time? find nearest parent function block 622353358Sdim Block *cur = █ 623353358Sdim while (cur->GetParent()) { 624353358Sdim cur = cur->GetParent(); 625353358Sdim } 626353358Sdim PdbCompilandSymId func_scope_id = 627353358Sdim PdbSymUid(cur->GetID()).asCompilandSym(); 628353358Sdim CVSymbol func_block_cvs = index.ReadSymbolRecord(func_scope_id); 629353358Sdim lldbassert(func_block_cvs.kind() == S_GPROC32 || 630353358Sdim func_block_cvs.kind() == S_LPROC32); 631353358Sdim 632353358Sdim PdbCompilandSymId frame_proc_id( 633353358Sdim func_scope_id.modi, func_scope_id.offset + func_block_cvs.length()); 634353358Sdim 635353358Sdim bool is_parameter = 636353358Sdim ((local.Flags & LocalSymFlags::IsParameter) != LocalSymFlags::None); 637353358Sdim RegisterId base_reg = 638353358Sdim GetBaseFrameRegister(index, frame_proc_id, is_parameter); 639353358Sdim 640353358Sdim if (base_reg == RegisterId::VFRAME) { 641353358Sdim llvm::StringRef program; 642353358Sdim if (GetFrameDataProgram(index, ranges, program)) { 643353358Sdim result.location = 644360784Sdim MakeVFrameRelLocationExpression(program, loc.Hdr.Offset, module); 645353358Sdim result.ranges = std::move(ranges); 646353358Sdim } else { 647353358Sdim // invalid variable 648353358Sdim } 649353358Sdim } else { 650353358Sdim result.location = 651360784Sdim MakeRegRelLocationExpression(base_reg, loc.Hdr.Offset, module); 652353358Sdim result.ranges = std::move(ranges); 653353358Sdim } 654353358Sdim } else if (loc_specifier_cvs.kind() == S_DEFRANGE_REGISTER_REL) { 655353358Sdim DefRangeRegisterRelSym loc(SymbolRecordKind::DefRangeRegisterRelSym); 656353358Sdim cantFail(SymbolDeserializer::deserializeAs<DefRangeRegisterRelSym>( 657353358Sdim loc_specifier_cvs, loc)); 658353358Sdim 659353358Sdim Variable::RangeList ranges = MakeRangeList(index, loc.Range, loc.Gaps); 660353358Sdim 661353358Sdim RegisterId base_reg = (RegisterId)(uint16_t)loc.Hdr.Register; 662353358Sdim 663353358Sdim if (base_reg == RegisterId::VFRAME) { 664353358Sdim llvm::StringRef program; 665353358Sdim if (GetFrameDataProgram(index, ranges, program)) { 666353358Sdim result.location = MakeVFrameRelLocationExpression( 667353358Sdim program, loc.Hdr.BasePointerOffset, module); 668353358Sdim result.ranges = std::move(ranges); 669353358Sdim } else { 670353358Sdim // invalid variable 671353358Sdim } 672353358Sdim } else { 673353358Sdim result.location = MakeRegRelLocationExpression( 674353358Sdim base_reg, loc.Hdr.BasePointerOffset, module); 675353358Sdim result.ranges = std::move(ranges); 676353358Sdim } 677343181Sdim } 678353358Sdim 679353358Sdim // FIXME: Handle other kinds 680343181Sdim return result; 681343181Sdim } 682343181Sdim llvm_unreachable("Symbol is not a local variable!"); 683343181Sdim return result; 684343181Sdim} 685343181Sdim 686343181Sdimlldb::BasicType 687343181Sdimlldb_private::npdb::GetCompilerTypeForSimpleKind(SimpleTypeKind kind) { 688343181Sdim switch (kind) { 689343181Sdim case SimpleTypeKind::Boolean128: 690343181Sdim case SimpleTypeKind::Boolean16: 691343181Sdim case SimpleTypeKind::Boolean32: 692343181Sdim case SimpleTypeKind::Boolean64: 693343181Sdim case SimpleTypeKind::Boolean8: 694343181Sdim return lldb::eBasicTypeBool; 695343181Sdim case SimpleTypeKind::Byte: 696343181Sdim case SimpleTypeKind::UnsignedCharacter: 697343181Sdim return lldb::eBasicTypeUnsignedChar; 698343181Sdim case SimpleTypeKind::NarrowCharacter: 699343181Sdim return lldb::eBasicTypeChar; 700343181Sdim case SimpleTypeKind::SignedCharacter: 701343181Sdim case SimpleTypeKind::SByte: 702343181Sdim return lldb::eBasicTypeSignedChar; 703343181Sdim case SimpleTypeKind::Character16: 704343181Sdim return lldb::eBasicTypeChar16; 705343181Sdim case SimpleTypeKind::Character32: 706343181Sdim return lldb::eBasicTypeChar32; 707343181Sdim case SimpleTypeKind::Complex80: 708343181Sdim return lldb::eBasicTypeLongDoubleComplex; 709343181Sdim case SimpleTypeKind::Complex64: 710343181Sdim return lldb::eBasicTypeDoubleComplex; 711343181Sdim case SimpleTypeKind::Complex32: 712343181Sdim return lldb::eBasicTypeFloatComplex; 713343181Sdim case SimpleTypeKind::Float128: 714343181Sdim case SimpleTypeKind::Float80: 715343181Sdim return lldb::eBasicTypeLongDouble; 716343181Sdim case SimpleTypeKind::Float64: 717343181Sdim return lldb::eBasicTypeDouble; 718343181Sdim case SimpleTypeKind::Float32: 719343181Sdim return lldb::eBasicTypeFloat; 720343181Sdim case SimpleTypeKind::Float16: 721343181Sdim return lldb::eBasicTypeHalf; 722343181Sdim case SimpleTypeKind::Int128: 723343181Sdim return lldb::eBasicTypeInt128; 724343181Sdim case SimpleTypeKind::Int64: 725343181Sdim case SimpleTypeKind::Int64Quad: 726343181Sdim return lldb::eBasicTypeLongLong; 727343181Sdim case SimpleTypeKind::Int32: 728343181Sdim return lldb::eBasicTypeInt; 729343181Sdim case SimpleTypeKind::Int16: 730343181Sdim case SimpleTypeKind::Int16Short: 731343181Sdim return lldb::eBasicTypeShort; 732343181Sdim case SimpleTypeKind::UInt128: 733343181Sdim return lldb::eBasicTypeUnsignedInt128; 734343181Sdim case SimpleTypeKind::UInt64: 735343181Sdim case SimpleTypeKind::UInt64Quad: 736343181Sdim return lldb::eBasicTypeUnsignedLongLong; 737343181Sdim case SimpleTypeKind::HResult: 738343181Sdim case SimpleTypeKind::UInt32: 739343181Sdim return lldb::eBasicTypeUnsignedInt; 740343181Sdim case SimpleTypeKind::UInt16: 741343181Sdim case SimpleTypeKind::UInt16Short: 742343181Sdim return lldb::eBasicTypeUnsignedShort; 743343181Sdim case SimpleTypeKind::Int32Long: 744343181Sdim return lldb::eBasicTypeLong; 745343181Sdim case SimpleTypeKind::UInt32Long: 746343181Sdim return lldb::eBasicTypeUnsignedLong; 747343181Sdim case SimpleTypeKind::Void: 748343181Sdim return lldb::eBasicTypeVoid; 749343181Sdim case SimpleTypeKind::WideCharacter: 750343181Sdim return lldb::eBasicTypeWChar; 751343181Sdim default: 752343181Sdim return lldb::eBasicTypeInvalid; 753343181Sdim } 754343181Sdim} 755343181Sdim 756343181Sdimsize_t lldb_private::npdb::GetTypeSizeForSimpleKind(SimpleTypeKind kind) { 757343181Sdim switch (kind) { 758343181Sdim case SimpleTypeKind::Boolean128: 759343181Sdim case SimpleTypeKind::Int128: 760343181Sdim case SimpleTypeKind::UInt128: 761343181Sdim case SimpleTypeKind::Float128: 762343181Sdim return 16; 763343181Sdim case SimpleTypeKind::Complex80: 764343181Sdim case SimpleTypeKind::Float80: 765343181Sdim return 10; 766343181Sdim case SimpleTypeKind::Boolean64: 767343181Sdim case SimpleTypeKind::Complex64: 768343181Sdim case SimpleTypeKind::UInt64: 769343181Sdim case SimpleTypeKind::UInt64Quad: 770343181Sdim case SimpleTypeKind::Float64: 771343181Sdim case SimpleTypeKind::Int64: 772343181Sdim case SimpleTypeKind::Int64Quad: 773343181Sdim return 8; 774343181Sdim case SimpleTypeKind::Boolean32: 775343181Sdim case SimpleTypeKind::Character32: 776343181Sdim case SimpleTypeKind::Complex32: 777343181Sdim case SimpleTypeKind::Float32: 778343181Sdim case SimpleTypeKind::Int32: 779343181Sdim case SimpleTypeKind::Int32Long: 780343181Sdim case SimpleTypeKind::UInt32Long: 781343181Sdim case SimpleTypeKind::HResult: 782343181Sdim case SimpleTypeKind::UInt32: 783343181Sdim return 4; 784343181Sdim case SimpleTypeKind::Boolean16: 785343181Sdim case SimpleTypeKind::Character16: 786343181Sdim case SimpleTypeKind::Float16: 787343181Sdim case SimpleTypeKind::Int16: 788343181Sdim case SimpleTypeKind::Int16Short: 789343181Sdim case SimpleTypeKind::UInt16: 790343181Sdim case SimpleTypeKind::UInt16Short: 791343181Sdim case SimpleTypeKind::WideCharacter: 792343181Sdim return 2; 793343181Sdim case SimpleTypeKind::Boolean8: 794343181Sdim case SimpleTypeKind::Byte: 795343181Sdim case SimpleTypeKind::UnsignedCharacter: 796343181Sdim case SimpleTypeKind::NarrowCharacter: 797343181Sdim case SimpleTypeKind::SignedCharacter: 798343181Sdim case SimpleTypeKind::SByte: 799343181Sdim return 1; 800343181Sdim case SimpleTypeKind::Void: 801343181Sdim default: 802343181Sdim return 0; 803343181Sdim } 804343181Sdim} 805343181Sdim 806343181SdimPdbTypeSymId lldb_private::npdb::GetBestPossibleDecl(PdbTypeSymId id, 807343181Sdim TpiStream &tpi) { 808343181Sdim if (id.index.isSimple()) 809343181Sdim return id; 810343181Sdim 811343181Sdim CVType cvt = tpi.getType(id.index); 812343181Sdim 813343181Sdim // Only tag records have a best and a worst record. 814343181Sdim if (!IsTagRecord(cvt)) 815343181Sdim return id; 816343181Sdim 817343181Sdim // Tag records that are not forward decls are full decls, hence they are the 818343181Sdim // best. 819343181Sdim if (!IsForwardRefUdt(cvt)) 820343181Sdim return id; 821343181Sdim 822343181Sdim return llvm::cantFail(tpi.findFullDeclForForwardRef(id.index)); 823343181Sdim} 824343181Sdim 825343181Sdimtemplate <typename RecordType> static size_t GetSizeOfTypeInternal(CVType cvt) { 826343181Sdim RecordType record; 827343181Sdim llvm::cantFail(TypeDeserializer::deserializeAs<RecordType>(cvt, record)); 828343181Sdim return record.getSize(); 829343181Sdim} 830343181Sdim 831343181Sdimsize_t lldb_private::npdb::GetSizeOfType(PdbTypeSymId id, 832343181Sdim llvm::pdb::TpiStream &tpi) { 833343181Sdim if (id.index.isSimple()) { 834343181Sdim switch (id.index.getSimpleMode()) { 835343181Sdim case SimpleTypeMode::Direct: 836343181Sdim return GetTypeSizeForSimpleKind(id.index.getSimpleKind()); 837343181Sdim case SimpleTypeMode::NearPointer32: 838343181Sdim case SimpleTypeMode::FarPointer32: 839343181Sdim return 4; 840343181Sdim case SimpleTypeMode::NearPointer64: 841343181Sdim return 8; 842343181Sdim case SimpleTypeMode::NearPointer128: 843343181Sdim return 16; 844343181Sdim default: 845343181Sdim break; 846343181Sdim } 847343181Sdim return 0; 848343181Sdim } 849343181Sdim 850343181Sdim TypeIndex index = id.index; 851343181Sdim if (IsForwardRefUdt(index, tpi)) 852343181Sdim index = llvm::cantFail(tpi.findFullDeclForForwardRef(index)); 853343181Sdim 854343181Sdim CVType cvt = tpi.getType(index); 855343181Sdim switch (cvt.kind()) { 856343181Sdim case LF_MODIFIER: 857343181Sdim return GetSizeOfType({LookThroughModifierRecord(cvt)}, tpi); 858343181Sdim case LF_ENUM: { 859343181Sdim EnumRecord record; 860343181Sdim llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, record)); 861343181Sdim return GetSizeOfType({record.UnderlyingType}, tpi); 862343181Sdim } 863343181Sdim case LF_POINTER: 864343181Sdim return GetSizeOfTypeInternal<PointerRecord>(cvt); 865343181Sdim case LF_ARRAY: 866343181Sdim return GetSizeOfTypeInternal<ArrayRecord>(cvt); 867343181Sdim case LF_CLASS: 868343181Sdim case LF_STRUCTURE: 869343181Sdim case LF_INTERFACE: 870343181Sdim return GetSizeOfTypeInternal<ClassRecord>(cvt); 871343181Sdim case LF_UNION: 872343181Sdim return GetSizeOfTypeInternal<UnionRecord>(cvt); 873343181Sdim default: 874343181Sdim break; 875343181Sdim } 876343181Sdim return 0; 877343181Sdim} 878