LLDB  mainline
Materializer.cpp
Go to the documentation of this file.
1 //===-- Materializer.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 
14 #include "lldb/Symbol/Symbol.h"
15 #include "lldb/Symbol/Type.h"
16 #include "lldb/Symbol/Variable.h"
19 #include "lldb/Target/StackFrame.h"
20 #include "lldb/Target/Target.h"
21 #include "lldb/Target/Thread.h"
22 #include "lldb/Utility/LLDBLog.h"
23 #include "lldb/Utility/Log.h"
25 
26 #include <memory>
27 
28 using namespace lldb_private;
29 
31  uint32_t size = entity.GetSize();
32  uint32_t alignment = entity.GetAlignment();
33 
34  uint32_t ret;
35 
36  if (m_current_offset == 0)
37  m_struct_alignment = alignment;
38 
39  if (m_current_offset % alignment)
40  m_current_offset += (alignment - (m_current_offset % alignment));
41 
42  ret = m_current_offset;
43 
44  m_current_offset += size;
45 
46  return ret;
47 }
48 
50 public:
51  EntityPersistentVariable(lldb::ExpressionVariableSP &persistent_variable_sp,
53  : Entity(), m_persistent_variable_sp(persistent_variable_sp),
54  m_delegate(delegate) {
55  // Hard-coding to maximum size of a pointer since persistent variables are
56  // materialized by reference
57  m_size = 8;
58  m_alignment = 8;
59  }
60 
61  void MakeAllocation(IRMemoryMap &map, Status &err) {
63 
64  // Allocate a spare memory area to store the persistent variable's
65  // contents.
66 
67  Status allocate_error;
68  const bool zero_memory = false;
69 
70  lldb::addr_t mem = map.Malloc(
71  m_persistent_variable_sp->GetByteSize().value_or(0), 8,
72  lldb::ePermissionsReadable | lldb::ePermissionsWritable,
73  IRMemoryMap::eAllocationPolicyMirror, zero_memory, allocate_error);
74 
75  if (!allocate_error.Success()) {
77  "couldn't allocate a memory area to store %s: %s",
78  m_persistent_variable_sp->GetName().GetCString(),
79  allocate_error.AsCString());
80  return;
81  }
82 
83  LLDB_LOGF(log, "Allocated %s (0x%" PRIx64 ") successfully",
84  m_persistent_variable_sp->GetName().GetCString(), mem);
85 
86  // Put the location of the spare memory into the live data of the
87  // ValueObject.
88 
89  m_persistent_variable_sp->m_live_sp = ValueObjectConstResult::Create(
91  m_persistent_variable_sp->GetCompilerType(),
92  m_persistent_variable_sp->GetName(), mem, eAddressTypeLoad,
93  map.GetAddressByteSize());
94 
95  // Clear the flag if the variable will never be deallocated.
96 
97  if (m_persistent_variable_sp->m_flags &
99  Status leak_error;
100  map.Leak(mem, leak_error);
101  m_persistent_variable_sp->m_flags &=
102  ~ExpressionVariable::EVNeedsAllocation;
103  }
104 
105  // Write the contents of the variable to the area.
106 
107  Status write_error;
108 
109  map.WriteMemory(mem, m_persistent_variable_sp->GetValueBytes(),
110  m_persistent_variable_sp->GetByteSize().value_or(0),
111  write_error);
112 
113  if (!write_error.Success()) {
115  "couldn't write %s to the target: %s",
116  m_persistent_variable_sp->GetName().AsCString(),
117  write_error.AsCString());
118  return;
119  }
120  }
121 
123  Status deallocate_error;
124 
125  map.Free((lldb::addr_t)m_persistent_variable_sp->m_live_sp->GetValue()
126  .GetScalar()
127  .ULongLong(),
128  deallocate_error);
129 
130  m_persistent_variable_sp->m_live_sp.reset();
131 
132  if (!deallocate_error.Success()) {
134  "couldn't deallocate memory for %s: %s",
135  m_persistent_variable_sp->GetName().GetCString(),
136  deallocate_error.AsCString());
137  }
138  }
139 
140  void Materialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map,
141  lldb::addr_t process_address, Status &err) override {
143 
144  const lldb::addr_t load_addr = process_address + m_offset;
145 
146  if (log) {
147  LLDB_LOGF(log,
148  "EntityPersistentVariable::Materialize [address = 0x%" PRIx64
149  ", m_name = %s, m_flags = 0x%hx]",
150  (uint64_t)load_addr,
151  m_persistent_variable_sp->GetName().AsCString(),
152  m_persistent_variable_sp->m_flags);
153  }
154 
155  if (m_persistent_variable_sp->m_flags &
157  MakeAllocation(map, err);
158  m_persistent_variable_sp->m_flags |=
160 
161  if (!err.Success())
162  return;
163  }
164 
165  if ((m_persistent_variable_sp->m_flags &
167  m_persistent_variable_sp->m_live_sp) ||
168  m_persistent_variable_sp->m_flags &
170  Status write_error;
171 
173  load_addr,
174  m_persistent_variable_sp->m_live_sp->GetValue().GetScalar(),
175  map.GetAddressByteSize(), write_error);
176 
177  if (!write_error.Success()) {
179  "couldn't write the location of %s to memory: %s",
180  m_persistent_variable_sp->GetName().AsCString(),
181  write_error.AsCString());
182  }
183  } else {
185  "no materialization happened for persistent variable %s",
186  m_persistent_variable_sp->GetName().AsCString());
187  return;
188  }
189  }
190 
191  void Dematerialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map,
192  lldb::addr_t process_address, lldb::addr_t frame_top,
193  lldb::addr_t frame_bottom, Status &err) override {
195 
196  const lldb::addr_t load_addr = process_address + m_offset;
197 
198  if (log) {
199  LLDB_LOGF(log,
200  "EntityPersistentVariable::Dematerialize [address = 0x%" PRIx64
201  ", m_name = %s, m_flags = 0x%hx]",
202  (uint64_t)process_address + m_offset,
203  m_persistent_variable_sp->GetName().AsCString(),
204  m_persistent_variable_sp->m_flags);
205  }
206 
207  if (m_delegate) {
208  m_delegate->DidDematerialize(m_persistent_variable_sp);
209  }
210 
211  if ((m_persistent_variable_sp->m_flags &
213  (m_persistent_variable_sp->m_flags &
215  if (m_persistent_variable_sp->m_flags &
217  !m_persistent_variable_sp->m_live_sp) {
218  // If the reference comes from the program, then the
219  // ClangExpressionVariable's live variable data hasn't been set up yet.
220  // Do this now.
221 
222  lldb::addr_t location;
223  Status read_error;
224 
225  map.ReadPointerFromMemory(&location, load_addr, read_error);
226 
227  if (!read_error.Success()) {
229  "couldn't read the address of program-allocated variable %s: %s",
230  m_persistent_variable_sp->GetName().GetCString(),
231  read_error.AsCString());
232  return;
233  }
234 
235  m_persistent_variable_sp->m_live_sp = ValueObjectConstResult::Create(
237  m_persistent_variable_sp.get()->GetCompilerType(),
238  m_persistent_variable_sp->GetName(), location, eAddressTypeLoad,
239  m_persistent_variable_sp->GetByteSize().value_or(0));
240 
241  if (frame_top != LLDB_INVALID_ADDRESS &&
242  frame_bottom != LLDB_INVALID_ADDRESS && location >= frame_bottom &&
243  location <= frame_top) {
244  // If the variable is resident in the stack frame created by the
245  // expression, then it cannot be relied upon to stay around. We
246  // treat it as needing reallocation.
247  m_persistent_variable_sp->m_flags |=
249  m_persistent_variable_sp->m_flags |=
251  m_persistent_variable_sp->m_flags |=
253  m_persistent_variable_sp->m_flags &=
254  ~ExpressionVariable::EVIsProgramReference;
255  }
256  }
257 
258  lldb::addr_t mem = m_persistent_variable_sp->m_live_sp->GetValue()
259  .GetScalar()
260  .ULongLong();
261 
262  if (!m_persistent_variable_sp->m_live_sp) {
264  "couldn't find the memory area used to store %s",
265  m_persistent_variable_sp->GetName().GetCString());
266  return;
267  }
268 
269  if (m_persistent_variable_sp->m_live_sp->GetValue()
270  .GetValueAddressType() != eAddressTypeLoad) {
272  "the address of the memory area for %s is in an incorrect format",
273  m_persistent_variable_sp->GetName().GetCString());
274  return;
275  }
276 
277  if (m_persistent_variable_sp->m_flags &
279  m_persistent_variable_sp->m_flags &
281  LLDB_LOGF(log, "Dematerializing %s from 0x%" PRIx64 " (size = %llu)",
282  m_persistent_variable_sp->GetName().GetCString(),
283  (uint64_t)mem,
284  (unsigned long long)m_persistent_variable_sp->GetByteSize()
285  .value_or(0));
286 
287  // Read the contents of the spare memory area
288 
289  m_persistent_variable_sp->ValueUpdated();
290 
291  Status read_error;
292 
293  map.ReadMemory(m_persistent_variable_sp->GetValueBytes(), mem,
294  m_persistent_variable_sp->GetByteSize().value_or(0),
295  read_error);
296 
297  if (!read_error.Success()) {
299  "couldn't read the contents of %s from memory: %s",
300  m_persistent_variable_sp->GetName().GetCString(),
301  read_error.AsCString());
302  return;
303  }
304 
305  m_persistent_variable_sp->m_flags &=
306  ~ExpressionVariable::EVNeedsFreezeDry;
307  }
308  } else {
310  "no dematerialization happened for persistent variable %s",
311  m_persistent_variable_sp->GetName().AsCString());
312  return;
313  }
314 
315  lldb::ProcessSP process_sp =
317  if (!process_sp || !process_sp->CanJIT()) {
318  // Allocations are not persistent so persistent variables cannot stay
319  // materialized.
320 
321  m_persistent_variable_sp->m_flags |=
323 
324  DestroyAllocation(map, err);
325  if (!err.Success())
326  return;
327  } else if (m_persistent_variable_sp->m_flags &
329  !(m_persistent_variable_sp->m_flags &
331  DestroyAllocation(map, err);
332  if (!err.Success())
333  return;
334  }
335  }
336 
337  void DumpToLog(IRMemoryMap &map, lldb::addr_t process_address,
338  Log *log) override {
339  StreamString dump_stream;
340 
341  Status err;
342 
343  const lldb::addr_t load_addr = process_address + m_offset;
344 
345  dump_stream.Printf("0x%" PRIx64 ": EntityPersistentVariable (%s)\n",
346  load_addr,
347  m_persistent_variable_sp->GetName().AsCString());
348 
349  {
350  dump_stream.Printf("Pointer:\n");
351 
352  DataBufferHeap data(m_size, 0);
353 
354  map.ReadMemory(data.GetBytes(), load_addr, m_size, err);
355 
356  if (!err.Success()) {
357  dump_stream.Printf(" <could not be read>\n");
358  } else {
359  DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16,
360  load_addr);
361 
362  dump_stream.PutChar('\n');
363  }
364  }
365 
366  {
367  dump_stream.Printf("Target:\n");
368 
369  lldb::addr_t target_address;
370 
371  map.ReadPointerFromMemory(&target_address, load_addr, err);
372 
373  if (!err.Success()) {
374  dump_stream.Printf(" <could not be read>\n");
375  } else {
376  DataBufferHeap data(m_persistent_variable_sp->GetByteSize().value_or(0),
377  0);
378 
379  map.ReadMemory(data.GetBytes(), target_address,
380  m_persistent_variable_sp->GetByteSize().value_or(0),
381  err);
382 
383  if (!err.Success()) {
384  dump_stream.Printf(" <could not be read>\n");
385  } else {
386  DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16,
387  target_address);
388 
389  dump_stream.PutChar('\n');
390  }
391  }
392  }
393 
394  log->PutString(dump_stream.GetString());
395  }
396 
397  void Wipe(IRMemoryMap &map, lldb::addr_t process_address) override {}
398 
399 private:
400  lldb::ExpressionVariableSP m_persistent_variable_sp;
402 };
403 
405  lldb::ExpressionVariableSP &persistent_variable_sp,
406  PersistentVariableDelegate *delegate, Status &err) {
407  EntityVector::iterator iter = m_entities.insert(m_entities.end(), EntityUP());
408  *iter = std::make_unique<EntityPersistentVariable>(persistent_variable_sp,
409  delegate);
410  uint32_t ret = AddStructMember(**iter);
411  (*iter)->SetOffset(ret);
412  return ret;
413 }
414 
416 public:
417  EntityVariable(lldb::VariableSP &variable_sp)
418  : Entity(), m_variable_sp(variable_sp) {
419  // Hard-coding to maximum size of a pointer since all variables are
420  // materialized by reference
421  m_size = 8;
422  m_alignment = 8;
423  m_is_reference =
424  m_variable_sp->GetType()->GetForwardCompilerType().IsReferenceType();
425  }
426 
427  void Materialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map,
428  lldb::addr_t process_address, Status &err) override {
430 
431  const lldb::addr_t load_addr = process_address + m_offset;
432  if (log) {
433  LLDB_LOGF(log,
434  "EntityVariable::Materialize [address = 0x%" PRIx64
435  ", m_variable_sp = %s]",
436  (uint64_t)load_addr, m_variable_sp->GetName().AsCString());
437  }
438 
439  ExecutionContextScope *scope = frame_sp.get();
440 
441  if (!scope)
442  scope = map.GetBestExecutionContextScope();
443 
444  lldb::ValueObjectSP valobj_sp =
445  ValueObjectVariable::Create(scope, m_variable_sp);
446 
447  if (!valobj_sp) {
449  "couldn't get a value object for variable %s",
450  m_variable_sp->GetName().AsCString());
451  return;
452  }
453 
454  Status valobj_error = valobj_sp->GetError();
455 
456  if (valobj_error.Fail()) {
457  err.SetErrorStringWithFormat("couldn't get the value of variable %s: %s",
458  m_variable_sp->GetName().AsCString(),
459  valobj_error.AsCString());
460  return;
461  }
462 
463  if (m_is_reference) {
464  DataExtractor valobj_extractor;
465  Status extract_error;
466  valobj_sp->GetData(valobj_extractor, extract_error);
467 
468  if (!extract_error.Success()) {
470  "couldn't read contents of reference variable %s: %s",
471  m_variable_sp->GetName().AsCString(), extract_error.AsCString());
472  return;
473  }
474 
475  lldb::offset_t offset = 0;
476  lldb::addr_t reference_addr = valobj_extractor.GetAddress(&offset);
477 
478  Status write_error;
479  map.WritePointerToMemory(load_addr, reference_addr, write_error);
480 
481  if (!write_error.Success()) {
482  err.SetErrorStringWithFormat("couldn't write the contents of reference "
483  "variable %s to memory: %s",
484  m_variable_sp->GetName().AsCString(),
485  write_error.AsCString());
486  return;
487  }
488  } else {
489  AddressType address_type = eAddressTypeInvalid;
490  const bool scalar_is_load_address = false;
491  lldb::addr_t addr_of_valobj =
492  valobj_sp->GetAddressOf(scalar_is_load_address, &address_type);
493  if (addr_of_valobj != LLDB_INVALID_ADDRESS) {
494  Status write_error;
495  map.WritePointerToMemory(load_addr, addr_of_valobj, write_error);
496 
497  if (!write_error.Success()) {
499  "couldn't write the address of variable %s to memory: %s",
500  m_variable_sp->GetName().AsCString(), write_error.AsCString());
501  return;
502  }
503  } else {
504  DataExtractor data;
505  Status extract_error;
506  valobj_sp->GetData(data, extract_error);
507  if (!extract_error.Success()) {
508  err.SetErrorStringWithFormat("couldn't get the value of %s: %s",
509  m_variable_sp->GetName().AsCString(),
510  extract_error.AsCString());
511  return;
512  }
513 
514  if (m_temporary_allocation != LLDB_INVALID_ADDRESS) {
516  "trying to create a temporary region for %s but one exists",
517  m_variable_sp->GetName().AsCString());
518  return;
519  }
520 
521  if (data.GetByteSize() < m_variable_sp->GetType()->GetByteSize(scope)) {
522  if (data.GetByteSize() == 0 &&
523  !m_variable_sp->LocationExpression().IsValid()) {
524  err.SetErrorStringWithFormat("the variable '%s' has no location, "
525  "it may have been optimized out",
526  m_variable_sp->GetName().AsCString());
527  } else {
529  "size of variable %s (%" PRIu64
530  ") is larger than the ValueObject's size (%" PRIu64 ")",
531  m_variable_sp->GetName().AsCString(),
532  m_variable_sp->GetType()->GetByteSize(scope).value_or(0),
533  data.GetByteSize());
534  }
535  return;
536  }
537 
538  llvm::Optional<size_t> opt_bit_align =
539  m_variable_sp->GetType()->GetLayoutCompilerType().GetTypeBitAlign(scope);
540  if (!opt_bit_align) {
541  err.SetErrorStringWithFormat("can't get the type alignment for %s",
542  m_variable_sp->GetName().AsCString());
543  return;
544  }
545 
546  size_t byte_align = (*opt_bit_align + 7) / 8;
547 
548  Status alloc_error;
549  const bool zero_memory = false;
550 
551  m_temporary_allocation = map.Malloc(
552  data.GetByteSize(), byte_align,
553  lldb::ePermissionsReadable | lldb::ePermissionsWritable,
554  IRMemoryMap::eAllocationPolicyMirror, zero_memory, alloc_error);
555 
556  m_temporary_allocation_size = data.GetByteSize();
557 
558  m_original_data = std::make_shared<DataBufferHeap>(data.GetDataStart(),
559  data.GetByteSize());
560 
561  if (!alloc_error.Success()) {
563  "couldn't allocate a temporary region for %s: %s",
564  m_variable_sp->GetName().AsCString(), alloc_error.AsCString());
565  return;
566  }
567 
568  Status write_error;
569 
570  map.WriteMemory(m_temporary_allocation, data.GetDataStart(),
571  data.GetByteSize(), write_error);
572 
573  if (!write_error.Success()) {
575  "couldn't write to the temporary region for %s: %s",
576  m_variable_sp->GetName().AsCString(), write_error.AsCString());
577  return;
578  }
579 
580  Status pointer_write_error;
581 
582  map.WritePointerToMemory(load_addr, m_temporary_allocation,
583  pointer_write_error);
584 
585  if (!pointer_write_error.Success()) {
587  "couldn't write the address of the temporary region for %s: %s",
588  m_variable_sp->GetName().AsCString(),
589  pointer_write_error.AsCString());
590  }
591  }
592  }
593  }
594 
595  void Dematerialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map,
596  lldb::addr_t process_address, lldb::addr_t frame_top,
597  lldb::addr_t frame_bottom, Status &err) override {
599 
600  const lldb::addr_t load_addr = process_address + m_offset;
601  if (log) {
602  LLDB_LOGF(log,
603  "EntityVariable::Dematerialize [address = 0x%" PRIx64
604  ", m_variable_sp = %s]",
605  (uint64_t)load_addr, m_variable_sp->GetName().AsCString());
606  }
607 
608  if (m_temporary_allocation != LLDB_INVALID_ADDRESS) {
609  ExecutionContextScope *scope = frame_sp.get();
610 
611  if (!scope)
612  scope = map.GetBestExecutionContextScope();
613 
614  lldb::ValueObjectSP valobj_sp =
615  ValueObjectVariable::Create(scope, m_variable_sp);
616 
617  if (!valobj_sp) {
619  "couldn't get a value object for variable %s",
620  m_variable_sp->GetName().AsCString());
621  return;
622  }
623 
625 
626  Status extract_error;
627 
628  map.GetMemoryData(data, m_temporary_allocation,
629  valobj_sp->GetByteSize().value_or(0), extract_error);
630 
631  if (!extract_error.Success()) {
632  err.SetErrorStringWithFormat("couldn't get the data for variable %s",
633  m_variable_sp->GetName().AsCString());
634  return;
635  }
636 
637  bool actually_write = true;
638 
639  if (m_original_data) {
640  if ((data.GetByteSize() == m_original_data->GetByteSize()) &&
641  !memcmp(m_original_data->GetBytes(), data.GetDataStart(),
642  data.GetByteSize())) {
643  actually_write = false;
644  }
645  }
646 
647  Status set_error;
648 
649  if (actually_write) {
650  valobj_sp->SetData(data, set_error);
651 
652  if (!set_error.Success()) {
654  "couldn't write the new contents of %s back into the variable",
655  m_variable_sp->GetName().AsCString());
656  return;
657  }
658  }
659 
660  Status free_error;
661 
662  map.Free(m_temporary_allocation, free_error);
663 
664  if (!free_error.Success()) {
666  "couldn't free the temporary region for %s: %s",
667  m_variable_sp->GetName().AsCString(), free_error.AsCString());
668  return;
669  }
670 
671  m_original_data.reset();
672  m_temporary_allocation = LLDB_INVALID_ADDRESS;
673  m_temporary_allocation_size = 0;
674  }
675  }
676 
677  void DumpToLog(IRMemoryMap &map, lldb::addr_t process_address,
678  Log *log) override {
679  StreamString dump_stream;
680 
681  const lldb::addr_t load_addr = process_address + m_offset;
682  dump_stream.Printf("0x%" PRIx64 ": EntityVariable\n", load_addr);
683 
684  Status err;
685 
687 
688  {
689  dump_stream.Printf("Pointer:\n");
690 
691  DataBufferHeap data(m_size, 0);
692 
693  map.ReadMemory(data.GetBytes(), load_addr, m_size, err);
694 
695  if (!err.Success()) {
696  dump_stream.Printf(" <could not be read>\n");
697  } else {
698  DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
699  map.GetByteOrder(), map.GetAddressByteSize());
700 
701  DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16,
702  load_addr);
703 
704  lldb::offset_t offset = 0;
705 
706  ptr = extractor.GetAddress(&offset);
707 
708  dump_stream.PutChar('\n');
709  }
710  }
711 
712  if (m_temporary_allocation == LLDB_INVALID_ADDRESS) {
713  dump_stream.Printf("Points to process memory:\n");
714  } else {
715  dump_stream.Printf("Temporary allocation:\n");
716  }
717 
718  if (ptr == LLDB_INVALID_ADDRESS) {
719  dump_stream.Printf(" <could not be be found>\n");
720  } else {
721  DataBufferHeap data(m_temporary_allocation_size, 0);
722 
723  map.ReadMemory(data.GetBytes(), m_temporary_allocation,
724  m_temporary_allocation_size, err);
725 
726  if (!err.Success()) {
727  dump_stream.Printf(" <could not be read>\n");
728  } else {
729  DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16,
730  load_addr);
731 
732  dump_stream.PutChar('\n');
733  }
734  }
735 
736  log->PutString(dump_stream.GetString());
737  }
738 
739  void Wipe(IRMemoryMap &map, lldb::addr_t process_address) override {
740  if (m_temporary_allocation != LLDB_INVALID_ADDRESS) {
741  Status free_error;
742 
743  map.Free(m_temporary_allocation, free_error);
744 
745  m_temporary_allocation = LLDB_INVALID_ADDRESS;
746  m_temporary_allocation_size = 0;
747  }
748  }
749 
750 private:
751  lldb::VariableSP m_variable_sp;
752  bool m_is_reference = false;
753  lldb::addr_t m_temporary_allocation = LLDB_INVALID_ADDRESS;
754  size_t m_temporary_allocation_size = 0;
755  lldb::DataBufferSP m_original_data;
756 };
757 
758 uint32_t Materializer::AddVariable(lldb::VariableSP &variable_sp, Status &err) {
759  EntityVector::iterator iter = m_entities.insert(m_entities.end(), EntityUP());
760  *iter = std::make_unique<EntityVariable>(variable_sp);
761  uint32_t ret = AddStructMember(**iter);
762  (*iter)->SetOffset(ret);
763  return ret;
764 }
765 
767 public:
768  EntityResultVariable(const CompilerType &type, bool is_program_reference,
769  bool keep_in_memory,
771  : Entity(), m_type(type), m_is_program_reference(is_program_reference),
772  m_keep_in_memory(keep_in_memory), m_delegate(delegate) {
773  // Hard-coding to maximum size of a pointer since all results are
774  // materialized by reference
775  m_size = 8;
776  m_alignment = 8;
777  }
778 
779  void Materialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map,
780  lldb::addr_t process_address, Status &err) override {
781  if (!m_is_program_reference) {
782  if (m_temporary_allocation != LLDB_INVALID_ADDRESS) {
783  err.SetErrorString("Trying to create a temporary region for the result "
784  "but one exists");
785  return;
786  }
787 
788  const lldb::addr_t load_addr = process_address + m_offset;
789 
790  ExecutionContextScope *exe_scope = frame_sp.get();
791  if (!exe_scope)
792  exe_scope = map.GetBestExecutionContextScope();
793 
794  llvm::Optional<uint64_t> byte_size = m_type.GetByteSize(exe_scope);
795  if (!byte_size) {
796  err.SetErrorStringWithFormat("can't get size of type \"%s\"",
797  m_type.GetTypeName().AsCString());
798  return;
799  }
800 
801  llvm::Optional<size_t> opt_bit_align = m_type.GetTypeBitAlign(exe_scope);
802  if (!opt_bit_align) {
803  err.SetErrorStringWithFormat("can't get the alignment of type \"%s\"",
804  m_type.GetTypeName().AsCString());
805  return;
806  }
807 
808  size_t byte_align = (*opt_bit_align + 7) / 8;
809 
810  Status alloc_error;
811  const bool zero_memory = true;
812 
813  m_temporary_allocation = map.Malloc(
814  *byte_size, byte_align,
815  lldb::ePermissionsReadable | lldb::ePermissionsWritable,
816  IRMemoryMap::eAllocationPolicyMirror, zero_memory, alloc_error);
817  m_temporary_allocation_size = *byte_size;
818 
819  if (!alloc_error.Success()) {
821  "couldn't allocate a temporary region for the result: %s",
822  alloc_error.AsCString());
823  return;
824  }
825 
826  Status pointer_write_error;
827 
828  map.WritePointerToMemory(load_addr, m_temporary_allocation,
829  pointer_write_error);
830 
831  if (!pointer_write_error.Success()) {
832  err.SetErrorStringWithFormat("couldn't write the address of the "
833  "temporary region for the result: %s",
834  pointer_write_error.AsCString());
835  }
836  }
837  }
838 
839  void Dematerialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map,
840  lldb::addr_t process_address, lldb::addr_t frame_top,
841  lldb::addr_t frame_bottom, Status &err) override {
842  err.Clear();
843 
844  ExecutionContextScope *exe_scope = frame_sp.get();
845  if (!exe_scope)
846  exe_scope = map.GetBestExecutionContextScope();
847 
848  if (!exe_scope) {
849  err.SetErrorString("Couldn't dematerialize a result variable: invalid "
850  "execution context scope");
851  return;
852  }
853 
854  lldb::addr_t address;
855  Status read_error;
856  const lldb::addr_t load_addr = process_address + m_offset;
857 
858  map.ReadPointerFromMemory(&address, load_addr, read_error);
859 
860  if (!read_error.Success()) {
861  err.SetErrorString("Couldn't dematerialize a result variable: couldn't "
862  "read its address");
863  return;
864  }
865 
866  lldb::TargetSP target_sp = exe_scope->CalculateTarget();
867 
868  if (!target_sp) {
869  err.SetErrorString("Couldn't dematerialize a result variable: no target");
870  return;
871  }
872 
873  auto type_system_or_err =
874  target_sp->GetScratchTypeSystemForLanguage(m_type.GetMinimumLanguage());
875 
876  if (auto error = type_system_or_err.takeError()) {
877  err.SetErrorStringWithFormat("Couldn't dematerialize a result variable: "
878  "couldn't get the corresponding type "
879  "system: %s",
880  llvm::toString(std::move(error)).c_str());
881  return;
882  }
883  PersistentExpressionState *persistent_state =
884  type_system_or_err->GetPersistentExpressionState();
885 
886  if (!persistent_state) {
887  err.SetErrorString("Couldn't dematerialize a result variable: "
888  "corresponding type system doesn't handle persistent "
889  "variables");
890  return;
891  }
892 
893  ConstString name = m_delegate
894  ? m_delegate->GetName()
895  : persistent_state->GetNextPersistentVariableName();
896 
897  lldb::ExpressionVariableSP ret = persistent_state->CreatePersistentVariable(
898  exe_scope, name, m_type, map.GetByteOrder(), map.GetAddressByteSize());
899 
900  if (!ret) {
901  err.SetErrorStringWithFormat("couldn't dematerialize a result variable: "
902  "failed to make persistent variable %s",
903  name.AsCString());
904  return;
905  }
906 
907  lldb::ProcessSP process_sp =
909 
910  if (m_delegate) {
911  m_delegate->DidDematerialize(ret);
912  }
913 
914  bool can_persist =
915  (m_is_program_reference && process_sp && process_sp->CanJIT() &&
916  !(address >= frame_bottom && address < frame_top));
917 
918  if (can_persist && m_keep_in_memory) {
919  ret->m_live_sp = ValueObjectConstResult::Create(exe_scope, m_type, name,
920  address, eAddressTypeLoad,
921  map.GetAddressByteSize());
922  }
923 
924  ret->ValueUpdated();
925 
926  const size_t pvar_byte_size = ret->GetByteSize().value_or(0);
927  uint8_t *pvar_data = ret->GetValueBytes();
928 
929  map.ReadMemory(pvar_data, address, pvar_byte_size, read_error);
930 
931  if (!read_error.Success()) {
932  err.SetErrorString(
933  "Couldn't dematerialize a result variable: couldn't read its memory");
934  return;
935  }
936 
937  if (!can_persist || !m_keep_in_memory) {
939 
940  if (m_temporary_allocation != LLDB_INVALID_ADDRESS) {
941  Status free_error;
942  map.Free(m_temporary_allocation, free_error);
943  }
944  } else {
946  }
947 
948  m_temporary_allocation = LLDB_INVALID_ADDRESS;
949  m_temporary_allocation_size = 0;
950  }
951 
952  void DumpToLog(IRMemoryMap &map, lldb::addr_t process_address,
953  Log *log) override {
954  StreamString dump_stream;
955 
956  const lldb::addr_t load_addr = process_address + m_offset;
957 
958  dump_stream.Printf("0x%" PRIx64 ": EntityResultVariable\n", load_addr);
959 
960  Status err;
961 
963 
964  {
965  dump_stream.Printf("Pointer:\n");
966 
967  DataBufferHeap data(m_size, 0);
968 
969  map.ReadMemory(data.GetBytes(), load_addr, m_size, err);
970 
971  if (!err.Success()) {
972  dump_stream.Printf(" <could not be read>\n");
973  } else {
974  DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
975  map.GetByteOrder(), map.GetAddressByteSize());
976 
977  DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16,
978  load_addr);
979 
980  lldb::offset_t offset = 0;
981 
982  ptr = extractor.GetAddress(&offset);
983 
984  dump_stream.PutChar('\n');
985  }
986  }
987 
988  if (m_temporary_allocation == LLDB_INVALID_ADDRESS) {
989  dump_stream.Printf("Points to process memory:\n");
990  } else {
991  dump_stream.Printf("Temporary allocation:\n");
992  }
993 
994  if (ptr == LLDB_INVALID_ADDRESS) {
995  dump_stream.Printf(" <could not be be found>\n");
996  } else {
997  DataBufferHeap data(m_temporary_allocation_size, 0);
998 
999  map.ReadMemory(data.GetBytes(), m_temporary_allocation,
1000  m_temporary_allocation_size, err);
1001 
1002  if (!err.Success()) {
1003  dump_stream.Printf(" <could not be read>\n");
1004  } else {
1005  DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16,
1006  load_addr);
1007 
1008  dump_stream.PutChar('\n');
1009  }
1010  }
1011 
1012  log->PutString(dump_stream.GetString());
1013  }
1014 
1015  void Wipe(IRMemoryMap &map, lldb::addr_t process_address) override {
1016  if (!m_keep_in_memory && m_temporary_allocation != LLDB_INVALID_ADDRESS) {
1017  Status free_error;
1018 
1019  map.Free(m_temporary_allocation, free_error);
1020  }
1021 
1022  m_temporary_allocation = LLDB_INVALID_ADDRESS;
1023  m_temporary_allocation_size = 0;
1024  }
1025 
1026 private:
1030 
1031  lldb::addr_t m_temporary_allocation = LLDB_INVALID_ADDRESS;
1032  size_t m_temporary_allocation_size = 0;
1034 };
1035 
1037  bool is_program_reference,
1038  bool keep_in_memory,
1039  PersistentVariableDelegate *delegate,
1040  Status &err) {
1041  EntityVector::iterator iter = m_entities.insert(m_entities.end(), EntityUP());
1042  *iter = std::make_unique<EntityResultVariable>(type, is_program_reference,
1043  keep_in_memory, delegate);
1044  uint32_t ret = AddStructMember(**iter);
1045  (*iter)->SetOffset(ret);
1046  return ret;
1047 }
1048 
1050 public:
1051  EntitySymbol(const Symbol &symbol) : Entity(), m_symbol(symbol) {
1052  // Hard-coding to maximum size of a symbol
1053  m_size = 8;
1054  m_alignment = 8;
1055  }
1056 
1057  void Materialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map,
1058  lldb::addr_t process_address, Status &err) override {
1060 
1061  const lldb::addr_t load_addr = process_address + m_offset;
1062 
1063  if (log) {
1064  LLDB_LOGF(log,
1065  "EntitySymbol::Materialize [address = 0x%" PRIx64
1066  ", m_symbol = %s]",
1067  (uint64_t)load_addr, m_symbol.GetName().AsCString());
1068  }
1069 
1070  const Address sym_address = m_symbol.GetAddress();
1071 
1072  ExecutionContextScope *exe_scope = frame_sp.get();
1073  if (!exe_scope)
1074  exe_scope = map.GetBestExecutionContextScope();
1075 
1076  lldb::TargetSP target_sp;
1077 
1078  if (exe_scope)
1079  target_sp = map.GetBestExecutionContextScope()->CalculateTarget();
1080 
1081  if (!target_sp) {
1083  "couldn't resolve symbol %s because there is no target",
1084  m_symbol.GetName().AsCString());
1085  return;
1086  }
1087 
1088  lldb::addr_t resolved_address = sym_address.GetLoadAddress(target_sp.get());
1089 
1090  if (resolved_address == LLDB_INVALID_ADDRESS)
1091  resolved_address = sym_address.GetFileAddress();
1092 
1093  Status pointer_write_error;
1094 
1095  map.WritePointerToMemory(load_addr, resolved_address, pointer_write_error);
1096 
1097  if (!pointer_write_error.Success()) {
1099  "couldn't write the address of symbol %s: %s",
1100  m_symbol.GetName().AsCString(), pointer_write_error.AsCString());
1101  return;
1102  }
1103  }
1104 
1105  void Dematerialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map,
1106  lldb::addr_t process_address, lldb::addr_t frame_top,
1107  lldb::addr_t frame_bottom, Status &err) override {
1109 
1110  const lldb::addr_t load_addr = process_address + m_offset;
1111 
1112  if (log) {
1113  LLDB_LOGF(log,
1114  "EntitySymbol::Dematerialize [address = 0x%" PRIx64
1115  ", m_symbol = %s]",
1116  (uint64_t)load_addr, m_symbol.GetName().AsCString());
1117  }
1118 
1119  // no work needs to be done
1120  }
1121 
1122  void DumpToLog(IRMemoryMap &map, lldb::addr_t process_address,
1123  Log *log) override {
1124  StreamString dump_stream;
1125 
1126  Status err;
1127 
1128  const lldb::addr_t load_addr = process_address + m_offset;
1129 
1130  dump_stream.Printf("0x%" PRIx64 ": EntitySymbol (%s)\n", load_addr,
1131  m_symbol.GetName().AsCString());
1132 
1133  {
1134  dump_stream.Printf("Pointer:\n");
1135 
1136  DataBufferHeap data(m_size, 0);
1137 
1138  map.ReadMemory(data.GetBytes(), load_addr, m_size, err);
1139 
1140  if (!err.Success()) {
1141  dump_stream.Printf(" <could not be read>\n");
1142  } else {
1143  DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16,
1144  load_addr);
1145 
1146  dump_stream.PutChar('\n');
1147  }
1148  }
1149 
1150  log->PutString(dump_stream.GetString());
1151  }
1152 
1153  void Wipe(IRMemoryMap &map, lldb::addr_t process_address) override {}
1154 
1155 private:
1157 };
1158 
1160  EntityVector::iterator iter = m_entities.insert(m_entities.end(), EntityUP());
1161  *iter = std::make_unique<EntitySymbol>(symbol_sp);
1162  uint32_t ret = AddStructMember(**iter);
1163  (*iter)->SetOffset(ret);
1164  return ret;
1165 }
1166 
1168 public:
1169  EntityRegister(const RegisterInfo &register_info)
1170  : Entity(), m_register_info(register_info) {
1171  // Hard-coding alignment conservatively
1172  m_size = m_register_info.byte_size;
1173  m_alignment = m_register_info.byte_size;
1174  }
1175 
1176  void Materialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map,
1177  lldb::addr_t process_address, Status &err) override {
1179 
1180  const lldb::addr_t load_addr = process_address + m_offset;
1181 
1182  if (log) {
1183  LLDB_LOGF(log,
1184  "EntityRegister::Materialize [address = 0x%" PRIx64
1185  ", m_register_info = %s]",
1186  (uint64_t)load_addr, m_register_info.name);
1187  }
1188 
1189  RegisterValue reg_value;
1190 
1191  if (!frame_sp.get()) {
1193  "couldn't materialize register %s without a stack frame",
1194  m_register_info.name);
1195  return;
1196  }
1197 
1198  lldb::RegisterContextSP reg_context_sp = frame_sp->GetRegisterContext();
1199 
1200  if (!reg_context_sp->ReadRegister(&m_register_info, reg_value)) {
1201  err.SetErrorStringWithFormat("couldn't read the value of register %s",
1202  m_register_info.name);
1203  return;
1204  }
1205 
1206  DataExtractor register_data;
1207 
1208  if (!reg_value.GetData(register_data)) {
1209  err.SetErrorStringWithFormat("couldn't get the data for register %s",
1210  m_register_info.name);
1211  return;
1212  }
1213 
1214  if (register_data.GetByteSize() != m_register_info.byte_size) {
1216  "data for register %s had size %llu but we expected %llu",
1217  m_register_info.name, (unsigned long long)register_data.GetByteSize(),
1218  (unsigned long long)m_register_info.byte_size);
1219  return;
1220  }
1221 
1222  m_register_contents = std::make_shared<DataBufferHeap>(
1223  register_data.GetDataStart(), register_data.GetByteSize());
1224 
1225  Status write_error;
1226 
1227  map.WriteMemory(load_addr, register_data.GetDataStart(),
1228  register_data.GetByteSize(), write_error);
1229 
1230  if (!write_error.Success()) {
1232  "couldn't write the contents of register %s: %s",
1233  m_register_info.name, write_error.AsCString());
1234  return;
1235  }
1236  }
1237 
1238  void Dematerialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map,
1239  lldb::addr_t process_address, lldb::addr_t frame_top,
1240  lldb::addr_t frame_bottom, Status &err) override {
1242 
1243  const lldb::addr_t load_addr = process_address + m_offset;
1244 
1245  if (log) {
1246  LLDB_LOGF(log,
1247  "EntityRegister::Dematerialize [address = 0x%" PRIx64
1248  ", m_register_info = %s]",
1249  (uint64_t)load_addr, m_register_info.name);
1250  }
1251 
1252  Status extract_error;
1253 
1254  DataExtractor register_data;
1255 
1256  if (!frame_sp.get()) {
1258  "couldn't dematerialize register %s without a stack frame",
1259  m_register_info.name);
1260  return;
1261  }
1262 
1263  lldb::RegisterContextSP reg_context_sp = frame_sp->GetRegisterContext();
1264 
1265  map.GetMemoryData(register_data, load_addr, m_register_info.byte_size,
1266  extract_error);
1267 
1268  if (!extract_error.Success()) {
1269  err.SetErrorStringWithFormat("couldn't get the data for register %s: %s",
1270  m_register_info.name,
1271  extract_error.AsCString());
1272  return;
1273  }
1274 
1275  if (!memcmp(register_data.GetDataStart(), m_register_contents->GetBytes(),
1276  register_data.GetByteSize())) {
1277  // No write required, and in particular we avoid errors if the register
1278  // wasn't writable
1279 
1280  m_register_contents.reset();
1281  return;
1282  }
1283 
1284  m_register_contents.reset();
1285 
1286  RegisterValue register_value(register_data.GetData(),
1287  register_data.GetByteOrder());
1288 
1289  if (!reg_context_sp->WriteRegister(&m_register_info, register_value)) {
1290  err.SetErrorStringWithFormat("couldn't write the value of register %s",
1291  m_register_info.name);
1292  return;
1293  }
1294  }
1295 
1296  void DumpToLog(IRMemoryMap &map, lldb::addr_t process_address,
1297  Log *log) override {
1298  StreamString dump_stream;
1299 
1300  Status err;
1301 
1302  const lldb::addr_t load_addr = process_address + m_offset;
1303 
1304  dump_stream.Printf("0x%" PRIx64 ": EntityRegister (%s)\n", load_addr,
1305  m_register_info.name);
1306 
1307  {
1308  dump_stream.Printf("Value:\n");
1309 
1310  DataBufferHeap data(m_size, 0);
1311 
1312  map.ReadMemory(data.GetBytes(), load_addr, m_size, err);
1313 
1314  if (!err.Success()) {
1315  dump_stream.Printf(" <could not be read>\n");
1316  } else {
1317  DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16,
1318  load_addr);
1319 
1320  dump_stream.PutChar('\n');
1321  }
1322  }
1323 
1324  log->PutString(dump_stream.GetString());
1325  }
1326 
1327  void Wipe(IRMemoryMap &map, lldb::addr_t process_address) override {}
1328 
1329 private:
1330  RegisterInfo m_register_info;
1331  lldb::DataBufferSP m_register_contents;
1332 };
1333 
1334 uint32_t Materializer::AddRegister(const RegisterInfo &register_info,
1335  Status &err) {
1336  EntityVector::iterator iter = m_entities.insert(m_entities.end(), EntityUP());
1337  *iter = std::make_unique<EntityRegister>(register_info);
1338  uint32_t ret = AddStructMember(**iter);
1339  (*iter)->SetOffset(ret);
1340  return ret;
1341 }
1342 
1344  DematerializerSP dematerializer_sp = m_dematerializer_wp.lock();
1345 
1346  if (dematerializer_sp)
1347  dematerializer_sp->Wipe();
1348 }
1349 
1351 Materializer::Materialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map,
1352  lldb::addr_t process_address, Status &error) {
1353  ExecutionContextScope *exe_scope = frame_sp.get();
1354  if (!exe_scope)
1355  exe_scope = map.GetBestExecutionContextScope();
1356 
1357  DematerializerSP dematerializer_sp = m_dematerializer_wp.lock();
1358 
1359  if (dematerializer_sp) {
1360  error.SetErrorToGenericError();
1361  error.SetErrorString("Couldn't materialize: already materialized");
1362  }
1363 
1364  DematerializerSP ret(
1365  new Dematerializer(*this, frame_sp, map, process_address));
1366 
1367  if (!exe_scope) {
1368  error.SetErrorToGenericError();
1369  error.SetErrorString("Couldn't materialize: target doesn't exist");
1370  }
1371 
1372  for (EntityUP &entity_up : m_entities) {
1373  entity_up->Materialize(frame_sp, map, process_address, error);
1374 
1375  if (!error.Success())
1376  return DematerializerSP();
1377  }
1378 
1379  if (Log *log = GetLog(LLDBLog::Expressions)) {
1380  LLDB_LOGF(
1381  log,
1382  "Materializer::Materialize (frame_sp = %p, process_address = 0x%" PRIx64
1383  ") materialized:",
1384  static_cast<void *>(frame_sp.get()), process_address);
1385  for (EntityUP &entity_up : m_entities)
1386  entity_up->DumpToLog(map, process_address, log);
1387  }
1388 
1389  m_dematerializer_wp = ret;
1390 
1391  return ret;
1392 }
1393 
1395  lldb::addr_t frame_bottom,
1396  lldb::addr_t frame_top) {
1397  lldb::StackFrameSP frame_sp;
1398 
1399  lldb::ThreadSP thread_sp = m_thread_wp.lock();
1400  if (thread_sp)
1401  frame_sp = thread_sp->GetFrameWithStackID(m_stack_id);
1402 
1403  ExecutionContextScope *exe_scope = frame_sp.get();
1404  if (!exe_scope)
1405  exe_scope = m_map->GetBestExecutionContextScope();
1406 
1407  if (!IsValid()) {
1408  error.SetErrorToGenericError();
1409  error.SetErrorString("Couldn't dematerialize: invalid dematerializer");
1410  }
1411 
1412  if (!exe_scope) {
1413  error.SetErrorToGenericError();
1414  error.SetErrorString("Couldn't dematerialize: target is gone");
1415  } else {
1416  if (Log *log = GetLog(LLDBLog::Expressions)) {
1417  LLDB_LOGF(log,
1418  "Materializer::Dematerialize (frame_sp = %p, process_address "
1419  "= 0x%" PRIx64 ") about to dematerialize:",
1420  static_cast<void *>(frame_sp.get()), m_process_address);
1421  for (EntityUP &entity_up : m_materializer->m_entities)
1422  entity_up->DumpToLog(*m_map, m_process_address, log);
1423  }
1424 
1425  for (EntityUP &entity_up : m_materializer->m_entities) {
1426  entity_up->Dematerialize(frame_sp, *m_map, m_process_address, frame_top,
1427  frame_bottom, error);
1428 
1429  if (!error.Success())
1430  break;
1431  }
1432  }
1433 
1434  Wipe();
1435 }
1436 
1438  if (!IsValid())
1439  return;
1440 
1441  for (EntityUP &entity_up : m_materializer->m_entities) {
1442  entity_up->Wipe(*m_map, m_process_address);
1443  }
1444 
1445  m_materializer = nullptr;
1446  m_map = nullptr;
1447  m_process_address = LLDB_INVALID_ADDRESS;
1448 }
1449 
1451  default;
lldb_private::toString
const char * toString(AppleArm64ExceptionClass EC)
Definition: AppleArm64ExceptionClass.h:38
EntityVariable::EntityVariable
EntityVariable(lldb::VariableSP &variable_sp)
Definition: Materializer.cpp:417
EntityPersistentVariable
Definition: Materializer.cpp:49
lldb_private::Materializer::Entity::GetAlignment
uint32_t GetAlignment()
Definition: Materializer.h:107
lldb_private::Materializer::Materialize
DematerializerSP Materialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Status &err)
Definition: Materializer.cpp:1351
lldb_private::DataBufferHeap::GetByteSize
lldb::offset_t GetByteSize() const override
Definition: DataBufferHeap.cpp:43
ExpressionVariable.h
lldb_private::Materializer::m_current_offset
uint32_t m_current_offset
Definition: Materializer.h:129
lldb_private::Log::PutString
void PutString(llvm::StringRef str)
Definition: Log.cpp:134
EntityResultVariable::m_delegate
Materializer::PersistentVariableDelegate * m_delegate
Definition: Materializer.cpp:1033
lldb_private::DataExtractor::GetAddress
uint64_t GetAddress(lldb::offset_t *offset_ptr) const
Extract an address from *offset_ptr.
Definition: DataExtractor.cpp:649
EntityResultVariable::EntityResultVariable
EntityResultVariable(const CompilerType &type, bool is_program_reference, bool keep_in_memory, Materializer::PersistentVariableDelegate *delegate)
Definition: Materializer.cpp:768
lldb_private::RegisterValue
Definition: RegisterValue.h:28
lldb_private::Materializer::PersistentVariableDelegate::~PersistentVariableDelegate
virtual ~PersistentVariableDelegate()
lldb_private::Symbol
Definition: Symbol.h:20
EntityResultVariable::Materialize
void Materialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Status &err) override
Definition: Materializer.cpp:779
EntitySymbol::Wipe
void Wipe(IRMemoryMap &map, lldb::addr_t process_address) override
Definition: Materializer.cpp:1153
EntityVariable::DumpToLog
void DumpToLog(IRMemoryMap &map, lldb::addr_t process_address, Log *log) override
Definition: Materializer.cpp:677
lldb_private::AddressType
AddressType
Definition: lldb-private-enumerations.h:30
EntityVariable::m_variable_sp
lldb::VariableSP m_variable_sp
Definition: Materializer.cpp:751
EntityVariable::m_original_data
lldb::DataBufferSP m_original_data
Definition: Materializer.cpp:755
LLDB_LOGF
#define LLDB_LOGF(log,...)
Definition: Log.h:343
lldb_private::IRMemoryMap::Malloc
lldb::addr_t Malloc(size_t size, uint8_t alignment, uint32_t permissions, AllocationPolicy policy, bool zero_memory, Status &error)
Definition: IRMemoryMap.cpp:289
lldb_private::ExpressionVariable::EVIsLLDBAllocated
@ EVIsLLDBAllocated
This variable is resident in a location specifically allocated for it by LLDB in the target process.
Definition: ExpressionVariable.h:82
lldb_private::Materializer::Dematerializer::m_stack_id
StackID m_stack_id
Definition: Materializer.h:59
lldb_private::Materializer::AddPersistentVariable
uint32_t AddPersistentVariable(lldb::ExpressionVariableSP &persistent_variable_sp, PersistentVariableDelegate *delegate, Status &err)
Definition: Materializer.cpp:404
EntityPersistentVariable::Materialize
void Materialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Status &err) override
Definition: Materializer.cpp:140
EntityResultVariable::DumpToLog
void DumpToLog(IRMemoryMap &map, lldb::addr_t process_address, Log *log) override
Definition: Materializer.cpp:952
lldb_private::Materializer::Dematerializer::m_materializer
Materializer * m_materializer
Definition: Materializer.h:57
lldb_private::ConstString::AsCString
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
Definition: ConstString.h:193
lldb_private::Materializer::m_dematerializer_wp
DematerializerWP m_dematerializer_wp
Definition: Materializer.h:127
lldb::offset_t
uint64_t offset_t
Definition: lldb-types.h:87
RegisterValue.h
lldb_private::Materializer::Dematerializer::Dematerialize
void Dematerialize(Status &err, lldb::addr_t frame_top, lldb::addr_t frame_bottom)
Definition: Materializer.cpp:1394
StackFrame.h
EntityResultVariable::m_is_program_reference
bool m_is_program_reference
Definition: Materializer.cpp:1028
lldb::addr_t
uint64_t addr_t
Definition: lldb-types.h:83
lldb_private::StreamString::GetString
llvm::StringRef GetString() const
Definition: StreamString.cpp:51
lldb_private::IRMemoryMap::WriteScalarToMemory
void WriteScalarToMemory(lldb::addr_t process_address, Scalar &scalar, size_t size, Status &error)
Definition: IRMemoryMap.cpp:587
lldb_private::Materializer::AddResultVariable
uint32_t AddResultVariable(const CompilerType &type, bool is_lvalue, bool keep_in_memory, PersistentVariableDelegate *delegate, Status &err)
Definition: Materializer.cpp:1036
EntityRegister::Materialize
void Materialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Status &err) override
Definition: Materializer.cpp:1176
lldb_private::IRMemoryMap::Free
void Free(lldb::addr_t process_address, Status &error)
Definition: IRMemoryMap.cpp:446
lldb_private::Materializer::Entity
Definition: Materializer.h:91
Target.h
lldb_private::IRMemoryMap::GetByteOrder
lldb::ByteOrder GetByteOrder()
Definition: IRMemoryMap.cpp:228
lldb_private::ExpressionVariable::EVNeedsAllocation
@ EVNeedsAllocation
Space for this variable has yet to be allocated in the target process.
Definition: ExpressionVariable.h:88
error
static llvm::raw_ostream & error(Stream &strm)
Definition: CommandReturnObject.cpp:17
lldb_private::DumpHexBytes
void DumpHexBytes(Stream *s, const void *src, size_t src_len, uint32_t bytes_per_line, lldb::addr_t base_addr)
Definition: DumpDataExtractor.cpp:923
lldb_private::Status::Success
bool Success() const
Test for success condition.
Definition: Status.cpp:287
EntityResultVariable
Definition: Materializer.cpp:766
EntitySymbol::Materialize
void Materialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Status &err) override
Definition: Materializer.cpp:1057
EntitySymbol
Definition: Materializer.cpp:1049
lldb_private::PersistentExpressionState::GetNextPersistentVariableName
virtual ConstString GetNextPersistentVariableName(bool is_error=false)=0
Return a new persistent variable name with the specified prefix.
lldb_private::Materializer::~Materializer
~Materializer()
Definition: Materializer.cpp:1343
lldb_private::DataExtractor
Definition: DataExtractor.h:48
lldb_private::eAddressTypeInvalid
@ eAddressTypeInvalid
Definition: lldb-private-enumerations.h:31
Log.h
lldb_private::ExecutionContextScope
Definition: ExecutionContextScope.h:32
lldb_private::Materializer::Dematerializer::m_thread_wp
lldb::ThreadWP m_thread_wp
Definition: Materializer.h:58
lldb_private::Materializer::DematerializerSP
std::shared_ptr< Dematerializer > DematerializerSP
Definition: Materializer.h:64
lldb_private::Status::GetError
ValueType GetError() const
Access the error value.
Definition: Status.cpp:174
lldb_private::Materializer::AddRegister
uint32_t AddRegister(const RegisterInfo &register_info, Status &err)
Definition: Materializer.cpp:1334
EntityPersistentVariable::m_persistent_variable_sp
lldb::ExpressionVariableSP m_persistent_variable_sp
Definition: Materializer.cpp:400
EntityResultVariable::Wipe
void Wipe(IRMemoryMap &map, lldb::addr_t process_address) override
Definition: Materializer.cpp:1015
EntityResultVariable::m_keep_in_memory
bool m_keep_in_memory
Definition: Materializer.cpp:1029
lldb_private::Materializer::EntityUP
std::unique_ptr< Entity > EntityUP
Definition: Materializer.h:124
lldb_private::Status::Fail
bool Fail() const
Test for error condition.
Definition: Status.cpp:181
EntityPersistentVariable::Wipe
void Wipe(IRMemoryMap &map, lldb::addr_t process_address) override
Definition: Materializer.cpp:397
EntityRegister::m_register_info
RegisterInfo m_register_info
Definition: Materializer.cpp:1330
lldb_private::Status::SetErrorStringWithFormat
int SetErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Set the current error string to a formatted error string.
Definition: Status.cpp:255
EntitySymbol::Dematerialize
void Dematerialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, lldb::addr_t frame_top, lldb::addr_t frame_bottom, Status &err) override
Definition: Materializer.cpp:1105
EntityPersistentVariable::MakeAllocation
void MakeAllocation(IRMemoryMap &map, Status &err)
Definition: Materializer.cpp:61
lldb_private::Address::GetFileAddress
lldb::addr_t GetFileAddress() const
Get the file address.
Definition: Address.cpp:291
lldb_private::Materializer::Dematerializer::Wipe
void Wipe()
Definition: Materializer.cpp:1437
Type.h
EntityVariable
Definition: Materializer.cpp:415
lldb_private::RegisterValue::GetData
bool GetData(DataExtractor &data) const
Definition: RegisterValue.cpp:34
lldb_private::Materializer::AddSymbol
uint32_t AddSymbol(const Symbol &symbol_sp, Status &err)
Definition: Materializer.cpp:1159
lldb_private::DataExtractor::GetDataStart
const uint8_t * GetDataStart() const
Get the data start pointer.
Definition: DataExtractor.h:422
lldb_private::DataExtractor::GetByteOrder
lldb::ByteOrder GetByteOrder() const
Get the current byte order value.
Definition: DataExtractor.h:594
lldb_private::IRMemoryMap::eAllocationPolicyMirror
@ eAllocationPolicyMirror
The intent is that this allocation exist both in the host and the process and have the same content i...
Definition: IRMemoryMap.h:46
lldb_private::IRMemoryMap::Leak
void Leak(lldb::addr_t process_address, Status &error)
Definition: IRMemoryMap.cpp:430
lldb_private::ConstString
Definition: ConstString.h:40
lldb_private::IRMemoryMap::GetAddressByteSize
uint32_t GetAddressByteSize()
Definition: IRMemoryMap.cpp:242
lldb_private::StreamString
Definition: StreamString.h:23
lldb_private::Materializer::Entity::GetSize
uint32_t GetSize()
Definition: Materializer.h:109
EntityRegister::DumpToLog
void DumpToLog(IRMemoryMap &map, lldb::addr_t process_address, Log *log) override
Definition: Materializer.cpp:1296
lldb_private::Materializer::PersistentVariableDelegate
Definition: Materializer.h:70
EntityVariable::Materialize
void Materialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Status &err) override
Definition: Materializer.cpp:427
lldb_private::ExpressionVariable::EVNeedsFreezeDry
@ EVNeedsFreezeDry
Copy from m_live_sp to m_frozen_sp during dematerialization.
Definition: ExpressionVariable.h:93
EntityResultVariable::m_type
CompilerType m_type
Definition: Materializer.cpp:1027
lldb_private::eAddressTypeLoad
@ eAddressTypeLoad
Address is an address as in the current target inferior process.
Definition: lldb-private-enumerations.h:34
EntityRegister::Dematerialize
void Dematerialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, lldb::addr_t frame_top, lldb::addr_t frame_bottom, Status &err) override
Definition: Materializer.cpp:1238
EntityPersistentVariable::DumpToLog
void DumpToLog(IRMemoryMap &map, lldb::addr_t process_address, Log *log) override
Definition: Materializer.cpp:337
Thread.h
lldb_private::Stream::PutChar
size_t PutChar(char ch)
Definition: Stream.cpp:104
DumpDataExtractor.h
EntitySymbol::EntitySymbol
EntitySymbol(const Symbol &symbol)
Definition: Materializer.cpp:1051
EntityPersistentVariable::Dematerialize
void Dematerialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, lldb::addr_t frame_top, lldb::addr_t frame_bottom, Status &err) override
Definition: Materializer.cpp:191
lldb_private::IRMemoryMap::ReadMemory
void ReadMemory(uint8_t *bytes, lldb::addr_t process_address, size_t size, Status &error)
Definition: IRMemoryMap.cpp:621
lldb_private::Materializer::Dematerializer::m_process_address
lldb::addr_t m_process_address
Definition: Materializer.h:61
ValueObjectConstResult.h
Symbol.h
EntitySymbol::DumpToLog
void DumpToLog(IRMemoryMap &map, lldb::addr_t process_address, Log *log) override
Definition: Materializer.cpp:1122
lldb_private::Materializer::AddStructMember
uint32_t AddStructMember(Entity &entity)
Definition: Materializer.cpp:30
lldb_private::ExpressionVariable
Definition: ExpressionVariable.h:23
EntityRegister::m_register_contents
lldb::DataBufferSP m_register_contents
Definition: Materializer.cpp:1331
Materializer.h
lldb_private::Status
Definition: Status.h:44
lldb_private::ExpressionVariable::m_live_sp
lldb::ValueObjectSP m_live_sp
Definition: ExpressionVariable.h:111
lldb_private::IRMemoryMap::WriteMemory
void WriteMemory(lldb::addr_t process_address, const uint8_t *bytes, size_t size, Status &error)
Definition: IRMemoryMap.cpp:512
uint32_t
EntityRegister::Wipe
void Wipe(IRMemoryMap &map, lldb::addr_t process_address) override
Definition: Materializer.cpp:1327
lldb_private::ExpressionVariable::EVKeepInTarget
@ EVKeepInTarget
Keep the allocation after the expression is complete rather than freeze drying its contents and freei...
Definition: ExpressionVariable.h:95
EntityRegister::EntityRegister
EntityRegister(const RegisterInfo &register_info)
Definition: Materializer.cpp:1169
lldb_private::ExpressionVariable::EVIsProgramReference
@ EVIsProgramReference
This variable is a reference to a (possibly invalid) area managed by the target program.
Definition: ExpressionVariable.h:85
lldb_private::Address
Definition: Address.h:59
lldb_private::IRMemoryMap::GetMemoryData
void GetMemoryData(DataExtractor &extractor, lldb::addr_t process_address, size_t size, Status &error)
Definition: IRMemoryMap.cpp:773
EntityVariable::Dematerialize
void Dematerialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, lldb::addr_t frame_top, lldb::addr_t frame_bottom, Status &err) override
Definition: Materializer.cpp:595
EntityVariable::Wipe
void Wipe(IRMemoryMap &map, lldb::addr_t process_address) override
Definition: Materializer.cpp:739
lldb_private::Status::SetErrorString
void SetErrorString(llvm::StringRef err_str)
Set the current error string to err_str.
Definition: Status.cpp:241
lldb_private::Address::GetLoadAddress
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
Definition: Address.cpp:311
EntityPersistentVariable::EntityPersistentVariable
EntityPersistentVariable(lldb::ExpressionVariableSP &persistent_variable_sp, Materializer::PersistentVariableDelegate *delegate)
Definition: Materializer.cpp:51
LLDB_INVALID_ADDRESS
#define LLDB_INVALID_ADDRESS
Definition: lldb-defines.h:74
lldb_private::CompilerType
Generic representation of a type in a programming language.
Definition: CompilerType.h:33
lldb_private::ValueObjectConstResult::Create
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order, uint32_t addr_byte_size, lldb::addr_t address=LLDB_INVALID_ADDRESS)
Definition: ValueObjectConstResult.cpp:28
lldb_private::Stream::Printf
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:107
lldb_private::IRMemoryMap::WritePointerToMemory
void WritePointerToMemory(lldb::addr_t process_address, lldb::addr_t address, Status &error)
Definition: IRMemoryMap.cpp:612
EntityPersistentVariable::m_delegate
Materializer::PersistentVariableDelegate * m_delegate
Definition: Materializer.cpp:401
EntityResultVariable::Dematerialize
void Dematerialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, lldb::addr_t frame_top, lldb::addr_t frame_bottom, Status &err) override
Definition: Materializer.cpp:839
EntityPersistentVariable::DestroyAllocation
void DestroyAllocation(IRMemoryMap &map, Status &err)
Definition: Materializer.cpp:122
lldb_private::PersistentExpressionState
Definition: ExpressionVariable.h:203
lldb_private::IRMemoryMap::GetBestExecutionContextScope
ExecutionContextScope * GetBestExecutionContextScope() const
Definition: IRMemoryMap.cpp:256
lldb_private::ExecutionContextScope::CalculateProcess
virtual lldb::ProcessSP CalculateProcess()=0
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::Materializer::Dematerializer::m_map
IRMemoryMap * m_map
Definition: Materializer.h:60
lldb_private::ExecutionContextScope::CalculateTarget
virtual lldb::TargetSP CalculateTarget()=0
EntitySymbol::m_symbol
Symbol m_symbol
Definition: Materializer.cpp:1156
lldb_private::Status::Clear
void Clear()
Clear the object state.
Definition: Status.cpp:167
lldb_private::DataExtractor::GetData
const void * GetData(lldb::offset_t *offset_ptr, lldb::offset_t length) const
Extract length bytes from *offset_ptr.
Definition: DataExtractor.h:337
ValueObjectVariable.h
lldb_private::IRMemoryMap::ReadPointerFromMemory
void ReadPointerFromMemory(lldb::addr_t *address, lldb::addr_t process_address, Status &error)
Definition: IRMemoryMap.cpp:758
lldb_private::Log
Definition: Log.h:115
lldb_private::ValueObjectVariable::Create
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, const lldb::VariableSP &var_sp)
Definition: ValueObjectVariable.cpp:51
lldb_private::PersistentExpressionState::CreatePersistentVariable
virtual lldb::ExpressionVariableSP CreatePersistentVariable(const lldb::ValueObjectSP &valobj_sp)=0
lldb_private::Materializer::m_entities
EntityVector m_entities
Definition: Materializer.h:128
Variable.h
lldb_private::GetLog
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition: Log.h:308
lldb_private::Materializer::Dematerializer::IsValid
bool IsValid()
Definition: Materializer.h:39
lldb_private::DataExtractor::GetByteSize
uint64_t GetByteSize() const
Get the number of bytes contained in this object.
Definition: DataExtractor.h:270
lldb_private::DataBufferHeap
Definition: DataBufferHeap.h:30
lldb_private::LLDBLog::Expressions
@ Expressions
lldb_private::IRMemoryMap
Definition: IRMemoryMap.h:34
RegisterContext.h
lldb_private::Materializer::Dematerializer
Definition: Materializer.h:28
LLDBLog.h
ExecutionContext.h
lldb_private::Materializer::m_struct_alignment
uint32_t m_struct_alignment
Definition: Materializer.h:130
lldb_private::Materializer::AddVariable
uint32_t AddVariable(lldb::VariableSP &variable_sp, Status &err)
Definition: Materializer.cpp:758
lldb_private::Status::AsCString
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
Definition: Status.cpp:130
EntityRegister
Definition: Materializer.cpp:1167