LLDB  mainline
NSSet.cpp
Go to the documentation of this file.
1 //===-- NSSet.cpp -----------------------------------------------*- C++ -*-===//
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 "NSSet.h"
10 
12 #include "lldb/Core/ValueObject.h"
16 #include "lldb/Target/Language.h"
18 #include "lldb/Target/Target.h"
20 #include "lldb/Utility/Endian.h"
21 #include "lldb/Utility/Status.h"
22 #include "lldb/Utility/Stream.h"
23 
24 using namespace lldb;
25 using namespace lldb_private;
26 using namespace lldb_private::formatters;
27 
28 std::map<ConstString, CXXFunctionSummaryFormat::Callback> &
29 NSSet_Additionals::GetAdditionalSummaries() {
30  static std::map<ConstString, CXXFunctionSummaryFormat::Callback> g_map;
31  return g_map;
32 }
33 
34 std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback> &
35 NSSet_Additionals::GetAdditionalSynthetics() {
36  static std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback>
37  g_map;
38  return g_map;
39 }
40 
41 namespace lldb_private {
42 namespace formatters {
44 public:
45  NSSetISyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
46 
47  ~NSSetISyntheticFrontEnd() override;
48 
49  size_t CalculateNumChildren() override;
50 
51  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
52 
53  bool Update() override;
54 
55  bool MightHaveChildren() override;
56 
57  size_t GetIndexOfChildWithName(ConstString name) override;
58 
59 private:
60  struct DataDescriptor_32 {
61  uint32_t _used : 26;
62  uint32_t _szidx : 6;
63  };
64 
65  struct DataDescriptor_64 {
66  uint64_t _used : 58;
67  uint32_t _szidx : 6;
68  };
69 
70  struct SetItemDescriptor {
71  lldb::addr_t item_ptr;
72  lldb::ValueObjectSP valobj_sp;
73  };
74 
75  ExecutionContextRef m_exe_ctx_ref;
76  uint8_t m_ptr_size;
77  DataDescriptor_32 *m_data_32;
78  DataDescriptor_64 *m_data_64;
79  lldb::addr_t m_data_ptr;
80  std::vector<SetItemDescriptor> m_children;
81 };
82 
83 template <typename D32, typename D64>
85 public:
86  GenericNSSetMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
87 
89 
90  size_t CalculateNumChildren() override;
91 
92  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
93 
94  bool Update() override;
95 
96  bool MightHaveChildren() override;
97 
98  size_t GetIndexOfChildWithName(ConstString name) override;
99 
100 private:
101 
102  struct SetItemDescriptor {
103  lldb::addr_t item_ptr;
104  lldb::ValueObjectSP valobj_sp;
105  };
106 
107  ExecutionContextRef m_exe_ctx_ref;
108  uint8_t m_ptr_size;
109  D32 *m_data_32;
110  D64 *m_data_64;
111  std::vector<SetItemDescriptor> m_children;
112 };
113 
114 namespace Foundation1300 {
120  };
121 
123  uint64_t _used : 58;
124  uint64_t _size;
125  uint64_t _mutations;
126  uint64_t _objs_addr;
127  };
128 
131 }
132 
133 namespace Foundation1428 {
134  struct DataDescriptor_32 {
135  uint32_t _used : 26;
136  uint32_t _size;
139  };
140 
141  struct DataDescriptor_64 {
142  uint64_t _used : 58;
143  uint64_t _size;
144  uint64_t _objs_addr;
145  uint64_t _mutations;
146  };
147 
150 }
151 
152 namespace Foundation1437 {
153  struct DataDescriptor_32 {
155  // __table storage
157  uint32_t _muts;
158  uint32_t _used : 26;
159  uint32_t _szidx : 6;
160  };
161 
162  struct DataDescriptor_64 {
163  uint64_t _cow;
164  // __Table storage
165  uint64_t _objs_addr;
166  uint32_t _muts;
167  uint32_t _used : 26;
168  uint32_t _szidx : 6;
169  };
170 
173 
174  template <typename DD>
175  uint64_t
177  Status &error) {
178  const lldb::addr_t start_of_descriptor =
179  valobj_addr + process.GetAddressByteSize();
180  DD descriptor = DD();
181  process.ReadMemory(start_of_descriptor, &descriptor, sizeof(descriptor),
182  error);
183  if (error.Fail()) {
184  return 0;
185  }
186  return descriptor._used;
187  }
188 
189  uint64_t
191  Status &error) {
192  if (process.GetAddressByteSize() == 4) {
193  return __NSSetMSize_Impl<DataDescriptor_32>(process, valobj_addr, error);
194  } else {
195  return __NSSetMSize_Impl<DataDescriptor_64>(process, valobj_addr, error);
196  }
197  }
198 }
199 
201 public:
202  NSSetCodeRunningSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
203 
205 
206  size_t CalculateNumChildren() override;
207 
208  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
209 
210  bool Update() override;
211 
212  bool MightHaveChildren() override;
213 
214  size_t GetIndexOfChildWithName(ConstString name) override;
215 };
216 } // namespace formatters
217 } // namespace lldb_private
218 
219 template <bool cf_style>
221  ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
222  static ConstString g_TypeHint("NSSet");
223 
224  ProcessSP process_sp = valobj.GetProcessSP();
225  if (!process_sp)
226  return false;
227 
228  ObjCLanguageRuntime *runtime =
229  (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
231 
232  if (!runtime)
233  return false;
234 
236  runtime->GetClassDescriptor(valobj));
237 
238  if (!descriptor || !descriptor->IsValid())
239  return false;
240 
241  uint32_t ptr_size = process_sp->GetAddressByteSize();
242  bool is_64bit = (ptr_size == 8);
243 
244  lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
245 
246  if (!valobj_addr)
247  return false;
248 
249  uint64_t value = 0;
250 
251  ConstString class_name_cs = descriptor->GetClassName();
252  const char *class_name = class_name_cs.GetCString();
253 
254  if (!class_name || !*class_name)
255  return false;
256 
257  if (!strcmp(class_name, "__NSSetI") ||
258  !strcmp(class_name, "__NSOrderedSetI")) {
259  Status error;
260  value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
261  ptr_size, 0, error);
262  if (error.Fail())
263  return false;
264  value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
265  } else if (!strcmp(class_name, "__NSSetM")) {
266  AppleObjCRuntime *apple_runtime =
267  llvm::dyn_cast_or_null<AppleObjCRuntime>(runtime);
268  Status error;
269  if (apple_runtime && apple_runtime->GetFoundationVersion() >= 1437) {
270  value = Foundation1437::__NSSetMSize(*process_sp, valobj_addr, error);
271  } else {
272  value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
273  ptr_size, 0, error);
274  value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
275  }
276  if (error.Fail())
277  return false;
278  } else {
279  auto &map(NSSet_Additionals::GetAdditionalSummaries());
280  auto iter = map.find(class_name_cs), end = map.end();
281  if (iter != end)
282  return iter->second(valobj, stream, options);
283  else
284  return false;
285  }
286 
287  std::string prefix, suffix;
288  if (Language *language = Language::FindPlugin(options.GetLanguage())) {
289  if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix,
290  suffix)) {
291  prefix.clear();
292  suffix.clear();
293  }
294  }
295 
296  stream.Printf("%s%" PRIu64 " %s%s%s", prefix.c_str(), value, "element",
297  value == 1 ? "" : "s", suffix.c_str());
298  return true;
299 }
300 
303  CXXSyntheticChildren *synth, lldb::ValueObjectSP valobj_sp) {
304  lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
305  if (!process_sp)
306  return nullptr;
307  ObjCLanguageRuntime *runtime =
308  (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
310  if (!runtime)
311  return nullptr;
312 
313  CompilerType valobj_type(valobj_sp->GetCompilerType());
314  Flags flags(valobj_type.GetTypeInfo());
315 
316  if (flags.IsClear(eTypeIsPointer)) {
317  Status error;
318  valobj_sp = valobj_sp->AddressOf(error);
319  if (error.Fail() || !valobj_sp)
320  return nullptr;
321  }
322 
324  runtime->GetClassDescriptor(*valobj_sp));
325 
326  if (!descriptor || !descriptor->IsValid())
327  return nullptr;
328 
329  ConstString class_name_cs = descriptor->GetClassName();
330  const char *class_name = class_name_cs.GetCString();
331 
332  if (!class_name || !*class_name)
333  return nullptr;
334 
335  if (!strcmp(class_name, "__NSSetI") ||
336  !strcmp(class_name, "__NSOrderedSetI")) {
337  return (new NSSetISyntheticFrontEnd(valobj_sp));
338  } else if (!strcmp(class_name, "__NSSetM")) {
339  AppleObjCRuntime *apple_runtime =
340  llvm::dyn_cast_or_null<AppleObjCRuntime>(runtime);
341  if (apple_runtime) {
342  if (apple_runtime->GetFoundationVersion() >= 1437)
343  return (new Foundation1437::NSSetMSyntheticFrontEnd(valobj_sp));
344  else if (apple_runtime->GetFoundationVersion() >= 1428)
345  return (new Foundation1428::NSSetMSyntheticFrontEnd(valobj_sp));
346  else
347  return (new Foundation1300::NSSetMSyntheticFrontEnd(valobj_sp));
348  } else {
349  return (new Foundation1300::NSSetMSyntheticFrontEnd(valobj_sp));
350  }
351  } else {
352  auto &map(NSSet_Additionals::GetAdditionalSynthetics());
353  auto iter = map.find(class_name_cs), end = map.end();
354  if (iter != end)
355  return iter->second(synth, valobj_sp);
356  return nullptr;
357  }
358 }
359 
361  lldb::ValueObjectSP valobj_sp)
362  : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8),
363  m_data_32(nullptr), m_data_64(nullptr) {
364  if (valobj_sp)
365  Update();
366 }
367 
369  delete m_data_32;
370  m_data_32 = nullptr;
371  delete m_data_64;
372  m_data_64 = nullptr;
373 }
374 
375 size_t
377  ConstString name) {
378  const char *item_name = name.GetCString();
379  uint32_t idx = ExtractIndexFromString(item_name);
380  if (idx < UINT32_MAX && idx >= CalculateNumChildren())
381  return UINT32_MAX;
382  return idx;
383 }
384 
385 size_t
387  if (!m_data_32 && !m_data_64)
388  return 0;
389  return (m_data_32 ? m_data_32->_used : m_data_64->_used);
390 }
391 
393  m_children.clear();
394  delete m_data_32;
395  m_data_32 = nullptr;
396  delete m_data_64;
397  m_data_64 = nullptr;
398  m_ptr_size = 0;
399  ValueObjectSP valobj_sp = m_backend.GetSP();
400  if (!valobj_sp)
401  return false;
402  if (!valobj_sp)
403  return false;
404  m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
405  Status error;
406  if (valobj_sp->IsPointerType()) {
407  valobj_sp = valobj_sp->Dereference(error);
408  if (error.Fail() || !valobj_sp)
409  return false;
410  }
411  error.Clear();
412  lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
413  if (!process_sp)
414  return false;
415  m_ptr_size = process_sp->GetAddressByteSize();
416  uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size;
417  if (m_ptr_size == 4) {
418  m_data_32 = new DataDescriptor_32();
419  process_sp->ReadMemory(data_location, m_data_32, sizeof(DataDescriptor_32),
420  error);
421  } else {
422  m_data_64 = new DataDescriptor_64();
423  process_sp->ReadMemory(data_location, m_data_64, sizeof(DataDescriptor_64),
424  error);
425  }
426  if (error.Fail())
427  return false;
428  m_data_ptr = data_location + m_ptr_size;
429  return false;
430 }
431 
433  return true;
434 }
435 
436 lldb::ValueObjectSP
438  uint32_t num_children = CalculateNumChildren();
439 
440  if (idx >= num_children)
441  return lldb::ValueObjectSP();
442 
443  ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
444  if (!process_sp)
445  return lldb::ValueObjectSP();
446 
447  if (m_children.empty()) {
448  // do the scan phase
449  lldb::addr_t obj_at_idx = 0;
450 
451  uint32_t tries = 0;
452  uint32_t test_idx = 0;
453 
454  while (tries < num_children) {
455  obj_at_idx = m_data_ptr + (test_idx * m_ptr_size);
456  if (!process_sp)
457  return lldb::ValueObjectSP();
458  Status error;
459  obj_at_idx = process_sp->ReadPointerFromMemory(obj_at_idx, error);
460  if (error.Fail())
461  return lldb::ValueObjectSP();
462 
463  test_idx++;
464 
465  if (!obj_at_idx)
466  continue;
467  tries++;
468 
469  SetItemDescriptor descriptor = {obj_at_idx, lldb::ValueObjectSP()};
470 
471  m_children.push_back(descriptor);
472  }
473  }
474 
475  if (idx >= m_children.size()) // should never happen
476  return lldb::ValueObjectSP();
477 
478  SetItemDescriptor &set_item = m_children[idx];
479  if (!set_item.valobj_sp) {
480  auto ptr_size = process_sp->GetAddressByteSize();
481  DataBufferHeap buffer(ptr_size, 0);
482  switch (ptr_size) {
483  case 0: // architecture has no clue?? - fail
484  return lldb::ValueObjectSP();
485  case 4:
486  *((uint32_t *)buffer.GetBytes()) = (uint32_t)set_item.item_ptr;
487  break;
488  case 8:
489  *((uint64_t *)buffer.GetBytes()) = (uint64_t)set_item.item_ptr;
490  break;
491  default:
492  assert(false && "pointer size is not 4 nor 8 - get out of here ASAP");
493  }
494  StreamString idx_name;
495  idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
496 
497  DataExtractor data(buffer.GetBytes(), buffer.GetByteSize(),
498  process_sp->GetByteOrder(),
499  process_sp->GetAddressByteSize());
500 
501  set_item.valobj_sp = CreateValueObjectFromData(
502  idx_name.GetString(), data, m_exe_ctx_ref,
505  }
506  return set_item.valobj_sp;
507 }
508 
509 template <typename D32, typename D64>
512  lldb::ValueObjectSP valobj_sp)
513  : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8),
514  m_data_32(nullptr), m_data_64(nullptr) {
515  if (valobj_sp)
516  Update();
517 }
518 
519 template <typename D32, typename D64>
522  delete m_data_32;
523  m_data_32 = nullptr;
524  delete m_data_64;
525  m_data_64 = nullptr;
526 }
527 
528 template <typename D32, typename D64>
529 size_t
532  ConstString name) {
533  const char *item_name = name.GetCString();
534  uint32_t idx = ExtractIndexFromString(item_name);
535  if (idx < UINT32_MAX && idx >= CalculateNumChildren())
536  return UINT32_MAX;
537  return idx;
538 }
539 
540 template <typename D32, typename D64>
541 size_t
544  if (!m_data_32 && !m_data_64)
545  return 0;
546  return (m_data_32 ? m_data_32->_used : m_data_64->_used);
547 }
548 
549 template <typename D32, typename D64>
550 bool
553  m_children.clear();
554  ValueObjectSP valobj_sp = m_backend.GetSP();
555  m_ptr_size = 0;
556  delete m_data_32;
557  m_data_32 = nullptr;
558  delete m_data_64;
559  m_data_64 = nullptr;
560  if (!valobj_sp)
561  return false;
562  if (!valobj_sp)
563  return false;
564  m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
565  Status error;
566  if (valobj_sp->IsPointerType()) {
567  valobj_sp = valobj_sp->Dereference(error);
568  if (error.Fail() || !valobj_sp)
569  return false;
570  }
571  error.Clear();
572  lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
573  if (!process_sp)
574  return false;
575  m_ptr_size = process_sp->GetAddressByteSize();
576  uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size;
577  if (m_ptr_size == 4) {
578  m_data_32 = new D32();
579  process_sp->ReadMemory(data_location, m_data_32, sizeof(D32),
580  error);
581  } else {
582  m_data_64 = new D64();
583  process_sp->ReadMemory(data_location, m_data_64, sizeof(D64),
584  error);
585  }
586  if (error.Fail())
587  return false;
588  return false;
589 }
590 
591 template <typename D32, typename D64>
592 bool
595  return true;
596 }
597 
598 template <typename D32, typename D64>
599 lldb::ValueObjectSP
602  lldb::addr_t m_objs_addr =
603  (m_data_32 ? m_data_32->_objs_addr : m_data_64->_objs_addr);
604 
605  uint32_t num_children = CalculateNumChildren();
606 
607  if (idx >= num_children)
608  return lldb::ValueObjectSP();
609 
610  ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
611  if (!process_sp)
612  return lldb::ValueObjectSP();
613 
614  if (m_children.empty()) {
615  // do the scan phase
616  lldb::addr_t obj_at_idx = 0;
617 
618  uint32_t tries = 0;
619  uint32_t test_idx = 0;
620 
621  while (tries < num_children) {
622  obj_at_idx = m_objs_addr + (test_idx * m_ptr_size);
623  if (!process_sp)
624  return lldb::ValueObjectSP();
625  Status error;
626  obj_at_idx = process_sp->ReadPointerFromMemory(obj_at_idx, error);
627  if (error.Fail())
628  return lldb::ValueObjectSP();
629 
630  test_idx++;
631 
632  if (!obj_at_idx)
633  continue;
634  tries++;
635 
636  SetItemDescriptor descriptor = {obj_at_idx, lldb::ValueObjectSP()};
637 
638  m_children.push_back(descriptor);
639  }
640  }
641 
642  if (idx >= m_children.size()) // should never happen
643  return lldb::ValueObjectSP();
644 
645  SetItemDescriptor &set_item = m_children[idx];
646  if (!set_item.valobj_sp) {
647  auto ptr_size = process_sp->GetAddressByteSize();
648  DataBufferHeap buffer(ptr_size, 0);
649  switch (ptr_size) {
650  case 0: // architecture has no clue?? - fail
651  return lldb::ValueObjectSP();
652  case 4:
653  *((uint32_t *)buffer.GetBytes()) = (uint32_t)set_item.item_ptr;
654  break;
655  case 8:
656  *((uint64_t *)buffer.GetBytes()) = (uint64_t)set_item.item_ptr;
657  break;
658  default:
659  assert(false && "pointer size is not 4 nor 8 - get out of here ASAP");
660  }
661  StreamString idx_name;
662  idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
663 
664  DataExtractor data(buffer.GetBytes(), buffer.GetByteSize(),
665  process_sp->GetByteOrder(),
666  process_sp->GetAddressByteSize());
667 
668  set_item.valobj_sp = CreateValueObjectFromData(
669  idx_name.GetString(), data, m_exe_ctx_ref,
672  }
673  return set_item.valobj_sp;
674 }
675 
676 template bool lldb_private::formatters::NSSetSummaryProvider<true>(
677  ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options);
678 
679 template bool lldb_private::formatters::NSSetSummaryProvider<false>(
680  ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options);
An data extractor class.
Definition: DataExtractor.h:47
CompilerType GetCompilerType()
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
uint64_t __NSSetMSize_Impl(lldb_private::Process &process, lldb::addr_t valobj_addr, Status &error)
Definition: NSSet.cpp:176
lldb::ProcessSP GetProcessSP() const
Get accessor that creates a strong reference from the weak process reference contained in this object...
uint64_t __NSSetMSize(lldb_private::Process &process, lldb::addr_t valobj_addr, Status &error)
Definition: NSSet.cpp:190
std::shared_ptr< ClassDescriptor > ClassDescriptorSP
CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) const
GenericNSSetMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
Definition: NSSet.cpp:511
A subclass of DataBuffer that stores a data buffer on the heap.
size_t GetIndexOfChildWithName(ConstString name) override
Definition: NSSet.cpp:531
lldb::LanguageType GetLanguage() const
Definition: TypeSummary.cpp:42
size_t ExtractIndexFromString(const char *item_name)
SyntheticChildrenFrontEnd * NSSetSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
Definition: NSSet.cpp:302
#define UINT32_MAX
Definition: lldb-defines.h:31
lldb::ValueObjectSP CreateValueObjectFromData(llvm::StringRef name, const DataExtractor &data, const ExecutionContext &exe_ctx, CompilerType type)
void Clear()
Clear the object state.
Definition: Status.cpp:167
uint32_t GetAddressByteSize() const
Definition: Process.cpp:3370
llvm::StringRef GetString() const
A plug-in interface definition class for debugging a process.
Definition: Process.h:353
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:106
Execution context objects refer to objects in the execution of the program that is being debugged...
static size_t CalculateNumChildren(CompilerType container_type, CompilerType element_type, lldb_private::ExecutionContextScope *exe_scope=nullptr)
Definition: VectorType.cpp:168
bool NSSetSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition: NSSet.cpp:220
A class to manage flags.
Definition: Flags.h:22
uint64_t addr_t
Definition: lldb-types.h:83
size_t GetIndexOfChildWithName(ConstString name) override
Definition: NSSet.cpp:376
lldb::ValueObjectSP GetChildAtIndex(size_t idx) override
Definition: NSSet.cpp:601
A uniqued constant string class.
Definition: ConstString.h:38
bool Fail() const
Test for error condition.
Definition: Status.cpp:181
const char * GetCString() const
Get the string value as a C string.
Definition: ConstString.h:247
NSSetISyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
Definition: NSSet.cpp:360
lldb::ProcessSP GetProcessSP() const
Definition: ValueObject.h:361
virtual uint64_t GetValueAsUnsigned(uint64_t fail_value, bool *success=nullptr)
Definition: SBAddress.h:15
lldb::ValueObjectSP GetSP()
Definition: ValueObject.h:565
uint8_t * GetBytes() override
virtual ClassDescriptorSP GetClassDescriptor(ValueObject &in_value)
lldb::offset_t GetByteSize() const override
An error handling class.
Definition: Status.h:44
lldb::ValueObjectSP GetChildAtIndex(size_t idx) override
Definition: NSSet.cpp:437
virtual size_t ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, Status &error)
Read of memory from a process.
Definition: Process.cpp:1966