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