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
28using namespace lldb_private;
29using namespace lldb_private::npdb;
30using namespace llvm::codeview;
31using 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.
35static Variable::RangeList
36MakeRangeList(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
57namespace {
58struct 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.
82typedef RangeDataVector<lldb::addr_t, lldb::addr_t, MemberLocations, 0,
83                        MemberLocations::Comparator>
84    RangeMap;
85
86void 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
143void 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
198CVTagRecord 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
223CVTagRecord::CVTagRecord(ClassRecord &&c)
224    : cvclass(std::move(c)),
225      m_kind(cvclass.Kind == TypeRecordKind::Struct ? Struct : Class) {}
226CVTagRecord::CVTagRecord(UnionRecord &&u)
227    : cvunion(std::move(u)), m_kind(Union) {}
228CVTagRecord::CVTagRecord(EnumRecord &&e) : cvenum(std::move(e)), m_kind(Enum) {}
229
230PDB_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
282PDB_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
311bool 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
338bool 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
356template <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
362template <typename RecordT>
363static SegmentOffset GetSegmentAndOffset(const CVSymbol &sym) {
364  RecordT record = createRecord<RecordT>(sym);
365  return {record.Segment, record.CodeOffset};
366}
367
368template <>
369SegmentOffset GetSegmentAndOffset<TrampolineSym>(const CVSymbol &sym) {
370  TrampolineSym record = createRecord<TrampolineSym>(sym);
371  return {record.ThunkSection, record.ThunkOffset};
372}
373
374template <> SegmentOffset GetSegmentAndOffset<Thunk32Sym>(const CVSymbol &sym) {
375  Thunk32Sym record = createRecord<Thunk32Sym>(sym);
376  return {record.Segment, record.Offset};
377}
378
379template <>
380SegmentOffset GetSegmentAndOffset<CoffGroupSym>(const CVSymbol &sym) {
381  CoffGroupSym record = createRecord<CoffGroupSym>(sym);
382  return {record.Segment, record.Offset};
383}
384
385template <> SegmentOffset GetSegmentAndOffset<DataSym>(const CVSymbol &sym) {
386  DataSym record = createRecord<DataSym>(sym);
387  return {record.Segment, record.DataOffset};
388}
389
390template <>
391SegmentOffset GetSegmentAndOffset<ThreadLocalDataSym>(const CVSymbol &sym) {
392  ThreadLocalDataSym record = createRecord<ThreadLocalDataSym>(sym);
393  return {record.Segment, record.DataOffset};
394}
395
396SegmentOffset 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
442template <typename RecordT>
443SegmentOffsetLength GetSegmentOffsetAndLength(const CVSymbol &sym) {
444  RecordT record = createRecord<RecordT>(sym);
445  return {record.Segment, record.CodeOffset, record.CodeSize};
446}
447
448template <>
449SegmentOffsetLength
450GetSegmentOffsetAndLength<TrampolineSym>(const CVSymbol &sym) {
451  TrampolineSym record = createRecord<TrampolineSym>(sym);
452  return {record.ThunkSection, record.ThunkOffset, record.Size};
453}
454
455template <>
456SegmentOffsetLength GetSegmentOffsetAndLength<Thunk32Sym>(const CVSymbol &sym) {
457  Thunk32Sym record = createRecord<Thunk32Sym>(sym);
458  return SegmentOffsetLength{record.Segment, record.Offset, record.Length};
459}
460
461template <>
462SegmentOffsetLength
463GetSegmentOffsetAndLength<CoffGroupSym>(const CVSymbol &sym) {
464  CoffGroupSym record = createRecord<CoffGroupSym>(sym);
465  return SegmentOffsetLength{record.Segment, record.Offset, record.Size};
466}
467
468SegmentOffsetLength
469lldb_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
496bool 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
517bool 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
529bool 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
540bool 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
547bool 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
553lldb::AccessType
554lldb_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
568TypeIndex 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
592TypeIndex 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
599llvm::StringRef lldb_private::npdb::DropNameScope(llvm::StringRef name) {
600  return MSVCUndecoratedNameParser::DropScope(name);
601}
602
603VariableInfo 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
660static llvm::FixedStreamArray<FrameData>::Iterator
661GetCorrespondingFrameData(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
695static 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
715static 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
734VariableInfo 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
921lldb::BasicType
922lldb_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
993size_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
1044PdbTypeSymId 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
1063template <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
1069size_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