LLDB  mainline
IRMemoryMap.cpp
Go to the documentation of this file.
1 //===-- IRMemoryMap.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 
11 #include "lldb/Target/Process.h"
12 #include "lldb/Target/Target.h"
16 #include "lldb/Utility/LLDBLog.h"
17 #include "lldb/Utility/Log.h"
18 #include "lldb/Utility/Scalar.h"
19 #include "lldb/Utility/Status.h"
20 
21 using namespace lldb_private;
22 
23 IRMemoryMap::IRMemoryMap(lldb::TargetSP target_sp) : m_target_wp(target_sp) {
24  if (target_sp)
25  m_process_wp = target_sp->GetProcessSP();
26 }
27 
29  lldb::ProcessSP process_sp = m_process_wp.lock();
30 
31  if (process_sp) {
32  AllocationMap::iterator iter;
33 
34  Status err;
35 
36  while ((iter = m_allocations.begin()) != m_allocations.end()) {
37  err.Clear();
38  if (iter->second.m_leak)
39  m_allocations.erase(iter);
40  else
41  Free(iter->first, err);
42  }
43  }
44 }
45 
47  // The FindSpace algorithm's job is to find a region of memory that the
48  // underlying process is unlikely to be using.
49  //
50  // The memory returned by this function will never be written to. The only
51  // point is that it should not shadow process memory if possible, so that
52  // expressions processing real values from the process do not use the wrong
53  // data.
54  //
55  // If the process can in fact allocate memory (CanJIT() lets us know this)
56  // then this can be accomplished just be allocating memory in the inferior.
57  // Then no guessing is required.
58 
59  lldb::TargetSP target_sp = m_target_wp.lock();
60  lldb::ProcessSP process_sp = m_process_wp.lock();
61 
62  const bool process_is_alive = process_sp && process_sp->IsAlive();
63 
65  if (size == 0)
66  return ret;
67 
68  if (process_is_alive && process_sp->CanJIT()) {
69  Status alloc_error;
70 
71  ret = process_sp->AllocateMemory(size, lldb::ePermissionsReadable |
72  lldb::ePermissionsWritable,
73  alloc_error);
74 
75  if (!alloc_error.Success())
76  return LLDB_INVALID_ADDRESS;
77  else
78  return ret;
79  }
80 
81  // At this point we know that we need to hunt.
82  //
83  // First, go to the end of the existing allocations we've made if there are
84  // any allocations. Otherwise start at the beginning of memory.
85 
86  if (m_allocations.empty()) {
87  ret = 0x0;
88  } else {
89  auto back = m_allocations.rbegin();
90  lldb::addr_t addr = back->first;
91  size_t alloc_size = back->second.m_size;
92  ret = llvm::alignTo(addr + alloc_size, 4096);
93  }
94 
95  // Now, if it's possible to use the GetMemoryRegionInfo API to detect mapped
96  // regions, walk forward through memory until a region is found that has
97  // adequate space for our allocation.
98  if (process_is_alive) {
99  const uint64_t end_of_memory = process_sp->GetAddressByteSize() == 8
100  ? 0xffffffffffffffffull
101  : 0xffffffffull;
102 
103  lldbassert(process_sp->GetAddressByteSize() == 4 ||
104  end_of_memory != 0xffffffffull);
105 
106  MemoryRegionInfo region_info;
107  Status err = process_sp->GetMemoryRegionInfo(ret, region_info);
108  if (err.Success()) {
109  while (true) {
110  if (region_info.GetReadable() != MemoryRegionInfo::OptionalBool::eNo ||
111  region_info.GetWritable() != MemoryRegionInfo::OptionalBool::eNo ||
112  region_info.GetExecutable() !=
113  MemoryRegionInfo::OptionalBool::eNo) {
114  if (region_info.GetRange().GetRangeEnd() - 1 >= end_of_memory) {
115  ret = LLDB_INVALID_ADDRESS;
116  break;
117  } else {
118  ret = region_info.GetRange().GetRangeEnd();
119  }
120  } else if (ret + size < region_info.GetRange().GetRangeEnd()) {
121  return ret;
122  } else {
123  // ret stays the same. We just need to walk a bit further.
124  }
125 
126  err = process_sp->GetMemoryRegionInfo(
127  region_info.GetRange().GetRangeEnd(), region_info);
128  if (err.Fail()) {
129  lldbassert(0 && "GetMemoryRegionInfo() succeeded, then failed");
130  ret = LLDB_INVALID_ADDRESS;
131  break;
132  }
133  }
134  }
135  }
136 
137  // We've tried our algorithm, and it didn't work. Now we have to reset back
138  // to the end of the allocations we've already reported, or use a 'sensible'
139  // default if this is our first allocation.
140 
141  if (m_allocations.empty()) {
142  uint32_t address_byte_size = GetAddressByteSize();
143  if (address_byte_size != UINT32_MAX) {
144  switch (address_byte_size) {
145  case 8:
146  ret = 0xffffffff00000000ull;
147  break;
148  case 4:
149  ret = 0xee000000ull;
150  break;
151  default:
152  break;
153  }
154  }
155  } else {
156  auto back = m_allocations.rbegin();
157  lldb::addr_t addr = back->first;
158  size_t alloc_size = back->second.m_size;
159  ret = llvm::alignTo(addr + alloc_size, 4096);
160  }
161 
162  return ret;
163 }
164 
165 IRMemoryMap::AllocationMap::iterator
167  if (addr == LLDB_INVALID_ADDRESS)
168  return m_allocations.end();
169 
170  AllocationMap::iterator iter = m_allocations.lower_bound(addr);
171 
172  if (iter == m_allocations.end() || iter->first > addr) {
173  if (iter == m_allocations.begin())
174  return m_allocations.end();
175  iter--;
176  }
177 
178  if (iter->first <= addr && iter->first + iter->second.m_size >= addr + size)
179  return iter;
180 
181  return m_allocations.end();
182 }
183 
184 bool IRMemoryMap::IntersectsAllocation(lldb::addr_t addr, size_t size) const {
185  if (addr == LLDB_INVALID_ADDRESS)
186  return false;
187 
188  AllocationMap::const_iterator iter = m_allocations.lower_bound(addr);
189 
190  // Since we only know that the returned interval begins at a location greater
191  // than or equal to where the given interval begins, it's possible that the
192  // given interval intersects either the returned interval or the previous
193  // interval. Thus, we need to check both. Note that we only need to check
194  // these two intervals. Since all intervals are disjoint it is not possible
195  // that an adjacent interval does not intersect, but a non-adjacent interval
196  // does intersect.
197  if (iter != m_allocations.end()) {
198  if (AllocationsIntersect(addr, size, iter->second.m_process_start,
199  iter->second.m_size))
200  return true;
201  }
202 
203  if (iter != m_allocations.begin()) {
204  --iter;
205  if (AllocationsIntersect(addr, size, iter->second.m_process_start,
206  iter->second.m_size))
207  return true;
208  }
209 
210  return false;
211 }
212 
214  lldb::addr_t addr2, size_t size2) {
215  // Given two half open intervals [A, B) and [X, Y), the only 6 permutations
216  // that satisfy A<B and X<Y are the following:
217  // A B X Y
218  // A X B Y (intersects)
219  // A X Y B (intersects)
220  // X A B Y (intersects)
221  // X A Y B (intersects)
222  // X Y A B
223  // The first is B <= X, and the last is Y <= A. So the condition is !(B <= X
224  // || Y <= A)), or (X < B && A < Y)
225  return (addr2 < (addr1 + size1)) && (addr1 < (addr2 + size2));
226 }
227 
229  lldb::ProcessSP process_sp = m_process_wp.lock();
230 
231  if (process_sp)
232  return process_sp->GetByteOrder();
233 
234  lldb::TargetSP target_sp = m_target_wp.lock();
235 
236  if (target_sp)
237  return target_sp->GetArchitecture().GetByteOrder();
238 
240 }
241 
243  lldb::ProcessSP process_sp = m_process_wp.lock();
244 
245  if (process_sp)
246  return process_sp->GetAddressByteSize();
247 
248  lldb::TargetSP target_sp = m_target_wp.lock();
249 
250  if (target_sp)
251  return target_sp->GetArchitecture().GetAddressByteSize();
252 
253  return UINT32_MAX;
254 }
255 
257  lldb::ProcessSP process_sp = m_process_wp.lock();
258 
259  if (process_sp)
260  return process_sp.get();
261 
262  lldb::TargetSP target_sp = m_target_wp.lock();
263 
264  if (target_sp)
265  return target_sp.get();
266 
267  return nullptr;
268 }
269 
271  lldb::addr_t process_start, size_t size,
272  uint32_t permissions, uint8_t alignment,
273  AllocationPolicy policy)
274  : m_process_alloc(process_alloc), m_process_start(process_start),
275  m_size(size), m_policy(policy), m_leak(false), m_permissions(permissions),
276  m_alignment(alignment) {
277  switch (policy) {
278  default:
279  llvm_unreachable("Invalid AllocationPolicy");
282  m_data.SetByteSize(size);
283  break;
285  break;
286  }
287 }
288 
289 lldb::addr_t IRMemoryMap::Malloc(size_t size, uint8_t alignment,
290  uint32_t permissions, AllocationPolicy policy,
291  bool zero_memory, Status &error) {
293  error.Clear();
294 
295  lldb::ProcessSP process_sp;
296  lldb::addr_t allocation_address = LLDB_INVALID_ADDRESS;
297  lldb::addr_t aligned_address = LLDB_INVALID_ADDRESS;
298 
299  size_t allocation_size;
300 
301  if (size == 0) {
302  // FIXME: Malloc(0) should either return an invalid address or assert, in
303  // order to cut down on unnecessary allocations.
304  allocation_size = alignment;
305  } else {
306  // Round up the requested size to an aligned value.
307  allocation_size = llvm::alignTo(size, alignment);
308 
309  // The process page cache does not see the requested alignment. We can't
310  // assume its result will be any more than 1-byte aligned. To work around
311  // this, request `alignment - 1` additional bytes.
312  allocation_size += alignment - 1;
313  }
314 
315  switch (policy) {
316  default:
317  error.SetErrorToGenericError();
318  error.SetErrorString("Couldn't malloc: invalid allocation policy");
319  return LLDB_INVALID_ADDRESS;
321  allocation_address = FindSpace(allocation_size);
322  if (allocation_address == LLDB_INVALID_ADDRESS) {
323  error.SetErrorToGenericError();
324  error.SetErrorString("Couldn't malloc: address space is full");
325  return LLDB_INVALID_ADDRESS;
326  }
327  break;
329  process_sp = m_process_wp.lock();
330  LLDB_LOGF(log,
331  "IRMemoryMap::%s process_sp=0x%" PRIxPTR
332  ", process_sp->CanJIT()=%s, process_sp->IsAlive()=%s",
333  __FUNCTION__, reinterpret_cast<uintptr_t>(process_sp.get()),
334  process_sp && process_sp->CanJIT() ? "true" : "false",
335  process_sp && process_sp->IsAlive() ? "true" : "false");
336  if (process_sp && process_sp->CanJIT() && process_sp->IsAlive()) {
337  if (!zero_memory)
338  allocation_address =
339  process_sp->AllocateMemory(allocation_size, permissions, error);
340  else
341  allocation_address =
342  process_sp->CallocateMemory(allocation_size, permissions, error);
343 
344  if (!error.Success())
345  return LLDB_INVALID_ADDRESS;
346  } else {
347  LLDB_LOGF(log,
348  "IRMemoryMap::%s switching to eAllocationPolicyHostOnly "
349  "due to failed condition (see previous expr log message)",
350  __FUNCTION__);
351  policy = eAllocationPolicyHostOnly;
352  allocation_address = FindSpace(allocation_size);
353  if (allocation_address == LLDB_INVALID_ADDRESS) {
354  error.SetErrorToGenericError();
355  error.SetErrorString("Couldn't malloc: address space is full");
356  return LLDB_INVALID_ADDRESS;
357  }
358  }
359  break;
361  process_sp = m_process_wp.lock();
362  if (process_sp) {
363  if (process_sp->CanJIT() && process_sp->IsAlive()) {
364  if (!zero_memory)
365  allocation_address =
366  process_sp->AllocateMemory(allocation_size, permissions, error);
367  else
368  allocation_address =
369  process_sp->CallocateMemory(allocation_size, permissions, error);
370 
371  if (!error.Success())
372  return LLDB_INVALID_ADDRESS;
373  } else {
374  error.SetErrorToGenericError();
375  error.SetErrorString(
376  "Couldn't malloc: process doesn't support allocating memory");
377  return LLDB_INVALID_ADDRESS;
378  }
379  } else {
380  error.SetErrorToGenericError();
381  error.SetErrorString("Couldn't malloc: process doesn't exist, and this "
382  "memory must be in the process");
383  return LLDB_INVALID_ADDRESS;
384  }
385  break;
386  }
387 
388  lldb::addr_t mask = alignment - 1;
389  aligned_address = (allocation_address + mask) & (~mask);
390 
391  m_allocations.emplace(
392  std::piecewise_construct, std::forward_as_tuple(aligned_address),
393  std::forward_as_tuple(allocation_address, aligned_address,
394  allocation_size, permissions, alignment, policy));
395 
396  if (zero_memory) {
397  Status write_error;
398  std::vector<uint8_t> zero_buf(size, 0);
399  WriteMemory(aligned_address, zero_buf.data(), size, write_error);
400  }
401 
402  if (log) {
403  const char *policy_string;
404 
405  switch (policy) {
406  default:
407  policy_string = "<invalid policy>";
408  break;
410  policy_string = "eAllocationPolicyHostOnly";
411  break;
413  policy_string = "eAllocationPolicyProcessOnly";
414  break;
416  policy_string = "eAllocationPolicyMirror";
417  break;
418  }
419 
420  LLDB_LOGF(log,
421  "IRMemoryMap::Malloc (%" PRIu64 ", 0x%" PRIx64 ", 0x%" PRIx64
422  ", %s) -> 0x%" PRIx64,
423  (uint64_t)allocation_size, (uint64_t)alignment,
424  (uint64_t)permissions, policy_string, aligned_address);
425  }
426 
427  return aligned_address;
428 }
429 
430 void IRMemoryMap::Leak(lldb::addr_t process_address, Status &error) {
431  error.Clear();
432 
433  AllocationMap::iterator iter = m_allocations.find(process_address);
434 
435  if (iter == m_allocations.end()) {
436  error.SetErrorToGenericError();
437  error.SetErrorString("Couldn't leak: allocation doesn't exist");
438  return;
439  }
440 
441  Allocation &allocation = iter->second;
442 
443  allocation.m_leak = true;
444 }
445 
446 void IRMemoryMap::Free(lldb::addr_t process_address, Status &error) {
447  error.Clear();
448 
449  AllocationMap::iterator iter = m_allocations.find(process_address);
450 
451  if (iter == m_allocations.end()) {
452  error.SetErrorToGenericError();
453  error.SetErrorString("Couldn't free: allocation doesn't exist");
454  return;
455  }
456 
457  Allocation &allocation = iter->second;
458 
459  switch (allocation.m_policy) {
460  default:
462  lldb::ProcessSP process_sp = m_process_wp.lock();
463  if (process_sp) {
464  if (process_sp->CanJIT() && process_sp->IsAlive())
465  process_sp->DeallocateMemory(
466  allocation.m_process_alloc); // FindSpace allocated this for real
467  }
468 
469  break;
470  }
473  lldb::ProcessSP process_sp = m_process_wp.lock();
474  if (process_sp)
475  process_sp->DeallocateMemory(allocation.m_process_alloc);
476  }
477  }
478 
480  LLDB_LOGF(log,
481  "IRMemoryMap::Free (0x%" PRIx64 ") freed [0x%" PRIx64
482  "..0x%" PRIx64 ")",
483  (uint64_t)process_address, iter->second.m_process_start,
484  iter->second.m_process_start + iter->second.m_size);
485  }
486 
487  m_allocations.erase(iter);
488 }
489 
490 bool IRMemoryMap::GetAllocSize(lldb::addr_t address, size_t &size) {
491  AllocationMap::iterator iter = FindAllocation(address, size);
492  if (iter == m_allocations.end())
493  return false;
494 
495  Allocation &al = iter->second;
496 
497  if (address > (al.m_process_start + al.m_size)) {
498  size = 0;
499  return false;
500  }
501 
502  if (address > al.m_process_start) {
503  int dif = address - al.m_process_start;
504  size = al.m_size - dif;
505  return true;
506  }
507 
508  size = al.m_size;
509  return true;
510 }
511 
513  const uint8_t *bytes, size_t size,
514  Status &error) {
515  error.Clear();
516 
517  AllocationMap::iterator iter = FindAllocation(process_address, size);
518 
519  if (iter == m_allocations.end()) {
520  lldb::ProcessSP process_sp = m_process_wp.lock();
521 
522  if (process_sp) {
523  process_sp->WriteMemory(process_address, bytes, size, error);
524  return;
525  }
526 
527  error.SetErrorToGenericError();
528  error.SetErrorString("Couldn't write: no allocation contains the target "
529  "range and the process doesn't exist");
530  return;
531  }
532 
533  Allocation &allocation = iter->second;
534 
535  uint64_t offset = process_address - allocation.m_process_start;
536 
537  lldb::ProcessSP process_sp;
538 
539  switch (allocation.m_policy) {
540  default:
541  error.SetErrorToGenericError();
542  error.SetErrorString("Couldn't write: invalid allocation policy");
543  return;
545  if (!allocation.m_data.GetByteSize()) {
546  error.SetErrorToGenericError();
547  error.SetErrorString("Couldn't write: data buffer is empty");
548  return;
549  }
550  ::memcpy(allocation.m_data.GetBytes() + offset, bytes, size);
551  break;
553  if (!allocation.m_data.GetByteSize()) {
554  error.SetErrorToGenericError();
555  error.SetErrorString("Couldn't write: data buffer is empty");
556  return;
557  }
558  ::memcpy(allocation.m_data.GetBytes() + offset, bytes, size);
559  process_sp = m_process_wp.lock();
560  if (process_sp) {
561  process_sp->WriteMemory(process_address, bytes, size, error);
562  if (!error.Success())
563  return;
564  }
565  break;
567  process_sp = m_process_wp.lock();
568  if (process_sp) {
569  process_sp->WriteMemory(process_address, bytes, size, error);
570  if (!error.Success())
571  return;
572  }
573  break;
574  }
575 
577  LLDB_LOGF(log,
578  "IRMemoryMap::WriteMemory (0x%" PRIx64 ", 0x%" PRIxPTR
579  ", 0x%" PRId64 ") went to [0x%" PRIx64 "..0x%" PRIx64 ")",
580  (uint64_t)process_address, reinterpret_cast<uintptr_t>(bytes), (uint64_t)size,
581  (uint64_t)allocation.m_process_start,
582  (uint64_t)allocation.m_process_start +
583  (uint64_t)allocation.m_size);
584  }
585 }
586 
588  Scalar &scalar, size_t size,
589  Status &error) {
590  error.Clear();
591 
592  if (size == UINT32_MAX)
593  size = scalar.GetByteSize();
594 
595  if (size > 0) {
596  uint8_t buf[32];
597  const size_t mem_size =
598  scalar.GetAsMemoryData(buf, size, GetByteOrder(), error);
599  if (mem_size > 0) {
600  return WriteMemory(process_address, buf, mem_size, error);
601  } else {
602  error.SetErrorToGenericError();
603  error.SetErrorString(
604  "Couldn't write scalar: failed to get scalar as memory data");
605  }
606  } else {
607  error.SetErrorToGenericError();
608  error.SetErrorString("Couldn't write scalar: its size was zero");
609  }
610 }
611 
613  lldb::addr_t address, Status &error) {
614  error.Clear();
615 
616  Scalar scalar(address);
617 
618  WriteScalarToMemory(process_address, scalar, GetAddressByteSize(), error);
619 }
620 
621 void IRMemoryMap::ReadMemory(uint8_t *bytes, lldb::addr_t process_address,
622  size_t size, Status &error) {
623  error.Clear();
624 
625  AllocationMap::iterator iter = FindAllocation(process_address, size);
626 
627  if (iter == m_allocations.end()) {
628  lldb::ProcessSP process_sp = m_process_wp.lock();
629 
630  if (process_sp) {
631  process_sp->ReadMemory(process_address, bytes, size, error);
632  return;
633  }
634 
635  lldb::TargetSP target_sp = m_target_wp.lock();
636 
637  if (target_sp) {
638  Address absolute_address(process_address);
639  target_sp->ReadMemory(absolute_address, bytes, size, error, true);
640  return;
641  }
642 
643  error.SetErrorToGenericError();
644  error.SetErrorString("Couldn't read: no allocation contains the target "
645  "range, and neither the process nor the target exist");
646  return;
647  }
648 
649  Allocation &allocation = iter->second;
650 
651  uint64_t offset = process_address - allocation.m_process_start;
652 
653  if (offset > allocation.m_size) {
654  error.SetErrorToGenericError();
655  error.SetErrorString("Couldn't read: data is not in the allocation");
656  return;
657  }
658 
659  lldb::ProcessSP process_sp;
660 
661  switch (allocation.m_policy) {
662  default:
663  error.SetErrorToGenericError();
664  error.SetErrorString("Couldn't read: invalid allocation policy");
665  return;
667  if (!allocation.m_data.GetByteSize()) {
668  error.SetErrorToGenericError();
669  error.SetErrorString("Couldn't read: data buffer is empty");
670  return;
671  }
672  if (allocation.m_data.GetByteSize() < offset + size) {
673  error.SetErrorToGenericError();
674  error.SetErrorString("Couldn't read: not enough underlying data");
675  return;
676  }
677 
678  ::memcpy(bytes, allocation.m_data.GetBytes() + offset, size);
679  break;
681  process_sp = m_process_wp.lock();
682  if (process_sp) {
683  process_sp->ReadMemory(process_address, bytes, size, error);
684  if (!error.Success())
685  return;
686  } else {
687  if (!allocation.m_data.GetByteSize()) {
688  error.SetErrorToGenericError();
689  error.SetErrorString("Couldn't read: data buffer is empty");
690  return;
691  }
692  ::memcpy(bytes, allocation.m_data.GetBytes() + offset, size);
693  }
694  break;
696  process_sp = m_process_wp.lock();
697  if (process_sp) {
698  process_sp->ReadMemory(process_address, bytes, size, error);
699  if (!error.Success())
700  return;
701  }
702  break;
703  }
704 
706  LLDB_LOGF(log,
707  "IRMemoryMap::ReadMemory (0x%" PRIx64 ", 0x%" PRIxPTR
708  ", 0x%" PRId64 ") came from [0x%" PRIx64 "..0x%" PRIx64 ")",
709  (uint64_t)process_address, reinterpret_cast<uintptr_t>(bytes), (uint64_t)size,
710  (uint64_t)allocation.m_process_start,
711  (uint64_t)allocation.m_process_start +
712  (uint64_t)allocation.m_size);
713  }
714 }
715 
717  lldb::addr_t process_address,
718  size_t size, Status &error) {
719  error.Clear();
720 
721  if (size > 0) {
722  DataBufferHeap buf(size, 0);
723  ReadMemory(buf.GetBytes(), process_address, size, error);
724 
725  if (!error.Success())
726  return;
727 
728  DataExtractor extractor(buf.GetBytes(), buf.GetByteSize(), GetByteOrder(),
730 
731  lldb::offset_t offset = 0;
732 
733  switch (size) {
734  default:
735  error.SetErrorToGenericError();
736  error.SetErrorStringWithFormat(
737  "Couldn't read scalar: unsupported size %" PRIu64, (uint64_t)size);
738  return;
739  case 1:
740  scalar = extractor.GetU8(&offset);
741  break;
742  case 2:
743  scalar = extractor.GetU16(&offset);
744  break;
745  case 4:
746  scalar = extractor.GetU32(&offset);
747  break;
748  case 8:
749  scalar = extractor.GetU64(&offset);
750  break;
751  }
752  } else {
753  error.SetErrorToGenericError();
754  error.SetErrorString("Couldn't read scalar: its size was zero");
755  }
756 }
757 
759  lldb::addr_t process_address,
760  Status &error) {
761  error.Clear();
762 
763  Scalar pointer_scalar;
764  ReadScalarFromMemory(pointer_scalar, process_address, GetAddressByteSize(),
765  error);
766 
767  if (!error.Success())
768  return;
769 
770  *address = pointer_scalar.ULongLong();
771 }
772 
774  lldb::addr_t process_address, size_t size,
775  Status &error) {
776  error.Clear();
777 
778  if (size > 0) {
779  AllocationMap::iterator iter = FindAllocation(process_address, size);
780 
781  if (iter == m_allocations.end()) {
782  error.SetErrorToGenericError();
783  error.SetErrorStringWithFormat(
784  "Couldn't find an allocation containing [0x%" PRIx64 "..0x%" PRIx64
785  ")",
786  process_address, process_address + size);
787  return;
788  }
789 
790  Allocation &allocation = iter->second;
791 
792  switch (allocation.m_policy) {
793  default:
794  error.SetErrorToGenericError();
795  error.SetErrorString(
796  "Couldn't get memory data: invalid allocation policy");
797  return;
799  error.SetErrorToGenericError();
800  error.SetErrorString(
801  "Couldn't get memory data: memory is only in the target");
802  return;
804  lldb::ProcessSP process_sp = m_process_wp.lock();
805 
806  if (!allocation.m_data.GetByteSize()) {
807  error.SetErrorToGenericError();
808  error.SetErrorString("Couldn't get memory data: data buffer is empty");
809  return;
810  }
811  if (process_sp) {
812  process_sp->ReadMemory(allocation.m_process_start,
813  allocation.m_data.GetBytes(),
814  allocation.m_data.GetByteSize(), error);
815  if (!error.Success())
816  return;
817  uint64_t offset = process_address - allocation.m_process_start;
818  extractor = DataExtractor(allocation.m_data.GetBytes() + offset, size,
820  return;
821  }
822  } break;
824  if (!allocation.m_data.GetByteSize()) {
825  error.SetErrorToGenericError();
826  error.SetErrorString("Couldn't get memory data: data buffer is empty");
827  return;
828  }
829  uint64_t offset = process_address - allocation.m_process_start;
830  extractor = DataExtractor(allocation.m_data.GetBytes() + offset, size,
832  return;
833  }
834  } else {
835  error.SetErrorToGenericError();
836  error.SetErrorString("Couldn't get memory data: its size was zero");
837  return;
838  }
839 }
lldb_private::DataBufferHeap::GetByteSize
lldb::offset_t GetByteSize() const override
Definition: DataBufferHeap.cpp:43
Scalar.h
IRMemoryMap.h
lldb_private::DataBufferHeap::SetByteSize
lldb::offset_t SetByteSize(lldb::offset_t byte_size)
Set the number of bytes in the data buffer.
Definition: DataBufferHeap.cpp:47
lldb_private::IRMemoryMap::AllocationPolicy
AllocationPolicy
Definition: IRMemoryMap.h:39
lldb_private::Scalar
Definition: Scalar.h:34
LLDB_LOGF
#define LLDB_LOGF(log,...)
Definition: Log.h:270
lldb_private::IRMemoryMap::Malloc
lldb::addr_t Malloc(size_t size, uint8_t alignment, uint32_t permissions, AllocationPolicy policy, bool zero_memory, Status &error)
Definition: IRMemoryMap.cpp:289
lldb_private::Scalar::GetAsMemoryData
size_t GetAsMemoryData(void *dst, size_t dst_len, lldb::ByteOrder dst_byte_order, Status &error) const
Definition: Scalar.cpp:773
lldb_private::IRMemoryMap::FindAllocation
AllocationMap::iterator FindAllocation(lldb::addr_t addr, size_t size)
Definition: IRMemoryMap.cpp:166
lldb::offset_t
uint64_t offset_t
Definition: lldb-types.h:87
lldb_private::MemoryRegionInfo
Definition: MemoryRegionInfo.h:21
lldb_private::IRMemoryMap::eAllocationPolicyHostOnly
@ eAllocationPolicyHostOnly
This allocation was created in the host and will never make it into the process.
Definition: IRMemoryMap.h:42
lldb::addr_t
uint64_t addr_t
Definition: lldb-types.h:83
lldb_private::IRMemoryMap::AllocationsIntersect
static bool AllocationsIntersect(lldb::addr_t addr1, size_t size1, lldb::addr_t addr2, size_t size2)
Definition: IRMemoryMap.cpp:213
lldb_private::DataExtractor::GetU64
uint64_t GetU64(lldb::offset_t *offset_ptr) const
Extract a uint64_t value from *offset_ptr.
Definition: DataExtractor.cpp:474
lldb_private::IRMemoryMap::FindSpace
lldb::addr_t FindSpace(size_t size)
Definition: IRMemoryMap.cpp:46
lldb_private::IRMemoryMap::WriteScalarToMemory
void WriteScalarToMemory(lldb::addr_t process_address, Scalar &scalar, size_t size, Status &error)
Definition: IRMemoryMap.cpp:587
Process.h
lldb_private::IRMemoryMap::Free
void Free(lldb::addr_t process_address, Status &error)
Definition: IRMemoryMap.cpp:446
lldb_private::IRMemoryMap::Allocation::m_size
size_t m_size
The size of the requested allocation.
Definition: IRMemoryMap.h:94
lldb_private::MemoryRegionInfo::GetWritable
OptionalBool GetWritable() const
Definition: MemoryRegionInfo.h:44
Target.h
lldb_private::IRMemoryMap::GetByteOrder
lldb::ByteOrder GetByteOrder()
Definition: IRMemoryMap.cpp:228
lldb_private::IRMemoryMap::Allocation::m_data
DataBufferHeap m_data
Definition: IRMemoryMap.h:95
error
static llvm::raw_ostream & error(Stream &strm)
Definition: CommandReturnObject.cpp:17
lldb_private::Status::Success
bool Success() const
Test for success condition.
Definition: Status.cpp:287
LLDBAssert.h
lldb_private::MemoryRegionInfo::GetExecutable
OptionalBool GetExecutable() const
Definition: MemoryRegionInfo.h:46
lldb_private::DataExtractor
Definition: DataExtractor.h:48
lldb_private::Scalar::ULongLong
unsigned long long ULongLong(unsigned long long fail_value=0) const
Definition: Scalar.cpp:334
Log.h
lldb_private::ExecutionContextScope
Definition: ExecutionContextScope.h:32
MemoryRegionInfo.h
lldb_private::IRMemoryMap::IRMemoryMap
IRMemoryMap(lldb::TargetSP target_sp)
Definition: IRMemoryMap.cpp:23
lldb_private::Status::Fail
bool Fail() const
Test for error condition.
Definition: Status.cpp:181
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::IRMemoryMap::GetAddressByteSize
uint32_t GetAddressByteSize()
Definition: IRMemoryMap.cpp:242
lldb_private::IRMemoryMap::ReadScalarFromMemory
void ReadScalarFromMemory(Scalar &scalar, lldb::addr_t process_address, size_t size, Status &error)
Definition: IRMemoryMap.cpp:716
lldb_private::DataExtractor::GetU8
uint8_t GetU8(lldb::offset_t *offset_ptr) const
Extract a uint8_t value from *offset_ptr.
Definition: DataExtractor.cpp:316
lldb_private::IRMemoryMap::Allocation::m_process_alloc
lldb::addr_t m_process_alloc
The (unaligned) base for the remote allocation.
Definition: IRMemoryMap.h:91
lldb_private::Scalar::GetByteSize
size_t GetByteSize() const
Definition: Scalar.cpp:131
lldb_private::IRMemoryMap::~IRMemoryMap
~IRMemoryMap()
Definition: IRMemoryMap.cpp:28
lldb_private::IRMemoryMap::Allocation::m_policy
AllocationPolicy m_policy
Flags. Keep these grouped together to avoid structure padding.
Definition: IRMemoryMap.h:98
lldb_private::IRMemoryMap::Allocation::m_leak
bool m_leak
Definition: IRMemoryMap.h:99
lldb_private::IRMemoryMap::ReadMemory
void ReadMemory(uint8_t *bytes, lldb::addr_t process_address, size_t size, Status &error)
Definition: IRMemoryMap.cpp:621
lldbassert
#define lldbassert(x)
Definition: LLDBAssert.h:15
lldb_private::IRMemoryMap::Allocation::m_process_start
lldb::addr_t m_process_start
The base address of the allocation in the process.
Definition: IRMemoryMap.h:93
lldb_private::Status
Definition: Status.h:44
lldb_private::IRMemoryMap::WriteMemory
void WriteMemory(lldb::addr_t process_address, const uint8_t *bytes, size_t size, Status &error)
Definition: IRMemoryMap.cpp:512
lldb::eByteOrderInvalid
@ eByteOrderInvalid
Definition: lldb-enumerations.h:139
uint32_t
lldb_private::Address
Definition: Address.h:59
lldb_private::IRMemoryMap::GetMemoryData
void GetMemoryData(DataExtractor &extractor, lldb::addr_t process_address, size_t size, Status &error)
Definition: IRMemoryMap.cpp:773
UINT32_MAX
#define UINT32_MAX
Definition: lldb-defines.h:19
lldb_private::DataExtractor::GetU32
uint32_t GetU32(lldb::offset_t *offset_ptr) const
Extract a uint32_t value from *offset_ptr.
Definition: DataExtractor.cpp:425
LLDB_INVALID_ADDRESS
#define LLDB_INVALID_ADDRESS
Definition: lldb-defines.h:74
DataExtractor.h
lldb_private::IRMemoryMap::WritePointerToMemory
void WritePointerToMemory(lldb::addr_t process_address, lldb::addr_t address, Status &error)
Definition: IRMemoryMap.cpp:612
lldb_private::IRMemoryMap::Allocation
Definition: IRMemoryMap.h:89
lldb_private::MemoryRegionInfo::GetRange
RangeType & GetRange()
Definition: MemoryRegionInfo.h:36
Status.h
lldb_private::IRMemoryMap::GetBestExecutionContextScope
ExecutionContextScope * GetBestExecutionContextScope() const
Definition: IRMemoryMap.cpp:256
lldb_private::IRMemoryMap::m_allocations
AllocationMap m_allocations
Definition: IRMemoryMap.h:121
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::DataExtractor::GetU16
uint16_t GetU16(lldb::offset_t *offset_ptr) const
Extract a uint16_t value from *offset_ptr.
Definition: DataExtractor.cpp:347
lldb_private::IRMemoryMap::Allocation::Allocation
Allocation(lldb::addr_t process_alloc, lldb::addr_t process_start, size_t size, uint32_t permissions, uint8_t alignment, AllocationPolicy m_policy)
Definition: IRMemoryMap.cpp:270
lldb_private::Status::Clear
void Clear()
Clear the object state.
Definition: Status.cpp:167
lldb_private::IRMemoryMap::ReadPointerFromMemory
void ReadPointerFromMemory(lldb::addr_t *address, lldb::addr_t process_address, Status &error)
Definition: IRMemoryMap.cpp:758
lldb_private::IRMemoryMap::eAllocationPolicyProcessOnly
@ eAllocationPolicyProcessOnly
The intent is that this allocation exist only in the process.
Definition: IRMemoryMap.h:49
lldb_private::IRMemoryMap::GetAllocSize
bool GetAllocSize(lldb::addr_t address, size_t &size)
Definition: IRMemoryMap.cpp:490
lldb_private::Log
Definition: Log.h:48
lldb_private::GetLog
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition: Log.h:235
lldb_private::DataBufferHeap
Definition: DataBufferHeap.h:30
lldb_private::LLDBLog::Expressions
@ Expressions
lldb_private::IRMemoryMap::m_target_wp
lldb::TargetWP m_target_wp
Definition: IRMemoryMap.h:119
LLDBLog.h
DataBufferHeap.h
lldb_private::IRMemoryMap::m_process_wp
lldb::ProcessWP m_process_wp
Definition: IRMemoryMap.h:116
lldb_private::IRMemoryMap::IntersectsAllocation
bool IntersectsAllocation(lldb::addr_t addr, size_t size) const
Definition: IRMemoryMap.cpp:184
lldb::ByteOrder
ByteOrder
Byte ordering definitions.
Definition: lldb-enumerations.h:138
lldb_private::MemoryRegionInfo::GetReadable
OptionalBool GetReadable() const
Definition: MemoryRegionInfo.h:42
lldb_private::Range::GetRangeEnd
BaseType GetRangeEnd() const
Definition: RangeMap.h:73