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