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