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
31using namespace lldb;
32using namespace lldb_private;
33
34Value::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
45Value::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
57Value::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
70Value::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
88Value &
89Value::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
110void
111Value::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
120Value::ValueType
121Value::GetValueType() const
122{
123    return m_value_type;
124}
125
126AddressType
127Value::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
141RegisterInfo *
142Value::GetRegisterInfo() const
143{
144    if (m_context_type == eContextTypeRegisterInfo)
145        return static_cast<RegisterInfo *> (m_context);
146    return NULL;
147}
148
149Type *
150Value::GetType()
151{
152    if (m_context_type == eContextTypeLLDBType)
153        return static_cast<Type *> (m_context);
154    return NULL;
155}
156
157void
158Value::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
165bool
166Value::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
182uint64_t
183Value::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
220const ClangASTType &
221Value::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
258void
259Value::SetClangType (const ClangASTType &clang_type)
260{
261    m_clang_type = clang_type;
262}
263
264lldb::Format
265Value::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
290bool
291Value::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
318Error
319Value::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
622Scalar &
623Value::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
673Variable *
674Value::GetVariable()
675{
676    if (m_context_type == eContextTypeVariable)
677        return static_cast<Variable *> (m_context);
678    return NULL;
679}
680
681void
682Value::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
694const char *
695Value::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
708const char *
709Value::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
721ValueList::ValueList (const ValueList &rhs)
722{
723    m_values = rhs.m_values;
724}
725
726const ValueList &
727ValueList::operator= (const ValueList &rhs)
728{
729    m_values = rhs.m_values;
730    return *this;
731}
732
733void
734ValueList::PushValue (const Value &value)
735{
736    m_values.push_back (value);
737}
738
739size_t
740ValueList::GetSize()
741{
742    return m_values.size();
743}
744
745Value *
746ValueList::GetValueAtIndex (size_t idx)
747{
748    if (idx < GetSize())
749    {
750        return &(m_values[idx]);
751    }
752    else
753        return NULL;
754}
755
756void
757ValueList::Clear ()
758{
759    m_values.clear();
760}
761
762