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