1 //===-- IRMemoryMap.cpp -----------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/Core/DataBufferHeap.h"
11 #include "lldb/Core/DataExtractor.h"
12 #include "lldb/Core/Error.h"
13 #include "lldb/Core/Log.h"
14 #include "lldb/Core/Scalar.h"
15 #include "lldb/Expression/IRMemoryMap.h"
16 #include "lldb/Target/Process.h"
17 #include "lldb/Target/Target.h"
18 
19 using namespace lldb_private;
20 
21 IRMemoryMap::IRMemoryMap (lldb::TargetSP target_sp) :
22     m_target_wp(target_sp)
23 {
24     if (target_sp)
25         m_process_wp = target_sp->GetProcessSP();
26 }
27 
28 IRMemoryMap::~IRMemoryMap ()
29 {
30     lldb::ProcessSP process_sp = m_process_wp.lock();
31 
32     if (process_sp)
33     {
34         for (AllocationMap::value_type &allocation : m_allocations)
35         {
36             if (allocation.second.m_policy == eAllocationPolicyMirror ||
37                 allocation.second.m_policy == eAllocationPolicyProcessOnly ||
38                 (allocation.second.m_policy == eAllocationPolicyHostOnly && process_sp->CanJIT()))
39                 process_sp->DeallocateMemory(allocation.second.m_process_alloc);
40 
41             if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
42             {
43                 log->Printf("IRMemoryMap::~IRMemoryMap deallocated [0x%llx..0x%llx)",
44                             (uint64_t)allocation.second.m_process_start,
45                             (uint64_t)allocation.second.m_process_start + (uint64_t)allocation.second.m_size);
46             }
47         }
48     }
49 }
50 
51 lldb::addr_t
52 IRMemoryMap::FindSpace (size_t size)
53 {
54     lldb::TargetSP target_sp = m_target_wp.lock();
55     lldb::ProcessSP process_sp = m_process_wp.lock();
56 
57     lldb::addr_t ret = LLDB_INVALID_ADDRESS;
58 
59     if (process_sp && process_sp->CanJIT())
60     {
61         Error alloc_error;
62 
63         ret = process_sp->AllocateMemory(size, lldb::ePermissionsReadable | lldb::ePermissionsWritable, alloc_error);
64 
65         if (!alloc_error.Success())
66             return LLDB_INVALID_ADDRESS;
67         else
68             return ret;
69     }
70 
71     for (int iterations = 0; iterations < 16; ++iterations)
72     {
73         lldb::addr_t candidate;
74 
75         switch (target_sp->GetArchitecture().GetAddressByteSize())
76         {
77         case 4:
78             {
79                 uint32_t random_data = random();
80                 candidate = random_data;
81                 candidate &= ~0xfffull;
82                 break;
83             }
84         case 8:
85             {
86                 uint32_t random_low = random();
87                 uint32_t random_high = random();
88                 candidate = random_high;
89                 candidate <<= 32ull;
90                 candidate |= random_low;
91                 candidate &= ~0xfffull;
92                 break;
93             }
94         }
95 
96         if (IntersectsAllocation(candidate, size))
97             continue;
98 
99         char buf[1];
100 
101         Error err;
102 
103         if (process_sp &&
104             (process_sp->ReadMemory(candidate, buf, 1, err) == 1 ||
105              process_sp->ReadMemory(candidate + size, buf, 1, err) == 1))
106             continue;
107 
108         ret = candidate;
109     }
110 
111     return ret;
112 }
113 
114 IRMemoryMap::AllocationMap::iterator
115 IRMemoryMap::FindAllocation (lldb::addr_t addr, size_t size)
116 {
117     if (addr == LLDB_INVALID_ADDRESS)
118         return m_allocations.end();
119 
120     AllocationMap::iterator iter = m_allocations.lower_bound (addr);
121 
122     if (iter == m_allocations.end() ||
123         iter->first > addr)
124     {
125         if (iter == m_allocations.begin())
126             return m_allocations.end();
127         iter--;
128     }
129 
130     if (iter->first <= addr && iter->first + iter->second.m_size >= addr + size)
131         return iter;
132 
133     return m_allocations.end();
134 }
135 
136 bool
137 IRMemoryMap::IntersectsAllocation (lldb::addr_t addr, size_t size)
138 {
139     if (addr == LLDB_INVALID_ADDRESS)
140         return false;
141 
142     AllocationMap::iterator iter = m_allocations.lower_bound (addr);
143 
144     if (iter == m_allocations.end() ||
145         iter->first > addr)
146     {
147         if (iter == m_allocations.begin())
148             return false;
149 
150         iter--;
151     }
152 
153     while (iter != m_allocations.end() && iter->second.m_process_alloc < addr + size)
154     {
155         if (iter->second.m_process_start + iter->second.m_size > addr)
156             return true;
157 
158         ++iter;
159     }
160 
161     return false;
162 }
163 
164 lldb::ByteOrder
165 IRMemoryMap::GetByteOrder()
166 {
167     lldb::ProcessSP process_sp = m_process_wp.lock();
168 
169     if (process_sp)
170         return process_sp->GetByteOrder();
171 
172     lldb::TargetSP target_sp = m_target_wp.lock();
173 
174     if (target_sp)
175         return target_sp->GetArchitecture().GetByteOrder();
176 
177     return lldb::eByteOrderInvalid;
178 }
179 
180 uint32_t
181 IRMemoryMap::GetAddressByteSize()
182 {
183     lldb::ProcessSP process_sp = m_process_wp.lock();
184 
185     if (process_sp)
186         return process_sp->GetAddressByteSize();
187 
188     lldb::TargetSP target_sp = m_target_wp.lock();
189 
190     if (target_sp)
191         return target_sp->GetArchitecture().GetAddressByteSize();
192 
193     return UINT32_MAX;
194 }
195 
196 ExecutionContextScope *
197 IRMemoryMap::GetBestExecutionContextScope()
198 {
199     lldb::ProcessSP process_sp = m_process_wp.lock();
200 
201     if (process_sp)
202         return process_sp.get();
203 
204     lldb::TargetSP target_sp = m_target_wp.lock();
205 
206     if (target_sp)
207         return target_sp.get();
208 
209     return NULL;
210 }
211 
212 IRMemoryMap::Allocation::Allocation (lldb::addr_t process_alloc,
213                                      lldb::addr_t process_start,
214                                      size_t size,
215                                      uint32_t permissions,
216                                      uint8_t alignment,
217                                      AllocationPolicy policy)
218 {
219     m_process_alloc = process_alloc;
220     m_process_start = process_start;
221     m_size = size;
222     m_permissions = permissions;
223     m_alignment = alignment;
224     m_policy = policy;
225 
226     switch (policy)
227     {
228         default:
229             assert (0 && "We cannot reach this!");
230         case eAllocationPolicyHostOnly:
231             m_data.SetByteSize(size);
232             memset(m_data.GetBytes(), 0, size);
233             break;
234         case eAllocationPolicyProcessOnly:
235             break;
236         case eAllocationPolicyMirror:
237             m_data.SetByteSize(size);
238             memset(m_data.GetBytes(), 0, size);
239             break;
240     }
241 }
242 
243 lldb::addr_t
244 IRMemoryMap::Malloc (size_t size, uint8_t alignment, uint32_t permissions, AllocationPolicy policy, Error &error)
245 {
246     error.Clear();
247 
248     lldb::ProcessSP process_sp;
249     lldb::addr_t    allocation_address  = LLDB_INVALID_ADDRESS;
250     lldb::addr_t    aligned_address     = LLDB_INVALID_ADDRESS;
251 
252     size_t          alignment_mask = alignment - 1;
253     size_t          allocation_size;
254 
255     if (size == 0)
256         allocation_size = alignment;
257     else
258         allocation_size = (size & alignment_mask) ? ((size + alignment) & (~alignment_mask)) : size;
259 
260     switch (policy)
261     {
262     default:
263         error.SetErrorToGenericError();
264         error.SetErrorString("Couldn't malloc: invalid allocation policy");
265         return LLDB_INVALID_ADDRESS;
266     case eAllocationPolicyHostOnly:
267         allocation_address = FindSpace(allocation_size);
268         if (allocation_address == LLDB_INVALID_ADDRESS)
269         {
270             error.SetErrorToGenericError();
271             error.SetErrorString("Couldn't malloc: address space is full");
272             return LLDB_INVALID_ADDRESS;
273         }
274         break;
275     case eAllocationPolicyMirror:
276         process_sp = m_process_wp.lock();
277         if (process_sp && process_sp->CanJIT())
278         {
279             allocation_address = process_sp->AllocateMemory(allocation_size, permissions, error);
280             if (!error.Success())
281                 return LLDB_INVALID_ADDRESS;
282         }
283         else
284         {
285             policy = eAllocationPolicyHostOnly;
286             allocation_address = FindSpace(allocation_size);
287             if (allocation_address == LLDB_INVALID_ADDRESS)
288             {
289                 error.SetErrorToGenericError();
290                 error.SetErrorString("Couldn't malloc: address space is full");
291                 return LLDB_INVALID_ADDRESS;
292             }
293         }
294         break;
295     case eAllocationPolicyProcessOnly:
296         process_sp = m_process_wp.lock();
297         if (process_sp)
298         {
299             if (process_sp->CanJIT())
300             {
301                 allocation_address = process_sp->AllocateMemory(allocation_size, permissions, error);
302                 if (!error.Success())
303                     return LLDB_INVALID_ADDRESS;
304             }
305             else
306             {
307                 error.SetErrorToGenericError();
308                 error.SetErrorString("Couldn't malloc: process doesn't support allocating memory");
309                 return LLDB_INVALID_ADDRESS;
310             }
311         }
312         else
313         {
314             error.SetErrorToGenericError();
315             error.SetErrorString("Couldn't malloc: process doesn't exist, and this memory must be in the process");
316             return LLDB_INVALID_ADDRESS;
317         }
318         break;
319     }
320 
321 
322     lldb::addr_t mask = alignment - 1;
323     aligned_address = (allocation_address + mask) & (~mask);
324 
325     m_allocations[aligned_address] = Allocation(allocation_address,
326                                                 aligned_address,
327                                                 allocation_size,
328                                                 permissions,
329                                                 alignment,
330                                                 policy);
331 
332     if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
333     {
334         const char * policy_string;
335 
336         switch (policy)
337         {
338         default:
339             policy_string = "<invalid policy>";
340             break;
341         case eAllocationPolicyHostOnly:
342             policy_string = "eAllocationPolicyHostOnly";
343             break;
344         case eAllocationPolicyProcessOnly:
345             policy_string = "eAllocationPolicyProcessOnly";
346             break;
347         case eAllocationPolicyMirror:
348             policy_string = "eAllocationPolicyMirror";
349             break;
350         }
351 
352         log->Printf("IRMemoryMap::Malloc (%llu, 0x%llx, 0x%llx, %s) -> 0x%llx",
353                     (uint64_t)allocation_size,
354                     (uint64_t)alignment,
355                     (uint64_t)permissions,
356                     policy_string,
357                     aligned_address);
358     }
359 
360     return aligned_address;
361 }
362 
363 void
364 IRMemoryMap::Free (lldb::addr_t process_address, Error &error)
365 {
366     error.Clear();
367 
368     AllocationMap::iterator iter = m_allocations.find(process_address);
369 
370     if (iter == m_allocations.end())
371     {
372         error.SetErrorToGenericError();
373         error.SetErrorString("Couldn't free: allocation doesn't exist");
374         return;
375     }
376 
377     Allocation &allocation = iter->second;
378 
379     switch (allocation.m_policy)
380     {
381     default:
382     case eAllocationPolicyHostOnly:
383         {
384             lldb::ProcessSP process_sp = m_process_wp.lock();
385             if (process_sp && process_sp->CanJIT())
386                 process_sp->DeallocateMemory(allocation.m_process_alloc); // FindSpace allocated this for real
387 
388             break;
389         }
390     case eAllocationPolicyMirror:
391     case eAllocationPolicyProcessOnly:
392         {
393             lldb::ProcessSP process_sp = m_process_wp.lock();
394             if (process_sp)
395                 process_sp->DeallocateMemory(allocation.m_process_alloc);
396         }
397     }
398 
399     if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
400     {
401         log->Printf("IRMemoryMap::Free (0x%llx) freed [0x%llx..0x%llx)",
402                     (uint64_t)process_address,
403                     iter->second.m_process_start,
404                     iter->second.m_process_start + iter->second.m_size);
405     }
406 
407     m_allocations.erase(iter);
408 }
409 
410 void
411 IRMemoryMap::WriteMemory (lldb::addr_t process_address, const uint8_t *bytes, size_t size, Error &error)
412 {
413     error.Clear();
414 
415     AllocationMap::iterator iter = FindAllocation(process_address, size);
416 
417     if (iter == m_allocations.end())
418     {
419         lldb::ProcessSP process_sp = m_process_wp.lock();
420 
421         if (process_sp)
422         {
423             process_sp->WriteMemory(process_address, bytes, size, error);
424             return;
425         }
426 
427         error.SetErrorToGenericError();
428         error.SetErrorString("Couldn't write: no allocation contains the target range and the process doesn't exist");
429         return;
430     }
431 
432     Allocation &allocation = iter->second;
433 
434     uint64_t offset = process_address - allocation.m_process_start;
435 
436     lldb::ProcessSP process_sp;
437 
438     switch (allocation.m_policy)
439     {
440     default:
441         error.SetErrorToGenericError();
442         error.SetErrorString("Couldn't write: invalid allocation policy");
443         return;
444     case eAllocationPolicyHostOnly:
445         if (!allocation.m_data.GetByteSize())
446         {
447             error.SetErrorToGenericError();
448             error.SetErrorString("Couldn't write: data buffer is empty");
449             return;
450         }
451         ::memcpy (allocation.m_data.GetBytes() + offset, bytes, size);
452         break;
453     case eAllocationPolicyMirror:
454         if (!allocation.m_data.GetByteSize())
455         {
456             error.SetErrorToGenericError();
457             error.SetErrorString("Couldn't write: data buffer is empty");
458             return;
459         }
460         ::memcpy (allocation.m_data.GetBytes() + offset, bytes, size);
461         process_sp = m_process_wp.lock();
462         if (process_sp)
463         {
464             process_sp->WriteMemory(process_address, bytes, size, error);
465             if (!error.Success())
466                 return;
467         }
468         break;
469     case eAllocationPolicyProcessOnly:
470         process_sp = m_process_wp.lock();
471         if (process_sp)
472         {
473             process_sp->WriteMemory(process_address, bytes, size, error);
474             if (!error.Success())
475                 return;
476         }
477         break;
478     }
479 
480     if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
481     {
482         log->Printf("IRMemoryMap::WriteMemory (0x%llx, 0x%llx, 0x%lld) went to [0x%llx..0x%llx)",
483                     (uint64_t)process_address,
484                     (uint64_t)bytes,
485                     (uint64_t)size,
486                     (uint64_t)allocation.m_process_start,
487                     (uint64_t)allocation.m_process_start + (uint64_t)allocation.m_size);
488     }
489 }
490 
491 void
492 IRMemoryMap::WriteScalarToMemory (lldb::addr_t process_address, Scalar &scalar, size_t size, Error &error)
493 {
494     error.Clear();
495 
496     if (size == UINT32_MAX)
497         size = scalar.GetByteSize();
498 
499     if (size > 0)
500     {
501         uint8_t buf[32];
502         const size_t mem_size = scalar.GetAsMemoryData (buf, size, GetByteOrder(), error);
503         if (mem_size > 0)
504         {
505             return WriteMemory(process_address, buf, mem_size, error);
506         }
507         else
508         {
509             error.SetErrorToGenericError();
510             error.SetErrorString ("Couldn't write scalar: failed to get scalar as memory data");
511         }
512     }
513     else
514     {
515         error.SetErrorToGenericError();
516         error.SetErrorString ("Couldn't write scalar: its size was zero");
517     }
518     return;
519 }
520 
521 void
522 IRMemoryMap::WritePointerToMemory (lldb::addr_t process_address, lldb::addr_t address, Error &error)
523 {
524     error.Clear();
525 
526     Scalar scalar(address);
527 
528     WriteScalarToMemory(process_address, scalar, GetAddressByteSize(), error);
529 }
530 
531 void
532 IRMemoryMap::ReadMemory (uint8_t *bytes, lldb::addr_t process_address, size_t size, Error &error)
533 {
534     error.Clear();
535 
536     AllocationMap::iterator iter = FindAllocation(process_address, size);
537 
538     if (iter == m_allocations.end())
539     {
540         lldb::ProcessSP process_sp = m_process_wp.lock();
541 
542         if (process_sp)
543         {
544             process_sp->ReadMemory(process_address, bytes, size, error);
545             return;
546         }
547 
548         lldb::TargetSP target_sp = m_target_wp.lock();
549 
550         if (target_sp)
551         {
552             Address absolute_address(process_address);
553             target_sp->ReadMemory(absolute_address, false, bytes, size, error);
554             return;
555         }
556 
557         error.SetErrorToGenericError();
558         error.SetErrorString("Couldn't read: no allocation contains the target range, and neither the process nor the target exist");
559         return;
560     }
561 
562     Allocation &allocation = iter->second;
563 
564     uint64_t offset = process_address - allocation.m_process_start;
565 
566     lldb::ProcessSP process_sp;
567 
568     switch (allocation.m_policy)
569     {
570     default:
571         error.SetErrorToGenericError();
572         error.SetErrorString("Couldn't read: invalid allocation policy");
573         return;
574     case eAllocationPolicyHostOnly:
575         if (!allocation.m_data.GetByteSize())
576         {
577             error.SetErrorToGenericError();
578             error.SetErrorString("Couldn't read: data buffer is empty");
579             return;
580         }
581         ::memcpy (bytes, allocation.m_data.GetBytes() + offset, size);
582         break;
583     case eAllocationPolicyMirror:
584         process_sp = m_process_wp.lock();
585         if (process_sp)
586         {
587             process_sp->ReadMemory(process_address, bytes, size, error);
588             if (!error.Success())
589                 return;
590         }
591         else
592         {
593             if (!allocation.m_data.GetByteSize())
594             {
595                 error.SetErrorToGenericError();
596                 error.SetErrorString("Couldn't read: data buffer is empty");
597                 return;
598             }
599             ::memcpy (bytes, allocation.m_data.GetBytes() + offset, size);
600         }
601         break;
602     case eAllocationPolicyProcessOnly:
603         process_sp = m_process_wp.lock();
604         if (process_sp)
605         {
606             process_sp->ReadMemory(process_address, bytes, size, error);
607             if (!error.Success())
608                 return;
609         }
610         break;
611     }
612 
613     if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
614     {
615         log->Printf("IRMemoryMap::ReadMemory (0x%llx, 0x%llx, 0x%lld) came from [0x%llx..0x%llx)",
616                     (uint64_t)process_address,
617                     (uint64_t)bytes,
618                     (uint64_t)size,
619                     (uint64_t)allocation.m_process_start,
620                     (uint64_t)allocation.m_process_start + (uint64_t)allocation.m_size);
621     }
622 }
623 
624 void
625 IRMemoryMap::ReadScalarFromMemory (Scalar &scalar, lldb::addr_t process_address, size_t size, Error &error)
626 {
627     error.Clear();
628 
629     if (size > 0)
630     {
631         DataBufferHeap buf(size, 0);
632         ReadMemory(buf.GetBytes(), process_address, size, error);
633 
634         if (!error.Success())
635             return;
636 
637         DataExtractor extractor(buf.GetBytes(), buf.GetByteSize(), GetByteOrder(), GetAddressByteSize());
638 
639         lldb::offset_t offset = 0;
640 
641         switch (size)
642         {
643         default:
644             error.SetErrorToGenericError();
645             error.SetErrorStringWithFormat("Couldn't read scalar: unsupported size %lld", (unsigned long long)size);
646             return;
647         case 1: scalar = extractor.GetU8(&offset);  break;
648         case 2: scalar = extractor.GetU16(&offset); break;
649         case 4: scalar = extractor.GetU32(&offset); break;
650         case 8: scalar = extractor.GetU64(&offset); break;
651         }
652     }
653     else
654     {
655         error.SetErrorToGenericError();
656         error.SetErrorString ("Couldn't read scalar: its size was zero");
657     }
658     return;
659 }
660 
661 void
662 IRMemoryMap::ReadPointerFromMemory (lldb::addr_t *address, lldb::addr_t process_address, Error &error)
663 {
664     error.Clear();
665 
666     Scalar pointer_scalar;
667     ReadScalarFromMemory(pointer_scalar, process_address, GetAddressByteSize(), error);
668 
669     if (!error.Success())
670         return;
671 
672     *address = pointer_scalar.ULongLong();
673 
674     return;
675 }
676 
677 void
678 IRMemoryMap::GetMemoryData (DataExtractor &extractor, lldb::addr_t process_address, size_t size, Error &error)
679 {
680     error.Clear();
681 
682     if (size > 0)
683     {
684         AllocationMap::iterator iter = FindAllocation(process_address, size);
685 
686         if (iter == m_allocations.end())
687         {
688             error.SetErrorToGenericError();
689             error.SetErrorStringWithFormat("Couldn't find an allocation containing [0x%llx..0x%llx)", (unsigned long long)process_address, (unsigned long long)(process_address + size));
690             return;
691         }
692 
693         Allocation &allocation = iter->second;
694 
695         switch (allocation.m_policy)
696         {
697         default:
698             error.SetErrorToGenericError();
699             error.SetErrorString("Couldn't get memory data: invalid allocation policy");
700             return;
701         case eAllocationPolicyProcessOnly:
702             error.SetErrorToGenericError();
703             error.SetErrorString("Couldn't get memory data: memory is only in the target");
704             return;
705         case eAllocationPolicyMirror:
706             {
707                 lldb::ProcessSP process_sp = m_process_wp.lock();
708 
709                 if (!allocation.m_data.GetByteSize())
710                 {
711                     error.SetErrorToGenericError();
712                     error.SetErrorString("Couldn't get memory data: data buffer is empty");
713                     return;
714                 }
715                 if (process_sp)
716                 {
717                     process_sp->ReadMemory(allocation.m_process_start, allocation.m_data.GetBytes(), allocation.m_data.GetByteSize(), error);
718                     if (!error.Success())
719                         return;
720                     uint64_t offset = process_address - allocation.m_process_start;
721                     extractor = DataExtractor(allocation.m_data.GetBytes() + offset, size, GetByteOrder(), GetAddressByteSize());
722                     return;
723                 }
724             }
725         case eAllocationPolicyHostOnly:
726             if (!allocation.m_data.GetByteSize())
727             {
728                 error.SetErrorToGenericError();
729                 error.SetErrorString("Couldn't get memory data: data buffer is empty");
730                 return;
731             }
732             uint64_t offset = process_address - allocation.m_process_start;
733             extractor = DataExtractor(allocation.m_data.GetBytes() + offset, size, GetByteOrder(), GetAddressByteSize());
734             return;
735         }
736     }
737     else
738     {
739         error.SetErrorToGenericError();
740         error.SetErrorString ("Couldn't get memory data: its size was zero");
741         return;
742     }
743 }
744 
745 
746