1 //===-- Value.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/Value.h"
11 
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "lldb/Core/DataExtractor.h"
17 #include "lldb/Core/DataBufferHeap.h"
18 #include "lldb/Core/Module.h"
19 #include "lldb/Core/Stream.h"
20 #include "lldb/Symbol/ClangASTType.h"
21 #include "lldb/Symbol/ClangASTContext.h"
22 #include "lldb/Symbol/ObjectFile.h"
23 #include "lldb/Symbol/SymbolContext.h"
24 #include "lldb/Symbol/Type.h"
25 #include "lldb/Symbol/Variable.h"
26 #include "lldb/Target/ExecutionContext.h"
27 #include "lldb/Target/Process.h"
28 #include "lldb/Target/Target.h"
29 
30 using namespace lldb;
31 using namespace lldb_private;
32 
33 Value::Value() :
34     m_value (),
35     m_value_type (eValueTypeScalar),
36     m_context (NULL),
37     m_context_type (eContextTypeInvalid),
38     m_data_buffer ()
39 {
40 }
41 
42 Value::Value(const Scalar& scalar) :
43     m_value (scalar),
44     m_value_type (eValueTypeScalar),
45     m_context (NULL),
46     m_context_type (eContextTypeInvalid),
47     m_data_buffer ()
48 {
49 }
50 
51 
52 Value::Value(const uint8_t *bytes, int len) :
53     m_value (),
54     m_value_type (eValueTypeHostAddress),
55     m_context (NULL),
56     m_context_type (eContextTypeInvalid),
57     m_data_buffer ()
58 {
59     m_data_buffer.CopyData(bytes, len);
60     m_value = (uintptr_t)m_data_buffer.GetBytes();
61 }
62 
63 Value::Value(const Value &v) :
64     m_value(v.m_value),
65     m_value_type(v.m_value_type),
66     m_context(v.m_context),
67     m_context_type(v.m_context_type)
68 {
69     if ((uintptr_t)v.m_value.ULongLong(LLDB_INVALID_ADDRESS) == (uintptr_t)v.m_data_buffer.GetBytes())
70     {
71         m_data_buffer.CopyData(v.m_data_buffer.GetBytes(),
72                                v.m_data_buffer.GetByteSize());
73 
74         m_value = (uintptr_t)m_data_buffer.GetBytes();
75     }
76 }
77 
78 Value &
79 Value::operator=(const Value &rhs)
80 {
81     if (this != &rhs)
82     {
83         m_value = rhs.m_value;
84         m_value_type = rhs.m_value_type;
85         m_context = rhs.m_context;
86         m_context_type = rhs.m_context_type;
87         if ((uintptr_t)rhs.m_value.ULongLong(LLDB_INVALID_ADDRESS) == (uintptr_t)rhs.m_data_buffer.GetBytes())
88         {
89             m_data_buffer.CopyData(rhs.m_data_buffer.GetBytes(),
90                                    rhs.m_data_buffer.GetByteSize());
91 
92             m_value = (uintptr_t)m_data_buffer.GetBytes();
93         }
94     }
95     return *this;
96 }
97 
98 void
99 Value::Dump (Stream* strm)
100 {
101     m_value.GetValue (strm, true);
102     strm->Printf(", value_type = %s, context = %p, context_type = %s",
103                 Value::GetValueTypeAsCString(m_value_type),
104                 m_context,
105                 Value::GetContextTypeAsCString(m_context_type));
106 }
107 
108 Value::ValueType
109 Value::GetValueType() const
110 {
111     return m_value_type;
112 }
113 
114 AddressType
115 Value::GetValueAddressType () const
116 {
117     switch (m_value_type)
118     {
119     default:
120     case eValueTypeScalar:
121         break;
122     case eValueTypeLoadAddress: return eAddressTypeLoad;
123     case eValueTypeFileAddress: return eAddressTypeFile;
124     case eValueTypeHostAddress: return eAddressTypeHost;
125     }
126     return eAddressTypeInvalid;
127 }
128 
129 RegisterInfo *
130 Value::GetRegisterInfo()
131 {
132     if (m_context_type == eContextTypeRegisterInfo)
133         return static_cast<RegisterInfo *> (m_context);
134     return NULL;
135 }
136 
137 Type *
138 Value::GetType()
139 {
140     if (m_context_type == eContextTypeLLDBType)
141         return static_cast<Type *> (m_context);
142     return NULL;
143 }
144 
145 void
146 Value::ResizeData(int len)
147 {
148     m_value_type = eValueTypeHostAddress;
149     m_data_buffer.SetByteSize(len);
150     m_value = (uintptr_t)m_data_buffer.GetBytes();
151 }
152 
153 bool
154 Value::ValueOf(ExecutionContext *exe_ctx, clang::ASTContext *ast_context)
155 {
156     switch (m_context_type)
157     {
158     default:
159     case eContextTypeInvalid:
160     case eContextTypeClangType:         // clang::Type *
161     case eContextTypeRegisterInfo:      // RegisterInfo *
162     case eContextTypeLLDBType:          // Type *
163         break;
164 
165     case eContextTypeVariable:          // Variable *
166         ResolveValue(exe_ctx, ast_context);
167         return true;
168     }
169     return false;
170 }
171 
172 size_t
173 Value::GetValueByteSize (clang::ASTContext *ast_context, Error *error_ptr)
174 {
175     size_t byte_size = 0;
176 
177     switch (m_context_type)
178     {
179     default:
180     case eContextTypeInvalid:
181         // If we have no context, there is no way to know how much memory to read
182         if (error_ptr)
183             error_ptr->SetErrorString ("Invalid context type, there is no way to know how much memory to read.");
184         break;
185 
186     case eContextTypeClangType:
187         if (ast_context == NULL)
188         {
189             if (error_ptr)
190                 error_ptr->SetErrorString ("Can't determine size of opaque clang type with NULL ASTContext *.");
191         }
192         else
193         {
194             uint64_t bit_width = ClangASTType::GetClangTypeBitWidth (ast_context, m_context);
195             byte_size = (bit_width + 7 ) / 8;
196         }
197         break;
198 
199     case eContextTypeRegisterInfo:     // RegisterInfo *
200         if (GetRegisterInfo())
201             byte_size = GetRegisterInfo()->byte_size;
202         else if (error_ptr)
203                 error_ptr->SetErrorString ("Can't determine byte size with NULL RegisterInfo *.");
204 
205         break;
206 
207     case eContextTypeLLDBType:             // Type *
208         if (GetType())
209             byte_size = GetType()->GetByteSize();
210         else if (error_ptr)
211             error_ptr->SetErrorString ("Can't determine byte size with NULL Type *.");
212         break;
213 
214     case eContextTypeVariable:         // Variable *
215         if (GetVariable())
216             byte_size = GetVariable()->GetType()->GetByteSize();
217         else if (error_ptr)
218             error_ptr->SetErrorString ("Can't determine byte size with NULL Variable *.");
219         break;
220     }
221 
222     if (error_ptr)
223     {
224         if (byte_size == 0)
225         {
226             if (error_ptr->Success())
227                 error_ptr->SetErrorString("Unable to determine byte size.");
228         }
229         else
230         {
231             error_ptr->Clear();
232         }
233     }
234     return byte_size;
235 }
236 
237 clang_type_t
238 Value::GetClangType ()
239 {
240     switch (m_context_type)
241     {
242     default:
243     case eContextTypeInvalid:
244         break;
245 
246     case eContextTypeClangType:
247         return m_context;
248 
249     case eContextTypeRegisterInfo:
250         break;    // TODO: Eventually convert into a clang type?
251 
252     case eContextTypeLLDBType:
253         if (GetType())
254             return GetType()->GetClangForwardType();
255         break;
256 
257     case eContextTypeVariable:
258         if (GetVariable())
259             return GetVariable()->GetType()->GetClangForwardType();
260         break;
261     }
262 
263     return NULL;
264 }
265 
266 lldb::Format
267 Value::GetValueDefaultFormat ()
268 {
269     switch (m_context_type)
270     {
271     default:
272     case eContextTypeInvalid:
273         break;
274 
275     case eContextTypeClangType:
276         return ClangASTType::GetFormat (m_context);
277 
278     case eContextTypeRegisterInfo:
279         if (GetRegisterInfo())
280             return GetRegisterInfo()->format;
281         break;
282 
283     case eContextTypeLLDBType:
284         if (GetType())
285             return GetType()->GetFormat();
286         break;
287 
288     case eContextTypeVariable:
289         if (GetVariable())
290             return GetVariable()->GetType()->GetFormat();
291         break;
292 
293     }
294 
295     // Return a good default in case we can't figure anything out
296     return eFormatHex;
297 }
298 
299 bool
300 Value::GetData (DataExtractor &data)
301 {
302     switch (m_value_type)
303     {
304     default:
305         break;
306 
307     case eValueTypeScalar:
308         if (m_value.GetData (data))
309             return true;
310         break;
311 
312     case eValueTypeLoadAddress:
313     case eValueTypeFileAddress:
314     case eValueTypeHostAddress:
315         if (m_data_buffer.GetByteSize())
316         {
317             data.SetData(m_data_buffer.GetBytes(), m_data_buffer.GetByteSize(), data.GetByteOrder());
318             return true;
319         }
320         break;
321     }
322 
323     return false;
324 
325 }
326 
327 Error
328 Value::GetValueAsData (ExecutionContext *exe_ctx,
329                        clang::ASTContext *ast_context,
330                        DataExtractor &data,
331                        uint32_t data_offset,
332                        Module *module)
333 {
334     data.Clear();
335 
336     Error error;
337     lldb::addr_t address = LLDB_INVALID_ADDRESS;
338     AddressType address_type = eAddressTypeFile;
339     Address file_so_addr;
340     switch (m_value_type)
341     {
342     default:
343         error.SetErrorStringWithFormat("invalid value type %i", m_value_type);
344         break;
345 
346     case eValueTypeScalar:
347         data.SetByteOrder (lldb::endian::InlHostByteOrder());
348         if (m_context_type == eContextTypeClangType && ast_context)
349         {
350             uint32_t ptr_bit_width = ClangASTType::GetClangTypeBitWidth (ast_context,
351                                                                      ClangASTContext::GetVoidPtrType(ast_context, false));
352             uint32_t ptr_byte_size = (ptr_bit_width + 7) / 8;
353             data.SetAddressByteSize (ptr_byte_size);
354         }
355         else
356             data.SetAddressByteSize(sizeof(void *));
357         if (m_value.GetData (data))
358             return error;   // Success;
359         error.SetErrorStringWithFormat("extracting data from value failed");
360         break;
361 
362     case eValueTypeLoadAddress:
363         if (exe_ctx == NULL)
364         {
365             error.SetErrorString ("can't read load address (no execution context)");
366         }
367         else
368         {
369             Process *process = exe_ctx->GetProcessPtr();
370             if (process == NULL)
371             {
372                 error.SetErrorString ("can't read load address (invalid process)");
373             }
374             else
375             {
376                 address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
377                 address_type = eAddressTypeLoad;
378                 data.SetByteOrder(process->GetTarget().GetArchitecture().GetByteOrder());
379                 data.SetAddressByteSize(process->GetTarget().GetArchitecture().GetAddressByteSize());
380             }
381         }
382         break;
383 
384     case eValueTypeFileAddress:
385         if (exe_ctx == NULL)
386         {
387             error.SetErrorString ("can't read file address (no execution context)");
388         }
389         else if (exe_ctx->GetTargetPtr() == NULL)
390         {
391             error.SetErrorString ("can't read file address (invalid target)");
392         }
393         else
394         {
395             address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
396             if (address == LLDB_INVALID_ADDRESS)
397             {
398                 error.SetErrorString ("invalid file address");
399             }
400             else
401             {
402                 if (module == NULL)
403                 {
404                     // The only thing we can currently lock down to a module so that
405                     // we can resolve a file address, is a variable.
406                     Variable *variable = GetVariable();
407                     if (variable)
408                     {
409                         SymbolContext var_sc;
410                         variable->CalculateSymbolContext(&var_sc);
411                         module = var_sc.module_sp.get();
412                     }
413                 }
414 
415                 if (module)
416                 {
417                     bool resolved = false;
418                     ObjectFile *objfile = module->GetObjectFile();
419                     if (objfile)
420                     {
421                         Address so_addr(address, objfile->GetSectionList());
422                         addr_t load_address = so_addr.GetLoadAddress (exe_ctx->GetTargetPtr());
423                         if (load_address != LLDB_INVALID_ADDRESS)
424                         {
425                             resolved = true;
426                             address = load_address;
427                             address_type = eAddressTypeLoad;
428                             data.SetByteOrder(exe_ctx->GetTargetRef().GetArchitecture().GetByteOrder());
429                             data.SetAddressByteSize(exe_ctx->GetTargetRef().GetArchitecture().GetAddressByteSize());
430                         }
431                         else
432                         {
433                             if (so_addr.IsSectionOffset())
434                             {
435                                 resolved = true;
436                                 file_so_addr = so_addr;
437                                 data.SetByteOrder(objfile->GetByteOrder());
438                                 data.SetAddressByteSize(objfile->GetAddressByteSize());
439                             }
440                         }
441                     }
442                     if (!resolved)
443                     {
444                         Variable *variable = GetVariable();
445 
446                         if (module)
447                         {
448                             if (variable)
449                                 error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%llx for variable '%s' in %s%s%s",
450                                                                 address,
451                                                                 variable->GetName().AsCString(""),
452                                                                 module->GetFileSpec().GetDirectory().GetCString(),
453                                                                 module->GetFileSpec().GetDirectory() ? "/" : "",
454                                                                 module->GetFileSpec().GetFilename().GetCString());
455                             else
456                                 error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%llx in %s%s%s",
457                                                                 address,
458                                                                 module->GetFileSpec().GetDirectory().GetCString(),
459                                                                 module->GetFileSpec().GetDirectory() ? "/" : "",
460                                                                 module->GetFileSpec().GetFilename().GetCString());
461                         }
462                         else
463                         {
464                             if (variable)
465                                 error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%llx for variable '%s'",
466                                                                 address,
467                                                                 variable->GetName().AsCString(""));
468                             else
469                                 error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%llx", address);
470                         }
471                     }
472                 }
473                 else
474                 {
475                     // Can't convert a file address to anything valid without more
476                     // context (which Module it came from)
477                     error.SetErrorString ("can't read memory from file address without more context");
478                 }
479             }
480         }
481         break;
482 
483     case eValueTypeHostAddress:
484         address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
485         data.SetByteOrder(lldb::endian::InlHostByteOrder());
486         data.SetAddressByteSize(sizeof(void *));
487         address_type = eAddressTypeHost;
488         break;
489     }
490 
491     // Bail if we encountered any errors
492     if (error.Fail())
493         return error;
494 
495     if (address == LLDB_INVALID_ADDRESS)
496     {
497         error.SetErrorStringWithFormat ("invalid %s address", address_type == eAddressTypeHost ? "host" : "load");
498         return error;
499     }
500 
501     // If we got here, we need to read the value from memory
502     uint32_t byte_size = GetValueByteSize (ast_context, &error);
503 
504     // Bail if we encountered any errors getting the byte size
505     if (error.Fail())
506         return error;
507 
508     // Make sure we have enough room within "data", and if we don't make
509     // something large enough that does
510     if (!data.ValidOffsetForDataOfSize (data_offset, byte_size))
511     {
512         DataBufferSP data_sp(new DataBufferHeap (data_offset + byte_size, '\0'));
513         data.SetData(data_sp);
514     }
515 
516     uint8_t* dst = const_cast<uint8_t*>(data.PeekData (data_offset, byte_size));
517     if (dst != NULL)
518     {
519         if (address_type == eAddressTypeHost)
520         {
521             // The address is an address in this process, so just copy it
522             memcpy (dst, (uint8_t*)NULL + address, byte_size);
523         }
524         else if ((address_type == eAddressTypeLoad) || (address_type == eAddressTypeFile))
525         {
526             if (file_so_addr.IsValid())
527             {
528                 // We have a file address that we were able to translate into a
529                 // section offset address so we might be able to read this from
530                 // the object files if we don't have a live process. Lets always
531                 // try and read from the process if we have one though since we
532                 // want to read the actual value by setting "prefer_file_cache"
533                 // to false.
534                 const bool prefer_file_cache = false;
535                 if (exe_ctx->GetTargetRef().ReadMemory(file_so_addr, prefer_file_cache, dst, byte_size, error) != byte_size)
536                 {
537                     error.SetErrorStringWithFormat("read memory from 0x%llx failed", (uint64_t)address);
538                 }
539             }
540             else
541             {
542                 // The execution context might have a NULL process, but it
543                 // might have a valid process in the exe_ctx->target, so use
544                 // the ExecutionContext::GetProcess accessor to ensure we
545                 // get the process if there is one.
546                 Process *process = exe_ctx->GetProcessPtr();
547 
548                 if (process)
549                 {
550                     const size_t bytes_read = process->ReadMemory(address, dst, byte_size, error);
551                     if (bytes_read != byte_size)
552                         error.SetErrorStringWithFormat("read memory from 0x%llx failed (%u of %u bytes read)",
553                                                        (uint64_t)address,
554                                                        (uint32_t)bytes_read,
555                                                        (uint32_t)byte_size);
556                 }
557                 else
558                 {
559                     error.SetErrorStringWithFormat("read memory from 0x%llx failed (invalid process)", (uint64_t)address);
560                 }
561             }
562         }
563         else
564         {
565             error.SetErrorStringWithFormat ("unsupported AddressType value (%i)", address_type);
566         }
567     }
568     else
569     {
570         error.SetErrorStringWithFormat ("out of memory");
571     }
572 
573     return error;
574 }
575 
576 Scalar &
577 Value::ResolveValue(ExecutionContext *exe_ctx, clang::ASTContext *ast_context)
578 {
579     void *opaque_clang_qual_type = GetClangType();
580     if (opaque_clang_qual_type)
581     {
582         switch (m_value_type)
583         {
584         case eValueTypeScalar:               // raw scalar value
585             break;
586 
587         default:
588         case eValueTypeFileAddress:
589             m_value.Clear();
590             break;
591 
592         case eValueTypeLoadAddress:          // load address value
593         case eValueTypeHostAddress:          // host address value (for memory in the process that is using liblldb)
594             {
595                 AddressType address_type = m_value_type == eValueTypeLoadAddress ? eAddressTypeLoad : eAddressTypeHost;
596                 lldb::addr_t addr = m_value.ULongLong(LLDB_INVALID_ADDRESS);
597                 DataExtractor data;
598                 if (ClangASTType::ReadFromMemory (ast_context, opaque_clang_qual_type, exe_ctx, addr, address_type, data))
599                 {
600                     Scalar scalar;
601                     if (ClangASTType::GetValueAsScalar (ast_context, opaque_clang_qual_type, data, 0, data.GetByteSize(), scalar))
602                     {
603                         m_value = scalar;
604                         m_value_type = eValueTypeScalar;
605                     }
606                     else
607                     {
608                         if ((uintptr_t)addr != (uintptr_t)m_data_buffer.GetBytes())
609                         {
610                             m_value.Clear();
611                             m_value_type = eValueTypeScalar;
612                         }
613                     }
614                 }
615                 else
616                 {
617                     if ((uintptr_t)addr != (uintptr_t)m_data_buffer.GetBytes())
618                     {
619                         m_value.Clear();
620                         m_value_type = eValueTypeScalar;
621                     }
622                 }
623             }
624             break;
625         }
626     }
627     return m_value;
628 }
629 
630 Variable *
631 Value::GetVariable()
632 {
633     if (m_context_type == eContextTypeVariable)
634         return static_cast<Variable *> (m_context);
635     return NULL;
636 }
637 
638 const char *
639 Value::GetValueTypeAsCString (ValueType value_type)
640 {
641     switch (value_type)
642     {
643     case eValueTypeScalar:      return "scalar";
644     case eValueTypeFileAddress: return "file address";
645     case eValueTypeLoadAddress: return "load address";
646     case eValueTypeHostAddress: return "host address";
647     };
648     return "???";
649 }
650 
651 const char *
652 Value::GetContextTypeAsCString (ContextType context_type)
653 {
654     switch (context_type)
655     {
656     case eContextTypeInvalid:       return "invalid";
657     case eContextTypeClangType:     return "clang::Type *";
658     case eContextTypeRegisterInfo:  return "RegisterInfo *";
659     case eContextTypeLLDBType:      return "Type *";
660     case eContextTypeVariable:      return "Variable *";
661     };
662     return "???";
663 }
664 
665 ValueList::ValueList (const ValueList &rhs)
666 {
667     m_values = rhs.m_values;
668 }
669 
670 const ValueList &
671 ValueList::operator= (const ValueList &rhs)
672 {
673     m_values = rhs.m_values;
674     return *this;
675 }
676 
677 void
678 ValueList::PushValue (const Value &value)
679 {
680     m_values.push_back (value);
681 }
682 
683 size_t
684 ValueList::GetSize()
685 {
686     return m_values.size();
687 }
688 
689 Value *
690 ValueList::GetValueAtIndex (size_t idx)
691 {
692     if (idx < GetSize())
693     {
694         return &(m_values[idx]);
695     }
696     else
697         return NULL;
698 }
699 
700 void
701 ValueList::Clear ()
702 {
703     m_values.clear();
704 }
705