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