1 //===-- PdbUtil.cpp -------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "PdbUtil.h"
10 
11 #include "DWARFLocationExpression.h"
12 #include "PdbIndex.h"
13 #include "PdbSymUid.h"
14 
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"
20 
21 #include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h"
22 #include "Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.h"
23 #include "lldb/Symbol/Block.h"
24 #include "lldb/Utility/LLDBAssert.h"
25 #include "lldb/Utility/LLDBLog.h"
26 #include "lldb/lldb-enumerations.h"
27 
28 using namespace lldb_private;
29 using namespace lldb_private::npdb;
30 using namespace llvm::codeview;
31 using namespace llvm::pdb;
32 
33 // The returned range list is guaranteed to be sorted and no overlaps between
34 // adjacent ranges because fields in LocalVariableAddrGap are unsigned integers.
35 static Variable::RangeList
36 MakeRangeList(const PdbIndex &index, const LocalVariableAddrRange &range,
37               llvm::ArrayRef<LocalVariableAddrGap> gaps) {
38   lldb::addr_t start =
39       index.MakeVirtualAddress(range.ISectStart, range.OffsetStart);
40   if (start == LLDB_INVALID_ADDRESS)
41     return {};
42   lldb::addr_t end = start + range.Range;
43 
44   Variable::RangeList result;
45   while (!gaps.empty()) {
46     const LocalVariableAddrGap &gap = gaps.front();
47     lldb::addr_t gap_start = start + gap.GapStartOffset;
48     result.Append(start, gap_start - start);
49     start = gap_start + gap.Range;
50     gaps = gaps.drop_front();
51   }
52 
53   result.Append(start, end - start);
54   return result;
55 }
56 
57 namespace {
58 struct MemberLocations {
59   std::map<uint64_t, MemberValLocation> offset_to_location;
60   DWARFExpression expr;
61   bool is_dwarf = false;
62 
63   MemberLocations() = default;
64   MemberLocations(const DWARFExpression &expr) : expr(expr), is_dwarf(true) {}
65   MemberLocations(uint64_t offset, const MemberValLocation &member_loc) {
66     insert(offset, member_loc);
67   }
68 
69   void insert(uint64_t offset, const MemberValLocation &member_loc) {
70     offset_to_location[offset] = member_loc;
71   }
72 
73   struct Comparator {
74   public:
75     bool operator()(const MemberLocations &, const MemberLocations &) const {
76       return false;
77     }
78   };
79 };
80 
81 // A range map with address ranges to a map of pair of offset and locaitons.
82 typedef RangeDataVector<lldb::addr_t, lldb::addr_t, MemberLocations, 0,
83                         MemberLocations::Comparator>
84     RangeMap;
85 
86 void AddMemberLocationRanges(RangeMap &location_map, uint64_t offset,
87                              MemberValLocation member_loc,
88                              const Variable::RangeList &ranges) {
89   RangeMap new_location_map;
90   auto add_overlap_region = [&](lldb::addr_t base, lldb::addr_t end,
91                                 RangeMap::Entry *entry) {
92     RangeMap::Entry overlap_region = {base, end - base, entry->data};
93     overlap_region.data.insert(offset, member_loc);
94     new_location_map.Append(overlap_region);
95   };
96 
97   for (const auto &range : ranges) {
98     lldb::addr_t base = range.GetRangeBase();
99     lldb::addr_t end = range.GetRangeEnd();
100     uint32_t base_idx = location_map.FindEntryIndexThatContainsOrFollows(base);
101     while (auto *entry = location_map.GetMutableEntryAtIndex(base_idx)) {
102       if (base >= end || entry->base >= end)
103         break;
104       if (entry->data.is_dwarf)
105         base = entry->GetRangeEnd();
106       else {
107         lldb::addr_t entry_end = entry->GetRangeEnd();
108         if (base > entry->base) {
109           if (end < entry_end)
110             new_location_map.Append({end, entry_end - end, entry->data});
111           add_overlap_region(base, end < entry_end ? end : entry_end, entry);
112           entry->SetRangeEnd(base);
113         } else if (base < entry->base) {
114           new_location_map.Append(
115               {base, entry->base - base, {offset, member_loc}});
116           if (entry_end == end)
117             entry->data.insert(offset, member_loc);
118           else {
119             add_overlap_region(entry->base, end, entry);
120             entry->ShrinkFront(end - entry->base);
121           }
122         } else {
123           if (end < entry_end) {
124             new_location_map.Append({end, entry_end, entry->data});
125             entry->SetRangeEnd(end);
126           }
127           entry->data.insert(offset, member_loc);
128         }
129         base = entry_end;
130       }
131       ++base_idx;
132     }
133     if (base >= end)
134       continue;
135     new_location_map.Append({base, end - base, {offset, member_loc}});
136   }
137   for (const auto &entry : new_location_map)
138     location_map.Append(entry);
139   if (!new_location_map.IsEmpty())
140     location_map.Sort();
141 }
142 
143 void AddDwarfRange(RangeMap &location_map, const DWARFExpression &expr,
144                    const Variable::RangeList &ranges) {
145   if (!expr.IsValid())
146     return;
147   RangeMap new_location_map;
148   for (const auto &range : ranges) {
149     lldb::addr_t base = range.GetRangeBase();
150     lldb::addr_t end = range.GetRangeEnd();
151     uint32_t base_idx = location_map.FindEntryIndexThatContains(base);
152     uint32_t end_idx = location_map.FindEntryIndexThatContains(end - 1);
153     // range is within an entry.
154     if (base_idx == end_idx && base_idx != UINT32_MAX) {
155       auto *entry = location_map.GetMutableEntryAtIndex(base_idx);
156       if (base > entry->base) {
157         new_location_map.Append({entry->base, base - entry->base, entry->data});
158         entry->ShrinkFront(base - entry->base);
159       }
160       if (end == entry->GetRangeEnd())
161         entry->data = expr;
162       else {
163         entry->ShrinkFront(end - base);
164         new_location_map.Append({base, end - base, expr});
165       }
166       continue;
167     }
168     base_idx = location_map.FindEntryIndexThatContainsOrFollows(base);
169     if (auto *entry = location_map.GetMutableEntryAtIndex(base_idx)) {
170       if (entry->Contains(base) && entry->base != base) {
171         entry->SetRangeEnd(base);
172         ++base_idx;
173       }
174     }
175     end_idx = location_map.FindEntryIndexThatContainsOrFollows(end - 1);
176     if (auto *entry = location_map.GetMutableEntryAtIndex(end_idx)) {
177       if (entry->Contains(end - 1)) {
178         if (entry->GetRangeEnd() == end)
179           ++end_idx;
180         else
181           entry->ShrinkFront(end - entry->base);
182       }
183     }
184 
185     if (end_idx == UINT32_MAX)
186       end_idx = location_map.GetSize();
187     // Erase existing ranges covered by new range.
188     location_map.Erase(base_idx, end_idx);
189     new_location_map.Append({base, end - base, expr});
190   }
191 
192   for (const auto &entry : new_location_map)
193     location_map.Append(entry);
194   location_map.Sort();
195 }
196 } // namespace
197 
198 CVTagRecord CVTagRecord::create(CVType type) {
199   assert(IsTagRecord(type) && "type is not a tag record!");
200   switch (type.kind()) {
201   case LF_CLASS:
202   case LF_STRUCTURE:
203   case LF_INTERFACE: {
204     ClassRecord cr;
205     llvm::cantFail(TypeDeserializer::deserializeAs<ClassRecord>(type, cr));
206     return CVTagRecord(std::move(cr));
207   }
208   case LF_UNION: {
209     UnionRecord ur;
210     llvm::cantFail(TypeDeserializer::deserializeAs<UnionRecord>(type, ur));
211     return CVTagRecord(std::move(ur));
212   }
213   case LF_ENUM: {
214     EnumRecord er;
215     llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(type, er));
216     return CVTagRecord(std::move(er));
217   }
218   default:
219     llvm_unreachable("Unreachable!");
220   }
221 }
222 
223 CVTagRecord::CVTagRecord(ClassRecord &&c)
224     : cvclass(std::move(c)),
225       m_kind(cvclass.Kind == TypeRecordKind::Struct ? Struct : Class) {}
226 CVTagRecord::CVTagRecord(UnionRecord &&u)
227     : cvunion(std::move(u)), m_kind(Union) {}
228 CVTagRecord::CVTagRecord(EnumRecord &&e) : cvenum(std::move(e)), m_kind(Enum) {}
229 
230 PDB_SymType lldb_private::npdb::CVSymToPDBSym(SymbolKind kind) {
231   switch (kind) {
232   case S_COMPILE3:
233   case S_OBJNAME:
234     return PDB_SymType::CompilandDetails;
235   case S_ENVBLOCK:
236     return PDB_SymType::CompilandEnv;
237   case S_THUNK32:
238   case S_TRAMPOLINE:
239     return PDB_SymType::Thunk;
240   case S_COFFGROUP:
241     return PDB_SymType::CoffGroup;
242   case S_EXPORT:
243     return PDB_SymType::Export;
244   case S_LPROC32:
245   case S_GPROC32:
246   case S_LPROC32_DPC:
247     return PDB_SymType::Function;
248   case S_PUB32:
249     return PDB_SymType::PublicSymbol;
250   case S_INLINESITE:
251     return PDB_SymType::InlineSite;
252   case S_LOCAL:
253   case S_BPREL32:
254   case S_REGREL32:
255   case S_MANCONSTANT:
256   case S_CONSTANT:
257   case S_LDATA32:
258   case S_GDATA32:
259   case S_LMANDATA:
260   case S_GMANDATA:
261   case S_LTHREAD32:
262   case S_GTHREAD32:
263     return PDB_SymType::Data;
264   case S_BLOCK32:
265     return PDB_SymType::Block;
266   case S_LABEL32:
267     return PDB_SymType::Label;
268   case S_CALLSITEINFO:
269     return PDB_SymType::CallSite;
270   case S_HEAPALLOCSITE:
271     return PDB_SymType::HeapAllocationSite;
272   case S_CALLEES:
273     return PDB_SymType::Callee;
274   case S_CALLERS:
275     return PDB_SymType::Caller;
276   default:
277     lldbassert(false && "Invalid symbol record kind!");
278   }
279   return PDB_SymType::None;
280 }
281 
282 PDB_SymType lldb_private::npdb::CVTypeToPDBType(TypeLeafKind kind) {
283   switch (kind) {
284   case LF_ARRAY:
285     return PDB_SymType::ArrayType;
286   case LF_ARGLIST:
287     return PDB_SymType::FunctionSig;
288   case LF_BCLASS:
289     return PDB_SymType::BaseClass;
290   case LF_BINTERFACE:
291     return PDB_SymType::BaseInterface;
292   case LF_CLASS:
293   case LF_STRUCTURE:
294   case LF_INTERFACE:
295   case LF_UNION:
296     return PDB_SymType::UDT;
297   case LF_POINTER:
298     return PDB_SymType::PointerType;
299   case LF_ENUM:
300     return PDB_SymType::Enum;
301   case LF_PROCEDURE:
302     return PDB_SymType::FunctionSig;
303   case LF_BITFIELD:
304     return PDB_SymType::BuiltinType;
305   default:
306     lldbassert(false && "Invalid type record kind!");
307   }
308   return PDB_SymType::None;
309 }
310 
311 bool lldb_private::npdb::SymbolHasAddress(const CVSymbol &sym) {
312   switch (sym.kind()) {
313   case S_GPROC32:
314   case S_LPROC32:
315   case S_GPROC32_ID:
316   case S_LPROC32_ID:
317   case S_LPROC32_DPC:
318   case S_LPROC32_DPC_ID:
319   case S_THUNK32:
320   case S_TRAMPOLINE:
321   case S_COFFGROUP:
322   case S_BLOCK32:
323   case S_LABEL32:
324   case S_CALLSITEINFO:
325   case S_HEAPALLOCSITE:
326   case S_LDATA32:
327   case S_GDATA32:
328   case S_LMANDATA:
329   case S_GMANDATA:
330   case S_LTHREAD32:
331   case S_GTHREAD32:
332     return true;
333   default:
334     return false;
335   }
336 }
337 
338 bool lldb_private::npdb::SymbolIsCode(const CVSymbol &sym) {
339   switch (sym.kind()) {
340   case S_GPROC32:
341   case S_LPROC32:
342   case S_GPROC32_ID:
343   case S_LPROC32_ID:
344   case S_LPROC32_DPC:
345   case S_LPROC32_DPC_ID:
346   case S_THUNK32:
347   case S_TRAMPOLINE:
348   case S_COFFGROUP:
349   case S_BLOCK32:
350     return true;
351   default:
352     return false;
353   }
354 }
355 
356 template <typename RecordT> RecordT createRecord(const CVSymbol &sym) {
357   RecordT record(static_cast<SymbolRecordKind>(sym.kind()));
358   cantFail(SymbolDeserializer::deserializeAs<RecordT>(sym, record));
359   return record;
360 }
361 
362 template <typename RecordT>
363 static SegmentOffset GetSegmentAndOffset(const CVSymbol &sym) {
364   RecordT record = createRecord<RecordT>(sym);
365   return {record.Segment, record.CodeOffset};
366 }
367 
368 template <>
369 SegmentOffset GetSegmentAndOffset<TrampolineSym>(const CVSymbol &sym) {
370   TrampolineSym record = createRecord<TrampolineSym>(sym);
371   return {record.ThunkSection, record.ThunkOffset};
372 }
373 
374 template <> SegmentOffset GetSegmentAndOffset<Thunk32Sym>(const CVSymbol &sym) {
375   Thunk32Sym record = createRecord<Thunk32Sym>(sym);
376   return {record.Segment, record.Offset};
377 }
378 
379 template <>
380 SegmentOffset GetSegmentAndOffset<CoffGroupSym>(const CVSymbol &sym) {
381   CoffGroupSym record = createRecord<CoffGroupSym>(sym);
382   return {record.Segment, record.Offset};
383 }
384 
385 template <> SegmentOffset GetSegmentAndOffset<DataSym>(const CVSymbol &sym) {
386   DataSym record = createRecord<DataSym>(sym);
387   return {record.Segment, record.DataOffset};
388 }
389 
390 template <>
391 SegmentOffset GetSegmentAndOffset<ThreadLocalDataSym>(const CVSymbol &sym) {
392   ThreadLocalDataSym record = createRecord<ThreadLocalDataSym>(sym);
393   return {record.Segment, record.DataOffset};
394 }
395 
396 SegmentOffset lldb_private::npdb::GetSegmentAndOffset(const CVSymbol &sym) {
397   switch (sym.kind()) {
398   case S_GPROC32:
399   case S_LPROC32:
400   case S_GPROC32_ID:
401   case S_LPROC32_ID:
402   case S_LPROC32_DPC:
403   case S_LPROC32_DPC_ID:
404     return ::GetSegmentAndOffset<ProcSym>(sym);
405   case S_THUNK32:
406     return ::GetSegmentAndOffset<Thunk32Sym>(sym);
407     break;
408   case S_TRAMPOLINE:
409     return ::GetSegmentAndOffset<TrampolineSym>(sym);
410     break;
411   case S_COFFGROUP:
412     return ::GetSegmentAndOffset<CoffGroupSym>(sym);
413     break;
414   case S_BLOCK32:
415     return ::GetSegmentAndOffset<BlockSym>(sym);
416     break;
417   case S_LABEL32:
418     return ::GetSegmentAndOffset<LabelSym>(sym);
419     break;
420   case S_CALLSITEINFO:
421     return ::GetSegmentAndOffset<CallSiteInfoSym>(sym);
422     break;
423   case S_HEAPALLOCSITE:
424     return ::GetSegmentAndOffset<HeapAllocationSiteSym>(sym);
425     break;
426   case S_LDATA32:
427   case S_GDATA32:
428   case S_LMANDATA:
429   case S_GMANDATA:
430     return ::GetSegmentAndOffset<DataSym>(sym);
431     break;
432   case S_LTHREAD32:
433   case S_GTHREAD32:
434     return ::GetSegmentAndOffset<ThreadLocalDataSym>(sym);
435     break;
436   default:
437     lldbassert(false && "Record does not have a segment/offset!");
438   }
439   return {0, 0};
440 }
441 
442 template <typename RecordT>
443 SegmentOffsetLength GetSegmentOffsetAndLength(const CVSymbol &sym) {
444   RecordT record = createRecord<RecordT>(sym);
445   return {record.Segment, record.CodeOffset, record.CodeSize};
446 }
447 
448 template <>
449 SegmentOffsetLength
450 GetSegmentOffsetAndLength<TrampolineSym>(const CVSymbol &sym) {
451   TrampolineSym record = createRecord<TrampolineSym>(sym);
452   return {record.ThunkSection, record.ThunkOffset, record.Size};
453 }
454 
455 template <>
456 SegmentOffsetLength GetSegmentOffsetAndLength<Thunk32Sym>(const CVSymbol &sym) {
457   Thunk32Sym record = createRecord<Thunk32Sym>(sym);
458   return SegmentOffsetLength{record.Segment, record.Offset, record.Length};
459 }
460 
461 template <>
462 SegmentOffsetLength
463 GetSegmentOffsetAndLength<CoffGroupSym>(const CVSymbol &sym) {
464   CoffGroupSym record = createRecord<CoffGroupSym>(sym);
465   return SegmentOffsetLength{record.Segment, record.Offset, record.Size};
466 }
467 
468 SegmentOffsetLength
469 lldb_private::npdb::GetSegmentOffsetAndLength(const CVSymbol &sym) {
470   switch (sym.kind()) {
471   case S_GPROC32:
472   case S_LPROC32:
473   case S_GPROC32_ID:
474   case S_LPROC32_ID:
475   case S_LPROC32_DPC:
476   case S_LPROC32_DPC_ID:
477     return ::GetSegmentOffsetAndLength<ProcSym>(sym);
478   case S_THUNK32:
479     return ::GetSegmentOffsetAndLength<Thunk32Sym>(sym);
480     break;
481   case S_TRAMPOLINE:
482     return ::GetSegmentOffsetAndLength<TrampolineSym>(sym);
483     break;
484   case S_COFFGROUP:
485     return ::GetSegmentOffsetAndLength<CoffGroupSym>(sym);
486     break;
487   case S_BLOCK32:
488     return ::GetSegmentOffsetAndLength<BlockSym>(sym);
489     break;
490   default:
491     lldbassert(false && "Record does not have a segment/offset/length triple!");
492   }
493   return {0, 0, 0};
494 }
495 
496 bool lldb_private::npdb::IsForwardRefUdt(CVType cvt) {
497   ClassRecord cr;
498   UnionRecord ur;
499   EnumRecord er;
500   switch (cvt.kind()) {
501   case LF_CLASS:
502   case LF_STRUCTURE:
503   case LF_INTERFACE:
504     llvm::cantFail(TypeDeserializer::deserializeAs<ClassRecord>(cvt, cr));
505     return cr.isForwardRef();
506   case LF_UNION:
507     llvm::cantFail(TypeDeserializer::deserializeAs<UnionRecord>(cvt, ur));
508     return ur.isForwardRef();
509   case LF_ENUM:
510     llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er));
511     return er.isForwardRef();
512   default:
513     return false;
514   }
515 }
516 
517 bool lldb_private::npdb::IsTagRecord(llvm::codeview::CVType cvt) {
518   switch (cvt.kind()) {
519   case LF_CLASS:
520   case LF_STRUCTURE:
521   case LF_UNION:
522   case LF_ENUM:
523     return true;
524   default:
525     return false;
526   }
527 }
528 
529 bool lldb_private::npdb::IsClassStructUnion(llvm::codeview::CVType cvt) {
530   switch (cvt.kind()) {
531   case LF_CLASS:
532   case LF_STRUCTURE:
533   case LF_UNION:
534     return true;
535   default:
536     return false;
537   }
538 }
539 
540 bool lldb_private::npdb::IsForwardRefUdt(const PdbTypeSymId &id,
541                                          TpiStream &tpi) {
542   if (id.is_ipi || id.index.isSimple())
543     return false;
544   return IsForwardRefUdt(tpi.getType(id.index));
545 }
546 
547 bool lldb_private::npdb::IsTagRecord(const PdbTypeSymId &id, TpiStream &tpi) {
548   if (id.is_ipi || id.index.isSimple())
549     return false;
550   return IsTagRecord(tpi.getType(id.index));
551 }
552 
553 lldb::AccessType
554 lldb_private::npdb::TranslateMemberAccess(MemberAccess access) {
555   switch (access) {
556   case MemberAccess::Private:
557     return lldb::eAccessPrivate;
558   case MemberAccess::Protected:
559     return lldb::eAccessProtected;
560   case MemberAccess::Public:
561     return lldb::eAccessPublic;
562   case MemberAccess::None:
563     return lldb::eAccessNone;
564   }
565   llvm_unreachable("unreachable");
566 }
567 
568 TypeIndex lldb_private::npdb::GetFieldListIndex(CVType cvt) {
569   switch (cvt.kind()) {
570   case LF_CLASS:
571   case LF_STRUCTURE:
572   case LF_INTERFACE: {
573     ClassRecord cr;
574     cantFail(TypeDeserializer::deserializeAs<ClassRecord>(cvt, cr));
575     return cr.FieldList;
576   }
577   case LF_UNION: {
578     UnionRecord ur;
579     cantFail(TypeDeserializer::deserializeAs<UnionRecord>(cvt, ur));
580     return ur.FieldList;
581   }
582   case LF_ENUM: {
583     EnumRecord er;
584     cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er));
585     return er.FieldList;
586   }
587   default:
588     llvm_unreachable("Unreachable!");
589   }
590 }
591 
592 TypeIndex lldb_private::npdb::LookThroughModifierRecord(CVType modifier) {
593   lldbassert(modifier.kind() == LF_MODIFIER);
594   ModifierRecord mr;
595   llvm::cantFail(TypeDeserializer::deserializeAs<ModifierRecord>(modifier, mr));
596   return mr.ModifiedType;
597 }
598 
599 llvm::StringRef lldb_private::npdb::DropNameScope(llvm::StringRef name) {
600   return MSVCUndecoratedNameParser::DropScope(name);
601 }
602 
603 VariableInfo lldb_private::npdb::GetVariableNameInfo(CVSymbol sym) {
604   VariableInfo result = {};
605 
606   if (sym.kind() == S_REGREL32) {
607     RegRelativeSym reg(SymbolRecordKind::RegRelativeSym);
608     cantFail(SymbolDeserializer::deserializeAs<RegRelativeSym>(sym, reg));
609     result.type = reg.Type;
610     result.name = reg.Name;
611     return result;
612   }
613 
614   if (sym.kind() == S_REGISTER) {
615     RegisterSym reg(SymbolRecordKind::RegisterSym);
616     cantFail(SymbolDeserializer::deserializeAs<RegisterSym>(sym, reg));
617     result.type = reg.Index;
618     result.name = reg.Name;
619     return result;
620   }
621 
622   if (sym.kind() == S_LOCAL) {
623     LocalSym local(SymbolRecordKind::LocalSym);
624     cantFail(SymbolDeserializer::deserializeAs<LocalSym>(sym, local));
625     result.type = local.Type;
626     result.name = local.Name;
627     result.is_param =
628         ((local.Flags & LocalSymFlags::IsParameter) != LocalSymFlags::None);
629     return result;
630   }
631 
632   if (sym.kind() == S_GDATA32 || sym.kind() == S_LDATA32) {
633     DataSym data(SymbolRecordKind::DataSym);
634     cantFail(SymbolDeserializer::deserializeAs<DataSym>(sym, data));
635     result.type = data.Type;
636     result.name = data.Name;
637     return result;
638   }
639 
640   if (sym.kind() == S_GTHREAD32 || sym.kind() == S_LTHREAD32) {
641     ThreadLocalDataSym data(SymbolRecordKind::ThreadLocalDataSym);
642     cantFail(SymbolDeserializer::deserializeAs<ThreadLocalDataSym>(sym, data));
643     result.type = data.Type;
644     result.name = data.Name;
645     return result;
646   }
647 
648   if (sym.kind() == S_CONSTANT) {
649     ConstantSym constant(SymbolRecordKind::ConstantSym);
650     cantFail(SymbolDeserializer::deserializeAs<ConstantSym>(sym, constant));
651     result.type = constant.Type;
652     result.name = constant.Name;
653     return result;
654   }
655 
656   lldbassert(false && "Invalid variable record kind!");
657   return {};
658 }
659 
660 static llvm::FixedStreamArray<FrameData>::Iterator
661 GetCorrespondingFrameData(lldb::addr_t load_addr,
662                           const DebugFrameDataSubsectionRef &fpo_data,
663                           const Variable::RangeList &ranges) {
664   lldbassert(!ranges.IsEmpty());
665 
666   // assume that all variable ranges correspond to one frame data
667   using RangeListEntry = Variable::RangeList::Entry;
668   const RangeListEntry &range = ranges.GetEntryRef(0);
669 
670   auto it = fpo_data.begin();
671 
672   // start by searching first frame data range containing variable range
673   for (; it != fpo_data.end(); ++it) {
674     RangeListEntry fd_range(load_addr + it->RvaStart, it->CodeSize);
675 
676     if (fd_range.Contains(range)) {
677       break;
678     }
679   }
680 
681   // then first most nested entry that still contains variable range
682   auto found = it;
683   for (; it != fpo_data.end(); ++it) {
684     RangeListEntry fd_range(load_addr + it->RvaStart, it->CodeSize);
685 
686     if (!fd_range.Contains(range)) {
687       break;
688     }
689     found = it;
690   }
691 
692   return found;
693 }
694 
695 static bool GetFrameDataProgram(PdbIndex &index,
696                                 const Variable::RangeList &ranges,
697                                 llvm::StringRef &out_program) {
698   const DebugFrameDataSubsectionRef &new_fpo_data =
699       index.dbi().getNewFpoRecords();
700 
701   auto frame_data_it =
702       GetCorrespondingFrameData(index.GetLoadAddress(), new_fpo_data, ranges);
703   if (frame_data_it == new_fpo_data.end())
704     return false;
705 
706   PDBStringTable &strings = cantFail(index.pdb().getStringTable());
707   out_program = cantFail(strings.getStringForID(frame_data_it->FrameFunc));
708   return true;
709 }
710 
711 static RegisterId GetBaseFrameRegister(PdbIndex &index,
712                                        PdbCompilandSymId frame_proc_id,
713                                        bool is_parameter) {
714   CVSymbol frame_proc_cvs = index.ReadSymbolRecord(frame_proc_id);
715   if (frame_proc_cvs.kind() != S_FRAMEPROC)
716     return RegisterId::NONE;
717 
718   FrameProcSym frame_proc(SymbolRecordKind::FrameProcSym);
719   cantFail(SymbolDeserializer::deserializeAs<FrameProcSym>(frame_proc_cvs,
720                                                            frame_proc));
721 
722   CPUType cpu_type = index.compilands()
723                          .GetCompiland(frame_proc_id.modi)
724                          ->m_compile_opts->Machine;
725 
726   return is_parameter ? frame_proc.getParamFramePtrReg(cpu_type)
727                       : frame_proc.getLocalFramePtrReg(cpu_type);
728 }
729 
730 VariableInfo lldb_private::npdb::GetVariableLocationInfo(
731     PdbIndex &index, PdbCompilandSymId var_id, Block &func_block,
732     lldb::ModuleSP module) {
733 
734   CVSymbol sym = index.ReadSymbolRecord(var_id);
735 
736   VariableInfo result = GetVariableNameInfo(sym);
737 
738   if (sym.kind() == S_REGREL32) {
739     RegRelativeSym reg(SymbolRecordKind::RegRelativeSym);
740     cantFail(SymbolDeserializer::deserializeAs<RegRelativeSym>(sym, reg));
741     result.location = DWARFExpressionList(
742         module, MakeRegRelLocationExpression(reg.Register, reg.Offset, module),
743         nullptr);
744     return result;
745   }
746 
747   if (sym.kind() == S_REGISTER) {
748     RegisterSym reg(SymbolRecordKind::RegisterSym);
749     cantFail(SymbolDeserializer::deserializeAs<RegisterSym>(sym, reg));
750     result.location = DWARFExpressionList(
751         module, MakeEnregisteredLocationExpression(reg.Register, module),
752         nullptr);
753     return result;
754   }
755 
756   if (sym.kind() == S_LOCAL) {
757     LocalSym local(SymbolRecordKind::LocalSym);
758     if (llvm::Error error =
759             SymbolDeserializer::deserializeAs<LocalSym>(sym, local)) {
760       llvm::consumeError(std::move(error));
761       return result;
762     }
763 
764     PdbCompilandSymId loc_specifier_id(var_id.modi,
765                                        var_id.offset + sym.RecordData.size());
766     CVSymbol loc_specifier_cvs;
767     // Only used for S_DEFRANGE_FRAMEPOINTER_REL.
768     RegisterId base_reg = RegisterId::NONE;
769     size_t type_size = GetSizeOfType(result.type, index.tpi());
770     // A map from offset of a field in parent to size of the field.
771     std::map<uint64_t, size_t> offset_to_size;
772 
773     // When overlaps happens, always prefer the one that doesn't split the value
774     // into multiple locations and the location parsed first is perfered.
775     RangeMap location_map;
776 
777     // Iterate through all location records after S_LOCAL. They describe the
778     // value of this variable at different locations.
779     bool finished = false;
780     while (!finished) {
781       loc_specifier_cvs = index.ReadSymbolRecord(loc_specifier_id);
782       switch (loc_specifier_cvs.kind()) {
783       case S_DEFRANGE_FRAMEPOINTER_REL: {
784         DefRangeFramePointerRelSym loc(
785             SymbolRecordKind::DefRangeFramePointerRelSym);
786         if (llvm::Error error =
787                 SymbolDeserializer::deserializeAs<DefRangeFramePointerRelSym>(
788                     loc_specifier_cvs, loc)) {
789           llvm::consumeError(std::move(error));
790           return result;
791         }
792         Variable::RangeList raw_ranges =
793             MakeRangeList(index, loc.Range, loc.Gaps);
794         if (base_reg == RegisterId::NONE) {
795           PdbCompilandSymId func_scope_id =
796               PdbSymUid(func_block.GetID()).asCompilandSym();
797           CVSymbol func_block_cvs = index.ReadSymbolRecord(func_scope_id);
798           lldbassert(func_block_cvs.kind() == S_GPROC32 ||
799                      func_block_cvs.kind() == S_LPROC32);
800           PdbCompilandSymId frame_proc_id(func_scope_id.modi,
801                                           func_scope_id.offset +
802                                               func_block_cvs.length());
803           base_reg =
804               GetBaseFrameRegister(index, frame_proc_id, result.is_param);
805           if (base_reg == RegisterId::NONE)
806             break;
807         }
808         DWARFExpression expr;
809         if (base_reg == RegisterId::VFRAME) {
810           llvm::StringRef program;
811           if (GetFrameDataProgram(index, raw_ranges, program))
812             expr = MakeVFrameRelLocationExpression(program, loc.Hdr.Offset,
813                                                    module);
814           else {
815             // invalid variable
816           }
817         } else
818           expr = MakeRegRelLocationExpression(base_reg, loc.Hdr.Offset, module);
819         AddDwarfRange(location_map, expr, raw_ranges);
820         break;
821       }
822       case S_DEFRANGE_REGISTER: {
823         DefRangeRegisterSym loc(SymbolRecordKind::DefRangeRegisterSym);
824         if (llvm::Error error =
825                 SymbolDeserializer::deserializeAs<DefRangeRegisterSym>(
826                     loc_specifier_cvs, loc)) {
827           llvm::consumeError(std::move(error));
828           return result;
829         }
830         RegisterId reg_id = (RegisterId)(uint16_t)loc.Hdr.Register;
831         Variable::RangeList raw_ranges =
832             MakeRangeList(index, loc.Range, loc.Gaps);
833         DWARFExpression expr =
834             MakeEnregisteredLocationExpression(reg_id, module);
835         AddDwarfRange(location_map, expr, raw_ranges);
836         break;
837       }
838       case S_DEFRANGE_REGISTER_REL: {
839         DefRangeRegisterRelSym loc(SymbolRecordKind::DefRangeRegisterRelSym);
840         if (llvm::Error error =
841                 SymbolDeserializer::deserializeAs<DefRangeRegisterRelSym>(
842                     loc_specifier_cvs, loc)) {
843           llvm::consumeError(std::move(error));
844           return result;
845         }
846         Variable::RangeList raw_ranges =
847             MakeRangeList(index, loc.Range, loc.Gaps);
848         RegisterId reg_id = (RegisterId)(uint16_t)loc.Hdr.Register;
849         DWARFExpression expr;
850         if (reg_id == RegisterId::VFRAME) {
851           llvm::StringRef program;
852           if (GetFrameDataProgram(index, raw_ranges, program))
853             expr = MakeVFrameRelLocationExpression(
854                 program, loc.Hdr.BasePointerOffset, module);
855           else {
856             // invalid variable
857           }
858         } else {
859           expr = MakeRegRelLocationExpression(reg_id, loc.Hdr.BasePointerOffset,
860                                               module);
861         }
862         // FIXME: If it's UDT, we need to know the size of the value in byte.
863         if (!loc.hasSpilledUDTMember())
864           AddDwarfRange(location_map, expr, raw_ranges);
865         break;
866       }
867       case S_DEFRANGE_SUBFIELD_REGISTER: {
868         DefRangeSubfieldRegisterSym loc(
869             SymbolRecordKind::DefRangeSubfieldRegisterSym);
870         if (llvm::Error error =
871                 SymbolDeserializer::deserializeAs<DefRangeSubfieldRegisterSym>(
872                     loc_specifier_cvs, loc)) {
873           llvm::consumeError(std::move(error));
874           return result;
875         }
876 
877         Variable::RangeList ranges = MakeRangeList(index, loc.Range, loc.Gaps);
878         uint32_t reg_size =
879             GetRegisterSize((RegisterId)(uint16_t)loc.Hdr.Register);
880         if (reg_size == 0)
881           break;
882         offset_to_size[loc.Hdr.OffsetInParent] = reg_size;
883         AddMemberLocationRanges(location_map, loc.Hdr.OffsetInParent,
884                                 {loc.Hdr.Register, 0, true}, ranges);
885         break;
886       }
887       // FIXME: Handle other kinds. LLVM only generates the 4 types of records
888       // above. MSVC generates other location types.
889       case S_DEFRANGE:
890       case S_DEFRANGE_SUBFIELD:
891       case S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE:
892         break;
893       default:
894         finished = true;
895         break;
896       }
897       loc_specifier_id = PdbCompilandSymId(
898           loc_specifier_id.modi,
899           loc_specifier_id.offset + loc_specifier_cvs.RecordData.size());
900     }
901     for (const auto &entry : location_map) {
902       DWARFExpression dwarf_expr =
903           entry.data.is_dwarf ? entry.data.expr
904                               : MakeEnregisteredLocationExpressionForComposite(
905                                     entry.data.offset_to_location,
906                                     offset_to_size, type_size, module);
907 
908       result.location.AddExpression(entry.GetRangeBase(), entry.GetRangeEnd(),
909                                      dwarf_expr);
910     }
911     return result;
912   }
913   llvm_unreachable("Symbol is not a local variable!");
914   return result;
915 }
916 
917 lldb::BasicType
918 lldb_private::npdb::GetCompilerTypeForSimpleKind(SimpleTypeKind kind) {
919   switch (kind) {
920   case SimpleTypeKind::Boolean128:
921   case SimpleTypeKind::Boolean16:
922   case SimpleTypeKind::Boolean32:
923   case SimpleTypeKind::Boolean64:
924   case SimpleTypeKind::Boolean8:
925     return lldb::eBasicTypeBool;
926   case SimpleTypeKind::Byte:
927   case SimpleTypeKind::UnsignedCharacter:
928     return lldb::eBasicTypeUnsignedChar;
929   case SimpleTypeKind::NarrowCharacter:
930     return lldb::eBasicTypeChar;
931   case SimpleTypeKind::SignedCharacter:
932   case SimpleTypeKind::SByte:
933     return lldb::eBasicTypeSignedChar;
934   case SimpleTypeKind::Character16:
935     return lldb::eBasicTypeChar16;
936   case SimpleTypeKind::Character32:
937     return lldb::eBasicTypeChar32;
938   case SimpleTypeKind::Character8:
939     return lldb::eBasicTypeChar8;
940   case SimpleTypeKind::Complex80:
941     return lldb::eBasicTypeLongDoubleComplex;
942   case SimpleTypeKind::Complex64:
943     return lldb::eBasicTypeDoubleComplex;
944   case SimpleTypeKind::Complex32:
945     return lldb::eBasicTypeFloatComplex;
946   case SimpleTypeKind::Float128:
947   case SimpleTypeKind::Float80:
948     return lldb::eBasicTypeLongDouble;
949   case SimpleTypeKind::Float64:
950     return lldb::eBasicTypeDouble;
951   case SimpleTypeKind::Float32:
952     return lldb::eBasicTypeFloat;
953   case SimpleTypeKind::Float16:
954     return lldb::eBasicTypeHalf;
955   case SimpleTypeKind::Int128:
956     return lldb::eBasicTypeInt128;
957   case SimpleTypeKind::Int64:
958   case SimpleTypeKind::Int64Quad:
959     return lldb::eBasicTypeLongLong;
960   case SimpleTypeKind::Int32:
961     return lldb::eBasicTypeInt;
962   case SimpleTypeKind::Int16:
963   case SimpleTypeKind::Int16Short:
964     return lldb::eBasicTypeShort;
965   case SimpleTypeKind::UInt128:
966     return lldb::eBasicTypeUnsignedInt128;
967   case SimpleTypeKind::UInt64:
968   case SimpleTypeKind::UInt64Quad:
969     return lldb::eBasicTypeUnsignedLongLong;
970   case SimpleTypeKind::HResult:
971   case SimpleTypeKind::UInt32:
972     return lldb::eBasicTypeUnsignedInt;
973   case SimpleTypeKind::UInt16:
974   case SimpleTypeKind::UInt16Short:
975     return lldb::eBasicTypeUnsignedShort;
976   case SimpleTypeKind::Int32Long:
977     return lldb::eBasicTypeLong;
978   case SimpleTypeKind::UInt32Long:
979     return lldb::eBasicTypeUnsignedLong;
980   case SimpleTypeKind::Void:
981     return lldb::eBasicTypeVoid;
982   case SimpleTypeKind::WideCharacter:
983     return lldb::eBasicTypeWChar;
984   default:
985     return lldb::eBasicTypeInvalid;
986   }
987 }
988 
989 size_t lldb_private::npdb::GetTypeSizeForSimpleKind(SimpleTypeKind kind) {
990   switch (kind) {
991   case SimpleTypeKind::Boolean128:
992   case SimpleTypeKind::Int128:
993   case SimpleTypeKind::UInt128:
994   case SimpleTypeKind::Float128:
995     return 16;
996   case SimpleTypeKind::Complex80:
997   case SimpleTypeKind::Float80:
998     return 10;
999   case SimpleTypeKind::Boolean64:
1000   case SimpleTypeKind::Complex64:
1001   case SimpleTypeKind::UInt64:
1002   case SimpleTypeKind::UInt64Quad:
1003   case SimpleTypeKind::Float64:
1004   case SimpleTypeKind::Int64:
1005   case SimpleTypeKind::Int64Quad:
1006     return 8;
1007   case SimpleTypeKind::Boolean32:
1008   case SimpleTypeKind::Character32:
1009   case SimpleTypeKind::Complex32:
1010   case SimpleTypeKind::Float32:
1011   case SimpleTypeKind::Int32:
1012   case SimpleTypeKind::Int32Long:
1013   case SimpleTypeKind::UInt32Long:
1014   case SimpleTypeKind::HResult:
1015   case SimpleTypeKind::UInt32:
1016     return 4;
1017   case SimpleTypeKind::Boolean16:
1018   case SimpleTypeKind::Character16:
1019   case SimpleTypeKind::Float16:
1020   case SimpleTypeKind::Int16:
1021   case SimpleTypeKind::Int16Short:
1022   case SimpleTypeKind::UInt16:
1023   case SimpleTypeKind::UInt16Short:
1024   case SimpleTypeKind::WideCharacter:
1025     return 2;
1026   case SimpleTypeKind::Boolean8:
1027   case SimpleTypeKind::Byte:
1028   case SimpleTypeKind::UnsignedCharacter:
1029   case SimpleTypeKind::NarrowCharacter:
1030   case SimpleTypeKind::SignedCharacter:
1031   case SimpleTypeKind::SByte:
1032   case SimpleTypeKind::Character8:
1033     return 1;
1034   case SimpleTypeKind::Void:
1035   default:
1036     return 0;
1037   }
1038 }
1039 
1040 PdbTypeSymId lldb_private::npdb::GetBestPossibleDecl(PdbTypeSymId id,
1041                                                      TpiStream &tpi) {
1042   if (id.index.isSimple())
1043     return id;
1044 
1045   CVType cvt = tpi.getType(id.index);
1046 
1047   // Only tag records have a best and a worst record.
1048   if (!IsTagRecord(cvt))
1049     return id;
1050 
1051   // Tag records that are not forward decls are full decls, hence they are the
1052   // best.
1053   if (!IsForwardRefUdt(cvt))
1054     return id;
1055 
1056   return llvm::cantFail(tpi.findFullDeclForForwardRef(id.index));
1057 }
1058 
1059 template <typename RecordType> static size_t GetSizeOfTypeInternal(CVType cvt) {
1060   RecordType record;
1061   llvm::cantFail(TypeDeserializer::deserializeAs<RecordType>(cvt, record));
1062   return record.getSize();
1063 }
1064 
1065 size_t lldb_private::npdb::GetSizeOfType(PdbTypeSymId id,
1066                                          llvm::pdb::TpiStream &tpi) {
1067   if (id.index.isSimple()) {
1068     switch (id.index.getSimpleMode()) {
1069     case SimpleTypeMode::Direct:
1070       return GetTypeSizeForSimpleKind(id.index.getSimpleKind());
1071     case SimpleTypeMode::NearPointer32:
1072     case SimpleTypeMode::FarPointer32:
1073       return 4;
1074     case SimpleTypeMode::NearPointer64:
1075       return 8;
1076     case SimpleTypeMode::NearPointer128:
1077       return 16;
1078     default:
1079       break;
1080     }
1081     return 0;
1082   }
1083 
1084   TypeIndex index = id.index;
1085   if (IsForwardRefUdt(index, tpi))
1086     index = llvm::cantFail(tpi.findFullDeclForForwardRef(index));
1087 
1088   CVType cvt = tpi.getType(index);
1089   switch (cvt.kind()) {
1090   case LF_MODIFIER:
1091     return GetSizeOfType({LookThroughModifierRecord(cvt)}, tpi);
1092   case LF_ENUM: {
1093     EnumRecord record;
1094     llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, record));
1095     return GetSizeOfType({record.UnderlyingType}, tpi);
1096   }
1097   case LF_POINTER:
1098     return GetSizeOfTypeInternal<PointerRecord>(cvt);
1099   case LF_ARRAY:
1100     return GetSizeOfTypeInternal<ArrayRecord>(cvt);
1101   case LF_CLASS:
1102   case LF_STRUCTURE:
1103   case LF_INTERFACE:
1104     return GetSizeOfTypeInternal<ClassRecord>(cvt);
1105   case LF_UNION:
1106     return GetSizeOfTypeInternal<UnionRecord>(cvt);
1107   case LF_BITFIELD: {
1108     BitFieldRecord record;
1109     llvm::cantFail(TypeDeserializer::deserializeAs<BitFieldRecord>(cvt, record));
1110     return GetSizeOfType({record.Type}, tpi);
1111   }
1112   default:
1113     break;
1114   }
1115   return 0;
1116 }
1117