LLDB  mainline
PdbUtil.cpp
Go to the documentation of this file.
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 
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 
23 #include "lldb/Symbol/Block.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.
36 MakeRangeList(const PdbIndex &index, const LocalVariableAddrRange &range,
37  llvm::ArrayRef<LocalVariableAddrGap> gaps) {
38  lldb::addr_t start =
39  index.MakeVirtualAddress(range.ISectStart, range.OffsetStart);
40  if (start == LLDB_INVALID_ADDRESS)
41  return {};
42  lldb::addr_t end = start + range.Range;
43 
44  Variable::RangeList result;
45  while (!gaps.empty()) {
46  const LocalVariableAddrGap &gap = gaps.front();
47  lldb::addr_t gap_start = start + gap.GapStartOffset;
48  result.Append(start, gap_start - start);
49  start = gap_start + gap.Range;
50  gaps = gaps.drop_front();
51  }
52 
53  result.Append(start, end - start);
54  return result;
55 }
56 
57 namespace {
58 struct MemberLocations {
59  std::map<uint64_t, MemberValLocation> offset_to_location;
60  DWARFExpression expr;
61  bool is_dwarf = false;
62 
63  MemberLocations() = default;
64  MemberLocations(const DWARFExpression &expr) : expr(expr), is_dwarf(true) {}
65  MemberLocations(uint64_t offset, const MemberValLocation &member_loc) {
66  insert(offset, member_loc);
67  }
68 
69  void insert(uint64_t offset, const MemberValLocation &member_loc) {
70  offset_to_location[offset] = member_loc;
71  }
72 
73  struct Comparator {
74  public:
75  bool operator()(const MemberLocations &, const MemberLocations &) const {
76  return false;
77  }
78  };
79 };
80 
81 // A range map with address ranges to a map of pair of offset and locaitons.
82 typedef RangeDataVector<lldb::addr_t, lldb::addr_t, MemberLocations, 0,
83  MemberLocations::Comparator>
84  RangeMap;
85 
86 void AddMemberLocationRanges(RangeMap &location_map, uint64_t offset,
87  MemberValLocation member_loc,
88  const Variable::RangeList &ranges) {
89  RangeMap new_location_map;
90  auto add_overlap_region = [&](lldb::addr_t base, lldb::addr_t end,
91  RangeMap::Entry *entry) {
92  RangeMap::Entry overlap_region = {base, end - base, entry->data};
93  overlap_region.data.insert(offset, member_loc);
94  new_location_map.Append(overlap_region);
95  };
96 
97  for (const auto &range : ranges) {
98  lldb::addr_t base = range.GetRangeBase();
99  lldb::addr_t end = range.GetRangeEnd();
100  uint32_t base_idx = location_map.FindEntryIndexThatContainsOrFollows(base);
101  while (auto *entry = location_map.GetMutableEntryAtIndex(base_idx)) {
102  if (base >= end || entry->base >= end)
103  break;
104  if (entry->data.is_dwarf)
105  base = entry->GetRangeEnd();
106  else {
107  lldb::addr_t entry_end = entry->GetRangeEnd();
108  if (base > entry->base) {
109  if (end < entry_end)
110  new_location_map.Append({end, entry_end - end, entry->data});
111  add_overlap_region(base, end < entry_end ? end : entry_end, entry);
112  entry->SetRangeEnd(base);
113  } else if (base < entry->base) {
114  new_location_map.Append(
115  {base, entry->base - base, {offset, member_loc}});
116  if (entry_end == end)
117  entry->data.insert(offset, member_loc);
118  else {
119  add_overlap_region(entry->base, end, entry);
120  entry->ShrinkFront(end - entry->base);
121  }
122  } else {
123  if (end < entry_end) {
124  new_location_map.Append({end, entry_end, entry->data});
125  entry->SetRangeEnd(end);
126  }
127  entry->data.insert(offset, member_loc);
128  }
129  base = entry_end;
130  }
131  ++base_idx;
132  }
133  if (base >= end)
134  continue;
135  new_location_map.Append({base, end - base, {offset, member_loc}});
136  }
137  for (const auto &entry : new_location_map)
138  location_map.Append(entry);
139  if (!new_location_map.IsEmpty())
140  location_map.Sort();
141 }
142 
143 void AddDwarfRange(RangeMap &location_map, const DWARFExpression &expr,
144  const Variable::RangeList &ranges) {
145  if (!expr.IsValid())
146  return;
147  RangeMap new_location_map;
148  for (const auto &range : ranges) {
149  lldb::addr_t base = range.GetRangeBase();
150  lldb::addr_t end = range.GetRangeEnd();
151  uint32_t base_idx = location_map.FindEntryIndexThatContains(base);
152  uint32_t end_idx = location_map.FindEntryIndexThatContains(end - 1);
153  // range is within an entry.
154  if (base_idx == end_idx && base_idx != UINT32_MAX) {
155  auto *entry = location_map.GetMutableEntryAtIndex(base_idx);
156  if (base > entry->base) {
157  new_location_map.Append({entry->base, base - entry->base, entry->data});
158  entry->ShrinkFront(base - entry->base);
159  }
160  if (end == entry->GetRangeEnd())
161  entry->data = expr;
162  else {
163  entry->ShrinkFront(end - base);
164  new_location_map.Append({base, end - base, expr});
165  }
166  continue;
167  }
168  base_idx = location_map.FindEntryIndexThatContainsOrFollows(base);
169  if (auto *entry = location_map.GetMutableEntryAtIndex(base_idx)) {
170  if (entry->Contains(base) && entry->base != base) {
171  entry->SetRangeEnd(base);
172  ++base_idx;
173  }
174  }
175  end_idx = location_map.FindEntryIndexThatContainsOrFollows(end - 1);
176  if (auto *entry = location_map.GetMutableEntryAtIndex(end_idx)) {
177  if (entry->Contains(end - 1)) {
178  if (entry->GetRangeEnd() == end)
179  ++end_idx;
180  else
181  entry->ShrinkFront(end - entry->base);
182  }
183  }
184 
185  if (end_idx == UINT32_MAX)
186  end_idx = location_map.GetSize();
187  // Erase existing ranges covered by new range.
188  location_map.Erase(base_idx, end_idx);
189  new_location_map.Append({base, end - base, expr});
190  }
191 
192  for (const auto &entry : new_location_map)
193  location_map.Append(entry);
194  location_map.Sort();
195 }
196 } // namespace
197 
199  assert(IsTagRecord(type) && "type is not a tag record!");
200  switch (type.kind()) {
201  case LF_CLASS:
202  case LF_STRUCTURE:
203  case LF_INTERFACE: {
204  ClassRecord cr;
205  llvm::cantFail(TypeDeserializer::deserializeAs<ClassRecord>(type, cr));
206  return CVTagRecord(std::move(cr));
207  }
208  case LF_UNION: {
209  UnionRecord ur;
210  llvm::cantFail(TypeDeserializer::deserializeAs<UnionRecord>(type, ur));
211  return CVTagRecord(std::move(ur));
212  }
213  case LF_ENUM: {
214  EnumRecord er;
215  llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(type, er));
216  return CVTagRecord(std::move(er));
217  }
218  default:
219  llvm_unreachable("Unreachable!");
220  }
221 }
222 
223 CVTagRecord::CVTagRecord(ClassRecord &&c)
224  : cvclass(std::move(c)),
225  m_kind(cvclass.Kind == TypeRecordKind::Struct ? Struct : Class) {}
226 CVTagRecord::CVTagRecord(UnionRecord &&u)
227  : cvunion(std::move(u)), m_kind(Union) {}
228 CVTagRecord::CVTagRecord(EnumRecord &&e) : cvenum(std::move(e)), m_kind(Enum) {}
229 
230 PDB_SymType lldb_private::npdb::CVSymToPDBSym(SymbolKind kind) {
231  switch (kind) {
232  case S_COMPILE3:
233  case S_OBJNAME:
234  return PDB_SymType::CompilandDetails;
235  case S_ENVBLOCK:
236  return PDB_SymType::CompilandEnv;
237  case S_THUNK32:
238  case S_TRAMPOLINE:
239  return PDB_SymType::Thunk;
240  case S_COFFGROUP:
241  return PDB_SymType::CoffGroup;
242  case S_EXPORT:
243  return PDB_SymType::Export;
244  case S_LPROC32:
245  case S_GPROC32:
246  case S_LPROC32_DPC:
247  return PDB_SymType::Function;
248  case S_PUB32:
249  return PDB_SymType::PublicSymbol;
250  case S_INLINESITE:
251  return PDB_SymType::InlineSite;
252  case S_LOCAL:
253  case S_BPREL32:
254  case S_REGREL32:
255  case S_MANCONSTANT:
256  case S_CONSTANT:
257  case S_LDATA32:
258  case S_GDATA32:
259  case S_LMANDATA:
260  case S_GMANDATA:
261  case S_LTHREAD32:
262  case S_GTHREAD32:
263  return PDB_SymType::Data;
264  case S_BLOCK32:
265  return PDB_SymType::Block;
266  case S_LABEL32:
267  return PDB_SymType::Label;
268  case S_CALLSITEINFO:
269  return PDB_SymType::CallSite;
270  case S_HEAPALLOCSITE:
271  return PDB_SymType::HeapAllocationSite;
272  case S_CALLEES:
273  return PDB_SymType::Callee;
274  case S_CALLERS:
275  return PDB_SymType::Caller;
276  default:
277  lldbassert(false && "Invalid symbol record kind!");
278  }
279  return PDB_SymType::None;
280 }
281 
282 PDB_SymType lldb_private::npdb::CVTypeToPDBType(TypeLeafKind kind) {
283  switch (kind) {
284  case LF_ARRAY:
285  return PDB_SymType::ArrayType;
286  case LF_ARGLIST:
287  return PDB_SymType::FunctionSig;
288  case LF_BCLASS:
289  return PDB_SymType::BaseClass;
290  case LF_BINTERFACE:
291  return PDB_SymType::BaseInterface;
292  case LF_CLASS:
293  case LF_STRUCTURE:
294  case LF_INTERFACE:
295  case LF_UNION:
296  return PDB_SymType::UDT;
297  case LF_POINTER:
298  return PDB_SymType::PointerType;
299  case LF_ENUM:
300  return PDB_SymType::Enum;
301  case LF_PROCEDURE:
302  return PDB_SymType::FunctionSig;
303  case LF_BITFIELD:
304  return PDB_SymType::BuiltinType;
305  default:
306  lldbassert(false && "Invalid type record kind!");
307  }
308  return PDB_SymType::None;
309 }
310 
311 bool lldb_private::npdb::SymbolHasAddress(const CVSymbol &sym) {
312  switch (sym.kind()) {
313  case S_GPROC32:
314  case S_LPROC32:
315  case S_GPROC32_ID:
316  case S_LPROC32_ID:
317  case S_LPROC32_DPC:
318  case S_LPROC32_DPC_ID:
319  case S_THUNK32:
320  case S_TRAMPOLINE:
321  case S_COFFGROUP:
322  case S_BLOCK32:
323  case S_LABEL32:
324  case S_CALLSITEINFO:
325  case S_HEAPALLOCSITE:
326  case S_LDATA32:
327  case S_GDATA32:
328  case S_LMANDATA:
329  case S_GMANDATA:
330  case S_LTHREAD32:
331  case S_GTHREAD32:
332  return true;
333  default:
334  return false;
335  }
336 }
337 
338 bool lldb_private::npdb::SymbolIsCode(const CVSymbol &sym) {
339  switch (sym.kind()) {
340  case S_GPROC32:
341  case S_LPROC32:
342  case S_GPROC32_ID:
343  case S_LPROC32_ID:
344  case S_LPROC32_DPC:
345  case S_LPROC32_DPC_ID:
346  case S_THUNK32:
347  case S_TRAMPOLINE:
348  case S_COFFGROUP:
349  case S_BLOCK32:
350  return true;
351  default:
352  return false;
353  }
354 }
355 
356 template <typename RecordT> RecordT createRecord(const CVSymbol &sym) {
357  RecordT record(static_cast<SymbolRecordKind>(sym.kind()));
358  cantFail(SymbolDeserializer::deserializeAs<RecordT>(sym, record));
359  return record;
360 }
361 
362 template <typename RecordT>
363 static SegmentOffset GetSegmentAndOffset(const CVSymbol &sym) {
364  RecordT record = createRecord<RecordT>(sym);
365  return {record.Segment, record.CodeOffset};
366 }
367 
368 template <>
370  TrampolineSym record = createRecord<TrampolineSym>(sym);
371  return {record.ThunkSection, record.ThunkOffset};
372 }
373 
374 template <> SegmentOffset GetSegmentAndOffset<Thunk32Sym>(const CVSymbol &sym) {
375  Thunk32Sym record = createRecord<Thunk32Sym>(sym);
376  return {record.Segment, record.Offset};
377 }
378 
379 template <>
381  CoffGroupSym record = createRecord<CoffGroupSym>(sym);
382  return {record.Segment, record.Offset};
383 }
384 
385 template <> SegmentOffset GetSegmentAndOffset<DataSym>(const CVSymbol &sym) {
386  DataSym record = createRecord<DataSym>(sym);
387  return {record.Segment, record.DataOffset};
388 }
389 
390 template <>
392  ThreadLocalDataSym record = createRecord<ThreadLocalDataSym>(sym);
393  return {record.Segment, record.DataOffset};
394 }
395 
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:
407  break;
408  case S_TRAMPOLINE:
410  break;
411  case S_COFFGROUP:
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:
431  break;
432  case S_LTHREAD32:
433  case S_GTHREAD32:
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>
444  RecordT record = createRecord<RecordT>(sym);
445  return {record.Segment, record.CodeOffset, record.CodeSize};
446 }
447 
448 template <>
451  TrampolineSym record = createRecord<TrampolineSym>(sym);
452  return {record.ThunkSection, record.ThunkOffset, record.Size};
453 }
454 
455 template <>
457  Thunk32Sym record = createRecord<Thunk32Sym>(sym);
458  return SegmentOffsetLength{record.Segment, record.Offset, record.Length};
459 }
460 
461 template <>
464  CoffGroupSym record = createRecord<CoffGroupSym>(sym);
465  return SegmentOffsetLength{record.Segment, record.Offset, record.Size};
466 }
467 
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:
480  break;
481  case S_TRAMPOLINE:
483  break;
484  case S_COFFGROUP:
486  break;
487  case S_BLOCK32:
488  return ::GetSegmentOffsetAndLength<BlockSym>(sym);
489  break;
490  default:
491  lldbassert(false && "Record does not have a segment/offset/length triple!");
492  }
493  return {0, 0, 0};
494 }
495 
496 bool lldb_private::npdb::IsForwardRefUdt(CVType cvt) {
497  ClassRecord cr;
498  UnionRecord ur;
499  EnumRecord er;
500  switch (cvt.kind()) {
501  case LF_CLASS:
502  case LF_STRUCTURE:
503  case LF_INTERFACE:
504  llvm::cantFail(TypeDeserializer::deserializeAs<ClassRecord>(cvt, cr));
505  return cr.isForwardRef();
506  case LF_UNION:
507  llvm::cantFail(TypeDeserializer::deserializeAs<UnionRecord>(cvt, ur));
508  return ur.isForwardRef();
509  case LF_ENUM:
510  llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er));
511  return er.isForwardRef();
512  default:
513  return false;
514  }
515 }
516 
517 bool lldb_private::npdb::IsTagRecord(llvm::codeview::CVType cvt) {
518  switch (cvt.kind()) {
519  case LF_CLASS:
520  case LF_STRUCTURE:
521  case LF_UNION:
522  case LF_ENUM:
523  return true;
524  default:
525  return false;
526  }
527 }
528 
529 bool lldb_private::npdb::IsClassStructUnion(llvm::codeview::CVType cvt) {
530  switch (cvt.kind()) {
531  case LF_CLASS:
532  case LF_STRUCTURE:
533  case LF_UNION:
534  return true;
535  default:
536  return false;
537  }
538 }
539 
541  TpiStream &tpi) {
542  if (id.is_ipi || id.index.isSimple())
543  return false;
544  return IsForwardRefUdt(tpi.getType(id.index));
545 }
546 
547 bool lldb_private::npdb::IsTagRecord(const PdbTypeSymId &id, TpiStream &tpi) {
548  if (id.is_ipi || id.index.isSimple())
549  return false;
550  return IsTagRecord(tpi.getType(id.index));
551 }
552 
554 lldb_private::npdb::TranslateMemberAccess(MemberAccess access) {
555  switch (access) {
556  case MemberAccess::Private:
557  return lldb::eAccessPrivate;
558  case MemberAccess::Protected:
559  return lldb::eAccessProtected;
560  case MemberAccess::Public:
561  return lldb::eAccessPublic;
562  case MemberAccess::None:
563  return lldb::eAccessNone;
564  }
565  llvm_unreachable("unreachable");
566 }
567 
568 TypeIndex lldb_private::npdb::GetFieldListIndex(CVType cvt) {
569  switch (cvt.kind()) {
570  case LF_CLASS:
571  case LF_STRUCTURE:
572  case LF_INTERFACE: {
573  ClassRecord cr;
574  cantFail(TypeDeserializer::deserializeAs<ClassRecord>(cvt, cr));
575  return cr.FieldList;
576  }
577  case LF_UNION: {
578  UnionRecord ur;
579  cantFail(TypeDeserializer::deserializeAs<UnionRecord>(cvt, ur));
580  return ur.FieldList;
581  }
582  case LF_ENUM: {
583  EnumRecord er;
584  cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er));
585  return er.FieldList;
586  }
587  default:
588  llvm_unreachable("Unreachable!");
589  }
590 }
591 
592 TypeIndex lldb_private::npdb::LookThroughModifierRecord(CVType modifier) {
593  lldbassert(modifier.kind() == LF_MODIFIER);
594  ModifierRecord mr;
595  llvm::cantFail(TypeDeserializer::deserializeAs<ModifierRecord>(modifier, mr));
596  return mr.ModifiedType;
597 }
598 
599 llvm::StringRef lldb_private::npdb::DropNameScope(llvm::StringRef name) {
601 }
602 
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
662  const DebugFrameDataSubsectionRef &fpo_data,
663  const Variable::RangeList &ranges) {
664  lldbassert(!ranges.IsEmpty());
665 
666  // assume that all variable ranges correspond to one frame data
667  using RangeListEntry = Variable::RangeList::Entry;
668  const RangeListEntry &range = ranges.GetEntryRef(0);
669 
670  auto it = fpo_data.begin();
671 
672  // start by searching first frame data range containing variable range
673  for (; it != fpo_data.end(); ++it) {
674  RangeListEntry fd_range(load_addr + it->RvaStart, it->CodeSize);
675 
676  if (fd_range.Contains(range)) {
677  break;
678  }
679  }
680 
681  // then first most nested entry that still contains variable range
682  auto found = it;
683  for (; it != fpo_data.end(); ++it) {
684  RangeListEntry fd_range(load_addr + it->RvaStart, it->CodeSize);
685 
686  if (!fd_range.Contains(range)) {
687  break;
688  }
689  found = it;
690  }
691 
692  return found;
693 }
694 
695 static bool GetFrameDataProgram(PdbIndex &index,
696  const Variable::RangeList &ranges,
697  llvm::StringRef &out_program) {
698  const DebugFrameDataSubsectionRef &new_fpo_data =
699  index.dbi().getNewFpoRecords();
700 
701  auto frame_data_it =
702  GetCorrespondingFrameData(index.GetLoadAddress(), new_fpo_data, ranges);
703  if (frame_data_it == new_fpo_data.end())
704  return false;
705 
706  PDBStringTable &strings = cantFail(index.pdb().getStringTable());
707  out_program = cantFail(strings.getStringForID(frame_data_it->FrameFunc));
708  return true;
709 }
710 
711 static RegisterId GetBaseFrameRegister(PdbIndex &index,
712  PdbCompilandSymId frame_proc_id,
713  bool is_parameter) {
714  CVSymbol frame_proc_cvs = index.ReadSymbolRecord(frame_proc_id);
715  if (frame_proc_cvs.kind() != S_FRAMEPROC)
716  return RegisterId::NONE;
717 
718  FrameProcSym frame_proc(SymbolRecordKind::FrameProcSym);
719  cantFail(SymbolDeserializer::deserializeAs<FrameProcSym>(frame_proc_cvs,
720  frame_proc));
721 
722  CPUType cpu_type = index.compilands()
723  .GetCompiland(frame_proc_id.modi)
724  ->m_compile_opts->Machine;
725 
726  return is_parameter ? frame_proc.getParamFramePtrReg(cpu_type)
727  : frame_proc.getLocalFramePtrReg(cpu_type);
728 }
729 
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))
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);
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
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 
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:
929  case SimpleTypeKind::NarrowCharacter:
930  return lldb::eBasicTypeChar;
931  case SimpleTypeKind::SignedCharacter:
932  case SimpleTypeKind::SByte:
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:
942  case SimpleTypeKind::Complex64:
944  case SimpleTypeKind::Complex32:
946  case SimpleTypeKind::Float128:
947  case SimpleTypeKind::Float80:
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:
960  case SimpleTypeKind::Int32:
961  return lldb::eBasicTypeInt;
962  case SimpleTypeKind::Int16:
963  case SimpleTypeKind::Int16Short:
964  return lldb::eBasicTypeShort;
965  case SimpleTypeKind::UInt128:
967  case SimpleTypeKind::UInt64:
968  case SimpleTypeKind::UInt64Quad:
970  case SimpleTypeKind::HResult:
971  case SimpleTypeKind::UInt32:
973  case SimpleTypeKind::UInt16:
974  case SimpleTypeKind::UInt16Short:
976  case SimpleTypeKind::Int32Long:
977  return lldb::eBasicTypeLong;
978  case SimpleTypeKind::UInt32Long:
980  case SimpleTypeKind::Void:
981  return lldb::eBasicTypeVoid;
982  case SimpleTypeKind::WideCharacter:
983  return lldb::eBasicTypeWChar;
984  default:
986  }
987 }
988 
989 size_t lldb_private::npdb::GetTypeSizeForSimpleKind(SimpleTypeKind kind) {
990  switch (kind) {
991  case SimpleTypeKind::Boolean128:
992  case SimpleTypeKind::Int128:
993  case SimpleTypeKind::UInt128:
994  case SimpleTypeKind::Float128:
995  return 16;
996  case SimpleTypeKind::Complex80:
997  case SimpleTypeKind::Float80:
998  return 10;
999  case SimpleTypeKind::Boolean64:
1000  case SimpleTypeKind::Complex64:
1001  case SimpleTypeKind::UInt64:
1002  case SimpleTypeKind::UInt64Quad:
1003  case SimpleTypeKind::Float64:
1004  case SimpleTypeKind::Int64:
1005  case SimpleTypeKind::Int64Quad:
1006  return 8;
1007  case SimpleTypeKind::Boolean32:
1008  case SimpleTypeKind::Character32:
1009  case SimpleTypeKind::Complex32:
1010  case SimpleTypeKind::Float32:
1011  case SimpleTypeKind::Int32:
1012  case SimpleTypeKind::Int32Long:
1013  case SimpleTypeKind::UInt32Long:
1014  case SimpleTypeKind::HResult:
1015  case SimpleTypeKind::UInt32:
1016  return 4;
1017  case SimpleTypeKind::Boolean16:
1018  case SimpleTypeKind::Character16:
1019  case SimpleTypeKind::Float16:
1020  case SimpleTypeKind::Int16:
1021  case SimpleTypeKind::Int16Short:
1022  case SimpleTypeKind::UInt16:
1023  case SimpleTypeKind::UInt16Short:
1024  case SimpleTypeKind::WideCharacter:
1025  return 2;
1026  case SimpleTypeKind::Boolean8:
1027  case SimpleTypeKind::Byte:
1028  case SimpleTypeKind::UnsignedCharacter:
1029  case SimpleTypeKind::NarrowCharacter:
1030  case SimpleTypeKind::SignedCharacter:
1031  case SimpleTypeKind::SByte:
1032  case SimpleTypeKind::Character8:
1033  return 1;
1034  case SimpleTypeKind::Void:
1035  default:
1036  return 0;
1037  }
1038 }
1039 
1041  TpiStream &tpi) {
1042  if (id.index.isSimple())
1043  return id;
1044 
1045  CVType cvt = tpi.getType(id.index);
1046 
1047  // Only tag records have a best and a worst record.
1048  if (!IsTagRecord(cvt))
1049  return id;
1050 
1051  // Tag records that are not forward decls are full decls, hence they are the
1052  // best.
1053  if (!IsForwardRefUdt(cvt))
1054  return id;
1055 
1056  return llvm::cantFail(tpi.findFullDeclForForwardRef(id.index));
1057 }
1058 
1059 template <typename RecordType> static size_t GetSizeOfTypeInternal(CVType cvt) {
1060  RecordType record;
1061  llvm::cantFail(TypeDeserializer::deserializeAs<RecordType>(cvt, record));
1062  return record.getSize();
1063 }
1064 
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  default:
1108  break;
1109  }
1110  return 0;
1111 }
GetSegmentAndOffset< Thunk32Sym >
SegmentOffset GetSegmentAndOffset< Thunk32Sym >(const CVSymbol &sym)
Definition: PdbUtil.cpp:374
Block.h
lldb_private::npdb::MakeRegRelLocationExpression
DWARFExpression MakeRegRelLocationExpression(llvm::codeview::RegisterId reg, int32_t offset, lldb::ModuleSP module)
Definition: DWARFLocationExpression.cpp:171
lldb_private::npdb::CompileUnitIndex::GetCompiland
const CompilandIndexItem * GetCompiland(uint16_t modi) const
Definition: CompileUnitIndex.cpp:194
lldb_private::npdb::GetSegmentAndOffset
SegmentOffset GetSegmentAndOffset(const llvm::codeview::CVSymbol &sym)
lldb_private::npdb::GetFieldListIndex
llvm::codeview::TypeIndex GetFieldListIndex(llvm::codeview::CVType cvt)
lldb_private::npdb::IsClassStructUnion
bool IsClassStructUnion(llvm::codeview::CVType cvt)
Definition: PdbUtil.cpp:529
lldb::eBasicTypeBool
@ eBasicTypeBool
Definition: lldb-enumerations.h:769
lldb_private::npdb::PdbIndex::compilands
CompileUnitIndex & compilands()
Definition: PdbIndex.h:142
lldb::eAccessProtected
@ eAccessProtected
Definition: lldb-enumerations.h:511
lldb_private::npdb::PdbIndex::GetLoadAddress
lldb::addr_t GetLoadAddress() const
Definition: PdbIndex.h:115
GetFrameDataProgram
static bool GetFrameDataProgram(PdbIndex &index, const Variable::RangeList &ranges, llvm::StringRef &out_program)
Definition: PdbUtil.cpp:695
lldb_private::npdb::SegmentOffsetLength
Definition: PdbUtil.h:95
lldb_private::npdb::PdbSymUid::asCompilandSym
PdbCompilandSymId asCompilandSym() const
Definition: PdbSymUid.cpp:125
lldb_private::npdb::CVSymToPDBSym
llvm::pdb::PDB_SymType CVSymToPDBSym(llvm::codeview::SymbolKind kind)
lldb::eBasicTypeInvalid
@ eBasicTypeInvalid
Definition: lldb-enumerations.h:748
lldb_private::npdb::CVTypeToPDBType
llvm::pdb::PDB_SymType CVTypeToPDBType(llvm::codeview::TypeLeafKind kind)
lldb_private::npdb::PdbIndex
PdbIndex - Lazy access to the important parts of a PDB file.
Definition: PdbIndex.h:47
lldb_private::npdb::PdbCompilandSymId
Definition: PdbSymUid.h:44
lldb_private::npdb::VariableInfo::type
llvm::codeview::TypeIndex type
Definition: PdbUtil.h:105
lldb_private::npdb::LookThroughModifierRecord
llvm::codeview::TypeIndex LookThroughModifierRecord(llvm::codeview::CVType modifier)
lldb_private::npdb::SegmentOffset
Definition: PdbUtil.h:88
lldb_private::npdb::GetSegmentOffsetAndLength
SegmentOffsetLength GetSegmentOffsetAndLength(const llvm::codeview::CVSymbol &sym)
lldb_private::npdb::TranslateMemberAccess
lldb::AccessType TranslateMemberAccess(llvm::codeview::MemberAccess access)
lldb_private::npdb
Definition: TypeSystem.h:34
lldb_private::npdb::DropNameScope
llvm::StringRef DropNameScope(llvm::StringRef name)
Definition: PdbUtil.cpp:599
lldb::eBasicTypeUnsignedLong
@ eBasicTypeUnsignedLong
Definition: lldb-enumerations.h:764
lldb_private::RangeVector::GetEntryRef
Entry & GetEntryRef(size_t i)
Definition: RangeMap.h:303
lldb_private::npdb::PdbCompilandSymId::modi
uint16_t modi
Definition: PdbSymUid.h:49
lldb_private::npdb::PdbIndex::ReadSymbolRecord
llvm::codeview::CVSymbol ReadSymbolRecord(PdbCompilandSymId cu_sym) const
Definition: PdbIndex.cpp:186
lldb::eBasicTypeFloatComplex
@ eBasicTypeFloatComplex
Definition: lldb-enumerations.h:774
reg_size
static const size_t reg_size
Definition: ABISysV_arc.cpp:171
lldb::eBasicTypeChar16
@ eBasicTypeChar16
Definition: lldb-enumerations.h:756
lldb::eBasicTypeChar
@ eBasicTypeChar
Definition: lldb-enumerations.h:750
lldb_private::npdb::GetTypeSizeForSimpleKind
size_t GetTypeSizeForSimpleKind(llvm::codeview::SimpleTypeKind kind)
lldb::addr_t
uint64_t addr_t
Definition: lldb-types.h:83
lldb::BasicType
BasicType
Basic types enumeration for the public API SBType::GetBasicType().
Definition: lldb-enumerations.h:747
lldb_private::npdb::VariableInfo::name
llvm::StringRef name
Definition: PdbUtil.h:104
lldb_private::CompilerContextKind::Enum
@ Enum
MSVCUndecoratedNameParser::DropScope
static llvm::StringRef DropScope(llvm::StringRef name)
Definition: MSVCUndecoratedNameParser.cpp:98
lldb_private::npdb::MemberValLocation
Definition: DWARFLocationExpression.h:29
lldb_private::RangeVector::Append
void Append(const Entry &entry)
Definition: RangeMap.h:179
PdbIndex.h
lldb::eBasicTypeShort
@ eBasicTypeShort
Definition: lldb-enumerations.h:759
lldb_private::npdb::GetVariableNameInfo
VariableInfo GetVariableNameInfo(llvm::codeview::CVSymbol symbol)
lldb_private::npdb::GetRegisterSize
uint32_t GetRegisterSize(llvm::codeview::RegisterId register_id)
Definition: CodeViewRegisterMapping.cpp:654
lldb_private::DWARFExpressionList::AddExpression
bool AddExpression(lldb::addr_t base, lldb::addr_t end, DWARFExpression expr)
Definition: DWARFExpressionList.cpp:33
GetSegmentAndOffset< ThreadLocalDataSym >
SegmentOffset GetSegmentAndOffset< ThreadLocalDataSym >(const CVSymbol &sym)
Definition: PdbUtil.cpp:391
lldb_private::npdb::CVTagRecord::create
static CVTagRecord create(llvm::codeview::CVType type)
Definition: PdbUtil.cpp:198
lldb_private::npdb::CompilandIndexItem::m_compile_opts
llvm::Optional< llvm::codeview::Compile3Sym > m_compile_opts
Definition: CompileUnitIndex.h:65
lldb::eBasicTypeFloat
@ eBasicTypeFloat
Definition: lldb-enumerations.h:771
lldb::eBasicTypeUnsignedShort
@ eBasicTypeUnsignedShort
Definition: lldb-enumerations.h:760
error
static llvm::raw_ostream & error(Stream &strm)
Definition: CommandReturnObject.cpp:17
lldb_private::npdb::GetSizeOfType
size_t GetSizeOfType(PdbTypeSymId id, llvm::pdb::TpiStream &tpi)
Definition: PdbUtil.cpp:1065
GetSegmentAndOffset< DataSym >
SegmentOffset GetSegmentAndOffset< DataSym >(const CVSymbol &sym)
Definition: PdbUtil.cpp:385
LLDBAssert.h
GetSizeOfTypeInternal
static size_t GetSizeOfTypeInternal(CVType cvt)
Definition: PdbUtil.cpp:1059
GetSegmentAndOffset< TrampolineSym >
SegmentOffset GetSegmentAndOffset< TrampolineSym >(const CVSymbol &sym)
Definition: PdbUtil.cpp:369
lldb::eAccessNone
@ eAccessNone
Definition: lldb-enumerations.h:508
lldb_private::npdb::PdbIndex::tpi
llvm::pdb::TpiStream & tpi()
Definition: PdbIndex.h:124
lldb_private::npdb::GetCompilerTypeForSimpleKind
lldb::BasicType GetCompilerTypeForSimpleKind(llvm::codeview::SimpleTypeKind kind)
lldb::eBasicTypeInt
@ eBasicTypeInt
Definition: lldb-enumerations.h:761
lldb_private::DWARFExpression
Definition: DWARFExpression.h:36
llvm::pdb
Definition: DWARFLocationExpression.h:23
lldb_private::npdb::VariableInfo::location
DWARFExpressionList location
Definition: PdbUtil.h:106
lldb_private::CompilerContextKind::Union
@ Union
lldb::eBasicTypeChar8
@ eBasicTypeChar8
Definition: lldb-enumerations.h:758
lldb::eBasicTypeHalf
@ eBasicTypeHalf
Definition: lldb-enumerations.h:770
GetBaseFrameRegister
static RegisterId GetBaseFrameRegister(PdbIndex &index, PdbCompilandSymId frame_proc_id, bool is_parameter)
Definition: PdbUtil.cpp:711
lldb::eBasicTypeDouble
@ eBasicTypeDouble
Definition: lldb-enumerations.h:772
MSVCUndecoratedNameParser.h
lldb_private::npdb::PdbTypeSymId
Definition: PdbSymUid.h:70
lldb_private::npdb::PdbIndex::dbi
llvm::pdb::DbiStream & dbi()
Definition: PdbIndex.h:121
lldb_private::npdb::IsTagRecord
bool IsTagRecord(llvm::codeview::CVType cvt)
Definition: PdbUtil.cpp:517
lldb_private::npdb::PdbCompilandSymId::offset
uint32_t offset
Definition: PdbSymUid.h:54
lldb-enumerations.h
lldb_private::npdb::GetBestPossibleDecl
PdbTypeSymId GetBestPossibleDecl(PdbTypeSymId id, llvm::pdb::TpiStream &tpi)
lldb::eBasicTypeDoubleComplex
@ eBasicTypeDoubleComplex
Definition: lldb-enumerations.h:775
lldb::eBasicTypeVoid
@ eBasicTypeVoid
Definition: lldb-enumerations.h:749
lldb::eBasicTypeLong
@ eBasicTypeLong
Definition: lldb-enumerations.h:763
lldb::eBasicTypeUnsignedLongLong
@ eBasicTypeUnsignedLongLong
Definition: lldb-enumerations.h:766
lldb::eBasicTypeInt128
@ eBasicTypeInt128
Definition: lldb-enumerations.h:767
lldb_private::npdb::SymbolIsCode
bool SymbolIsCode(const llvm::codeview::CVSymbol &sym)
lldb_private::RangeVector::IsEmpty
bool IsEmpty() const
Definition: RangeMap.h:293
GetSegmentOffsetAndLength< TrampolineSym >
SegmentOffsetLength GetSegmentOffsetAndLength< TrampolineSym >(const CVSymbol &sym)
Definition: PdbUtil.cpp:450
lldb_private::RangeVector< lldb::addr_t, lldb::addr_t >
MakeRangeList
static Variable::RangeList MakeRangeList(const PdbIndex &index, const LocalVariableAddrRange &range, llvm::ArrayRef< LocalVariableAddrGap > gaps)
Definition: PdbUtil.cpp:36
PdbUtil.h
lldb_private::UserID::GetID
lldb::user_id_t GetID() const
Get accessor for the user ID.
Definition: UserID.h:47
lldb_private::npdb::SymbolHasAddress
bool SymbolHasAddress(const llvm::codeview::CVSymbol &sym)
lldb_private::CompilerContextKind::Class
@ Class
lldb::eBasicTypeUnsignedInt
@ eBasicTypeUnsignedInt
Definition: lldb-enumerations.h:762
lldb::eAccessPublic
@ eAccessPublic
Definition: lldb-enumerations.h:509
lldbassert
#define lldbassert(x)
Definition: LLDBAssert.h:15
GetSegmentOffsetAndLength< CoffGroupSym >
SegmentOffsetLength GetSegmentOffsetAndLength< CoffGroupSym >(const CVSymbol &sym)
Definition: PdbUtil.cpp:463
lldb_private::RangeVector< lldb::addr_t, lldb::addr_t >::Entry
Range< lldb::addr_t, lldb::addr_t > Entry
Definition: RangeMap.h:140
lldb_private::npdb::VariableInfo
Definition: PdbUtil.h:103
lldb_private::npdb::MakeVFrameRelLocationExpression
DWARFExpression MakeVFrameRelLocationExpression(llvm::StringRef fpo_program, int32_t offset, lldb::ModuleSP module)
Definition: DWARFLocationExpression.cpp:183
lldb::eBasicTypeLongDouble
@ eBasicTypeLongDouble
Definition: lldb-enumerations.h:773
lldb_private::npdb::CVTagRecord::CVTagRecord
CVTagRecord(llvm::codeview::ClassRecord &&c)
lldb_private::Block
Definition: Block.h:41
uint32_t
lldb::eAccessPrivate
@ eAccessPrivate
Definition: lldb-enumerations.h:510
PdbSymUid.h
id
void * id
Definition: PlatformiOSSimulatorCoreSimulatorSupport.h:20
DWARFLocationExpression.h
lldb_private::npdb::MakeEnregisteredLocationExpressionForComposite
DWARFExpression MakeEnregisteredLocationExpressionForComposite(const std::map< uint64_t, MemberValLocation > &offset_to_location, std::map< uint64_t, size_t > &offset_to_size, size_t total_size, lldb::ModuleSP module)
Definition: DWARFLocationExpression.cpp:260
lldb_private::RangeDataVector
Definition: RangeMap.h:440
lldb_private::npdb::PdbIndex::MakeVirtualAddress
lldb::addr_t MakeVirtualAddress(uint16_t segment, uint32_t offset) const
Definition: PdbIndex.cpp:61
UINT32_MAX
#define UINT32_MAX
Definition: lldb-defines.h:19
uint16_t
lldb::eBasicTypeSignedChar
@ eBasicTypeSignedChar
Definition: lldb-enumerations.h:751
LLDB_INVALID_ADDRESS
#define LLDB_INVALID_ADDRESS
Definition: lldb-defines.h:74
lldb::eBasicTypeLongLong
@ eBasicTypeLongLong
Definition: lldb-enumerations.h:765
GetCorrespondingFrameData
static llvm::FixedStreamArray< FrameData >::Iterator GetCorrespondingFrameData(lldb::addr_t load_addr, const DebugFrameDataSubsectionRef &fpo_data, const Variable::RangeList &ranges)
Definition: PdbUtil.cpp:661
lldb::eBasicTypeChar32
@ eBasicTypeChar32
Definition: lldb-enumerations.h:757
lldb::eBasicTypeLongDoubleComplex
@ eBasicTypeLongDoubleComplex
Definition: lldb-enumerations.h:776
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::npdb::MakeEnregisteredLocationExpression
DWARFExpression MakeEnregisteredLocationExpression(llvm::codeview::RegisterId reg, lldb::ModuleSP module)
Definition: DWARFLocationExpression.cpp:166
llvm::codeview
Definition: DWARFLocationExpression.h:20
Error
llvm::Error Error
Definition: UdtRecordCompleter.cpp:30
lldb::eBasicTypeUnsignedInt128
@ eBasicTypeUnsignedInt128
Definition: lldb-enumerations.h:768
GetSegmentAndOffset< CoffGroupSym >
SegmentOffset GetSegmentAndOffset< CoffGroupSym >(const CVSymbol &sym)
Definition: PdbUtil.cpp:380
lldb_private::npdb::PdbIndex::pdb
llvm::pdb::PDBFile & pdb()
Definition: PdbIndex.h:118
Entry
FormatEntity::Entry Entry
Definition: FormatEntity.cpp:82
lldb_private::DWARFExpressionList
Definition: DWARFExpressionList.h:24
createRecord
RecordT createRecord(const CVSymbol &sym)
Definition: PdbUtil.cpp:356
lldb_private::npdb::PdbSymUid
Definition: PdbSymUid.h:91
lldb_private::DWARFExpression::IsValid
bool IsValid() const
Return true if the location expression contains data.
Definition: DWARFExpression.cpp:56
lldb_private::npdb::CVTagRecord
Definition: PdbUtil.h:38
GetSegmentOffsetAndLength< Thunk32Sym >
SegmentOffsetLength GetSegmentOffsetAndLength< Thunk32Sym >(const CVSymbol &sym)
Definition: PdbUtil.cpp:456
lldb_private::npdb::VariableInfo::is_param
bool is_param
Definition: PdbUtil.h:107
lldb::eBasicTypeWChar
@ eBasicTypeWChar
Definition: lldb-enumerations.h:753
CodeViewRegisterMapping.h
LLDBLog.h
lldb::AccessType
AccessType
Definition: lldb-enumerations.h:507
lldb_private::CompilerContextKind::Struct
@ Struct
lldb_private::npdb::GetVariableLocationInfo
VariableInfo GetVariableLocationInfo(PdbIndex &index, PdbCompilandSymId var_id, Block &func_block, lldb::ModuleSP module)
Definition: PdbUtil.cpp:730
lldb_private::npdb::IsForwardRefUdt
bool IsForwardRefUdt(llvm::codeview::CVType cvt)
lldb::eBasicTypeUnsignedChar
@ eBasicTypeUnsignedChar
Definition: lldb-enumerations.h:752