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  PDBStringTable &strings = cantFail(index.pdb().getStringTable());
707  out_program = cantFail(strings.getStringForID(frame_data_it->FrameFunc));
708  return true;
709}
710
711static 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
730VariableInfo 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
917lldb::BasicType
918lldb_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
989size_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
1040PdbTypeSymId 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
1059template <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
1065size_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