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