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