xref: /freebsd/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
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
MakeRangeList(const PdbIndex & index,const LocalVariableAddrRange & range,llvm::ArrayRef<LocalVariableAddrGap> gaps)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;
MemberLocations__anon16cde6430111::MemberLocations64   MemberLocations(const DWARFExpression &expr) : expr(expr), is_dwarf(true) {}
MemberLocations__anon16cde6430111::MemberLocations65   MemberLocations(uint64_t offset, const MemberValLocation &member_loc) {
66     insert(offset, member_loc);
67   }
68 
insert__anon16cde6430111::MemberLocations69   void insert(uint64_t offset, const MemberValLocation &member_loc) {
70     offset_to_location[offset] = member_loc;
71   }
72 
73   struct Comparator {
74   public:
operator ()__anon16cde6430111::MemberLocations::Comparator75     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 
AddMemberLocationRanges(RangeMap & location_map,uint64_t offset,MemberValLocation member_loc,const Variable::RangeList & ranges)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 
AddDwarfRange(RangeMap & location_map,const DWARFExpression & expr,const Variable::RangeList & ranges)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 
create(CVType type)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 
CVTagRecord(ClassRecord && c)223 CVTagRecord::CVTagRecord(ClassRecord &&c)
224     : cvclass(std::move(c)),
225       m_kind(cvclass.Kind == TypeRecordKind::Struct ? Struct : Class) {}
CVTagRecord(UnionRecord && u)226 CVTagRecord::CVTagRecord(UnionRecord &&u)
227     : cvunion(std::move(u)), m_kind(Union) {}
CVTagRecord(EnumRecord && e)228 CVTagRecord::CVTagRecord(EnumRecord &&e) : cvenum(std::move(e)), m_kind(Enum) {}
229 
CVSymToPDBSym(SymbolKind kind)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 
CVTypeToPDBType(TypeLeafKind kind)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 
SymbolHasAddress(const CVSymbol & sym)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 
SymbolIsCode(const CVSymbol & sym)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 
createRecord(const CVSymbol & sym)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>
GetSegmentAndOffset(const CVSymbol & sym)363 static SegmentOffset GetSegmentAndOffset(const CVSymbol &sym) {
364   RecordT record = createRecord<RecordT>(sym);
365   return {record.Segment, record.CodeOffset};
366 }
367 
368 template <>
GetSegmentAndOffset(const CVSymbol & sym)369 SegmentOffset GetSegmentAndOffset<TrampolineSym>(const CVSymbol &sym) {
370   TrampolineSym record = createRecord<TrampolineSym>(sym);
371   return {record.ThunkSection, record.ThunkOffset};
372 }
373 
GetSegmentAndOffset(const CVSymbol & sym)374 template <> SegmentOffset GetSegmentAndOffset<Thunk32Sym>(const CVSymbol &sym) {
375   Thunk32Sym record = createRecord<Thunk32Sym>(sym);
376   return {record.Segment, record.Offset};
377 }
378 
379 template <>
GetSegmentAndOffset(const CVSymbol & sym)380 SegmentOffset GetSegmentAndOffset<CoffGroupSym>(const CVSymbol &sym) {
381   CoffGroupSym record = createRecord<CoffGroupSym>(sym);
382   return {record.Segment, record.Offset};
383 }
384 
GetSegmentAndOffset(const CVSymbol & sym)385 template <> SegmentOffset GetSegmentAndOffset<DataSym>(const CVSymbol &sym) {
386   DataSym record = createRecord<DataSym>(sym);
387   return {record.Segment, record.DataOffset};
388 }
389 
390 template <>
GetSegmentAndOffset(const CVSymbol & sym)391 SegmentOffset GetSegmentAndOffset<ThreadLocalDataSym>(const CVSymbol &sym) {
392   ThreadLocalDataSym record = createRecord<ThreadLocalDataSym>(sym);
393   return {record.Segment, record.DataOffset};
394 }
395 
GetSegmentAndOffset(const CVSymbol & sym)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>
GetSegmentOffsetAndLength(const CVSymbol & sym)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
GetSegmentOffsetAndLength(const CVSymbol & sym)450 GetSegmentOffsetAndLength<TrampolineSym>(const CVSymbol &sym) {
451   TrampolineSym record = createRecord<TrampolineSym>(sym);
452   return {record.ThunkSection, record.ThunkOffset, record.Size};
453 }
454 
455 template <>
GetSegmentOffsetAndLength(const CVSymbol & sym)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
GetSegmentOffsetAndLength(const CVSymbol & sym)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
GetSegmentOffsetAndLength(const CVSymbol & sym)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 
IsForwardRefUdt(CVType cvt)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 
IsTagRecord(llvm::codeview::CVType cvt)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 
IsClassStructUnion(llvm::codeview::CVType cvt)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 
IsForwardRefUdt(const PdbTypeSymId & id,TpiStream & tpi)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 
IsTagRecord(const PdbTypeSymId & id,TpiStream & tpi)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
TranslateMemberAccess(MemberAccess access)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 
GetFieldListIndex(CVType cvt)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 
LookThroughModifierRecord(CVType modifier)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 
DropNameScope(llvm::StringRef name)599 llvm::StringRef lldb_private::npdb::DropNameScope(llvm::StringRef name) {
600   return MSVCUndecoratedNameParser::DropScope(name);
601 }
602 
GetVariableNameInfo(CVSymbol sym)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
GetCorrespondingFrameData(lldb::addr_t load_addr,const DebugFrameDataSubsectionRef & fpo_data,const Variable::RangeList & ranges)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 
GetFrameDataProgram(PdbIndex & index,const Variable::RangeList & ranges,llvm::StringRef & out_program)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   auto strings = index.pdb().getStringTable();
707   if (!strings) {
708     consumeError(strings.takeError());
709     return false;
710   }
711   out_program = cantFail(strings->getStringForID(frame_data_it->FrameFunc));
712   return true;
713 }
714 
GetBaseFrameRegister(PdbIndex & index,PdbCompilandSymId frame_proc_id,bool is_parameter)715 static RegisterId GetBaseFrameRegister(PdbIndex &index,
716                                        PdbCompilandSymId frame_proc_id,
717                                        bool is_parameter) {
718   CVSymbol frame_proc_cvs = index.ReadSymbolRecord(frame_proc_id);
719   if (frame_proc_cvs.kind() != S_FRAMEPROC)
720     return RegisterId::NONE;
721 
722   FrameProcSym frame_proc(SymbolRecordKind::FrameProcSym);
723   cantFail(SymbolDeserializer::deserializeAs<FrameProcSym>(frame_proc_cvs,
724                                                            frame_proc));
725 
726   CPUType cpu_type = index.compilands()
727                          .GetCompiland(frame_proc_id.modi)
728                          ->m_compile_opts->Machine;
729 
730   return is_parameter ? frame_proc.getParamFramePtrReg(cpu_type)
731                       : frame_proc.getLocalFramePtrReg(cpu_type);
732 }
733 
GetVariableLocationInfo(PdbIndex & index,PdbCompilandSymId var_id,Block & func_block,lldb::ModuleSP module)734 VariableInfo lldb_private::npdb::GetVariableLocationInfo(
735     PdbIndex &index, PdbCompilandSymId var_id, Block &func_block,
736     lldb::ModuleSP module) {
737 
738   CVSymbol sym = index.ReadSymbolRecord(var_id);
739 
740   VariableInfo result = GetVariableNameInfo(sym);
741 
742   if (sym.kind() == S_REGREL32) {
743     RegRelativeSym reg(SymbolRecordKind::RegRelativeSym);
744     cantFail(SymbolDeserializer::deserializeAs<RegRelativeSym>(sym, reg));
745     result.location = DWARFExpressionList(
746         module, MakeRegRelLocationExpression(reg.Register, reg.Offset, module),
747         nullptr);
748     return result;
749   }
750 
751   if (sym.kind() == S_REGISTER) {
752     RegisterSym reg(SymbolRecordKind::RegisterSym);
753     cantFail(SymbolDeserializer::deserializeAs<RegisterSym>(sym, reg));
754     result.location = DWARFExpressionList(
755         module, MakeEnregisteredLocationExpression(reg.Register, module),
756         nullptr);
757     return result;
758   }
759 
760   if (sym.kind() == S_LOCAL) {
761     LocalSym local(SymbolRecordKind::LocalSym);
762     if (llvm::Error error =
763             SymbolDeserializer::deserializeAs<LocalSym>(sym, local)) {
764       llvm::consumeError(std::move(error));
765       return result;
766     }
767 
768     PdbCompilandSymId loc_specifier_id(var_id.modi,
769                                        var_id.offset + sym.RecordData.size());
770     CVSymbol loc_specifier_cvs;
771     // Only used for S_DEFRANGE_FRAMEPOINTER_REL.
772     RegisterId base_reg = RegisterId::NONE;
773     size_t type_size = GetSizeOfType(result.type, index.tpi());
774     // A map from offset of a field in parent to size of the field.
775     std::map<uint64_t, size_t> offset_to_size;
776 
777     // When overlaps happens, always prefer the one that doesn't split the value
778     // into multiple locations and the location parsed first is perfered.
779     RangeMap location_map;
780 
781     // Iterate through all location records after S_LOCAL. They describe the
782     // value of this variable at different locations.
783     bool finished = false;
784     while (!finished) {
785       loc_specifier_cvs = index.ReadSymbolRecord(loc_specifier_id);
786       switch (loc_specifier_cvs.kind()) {
787       case S_DEFRANGE_FRAMEPOINTER_REL: {
788         DefRangeFramePointerRelSym loc(
789             SymbolRecordKind::DefRangeFramePointerRelSym);
790         if (llvm::Error error =
791                 SymbolDeserializer::deserializeAs<DefRangeFramePointerRelSym>(
792                     loc_specifier_cvs, loc)) {
793           llvm::consumeError(std::move(error));
794           return result;
795         }
796         Variable::RangeList raw_ranges =
797             MakeRangeList(index, loc.Range, loc.Gaps);
798         if (base_reg == RegisterId::NONE) {
799           PdbCompilandSymId func_scope_id =
800               PdbSymUid(func_block.GetID()).asCompilandSym();
801           CVSymbol func_block_cvs = index.ReadSymbolRecord(func_scope_id);
802           lldbassert(func_block_cvs.kind() == S_GPROC32 ||
803                      func_block_cvs.kind() == S_LPROC32);
804           PdbCompilandSymId frame_proc_id(func_scope_id.modi,
805                                           func_scope_id.offset +
806                                               func_block_cvs.length());
807           base_reg =
808               GetBaseFrameRegister(index, frame_proc_id, result.is_param);
809           if (base_reg == RegisterId::NONE)
810             break;
811         }
812         DWARFExpression expr;
813         if (base_reg == RegisterId::VFRAME) {
814           llvm::StringRef program;
815           if (GetFrameDataProgram(index, raw_ranges, program))
816             expr = MakeVFrameRelLocationExpression(program, loc.Hdr.Offset,
817                                                    module);
818           else {
819             // invalid variable
820           }
821         } else
822           expr = MakeRegRelLocationExpression(base_reg, loc.Hdr.Offset, module);
823         AddDwarfRange(location_map, expr, raw_ranges);
824         break;
825       }
826       case S_DEFRANGE_REGISTER: {
827         DefRangeRegisterSym loc(SymbolRecordKind::DefRangeRegisterSym);
828         if (llvm::Error error =
829                 SymbolDeserializer::deserializeAs<DefRangeRegisterSym>(
830                     loc_specifier_cvs, loc)) {
831           llvm::consumeError(std::move(error));
832           return result;
833         }
834         RegisterId reg_id = (RegisterId)(uint16_t)loc.Hdr.Register;
835         Variable::RangeList raw_ranges =
836             MakeRangeList(index, loc.Range, loc.Gaps);
837         DWARFExpression expr =
838             MakeEnregisteredLocationExpression(reg_id, module);
839         AddDwarfRange(location_map, expr, raw_ranges);
840         break;
841       }
842       case S_DEFRANGE_REGISTER_REL: {
843         DefRangeRegisterRelSym loc(SymbolRecordKind::DefRangeRegisterRelSym);
844         if (llvm::Error error =
845                 SymbolDeserializer::deserializeAs<DefRangeRegisterRelSym>(
846                     loc_specifier_cvs, loc)) {
847           llvm::consumeError(std::move(error));
848           return result;
849         }
850         Variable::RangeList raw_ranges =
851             MakeRangeList(index, loc.Range, loc.Gaps);
852         RegisterId reg_id = (RegisterId)(uint16_t)loc.Hdr.Register;
853         DWARFExpression expr;
854         if (reg_id == RegisterId::VFRAME) {
855           llvm::StringRef program;
856           if (GetFrameDataProgram(index, raw_ranges, program))
857             expr = MakeVFrameRelLocationExpression(
858                 program, loc.Hdr.BasePointerOffset, module);
859           else {
860             // invalid variable
861           }
862         } else {
863           expr = MakeRegRelLocationExpression(reg_id, loc.Hdr.BasePointerOffset,
864                                               module);
865         }
866         // FIXME: If it's UDT, we need to know the size of the value in byte.
867         if (!loc.hasSpilledUDTMember())
868           AddDwarfRange(location_map, expr, raw_ranges);
869         break;
870       }
871       case S_DEFRANGE_SUBFIELD_REGISTER: {
872         DefRangeSubfieldRegisterSym loc(
873             SymbolRecordKind::DefRangeSubfieldRegisterSym);
874         if (llvm::Error error =
875                 SymbolDeserializer::deserializeAs<DefRangeSubfieldRegisterSym>(
876                     loc_specifier_cvs, loc)) {
877           llvm::consumeError(std::move(error));
878           return result;
879         }
880 
881         Variable::RangeList ranges = MakeRangeList(index, loc.Range, loc.Gaps);
882         uint32_t reg_size =
883             GetRegisterSize((RegisterId)(uint16_t)loc.Hdr.Register);
884         if (reg_size == 0)
885           break;
886         offset_to_size[loc.Hdr.OffsetInParent] = reg_size;
887         AddMemberLocationRanges(location_map, loc.Hdr.OffsetInParent,
888                                 {loc.Hdr.Register, 0, true}, ranges);
889         break;
890       }
891       // FIXME: Handle other kinds. LLVM only generates the 4 types of records
892       // above. MSVC generates other location types.
893       case S_DEFRANGE:
894       case S_DEFRANGE_SUBFIELD:
895       case S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE:
896         break;
897       default:
898         finished = true;
899         break;
900       }
901       loc_specifier_id = PdbCompilandSymId(
902           loc_specifier_id.modi,
903           loc_specifier_id.offset + loc_specifier_cvs.RecordData.size());
904     }
905     for (const auto &entry : location_map) {
906       DWARFExpression dwarf_expr =
907           entry.data.is_dwarf ? entry.data.expr
908                               : MakeEnregisteredLocationExpressionForComposite(
909                                     entry.data.offset_to_location,
910                                     offset_to_size, type_size, module);
911 
912       result.location.AddExpression(entry.GetRangeBase(), entry.GetRangeEnd(),
913                                      dwarf_expr);
914     }
915     return result;
916   }
917   llvm_unreachable("Symbol is not a local variable!");
918   return result;
919 }
920 
921 lldb::BasicType
GetCompilerTypeForSimpleKind(SimpleTypeKind kind)922 lldb_private::npdb::GetCompilerTypeForSimpleKind(SimpleTypeKind kind) {
923   switch (kind) {
924   case SimpleTypeKind::Boolean128:
925   case SimpleTypeKind::Boolean16:
926   case SimpleTypeKind::Boolean32:
927   case SimpleTypeKind::Boolean64:
928   case SimpleTypeKind::Boolean8:
929     return lldb::eBasicTypeBool;
930   case SimpleTypeKind::Byte:
931   case SimpleTypeKind::UnsignedCharacter:
932     return lldb::eBasicTypeUnsignedChar;
933   case SimpleTypeKind::NarrowCharacter:
934     return lldb::eBasicTypeChar;
935   case SimpleTypeKind::SignedCharacter:
936   case SimpleTypeKind::SByte:
937     return lldb::eBasicTypeSignedChar;
938   case SimpleTypeKind::Character16:
939     return lldb::eBasicTypeChar16;
940   case SimpleTypeKind::Character32:
941     return lldb::eBasicTypeChar32;
942   case SimpleTypeKind::Character8:
943     return lldb::eBasicTypeChar8;
944   case SimpleTypeKind::Complex80:
945     return lldb::eBasicTypeLongDoubleComplex;
946   case SimpleTypeKind::Complex64:
947     return lldb::eBasicTypeDoubleComplex;
948   case SimpleTypeKind::Complex32:
949     return lldb::eBasicTypeFloatComplex;
950   case SimpleTypeKind::Float128:
951   case SimpleTypeKind::Float80:
952     return lldb::eBasicTypeLongDouble;
953   case SimpleTypeKind::Float64:
954     return lldb::eBasicTypeDouble;
955   case SimpleTypeKind::Float32:
956     return lldb::eBasicTypeFloat;
957   case SimpleTypeKind::Float16:
958     return lldb::eBasicTypeHalf;
959   case SimpleTypeKind::Int128:
960     return lldb::eBasicTypeInt128;
961   case SimpleTypeKind::Int64:
962   case SimpleTypeKind::Int64Quad:
963     return lldb::eBasicTypeLongLong;
964   case SimpleTypeKind::Int32:
965     return lldb::eBasicTypeInt;
966   case SimpleTypeKind::Int16:
967   case SimpleTypeKind::Int16Short:
968     return lldb::eBasicTypeShort;
969   case SimpleTypeKind::UInt128:
970     return lldb::eBasicTypeUnsignedInt128;
971   case SimpleTypeKind::UInt64:
972   case SimpleTypeKind::UInt64Quad:
973     return lldb::eBasicTypeUnsignedLongLong;
974   case SimpleTypeKind::HResult:
975   case SimpleTypeKind::UInt32:
976     return lldb::eBasicTypeUnsignedInt;
977   case SimpleTypeKind::UInt16:
978   case SimpleTypeKind::UInt16Short:
979     return lldb::eBasicTypeUnsignedShort;
980   case SimpleTypeKind::Int32Long:
981     return lldb::eBasicTypeLong;
982   case SimpleTypeKind::UInt32Long:
983     return lldb::eBasicTypeUnsignedLong;
984   case SimpleTypeKind::Void:
985     return lldb::eBasicTypeVoid;
986   case SimpleTypeKind::WideCharacter:
987     return lldb::eBasicTypeWChar;
988   default:
989     return lldb::eBasicTypeInvalid;
990   }
991 }
992 
GetTypeSizeForSimpleKind(SimpleTypeKind kind)993 size_t lldb_private::npdb::GetTypeSizeForSimpleKind(SimpleTypeKind kind) {
994   switch (kind) {
995   case SimpleTypeKind::Boolean128:
996   case SimpleTypeKind::Int128:
997   case SimpleTypeKind::UInt128:
998   case SimpleTypeKind::Float128:
999     return 16;
1000   case SimpleTypeKind::Complex80:
1001   case SimpleTypeKind::Float80:
1002     return 10;
1003   case SimpleTypeKind::Boolean64:
1004   case SimpleTypeKind::Complex64:
1005   case SimpleTypeKind::UInt64:
1006   case SimpleTypeKind::UInt64Quad:
1007   case SimpleTypeKind::Float64:
1008   case SimpleTypeKind::Int64:
1009   case SimpleTypeKind::Int64Quad:
1010     return 8;
1011   case SimpleTypeKind::Boolean32:
1012   case SimpleTypeKind::Character32:
1013   case SimpleTypeKind::Complex32:
1014   case SimpleTypeKind::Float32:
1015   case SimpleTypeKind::Int32:
1016   case SimpleTypeKind::Int32Long:
1017   case SimpleTypeKind::UInt32Long:
1018   case SimpleTypeKind::HResult:
1019   case SimpleTypeKind::UInt32:
1020     return 4;
1021   case SimpleTypeKind::Boolean16:
1022   case SimpleTypeKind::Character16:
1023   case SimpleTypeKind::Float16:
1024   case SimpleTypeKind::Int16:
1025   case SimpleTypeKind::Int16Short:
1026   case SimpleTypeKind::UInt16:
1027   case SimpleTypeKind::UInt16Short:
1028   case SimpleTypeKind::WideCharacter:
1029     return 2;
1030   case SimpleTypeKind::Boolean8:
1031   case SimpleTypeKind::Byte:
1032   case SimpleTypeKind::UnsignedCharacter:
1033   case SimpleTypeKind::NarrowCharacter:
1034   case SimpleTypeKind::SignedCharacter:
1035   case SimpleTypeKind::SByte:
1036   case SimpleTypeKind::Character8:
1037     return 1;
1038   case SimpleTypeKind::Void:
1039   default:
1040     return 0;
1041   }
1042 }
1043 
GetBestPossibleDecl(PdbTypeSymId id,TpiStream & tpi)1044 PdbTypeSymId lldb_private::npdb::GetBestPossibleDecl(PdbTypeSymId id,
1045                                                      TpiStream &tpi) {
1046   if (id.index.isSimple())
1047     return id;
1048 
1049   CVType cvt = tpi.getType(id.index);
1050 
1051   // Only tag records have a best and a worst record.
1052   if (!IsTagRecord(cvt))
1053     return id;
1054 
1055   // Tag records that are not forward decls are full decls, hence they are the
1056   // best.
1057   if (!IsForwardRefUdt(cvt))
1058     return id;
1059 
1060   return llvm::cantFail(tpi.findFullDeclForForwardRef(id.index));
1061 }
1062 
GetSizeOfTypeInternal(CVType cvt)1063 template <typename RecordType> static size_t GetSizeOfTypeInternal(CVType cvt) {
1064   RecordType record;
1065   llvm::cantFail(TypeDeserializer::deserializeAs<RecordType>(cvt, record));
1066   return record.getSize();
1067 }
1068 
GetSizeOfType(PdbTypeSymId id,llvm::pdb::TpiStream & tpi)1069 size_t lldb_private::npdb::GetSizeOfType(PdbTypeSymId id,
1070                                          llvm::pdb::TpiStream &tpi) {
1071   if (id.index.isSimple()) {
1072     switch (id.index.getSimpleMode()) {
1073     case SimpleTypeMode::Direct:
1074       return GetTypeSizeForSimpleKind(id.index.getSimpleKind());
1075     case SimpleTypeMode::NearPointer32:
1076     case SimpleTypeMode::FarPointer32:
1077       return 4;
1078     case SimpleTypeMode::NearPointer64:
1079       return 8;
1080     case SimpleTypeMode::NearPointer128:
1081       return 16;
1082     default:
1083       break;
1084     }
1085     return 0;
1086   }
1087 
1088   TypeIndex index = id.index;
1089   if (IsForwardRefUdt(index, tpi))
1090     index = llvm::cantFail(tpi.findFullDeclForForwardRef(index));
1091 
1092   CVType cvt = tpi.getType(index);
1093   switch (cvt.kind()) {
1094   case LF_MODIFIER:
1095     return GetSizeOfType({LookThroughModifierRecord(cvt)}, tpi);
1096   case LF_ENUM: {
1097     EnumRecord record;
1098     llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, record));
1099     return GetSizeOfType({record.UnderlyingType}, tpi);
1100   }
1101   case LF_POINTER:
1102     return GetSizeOfTypeInternal<PointerRecord>(cvt);
1103   case LF_ARRAY:
1104     return GetSizeOfTypeInternal<ArrayRecord>(cvt);
1105   case LF_CLASS:
1106   case LF_STRUCTURE:
1107   case LF_INTERFACE:
1108     return GetSizeOfTypeInternal<ClassRecord>(cvt);
1109   case LF_UNION:
1110     return GetSizeOfTypeInternal<UnionRecord>(cvt);
1111   case LF_BITFIELD: {
1112     BitFieldRecord record;
1113     llvm::cantFail(TypeDeserializer::deserializeAs<BitFieldRecord>(cvt, record));
1114     return GetSizeOfType({record.Type}, tpi);
1115   }
1116   default:
1117     break;
1118   }
1119   return 0;
1120 }
1121