LLDB  mainline
AppleObjCClassDescriptorV2.cpp
Go to the documentation of this file.
1 //===-- AppleObjCClassDescriptorV2.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 
10 
12 #include "lldb/Utility/Log.h"
13 
14 using namespace lldb;
15 using namespace lldb_private;
16 
17 bool ClassDescriptorV2::Read_objc_class(
18  Process *process, std::unique_ptr<objc_class_t> &objc_class) const {
19  objc_class = std::make_unique<objc_class_t>();
20 
21  bool ret = objc_class->Read(process, m_objc_class_ptr);
22 
23  if (!ret)
24  objc_class.reset();
25 
26  return ret;
27 }
28 
30  switch (process->GetAddressByteSize()) {
31  case 4:
32  return 0xfffffffcUL;
33  case 8:
34  return 0x00007ffffffffff8UL;
35  default:
36  break;
37  }
38 
39  return LLDB_INVALID_ADDRESS;
40 }
41 
42 bool ClassDescriptorV2::objc_class_t::Read(Process *process,
43  lldb::addr_t addr) {
44  size_t ptr_size = process->GetAddressByteSize();
45 
46  size_t objc_class_size = ptr_size // uintptr_t isa;
47  + ptr_size // Class superclass;
48  + ptr_size // void *cache;
49  + ptr_size // IMP *vtable;
50  + ptr_size; // uintptr_t data_NEVER_USE;
51 
52  DataBufferHeap objc_class_buf(objc_class_size, '\0');
53  Status error;
54 
55  process->ReadMemory(addr, objc_class_buf.GetBytes(), objc_class_size, error);
56  if (error.Fail()) {
57  return false;
58  }
59 
60  DataExtractor extractor(objc_class_buf.GetBytes(), objc_class_size,
61  process->GetByteOrder(),
62  process->GetAddressByteSize());
63 
64  lldb::offset_t cursor = 0;
65 
66  m_isa = extractor.GetAddress_unchecked(&cursor); // uintptr_t isa;
67  m_superclass = extractor.GetAddress_unchecked(&cursor); // Class superclass;
68  m_cache_ptr = extractor.GetAddress_unchecked(&cursor); // void *cache;
69  m_vtable_ptr = extractor.GetAddress_unchecked(&cursor); // IMP *vtable;
70  lldb::addr_t data_NEVER_USE =
71  extractor.GetAddress_unchecked(&cursor); // uintptr_t data_NEVER_USE;
72 
73  m_flags = (uint8_t)(data_NEVER_USE & (lldb::addr_t)3);
74  m_data_ptr = data_NEVER_USE & GetClassDataMask(process);
75 
76  return true;
77 }
78 
79 bool ClassDescriptorV2::class_rw_t::Read(Process *process, lldb::addr_t addr) {
80  size_t ptr_size = process->GetAddressByteSize();
81 
82  size_t size = sizeof(uint32_t) // uint32_t flags;
83  + sizeof(uint32_t) // uint32_t version;
84  + ptr_size // const class_ro_t *ro;
85  + ptr_size // union { method_list_t **method_lists;
86  // method_list_t *method_list; };
87  + ptr_size // struct chained_property_list *properties;
88  + ptr_size // const protocol_list_t **protocols;
89  + ptr_size // Class firstSubclass;
90  + ptr_size; // Class nextSiblingClass;
91 
92  DataBufferHeap buffer(size, '\0');
93  Status error;
94 
95  process->ReadMemory(addr, buffer.GetBytes(), size, error);
96  if (error.Fail()) {
97  return false;
98  }
99 
100  DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(),
101  process->GetAddressByteSize());
102 
103  lldb::offset_t cursor = 0;
104 
105  m_flags = extractor.GetU32_unchecked(&cursor);
106  m_version = extractor.GetU32_unchecked(&cursor);
107  m_ro_ptr = extractor.GetAddress_unchecked(&cursor);
108  m_method_list_ptr = extractor.GetAddress_unchecked(&cursor);
109  m_properties_ptr = extractor.GetAddress_unchecked(&cursor);
110  m_firstSubclass = extractor.GetAddress_unchecked(&cursor);
111  m_nextSiblingClass = extractor.GetAddress_unchecked(&cursor);
112 
113  if (m_ro_ptr & 1) {
114  DataBufferHeap buffer(ptr_size, '\0');
115  process->ReadMemory(m_ro_ptr ^ 1, buffer.GetBytes(), ptr_size, error);
116  if (error.Fail())
117  return false;
118  cursor = 0;
119  DataExtractor extractor(buffer.GetBytes(), ptr_size,
120  process->GetByteOrder(),
121  process->GetAddressByteSize());
122  m_ro_ptr = extractor.GetAddress_unchecked(&cursor);
123  }
124 
125  return true;
126 }
127 
128 bool ClassDescriptorV2::class_ro_t::Read(Process *process, lldb::addr_t addr) {
129  size_t ptr_size = process->GetAddressByteSize();
130 
131  size_t size = sizeof(uint32_t) // uint32_t flags;
132  + sizeof(uint32_t) // uint32_t instanceStart;
133  + sizeof(uint32_t) // uint32_t instanceSize;
134  + (ptr_size == 8 ? sizeof(uint32_t)
135  : 0) // uint32_t reserved; // __LP64__ only
136  + ptr_size // const uint8_t *ivarLayout;
137  + ptr_size // const char *name;
138  + ptr_size // const method_list_t *baseMethods;
139  + ptr_size // const protocol_list_t *baseProtocols;
140  + ptr_size // const ivar_list_t *ivars;
141  + ptr_size // const uint8_t *weakIvarLayout;
142  + ptr_size; // const property_list_t *baseProperties;
143 
144  DataBufferHeap buffer(size, '\0');
145  Status error;
146 
147  process->ReadMemory(addr, buffer.GetBytes(), size, error);
148  if (error.Fail()) {
149  return false;
150  }
151 
152  DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(),
153  process->GetAddressByteSize());
154 
155  lldb::offset_t cursor = 0;
156 
157  m_flags = extractor.GetU32_unchecked(&cursor);
158  m_instanceStart = extractor.GetU32_unchecked(&cursor);
159  m_instanceSize = extractor.GetU32_unchecked(&cursor);
160  if (ptr_size == 8)
161  m_reserved = extractor.GetU32_unchecked(&cursor);
162  else
163  m_reserved = 0;
164  m_ivarLayout_ptr = extractor.GetAddress_unchecked(&cursor);
165  m_name_ptr = extractor.GetAddress_unchecked(&cursor);
166  m_baseMethods_ptr = extractor.GetAddress_unchecked(&cursor);
167  m_baseProtocols_ptr = extractor.GetAddress_unchecked(&cursor);
168  m_ivars_ptr = extractor.GetAddress_unchecked(&cursor);
169  m_weakIvarLayout_ptr = extractor.GetAddress_unchecked(&cursor);
170  m_baseProperties_ptr = extractor.GetAddress_unchecked(&cursor);
171 
172  DataBufferHeap name_buf(1024, '\0');
173 
174  process->ReadCStringFromMemory(m_name_ptr, (char *)name_buf.GetBytes(),
175  name_buf.GetByteSize(), error);
176 
177  if (error.Fail()) {
178  return false;
179  }
180 
181  m_name.assign((char *)name_buf.GetBytes());
182 
183  return true;
184 }
185 
186 bool ClassDescriptorV2::Read_class_row(
187  Process *process, const objc_class_t &objc_class,
188  std::unique_ptr<class_ro_t> &class_ro,
189  std::unique_ptr<class_rw_t> &class_rw) const {
190  class_ro.reset();
191  class_rw.reset();
192 
193  Status error;
194  uint32_t class_row_t_flags = process->ReadUnsignedIntegerFromMemory(
195  objc_class.m_data_ptr, sizeof(uint32_t), 0, error);
196  if (!error.Success())
197  return false;
198 
199  if (class_row_t_flags & RW_REALIZED) {
200  class_rw = std::make_unique<class_rw_t>();
201 
202  if (!class_rw->Read(process, objc_class.m_data_ptr)) {
203  class_rw.reset();
204  return false;
205  }
206 
207  class_ro = std::make_unique<class_ro_t>();
208 
209  if (!class_ro->Read(process, class_rw->m_ro_ptr)) {
210  class_rw.reset();
211  class_ro.reset();
212  return false;
213  }
214  } else {
215  class_ro = std::make_unique<class_ro_t>();
216 
217  if (!class_ro->Read(process, objc_class.m_data_ptr)) {
218  class_ro.reset();
219  return false;
220  }
221  }
222 
223  return true;
224 }
225 
226 bool ClassDescriptorV2::method_list_t::Read(Process *process,
227  lldb::addr_t addr) {
228  size_t size = sizeof(uint32_t) // uint32_t entsize_NEVER_USE;
229  + sizeof(uint32_t); // uint32_t count;
230 
231  DataBufferHeap buffer(size, '\0');
232  Status error;
233 
234  process->ReadMemory(addr, buffer.GetBytes(), size, error);
235  if (error.Fail()) {
236  return false;
237  }
238 
239  DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(),
240  process->GetAddressByteSize());
241 
242  lldb::offset_t cursor = 0;
243 
244  uint32_t entsize = extractor.GetU32_unchecked(&cursor);
245  m_is_small = (entsize & 0x80000000) != 0;
246  m_has_direct_selector = (entsize & 0x40000000) != 0;
247  m_entsize = entsize & 0xfffc;
248  m_count = extractor.GetU32_unchecked(&cursor);
249  m_first_ptr = addr + cursor;
250 
251  return true;
252 }
253 
254 bool ClassDescriptorV2::method_t::Read(Process *process, lldb::addr_t addr,
255  lldb::addr_t relative_selector_base_addr,
256  bool is_small, bool has_direct_sel) {
257  size_t ptr_size = process->GetAddressByteSize();
258  size_t size = GetSize(process, is_small);
259 
260  DataBufferHeap buffer(size, '\0');
261  Status error;
262 
263  process->ReadMemory(addr, buffer.GetBytes(), size, error);
264  if (error.Fail()) {
265  return false;
266  }
267 
268  DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(),
269  ptr_size);
270  lldb::offset_t cursor = 0;
271 
272  if (is_small) {
273  uint32_t nameref_offset = extractor.GetU32_unchecked(&cursor);
274  uint32_t types_offset = extractor.GetU32_unchecked(&cursor);
275  uint32_t imp_offset = extractor.GetU32_unchecked(&cursor);
276 
277  m_name_ptr = addr + nameref_offset;
278 
279  if (!has_direct_sel) {
280  // The SEL offset points to a SELRef. We need to dereference twice.
281  m_name_ptr = process->ReadUnsignedIntegerFromMemory(m_name_ptr, ptr_size,
282  0, error);
283  if (!error.Success())
284  return false;
285  } else if (relative_selector_base_addr != LLDB_INVALID_ADDRESS) {
286  m_name_ptr = relative_selector_base_addr + nameref_offset;
287  }
288  m_types_ptr = addr + 4 + types_offset;
289  m_imp_ptr = addr + 8 + imp_offset;
290  } else {
291  m_name_ptr = extractor.GetAddress_unchecked(&cursor);
292  m_types_ptr = extractor.GetAddress_unchecked(&cursor);
293  m_imp_ptr = extractor.GetAddress_unchecked(&cursor);
294  }
295 
296  process->ReadCStringFromMemory(m_name_ptr, m_name, error);
297  if (error.Fail()) {
298  return false;
299  }
300 
301  process->ReadCStringFromMemory(m_types_ptr, m_types, error);
302  return !error.Fail();
303 }
304 
305 bool ClassDescriptorV2::ivar_list_t::Read(Process *process, lldb::addr_t addr) {
306  size_t size = sizeof(uint32_t) // uint32_t entsize;
307  + sizeof(uint32_t); // uint32_t count;
308 
309  DataBufferHeap buffer(size, '\0');
310  Status error;
311 
312  process->ReadMemory(addr, buffer.GetBytes(), size, error);
313  if (error.Fail()) {
314  return false;
315  }
316 
317  DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(),
318  process->GetAddressByteSize());
319 
320  lldb::offset_t cursor = 0;
321 
322  m_entsize = extractor.GetU32_unchecked(&cursor);
323  m_count = extractor.GetU32_unchecked(&cursor);
324  m_first_ptr = addr + cursor;
325 
326  return true;
327 }
328 
329 bool ClassDescriptorV2::ivar_t::Read(Process *process, lldb::addr_t addr) {
330  size_t size = GetSize(process);
331 
332  DataBufferHeap buffer(size, '\0');
333  Status error;
334 
335  process->ReadMemory(addr, buffer.GetBytes(), size, error);
336  if (error.Fail()) {
337  return false;
338  }
339 
340  DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(),
341  process->GetAddressByteSize());
342 
343  lldb::offset_t cursor = 0;
344 
345  m_offset_ptr = extractor.GetAddress_unchecked(&cursor);
346  m_name_ptr = extractor.GetAddress_unchecked(&cursor);
347  m_type_ptr = extractor.GetAddress_unchecked(&cursor);
348  m_alignment = extractor.GetU32_unchecked(&cursor);
349  m_size = extractor.GetU32_unchecked(&cursor);
350 
351  process->ReadCStringFromMemory(m_name_ptr, m_name, error);
352  if (error.Fail()) {
353  return false;
354  }
355 
356  process->ReadCStringFromMemory(m_type_ptr, m_type, error);
357  return !error.Fail();
358 }
359 
360 bool ClassDescriptorV2::Describe(
361  std::function<void(ObjCLanguageRuntime::ObjCISA)> const &superclass_func,
362  std::function<bool(const char *, const char *)> const &instance_method_func,
363  std::function<bool(const char *, const char *)> const &class_method_func,
364  std::function<bool(const char *, const char *, lldb::addr_t,
365  uint64_t)> const &ivar_func) const {
366  lldb_private::Process *process = m_runtime.GetProcess();
367 
368  std::unique_ptr<objc_class_t> objc_class;
369  std::unique_ptr<class_ro_t> class_ro;
370  std::unique_ptr<class_rw_t> class_rw;
371 
372  if (!Read_objc_class(process, objc_class))
373  return false;
374  if (!Read_class_row(process, *objc_class, class_ro, class_rw))
375  return false;
376 
377  static ConstString NSObject_name("NSObject");
378 
379  if (m_name != NSObject_name && superclass_func)
380  superclass_func(objc_class->m_superclass);
381 
382  if (instance_method_func) {
383  std::unique_ptr<method_list_t> base_method_list;
384 
385  base_method_list = std::make_unique<method_list_t>();
386  if (!base_method_list->Read(process, class_ro->m_baseMethods_ptr))
387  return false;
388 
389  bool is_small = base_method_list->m_is_small;
390  bool has_direct_selector = base_method_list->m_has_direct_selector;
391 
392  if (base_method_list->m_entsize != method_t::GetSize(process, is_small))
393  return false;
394 
395  std::unique_ptr<method_t> method = std::make_unique<method_t>();
396  lldb::addr_t relative_selector_base_addr =
397  m_runtime.GetRelativeSelectorBaseAddr();
398  for (uint32_t i = 0, e = base_method_list->m_count; i < e; ++i) {
399  method->Read(process,
400  base_method_list->m_first_ptr +
401  (i * base_method_list->m_entsize),
402  relative_selector_base_addr, is_small, has_direct_selector);
403 
404  if (instance_method_func(method->m_name.c_str(), method->m_types.c_str()))
405  break;
406  }
407  }
408 
409  if (class_method_func) {
410  AppleObjCRuntime::ClassDescriptorSP metaclass(GetMetaclass());
411 
412  // We don't care about the metaclass's superclass, or its class methods.
413  // Its instance methods are our class methods.
414 
415  if (metaclass) {
416  metaclass->Describe(
417  std::function<void(ObjCLanguageRuntime::ObjCISA)>(nullptr),
418  class_method_func,
419  std::function<bool(const char *, const char *)>(nullptr),
420  std::function<bool(const char *, const char *, lldb::addr_t,
421  uint64_t)>(nullptr));
422  }
423  }
424 
425  if (ivar_func) {
426  if (class_ro->m_ivars_ptr != 0) {
427  ivar_list_t ivar_list;
428  if (!ivar_list.Read(process, class_ro->m_ivars_ptr))
429  return false;
430 
431  if (ivar_list.m_entsize != ivar_t::GetSize(process))
432  return false;
433 
434  ivar_t ivar;
435 
436  for (uint32_t i = 0, e = ivar_list.m_count; i < e; ++i) {
437  ivar.Read(process, ivar_list.m_first_ptr + (i * ivar_list.m_entsize));
438 
439  if (ivar_func(ivar.m_name.c_str(), ivar.m_type.c_str(),
440  ivar.m_offset_ptr, ivar.m_size))
441  break;
442  }
443  }
444  }
445 
446  return true;
447 }
448 
449 ConstString ClassDescriptorV2::GetClassName() {
450  if (!m_name) {
451  lldb_private::Process *process = m_runtime.GetProcess();
452 
453  if (process) {
454  std::unique_ptr<objc_class_t> objc_class;
455  std::unique_ptr<class_ro_t> class_ro;
456  std::unique_ptr<class_rw_t> class_rw;
457 
458  if (!Read_objc_class(process, objc_class))
459  return m_name;
460  if (!Read_class_row(process, *objc_class, class_ro, class_rw))
461  return m_name;
462 
463  m_name = ConstString(class_ro->m_name.c_str());
464  }
465  }
466  return m_name;
467 }
468 
469 ObjCLanguageRuntime::ClassDescriptorSP ClassDescriptorV2::GetSuperclass() {
470  lldb_private::Process *process = m_runtime.GetProcess();
471 
472  if (!process)
474 
475  std::unique_ptr<objc_class_t> objc_class;
476 
477  if (!Read_objc_class(process, objc_class))
479 
480  return m_runtime.ObjCLanguageRuntime::GetClassDescriptorFromISA(
481  objc_class->m_superclass);
482 }
483 
484 ObjCLanguageRuntime::ClassDescriptorSP ClassDescriptorV2::GetMetaclass() const {
485  lldb_private::Process *process = m_runtime.GetProcess();
486 
487  if (!process)
489 
490  std::unique_ptr<objc_class_t> objc_class;
491 
492  if (!Read_objc_class(process, objc_class))
494 
495  lldb::addr_t candidate_isa = m_runtime.GetPointerISA(objc_class->m_isa);
496 
498  new ClassDescriptorV2(m_runtime, candidate_isa, nullptr));
499 }
500 
501 uint64_t ClassDescriptorV2::GetInstanceSize() {
502  lldb_private::Process *process = m_runtime.GetProcess();
503 
504  if (process) {
505  std::unique_ptr<objc_class_t> objc_class;
506  std::unique_ptr<class_ro_t> class_ro;
507  std::unique_ptr<class_rw_t> class_rw;
508 
509  if (!Read_objc_class(process, objc_class))
510  return 0;
511  if (!Read_class_row(process, *objc_class, class_ro, class_rw))
512  return 0;
513 
514  return class_ro->m_instanceSize;
515  }
516 
517  return 0;
518 }
519 
520 ClassDescriptorV2::iVarsStorage::iVarsStorage() : m_ivars(), m_mutex() {}
521 
522 size_t ClassDescriptorV2::iVarsStorage::size() { return m_ivars.size(); }
523 
525 operator[](size_t idx) {
526  return m_ivars[idx];
527 }
528 
530  ClassDescriptorV2 &descriptor) {
531  if (m_filled)
532  return;
533  std::lock_guard<std::recursive_mutex> guard(m_mutex);
535  LLDB_LOGV(log, "class_name = {0}", descriptor.GetClassName());
536  m_filled = true;
537  ObjCLanguageRuntime::EncodingToTypeSP encoding_to_type_sp(
538  runtime.GetEncodingToType());
539  Process *process(runtime.GetProcess());
540  if (!encoding_to_type_sp)
541  return;
542  descriptor.Describe(nullptr, nullptr, nullptr, [this, process,
543  encoding_to_type_sp,
544  log](const char *name,
545  const char *type,
546  lldb::addr_t offset_ptr,
547  uint64_t size) -> bool {
548  const bool for_expression = false;
549  const bool stop_loop = false;
550  LLDB_LOGV(log, "name = {0}, encoding = {1}, offset_ptr = {2:x}, size = {3}",
551  name, type, offset_ptr, size);
552  CompilerType ivar_type =
553  encoding_to_type_sp->RealizeType(type, for_expression);
554  if (ivar_type) {
555  LLDB_LOGV(log,
556  "name = {0}, encoding = {1}, offset_ptr = {2:x}, size = "
557  "{3}, type_size = {4}",
558  name, type, offset_ptr, size,
559  ivar_type.GetByteSize(nullptr).getValueOr(0));
560  Scalar offset_scalar;
561  Status error;
562  const int offset_ptr_size = 4;
563  const bool is_signed = false;
564  size_t read = process->ReadScalarIntegerFromMemory(
565  offset_ptr, offset_ptr_size, is_signed, offset_scalar, error);
566  if (error.Success() && 4 == read) {
567  LLDB_LOGV(log, "offset_ptr = {0:x} --> {1}", offset_ptr,
568  offset_scalar.SInt());
569  m_ivars.push_back(
570  {ConstString(name), ivar_type, size, offset_scalar.SInt()});
571  } else
572  LLDB_LOGV(log, "offset_ptr = {0:x} --> read fail, read = %{1}",
573  offset_ptr, read);
574  }
575  return stop_loop;
576  });
577 }
578 
581 }
lldb_private::DataBufferHeap::GetBytes
uint8_t * GetBytes() override
Definition: DataBufferHeap.cpp:34
lldb_private::DataBufferHeap::GetByteSize
lldb::offset_t GetByteSize() const override
Definition: DataBufferHeap.cpp:45
lldb_private::ClassDescriptorV2::ivar_t::m_size
uint32_t m_size
Definition: AppleObjCClassDescriptorV2.h:186
lldb_private::ClassDescriptorV2::ivar_list_t::m_count
uint32_t m_count
Definition: AppleObjCClassDescriptorV2.h:175
lldb_private::Process::ReadMemory
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:1914
FunctionCaller.h
lldb_private::ClassDescriptorV2::ivar_list_t::m_entsize
uint32_t m_entsize
Definition: AppleObjCClassDescriptorV2.h:174
lldb_private::Process::ReadScalarIntegerFromMemory
size_t ReadScalarIntegerFromMemory(lldb::addr_t addr, uint32_t byte_size, bool is_signed, Scalar &scalar, Status &error)
Definition: Process.cpp:2255
lldb_private::ObjCLanguageRuntime::ClassDescriptorSP
std::shared_ptr< ClassDescriptor > ClassDescriptorSP
Definition: ObjCLanguageRuntime.h:44
lldb_private::ClassDescriptorV2::ivar_t::m_type
std::string m_type
Definition: AppleObjCClassDescriptorV2.h:189
lldb_private::ClassDescriptorV2::GetIVarInformation
void GetIVarInformation()
Definition: AppleObjCClassDescriptorV2.cpp:579
lldb_private::Scalar
Definition: Scalar.h:34
lldb_private::Process
Definition: Process.h:342
lldb_private::ObjCLanguageRuntime::EncodingToTypeSP
std::shared_ptr< EncodingToType > EncodingToTypeSP
Definition: ObjCLanguageRuntime.h:220
lldb_private::ClassDescriptorV2::m_runtime
AppleObjCRuntimeV2 & m_runtime
Definition: AppleObjCClassDescriptorV2.h:236
lldb_private::AppleObjCRuntimeV2
Definition: AppleObjCRuntimeV2.h:25
lldb_private::ClassDescriptorV2::objc_class_t
Definition: AppleObjCClassDescriptorV2.h:79
lldb_private::CompilerType::GetByteSize
llvm::Optional< uint64_t > GetByteSize(ExecutionContextScope *exe_scope) const
Return the size of the type in bytes.
Definition: CompilerType.cpp:489
lldb::offset_t
uint64_t offset_t
Definition: lldb-types.h:87
lldb_private::ClassDescriptorV2::iVarsStorage::size
size_t size()
Definition: AppleObjCClassDescriptorV2.cpp:522
lldb_private::Process::ReadCStringFromMemory
size_t ReadCStringFromMemory(lldb::addr_t vm_addr, char *cstr, size_t cstr_max_len, Status &error)
Read a NULL terminated C string from memory.
Definition: Process.cpp:2028
lldb::addr_t
uint64_t addr_t
Definition: lldb-types.h:83
LLDB_LOGV
#define LLDB_LOGV(log,...)
Definition: Log.h:256
lldb_private::ClassDescriptorV2::objc_class_t::m_data_ptr
lldb::addr_t m_data_ptr
Definition: AppleObjCClassDescriptorV2.h:84
lldb_private::ClassDescriptorV2::m_ivars_storage
iVarsStorage m_ivars_storage
Definition: AppleObjCClassDescriptorV2.h:241
error
static llvm::raw_ostream & error(Stream &strm)
Definition: CommandReturnObject.cpp:17
lldb_private::ClassDescriptorV2::iVarsStorage::fill
void fill(AppleObjCRuntimeV2 &runtime, ClassDescriptorV2 &descriptor)
Definition: AppleObjCClassDescriptorV2.cpp:529
lldb_private::DataExtractor
Definition: DataExtractor.h:48
Log.h
lldb_private::DataExtractor::GetAddress_unchecked
uint64_t GetAddress_unchecked(lldb::offset_t *offset_ptr) const
Definition: DataExtractor.cpp:656
lldb_private::Process::GetAddressByteSize
uint32_t GetAddressByteSize() const
Definition: Process.cpp:3340
lldb_private::ConstString
Definition: ConstString.h:40
LIBLLDB_LOG_TYPES
#define LIBLLDB_LOG_TYPES
Definition: Logging.h:33
lldb_private::GetLogIfAllCategoriesSet
Log * GetLogIfAllCategoriesSet(uint32_t mask)
Definition: Logging.cpp:58
lldb_private::ClassDescriptorV2::Describe
bool Describe(std::function< void(ObjCLanguageRuntime::ObjCISA)> const &superclass_func, std::function< bool(const char *, const char *)> const &instance_method_func, std::function< bool(const char *, const char *)> const &class_method_func, std::function< bool(const char *, const char *, lldb::addr_t, uint64_t)> const &ivar_func) const override
Definition: AppleObjCClassDescriptorV2.cpp:360
lldb_private::ClassDescriptorV2::ivar_list_t::Read
bool Read(Process *process, lldb::addr_t addr)
Definition: AppleObjCClassDescriptorV2.cpp:305
lldb_private::ClassDescriptorV2::iVarsStorage::operator[]
iVarDescriptor & operator[](size_t idx)
Definition: AppleObjCClassDescriptorV2.cpp:525
lldb_private::Status
Definition: Status.h:44
uint32_t
lldb_private::Runtime::GetProcess
Process * GetProcess()
Definition: Runtime.h:22
lldb_private::ClassDescriptorV2::ivar_t::Read
bool Read(Process *process, lldb::addr_t addr)
Definition: AppleObjCClassDescriptorV2.cpp:329
lldb_private::ClassDescriptorV2::ivar_list_t
Definition: AppleObjCClassDescriptorV2.h:173
lldb_private::ObjCLanguageRuntime::ObjCISA
lldb::addr_t ObjCISA
Definition: ObjCLanguageRuntime.h:42
lldb_private::ObjCLanguageRuntime::ClassDescriptor::iVarDescriptor
Definition: ObjCLanguageRuntime.h:127
lldb_private::ClassDescriptorV2::ivar_t
Definition: AppleObjCClassDescriptorV2.h:181
LLDB_INVALID_ADDRESS
#define LLDB_INVALID_ADDRESS
Definition: lldb-defines.h:86
lldb_private::ClassDescriptorV2::ivar_t::m_offset_ptr
lldb::addr_t m_offset_ptr
Definition: AppleObjCClassDescriptorV2.h:182
lldb_private::CompilerType
Generic representation of a type in a programming language.
Definition: CompilerType.h:33
lldb_private::AppleObjCRuntimeV2::GetEncodingToType
EncodingToTypeSP GetEncodingToType() override
Definition: AppleObjCRuntimeV2.cpp:2951
lldb_private::ClassDescriptorV2
Definition: AppleObjCClassDescriptorV2.h:21
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::ClassDescriptorV2::GetClassName
ConstString GetClassName() override
Definition: AppleObjCClassDescriptorV2.cpp:449
GetClassDataMask
static lldb::addr_t GetClassDataMask(Process *process)
Definition: AppleObjCClassDescriptorV2.cpp:29
AppleObjCClassDescriptorV2.h
lldb_private::Process::ReadUnsignedIntegerFromMemory
uint64_t ReadUnsignedIntegerFromMemory(lldb::addr_t load_addr, size_t byte_size, uint64_t fail_value, Status &error)
Reads an unsigned integer of the specified byte size from process memory.
Definition: Process.cpp:2100
lldb_private::Process::GetByteOrder
lldb::ByteOrder GetByteOrder() const
Definition: Process.cpp:3336
lldb_private::Log
Definition: Log.h:49
lldb_private::DataBufferHeap
Definition: DataBufferHeap.h:30
lldb_private::ClassDescriptorV2::ivar_t::m_name
std::string m_name
Definition: AppleObjCClassDescriptorV2.h:188
lldb
Definition: SBAddress.h:15
lldb_private::Scalar::SInt
int SInt(int fail_value=0) const
Definition: Scalar.cpp:318
lldb_private::DataExtractor::GetU32_unchecked
uint32_t GetU32_unchecked(lldb::offset_t *offset_ptr) const
Definition: DataExtractor.cpp:372
lldb_private::ClassDescriptorV2::ivar_list_t::m_first_ptr
lldb::addr_t m_first_ptr
Definition: AppleObjCClassDescriptorV2.h:176