15 #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
16 #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
17 #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
18 #include "llvm/DebugInfo/PDB/Native/DbiStream.h"
19 #include "llvm/DebugInfo/PDB/Native/TpiStream.h"
34 llvm::ArrayRef<LocalVariableAddrGap> gaps) {
40 while (!gaps.empty()) {
41 const LocalVariableAddrGap &gap = gaps.front();
43 result.
Append(start, gap_start - start);
44 start = gap_start + gap.Range;
45 gaps = gaps.drop_front();
48 result.
Append(start, end - start);
55 std::map<uint64_t, std::pair<RegisterId, uint32_t>> &members_info,
57 : members_info(members_info), tpi(tpi) {}
58 std::map<uint64_t, std::pair<RegisterId, uint32_t>> &members_info;
61 DataMemberRecord &member)
override {
62 auto it = members_info.insert(
63 {member.getFieldOffset(),
64 {llvm::codeview::RegisterId::NONE,
GetSizeOfType(member.Type, tpi)}});
66 return llvm::make_error<CodeViewError>(cv_error_code::corrupt_record);
67 return llvm::Error::success();
73 assert(
IsTagRecord(type) &&
"type is not a tag record!");
74 switch (type.kind()) {
79 llvm::cantFail(TypeDeserializer::deserializeAs<ClassRecord>(type, cr));
84 llvm::cantFail(TypeDeserializer::deserializeAs<UnionRecord>(type, ur));
89 llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(type, er));
93 llvm_unreachable(
"Unreachable!");
98 : cvclass(std::move(c)),
101 : cvunion(std::move(u)), m_kind(
Union) {}
108 return PDB_SymType::CompilandDetails;
110 return PDB_SymType::CompilandEnv;
113 return PDB_SymType::Thunk;
115 return PDB_SymType::CoffGroup;
117 return PDB_SymType::Export;
121 return PDB_SymType::Function;
123 return PDB_SymType::PublicSymbol;
125 return PDB_SymType::InlineSite;
137 return PDB_SymType::Data;
139 return PDB_SymType::Block;
141 return PDB_SymType::Label;
143 return PDB_SymType::CallSite;
144 case S_HEAPALLOCSITE:
145 return PDB_SymType::HeapAllocationSite;
147 return PDB_SymType::Callee;
149 return PDB_SymType::Caller;
151 lldbassert(
false &&
"Invalid symbol record kind!");
153 return PDB_SymType::None;
159 return PDB_SymType::ArrayType;
161 return PDB_SymType::FunctionSig;
163 return PDB_SymType::BaseClass;
165 return PDB_SymType::BaseInterface;
170 return PDB_SymType::UDT;
172 return PDB_SymType::PointerType;
174 return PDB_SymType::Enum;
176 return PDB_SymType::FunctionSig;
178 return PDB_SymType::BuiltinType;
180 lldbassert(
false &&
"Invalid type record kind!");
182 return PDB_SymType::None;
186 switch (sym.kind()) {
192 case S_LPROC32_DPC_ID:
199 case S_HEAPALLOCSITE:
213 switch (sym.kind()) {
219 case S_LPROC32_DPC_ID:
230 template <
typename RecordT> RecordT
createRecord(
const CVSymbol &sym) {
231 RecordT record(
static_cast<SymbolRecordKind
>(sym.kind()));
232 cantFail(SymbolDeserializer::deserializeAs<RecordT>(sym, record));
236 template <
typename RecordT>
238 RecordT record = createRecord<RecordT>(sym);
239 return {record.Segment, record.CodeOffset};
244 TrampolineSym record = createRecord<TrampolineSym>(sym);
245 return {record.ThunkSection, record.ThunkOffset};
249 Thunk32Sym record = createRecord<Thunk32Sym>(sym);
250 return {record.Segment, record.Offset};
255 CoffGroupSym record = createRecord<CoffGroupSym>(sym);
256 return {record.Segment, record.Offset};
260 DataSym record = createRecord<DataSym>(sym);
261 return {record.Segment, record.DataOffset};
266 ThreadLocalDataSym record = createRecord<ThreadLocalDataSym>(sym);
267 return {record.Segment, record.DataOffset};
271 switch (sym.kind()) {
277 case S_LPROC32_DPC_ID:
278 return ::GetSegmentAndOffset<ProcSym>(sym);
289 return ::GetSegmentAndOffset<BlockSym>(sym);
292 return ::GetSegmentAndOffset<LabelSym>(sym);
295 return ::GetSegmentAndOffset<CallSiteInfoSym>(sym);
297 case S_HEAPALLOCSITE:
298 return ::GetSegmentAndOffset<HeapAllocationSiteSym>(sym);
311 lldbassert(
false &&
"Record does not have a segment/offset!");
316 template <
typename RecordT>
318 RecordT record = createRecord<RecordT>(sym);
319 return {record.Segment, record.CodeOffset, record.CodeSize};
325 TrampolineSym record = createRecord<TrampolineSym>(sym);
326 return {record.ThunkSection, record.ThunkOffset, record.Size};
331 Thunk32Sym record = createRecord<Thunk32Sym>(sym);
338 CoffGroupSym record = createRecord<CoffGroupSym>(sym);
344 switch (sym.kind()) {
350 case S_LPROC32_DPC_ID:
351 return ::GetSegmentOffsetAndLength<ProcSym>(sym);
362 return ::GetSegmentOffsetAndLength<BlockSym>(sym);
365 lldbassert(
false &&
"Record does not have a segment/offset/length triple!");
374 switch (cvt.kind()) {
378 llvm::cantFail(TypeDeserializer::deserializeAs<ClassRecord>(cvt, cr));
379 return cr.isForwardRef();
381 llvm::cantFail(TypeDeserializer::deserializeAs<UnionRecord>(cvt, ur));
382 return ur.isForwardRef();
384 llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er));
385 return er.isForwardRef();
392 switch (cvt.kind()) {
404 switch (cvt.kind()) {
416 if (
id.is_ipi ||
id.index.isSimple())
422 if (
id.is_ipi ||
id.index.isSimple())
430 case MemberAccess::Private:
432 case MemberAccess::Protected:
434 case MemberAccess::Public:
436 case MemberAccess::None:
439 llvm_unreachable(
"unreachable");
443 switch (cvt.kind()) {
448 cantFail(TypeDeserializer::deserializeAs<ClassRecord>(cvt, cr));
453 cantFail(TypeDeserializer::deserializeAs<UnionRecord>(cvt, ur));
458 cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er));
462 llvm_unreachable(
"Unreachable!");
469 llvm::cantFail(TypeDeserializer::deserializeAs<ModifierRecord>(modifier, mr));
470 return mr.ModifiedType;
480 if (sym.kind() == S_REGREL32) {
481 RegRelativeSym reg(SymbolRecordKind::RegRelativeSym);
482 cantFail(SymbolDeserializer::deserializeAs<RegRelativeSym>(sym, reg));
483 result.
type = reg.Type;
484 result.
name = reg.Name;
488 if (sym.kind() == S_REGISTER) {
489 RegisterSym reg(SymbolRecordKind::RegisterSym);
490 cantFail(SymbolDeserializer::deserializeAs<RegisterSym>(sym, reg));
491 result.
type = reg.Index;
492 result.
name = reg.Name;
496 if (sym.kind() == S_LOCAL) {
497 LocalSym local(SymbolRecordKind::LocalSym);
498 cantFail(SymbolDeserializer::deserializeAs<LocalSym>(sym, local));
499 result.
type = local.Type;
500 result.
name = local.Name;
502 ((local.Flags & LocalSymFlags::IsParameter) != LocalSymFlags::None);
506 if (sym.kind() == S_GDATA32 || sym.kind() == S_LDATA32) {
507 DataSym data(SymbolRecordKind::DataSym);
508 cantFail(SymbolDeserializer::deserializeAs<DataSym>(sym, data));
509 result.
type = data.Type;
510 result.
name = data.Name;
514 if (sym.kind() == S_GTHREAD32 || sym.kind() == S_LTHREAD32) {
515 ThreadLocalDataSym data(SymbolRecordKind::ThreadLocalDataSym);
516 cantFail(SymbolDeserializer::deserializeAs<ThreadLocalDataSym>(sym, data));
517 result.
type = data.Type;
518 result.
name = data.Name;
522 if (sym.kind() == S_CONSTANT) {
523 ConstantSym constant(SymbolRecordKind::ConstantSym);
524 cantFail(SymbolDeserializer::deserializeAs<ConstantSym>(sym, constant));
525 result.
type = constant.Type;
526 result.
name = constant.Name;
530 lldbassert(
false &&
"Invalid variable record kind!");
534 static llvm::FixedStreamArray<FrameData>::Iterator
536 const DebugFrameDataSubsectionRef &fpo_data,
542 const RangeListEntry &range = ranges.
GetEntryRef(0);
544 auto it = fpo_data.begin();
547 for (; it != fpo_data.end(); ++it) {
548 RangeListEntry fd_range(load_addr + it->RvaStart, it->CodeSize);
550 if (fd_range.Contains(range)) {
557 for (; it != fpo_data.end(); ++it) {
558 RangeListEntry fd_range(load_addr + it->RvaStart, it->CodeSize);
560 if (!fd_range.Contains(range)) {
571 llvm::StringRef &out_program) {
572 const DebugFrameDataSubsectionRef &new_fpo_data =
573 index.
dbi().getNewFpoRecords();
577 if (frame_data_it == new_fpo_data.end())
580 PDBStringTable &strings = cantFail(index.
pdb().getStringTable());
581 out_program = cantFail(strings.getStringForID(frame_data_it->FrameFunc));
589 lldbassert(frame_proc_cvs.kind() == S_FRAMEPROC);
591 FrameProcSym frame_proc(SymbolRecordKind::FrameProcSym);
592 cantFail(SymbolDeserializer::deserializeAs<FrameProcSym>(frame_proc_cvs,
599 return is_parameter ? frame_proc.getParamFramePtrReg(cpu_type)
600 : frame_proc.getLocalFramePtrReg(cpu_type);
605 lldb::ModuleSP module) {
611 if (sym.kind() == S_REGREL32) {
612 RegRelativeSym reg(SymbolRecordKind::RegRelativeSym);
613 cantFail(SymbolDeserializer::deserializeAs<RegRelativeSym>(sym, reg));
620 if (sym.kind() == S_REGISTER) {
621 RegisterSym reg(SymbolRecordKind::RegisterSym);
622 cantFail(SymbolDeserializer::deserializeAs<RegisterSym>(sym, reg));
628 if (sym.kind() == S_LOCAL) {
629 LocalSym local(SymbolRecordKind::LocalSym);
630 cantFail(SymbolDeserializer::deserializeAs<LocalSym>(sym, local));
633 var_id.
offset + sym.RecordData.size());
635 switch(loc_specifier_cvs.kind()) {
636 case S_DEFRANGE_FRAMEPOINTER_REL: {
637 DefRangeFramePointerRelSym loc(
638 SymbolRecordKind::DefRangeFramePointerRelSym);
639 cantFail(SymbolDeserializer::deserializeAs<DefRangeFramePointerRelSym>(
640 loc_specifier_cvs, loc));
653 lldbassert(func_block_cvs.kind() == S_GPROC32 ||
654 func_block_cvs.kind() == S_LPROC32);
657 func_scope_id.
modi, func_scope_id.
offset + func_block_cvs.length());
659 RegisterId base_reg =
662 if (base_reg == RegisterId::VFRAME) {
663 llvm::StringRef program;
667 result.
ranges = std::move(ranges);
674 result.
ranges = std::move(ranges);
678 case S_DEFRANGE_REGISTER_REL: {
679 DefRangeRegisterRelSym loc(SymbolRecordKind::DefRangeRegisterRelSym);
680 cantFail(SymbolDeserializer::deserializeAs<DefRangeRegisterRelSym>(
681 loc_specifier_cvs, loc));
685 RegisterId base_reg = (RegisterId)(
uint16_t)loc.Hdr.Register;
687 if (base_reg == RegisterId::VFRAME) {
688 llvm::StringRef program;
691 program, loc.Hdr.BasePointerOffset, module);
692 result.
ranges = std::move(ranges);
698 base_reg, loc.Hdr.BasePointerOffset, module);
699 result.
ranges = std::move(ranges);
703 case S_DEFRANGE_REGISTER: {
704 DefRangeRegisterSym loc(SymbolRecordKind::DefRangeRegisterSym);
705 cantFail(SymbolDeserializer::deserializeAs<DefRangeRegisterSym>(
706 loc_specifier_cvs, loc));
708 RegisterId base_reg = (RegisterId)(
uint16_t)loc.Hdr.Register;
713 case S_DEFRANGE_SUBFIELD_REGISTER: {
718 std::map<uint64_t, std::pair<RegisterId, uint32_t>> members_info;
719 bool is_simple_type = result.
type.isSimple();
720 if (!is_simple_type) {
721 CVType class_cvt = index.
tpi().getType(result.
type);
723 CVType field_list = index.
tpi().getType(class_record.FieldList);
724 FindMembersSize find_members_size(members_info, index.
tpi());
726 visitMemberRecordStream(field_list.data(), find_members_size)) {
727 llvm::consumeError(std::move(err));
732 size_t member_idx = 0;
735 while (loc_specifier_cvs.kind() == S_DEFRANGE_SUBFIELD_REGISTER) {
736 if (!is_simple_type && member_idx >= members_info.size())
739 DefRangeSubfieldRegisterSym loc(
740 SymbolRecordKind::DefRangeSubfieldRegisterSym);
741 cantFail(SymbolDeserializer::deserializeAs<DefRangeSubfieldRegisterSym>(
742 loc_specifier_cvs, loc));
752 if (is_simple_type) {
753 if (members_info.count(loc.Hdr.OffsetInParent)) {
758 members_info[loc.Hdr.OffsetInParent] = {
759 (RegisterId)(
uint16_t)loc.Hdr.Register, 0};
761 if (!members_info.count(loc.Hdr.OffsetInParent)) {
766 members_info[loc.Hdr.OffsetInParent].first =
767 (RegisterId)(
uint16_t)loc.Hdr.Register;
771 loc_specifier_id.
modi,
772 loc_specifier_id.
offset + loc_specifier_cvs.RecordData.size());
776 if (is_simple_type) {
777 auto cur = members_info.begin();
778 auto end = members_info.end();
782 while (next != end) {
783 cur->second.second = next->first - cur->first;
784 size += cur->second.second;
801 llvm_unreachable(
"Symbol is not a local variable!");
808 case SimpleTypeKind::Boolean128:
809 case SimpleTypeKind::Boolean16:
810 case SimpleTypeKind::Boolean32:
811 case SimpleTypeKind::Boolean64:
812 case SimpleTypeKind::Boolean8:
814 case SimpleTypeKind::Byte:
815 case SimpleTypeKind::UnsignedCharacter:
817 case SimpleTypeKind::NarrowCharacter:
819 case SimpleTypeKind::SignedCharacter:
820 case SimpleTypeKind::SByte:
822 case SimpleTypeKind::Character16:
824 case SimpleTypeKind::Character32:
826 case SimpleTypeKind::Character8:
828 case SimpleTypeKind::Complex80:
830 case SimpleTypeKind::Complex64:
832 case SimpleTypeKind::Complex32:
834 case SimpleTypeKind::Float128:
835 case SimpleTypeKind::Float80:
837 case SimpleTypeKind::Float64:
839 case SimpleTypeKind::Float32:
841 case SimpleTypeKind::Float16:
843 case SimpleTypeKind::Int128:
845 case SimpleTypeKind::Int64:
846 case SimpleTypeKind::Int64Quad:
848 case SimpleTypeKind::Int32:
850 case SimpleTypeKind::Int16:
851 case SimpleTypeKind::Int16Short:
853 case SimpleTypeKind::UInt128:
855 case SimpleTypeKind::UInt64:
856 case SimpleTypeKind::UInt64Quad:
858 case SimpleTypeKind::HResult:
859 case SimpleTypeKind::UInt32:
861 case SimpleTypeKind::UInt16:
862 case SimpleTypeKind::UInt16Short:
864 case SimpleTypeKind::Int32Long:
866 case SimpleTypeKind::UInt32Long:
868 case SimpleTypeKind::Void:
870 case SimpleTypeKind::WideCharacter:
879 case SimpleTypeKind::Boolean128:
880 case SimpleTypeKind::Int128:
881 case SimpleTypeKind::UInt128:
882 case SimpleTypeKind::Float128:
884 case SimpleTypeKind::Complex80:
885 case SimpleTypeKind::Float80:
887 case SimpleTypeKind::Boolean64:
888 case SimpleTypeKind::Complex64:
889 case SimpleTypeKind::UInt64:
890 case SimpleTypeKind::UInt64Quad:
891 case SimpleTypeKind::Float64:
892 case SimpleTypeKind::Int64:
893 case SimpleTypeKind::Int64Quad:
895 case SimpleTypeKind::Boolean32:
896 case SimpleTypeKind::Character32:
897 case SimpleTypeKind::Complex32:
898 case SimpleTypeKind::Float32:
899 case SimpleTypeKind::Int32:
900 case SimpleTypeKind::Int32Long:
901 case SimpleTypeKind::UInt32Long:
902 case SimpleTypeKind::HResult:
903 case SimpleTypeKind::UInt32:
905 case SimpleTypeKind::Boolean16:
906 case SimpleTypeKind::Character16:
907 case SimpleTypeKind::Float16:
908 case SimpleTypeKind::Int16:
909 case SimpleTypeKind::Int16Short:
910 case SimpleTypeKind::UInt16:
911 case SimpleTypeKind::UInt16Short:
912 case SimpleTypeKind::WideCharacter:
914 case SimpleTypeKind::Boolean8:
915 case SimpleTypeKind::Byte:
916 case SimpleTypeKind::UnsignedCharacter:
917 case SimpleTypeKind::NarrowCharacter:
918 case SimpleTypeKind::SignedCharacter:
919 case SimpleTypeKind::SByte:
920 case SimpleTypeKind::Character8:
922 case SimpleTypeKind::Void:
930 if (
id.index.isSimple())
933 CVType cvt = tpi.getType(
id.index);
944 return llvm::cantFail(tpi.findFullDeclForForwardRef(
id.index));
949 llvm::cantFail(TypeDeserializer::deserializeAs<RecordType>(cvt, record));
950 return record.getSize();
954 llvm::pdb::TpiStream &tpi) {
955 if (
id.index.isSimple()) {
956 switch (
id.index.getSimpleMode()) {
957 case SimpleTypeMode::Direct:
959 case SimpleTypeMode::NearPointer32:
960 case SimpleTypeMode::FarPointer32:
962 case SimpleTypeMode::NearPointer64:
964 case SimpleTypeMode::NearPointer128:
972 TypeIndex index =
id.index;
974 index = llvm::cantFail(tpi.findFullDeclForForwardRef(index));
976 CVType cvt = tpi.getType(index);
977 switch (cvt.kind()) {
982 llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, record));
986 return GetSizeOfTypeInternal<PointerRecord>(cvt);
988 return GetSizeOfTypeInternal<ArrayRecord>(cvt);
992 return GetSizeOfTypeInternal<ClassRecord>(cvt);
994 return GetSizeOfTypeInternal<UnionRecord>(cvt);