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