Value.cpp revision 263363
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        {
343            data.SetByteOrder (lldb::endian::InlHostByteOrder());
344            if (ast_type.IsValid())
345                data.SetAddressByteSize (ast_type.GetPointerByteSize());
346            else
347                data.SetAddressByteSize(sizeof(void *));
348
349            uint32_t limit_byte_size = UINT32_MAX;
350
351            if (ast_type.IsValid() && ast_type.IsScalarType())
352            {
353                uint64_t type_encoding_count = 0;
354                lldb::Encoding type_encoding = ast_type.GetEncoding(type_encoding_count);
355
356                if (type_encoding == eEncodingUint || type_encoding == eEncodingSint)
357                    limit_byte_size = ast_type.GetByteSize();
358            }
359
360            if (m_value.GetData (data, limit_byte_size))
361                return error;   // Success;
362
363            error.SetErrorStringWithFormat("extracting data from value failed");
364            break;
365        }
366    case eValueTypeLoadAddress:
367        if (exe_ctx == NULL)
368        {
369            error.SetErrorString ("can't read load address (no execution context)");
370        }
371        else
372        {
373            Process *process = exe_ctx->GetProcessPtr();
374            if (process == NULL || !process->IsAlive())
375            {
376                Target *target = exe_ctx->GetTargetPtr();
377                if (target)
378                {
379                    // Allow expressions to run and evaluate things when the target
380                    // has memory sections loaded. This allows you to use "target modules load"
381                    // to load your executable and any shared libraries, then execute
382                    // commands where you can look at types in data sections.
383                    const SectionLoadList &target_sections = target->GetSectionLoadList();
384                    if (!target_sections.IsEmpty())
385                    {
386                        address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
387                        if (target_sections.ResolveLoadAddress(address, file_so_addr))
388                        {
389                            address_type = eAddressTypeLoad;
390                            data.SetByteOrder(target->GetArchitecture().GetByteOrder());
391                            data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
392                        }
393                        else
394                            address = LLDB_INVALID_ADDRESS;
395                    }
396//                    else
397//                    {
398//                        ModuleSP exe_module_sp (target->GetExecutableModule());
399//                        if (exe_module_sp)
400//                        {
401//                            address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
402//                            if (address != LLDB_INVALID_ADDRESS)
403//                            {
404//                                if (exe_module_sp->ResolveFileAddress(address, file_so_addr))
405//                                {
406//                                    data.SetByteOrder(target->GetArchitecture().GetByteOrder());
407//                                    data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
408//                                    address_type = eAddressTypeFile;
409//                                }
410//                                else
411//                                {
412//                                    address = LLDB_INVALID_ADDRESS;
413//                                }
414//                            }
415//                        }
416//                    }
417                }
418                else
419                {
420                    error.SetErrorString ("can't read load address (invalid process)");
421                }
422            }
423            else
424            {
425                address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
426                address_type = eAddressTypeLoad;
427                data.SetByteOrder(process->GetTarget().GetArchitecture().GetByteOrder());
428                data.SetAddressByteSize(process->GetTarget().GetArchitecture().GetAddressByteSize());
429            }
430        }
431        break;
432
433    case eValueTypeFileAddress:
434        if (exe_ctx == NULL)
435        {
436            error.SetErrorString ("can't read file address (no execution context)");
437        }
438        else if (exe_ctx->GetTargetPtr() == NULL)
439        {
440            error.SetErrorString ("can't read file address (invalid target)");
441        }
442        else
443        {
444            address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
445            if (address == LLDB_INVALID_ADDRESS)
446            {
447                error.SetErrorString ("invalid file address");
448            }
449            else
450            {
451                if (module == NULL)
452                {
453                    // The only thing we can currently lock down to a module so that
454                    // we can resolve a file address, is a variable.
455                    Variable *variable = GetVariable();
456                    if (variable)
457                    {
458                        SymbolContext var_sc;
459                        variable->CalculateSymbolContext(&var_sc);
460                        module = var_sc.module_sp.get();
461                    }
462                }
463
464                if (module)
465                {
466                    bool resolved = false;
467                    ObjectFile *objfile = module->GetObjectFile();
468                    if (objfile)
469                    {
470                        Address so_addr(address, objfile->GetSectionList());
471                        addr_t load_address = so_addr.GetLoadAddress (exe_ctx->GetTargetPtr());
472                        bool process_launched_and_stopped = exe_ctx->GetProcessPtr()
473                            ? StateIsStoppedState(exe_ctx->GetProcessPtr()->GetState(), true /* must_exist */)
474                            : false;
475                        // Don't use the load address if the process has exited.
476                        if (load_address != LLDB_INVALID_ADDRESS && process_launched_and_stopped)
477                        {
478                            resolved = true;
479                            address = load_address;
480                            address_type = eAddressTypeLoad;
481                            data.SetByteOrder(exe_ctx->GetTargetRef().GetArchitecture().GetByteOrder());
482                            data.SetAddressByteSize(exe_ctx->GetTargetRef().GetArchitecture().GetAddressByteSize());
483                        }
484                        else
485                        {
486                            if (so_addr.IsSectionOffset())
487                            {
488                                resolved = true;
489                                file_so_addr = so_addr;
490                                data.SetByteOrder(objfile->GetByteOrder());
491                                data.SetAddressByteSize(objfile->GetAddressByteSize());
492                            }
493                        }
494                    }
495                    if (!resolved)
496                    {
497                        Variable *variable = GetVariable();
498
499                        if (module)
500                        {
501                            if (variable)
502                                error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%" PRIx64 " for variable '%s' in %s",
503                                                                address,
504                                                                variable->GetName().AsCString(""),
505                                                                module->GetFileSpec().GetPath().c_str());
506                            else
507                                error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%" PRIx64 " in %s",
508                                                                address,
509                                                                module->GetFileSpec().GetPath().c_str());
510                        }
511                        else
512                        {
513                            if (variable)
514                                error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%" PRIx64 " for variable '%s'",
515                                                                address,
516                                                                variable->GetName().AsCString(""));
517                            else
518                                error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%" PRIx64, address);
519                        }
520                    }
521                }
522                else
523                {
524                    // Can't convert a file address to anything valid without more
525                    // context (which Module it came from)
526                    error.SetErrorString ("can't read memory from file address without more context");
527                }
528            }
529        }
530        break;
531
532    case eValueTypeHostAddress:
533        address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
534        address_type = eAddressTypeHost;
535        if (exe_ctx)
536        {
537            Target *target = exe_ctx->GetTargetPtr();
538            if (target)
539            {
540                data.SetByteOrder(target->GetArchitecture().GetByteOrder());
541                data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
542                break;
543            }
544        }
545        // fallback to host settings
546        data.SetByteOrder(lldb::endian::InlHostByteOrder());
547        data.SetAddressByteSize(sizeof(void *));
548        break;
549    }
550
551    // Bail if we encountered any errors
552    if (error.Fail())
553        return error;
554
555    if (address == LLDB_INVALID_ADDRESS)
556    {
557        error.SetErrorStringWithFormat ("invalid %s address", address_type == eAddressTypeHost ? "host" : "load");
558        return error;
559    }
560
561    // If we got here, we need to read the value from memory
562    size_t byte_size = GetValueByteSize (&error);
563
564    // Bail if we encountered any errors getting the byte size
565    if (error.Fail())
566        return error;
567
568    // Make sure we have enough room within "data", and if we don't make
569    // something large enough that does
570    if (!data.ValidOffsetForDataOfSize (data_offset, byte_size))
571    {
572        DataBufferSP data_sp(new DataBufferHeap (data_offset + byte_size, '\0'));
573        data.SetData(data_sp);
574    }
575
576    uint8_t* dst = const_cast<uint8_t*>(data.PeekData (data_offset, byte_size));
577    if (dst != NULL)
578    {
579        if (address_type == eAddressTypeHost)
580        {
581            // The address is an address in this process, so just copy it
582            memcpy (dst, (uint8_t*)NULL + address, byte_size);
583        }
584        else if ((address_type == eAddressTypeLoad) || (address_type == eAddressTypeFile))
585        {
586            if (file_so_addr.IsValid())
587            {
588                // We have a file address that we were able to translate into a
589                // section offset address so we might be able to read this from
590                // the object files if we don't have a live process. Lets always
591                // try and read from the process if we have one though since we
592                // want to read the actual value by setting "prefer_file_cache"
593                // to false.
594                const bool prefer_file_cache = false;
595                if (exe_ctx->GetTargetRef().ReadMemory(file_so_addr, prefer_file_cache, dst, byte_size, error) != byte_size)
596                {
597                    error.SetErrorStringWithFormat("read memory from 0x%" PRIx64 " failed", (uint64_t)address);
598                }
599            }
600            else
601            {
602                // The execution context might have a NULL process, but it
603                // might have a valid process in the exe_ctx->target, so use
604                // the ExecutionContext::GetProcess accessor to ensure we
605                // get the process if there is one.
606                Process *process = exe_ctx->GetProcessPtr();
607
608                if (process)
609                {
610                    const size_t bytes_read = process->ReadMemory(address, dst, byte_size, error);
611                    if (bytes_read != byte_size)
612                        error.SetErrorStringWithFormat("read memory from 0x%" PRIx64 " failed (%u of %u bytes read)",
613                                                       (uint64_t)address,
614                                                       (uint32_t)bytes_read,
615                                                       (uint32_t)byte_size);
616                }
617                else
618                {
619                    error.SetErrorStringWithFormat("read memory from 0x%" PRIx64 " failed (invalid process)", (uint64_t)address);
620                }
621            }
622        }
623        else
624        {
625            error.SetErrorStringWithFormat ("unsupported AddressType value (%i)", address_type);
626        }
627    }
628    else
629    {
630        error.SetErrorStringWithFormat ("out of memory");
631    }
632
633    return error;
634}
635
636Scalar &
637Value::ResolveValue(ExecutionContext *exe_ctx)
638{
639    const ClangASTType &clang_type = GetClangType();
640    if (clang_type.IsValid())
641    {
642        switch (m_value_type)
643        {
644        case eValueTypeScalar:               // raw scalar value
645            break;
646
647        default:
648        case eValueTypeFileAddress:
649        case eValueTypeLoadAddress:          // load address value
650        case eValueTypeHostAddress:          // host address value (for memory in the process that is using liblldb)
651            {
652                DataExtractor data;
653                lldb::addr_t addr = m_value.ULongLong(LLDB_INVALID_ADDRESS);
654                Error error (GetValueAsData (exe_ctx, data, 0, NULL));
655                if (error.Success())
656                {
657                    Scalar scalar;
658                    if (clang_type.GetValueAsScalar (data, 0, data.GetByteSize(), scalar))
659                    {
660                        m_value = scalar;
661                        m_value_type = eValueTypeScalar;
662                    }
663                    else
664                    {
665                        if ((uintptr_t)addr != (uintptr_t)m_data_buffer.GetBytes())
666                        {
667                            m_value.Clear();
668                            m_value_type = eValueTypeScalar;
669                        }
670                    }
671                }
672                else
673                {
674                    if ((uintptr_t)addr != (uintptr_t)m_data_buffer.GetBytes())
675                    {
676                        m_value.Clear();
677                        m_value_type = eValueTypeScalar;
678                    }
679                }
680            }
681            break;
682        }
683    }
684    return m_value;
685}
686
687Variable *
688Value::GetVariable()
689{
690    if (m_context_type == eContextTypeVariable)
691        return static_cast<Variable *> (m_context);
692    return NULL;
693}
694
695void
696Value::Clear()
697{
698    m_value.Clear();
699    m_vector.Clear();
700    m_clang_type.Clear();
701    m_value_type = eValueTypeScalar;
702    m_context = NULL;
703    m_context_type = eContextTypeInvalid;
704    m_data_buffer.Clear();
705}
706
707
708const char *
709Value::GetValueTypeAsCString (ValueType value_type)
710{
711    switch (value_type)
712    {
713    case eValueTypeScalar:      return "scalar";
714    case eValueTypeVector:      return "vector";
715    case eValueTypeFileAddress: return "file address";
716    case eValueTypeLoadAddress: return "load address";
717    case eValueTypeHostAddress: return "host address";
718    };
719    return "???";
720}
721
722const char *
723Value::GetContextTypeAsCString (ContextType context_type)
724{
725    switch (context_type)
726    {
727    case eContextTypeInvalid:       return "invalid";
728    case eContextTypeRegisterInfo:  return "RegisterInfo *";
729    case eContextTypeLLDBType:      return "Type *";
730    case eContextTypeVariable:      return "Variable *";
731    };
732    return "???";
733}
734
735ValueList::ValueList (const ValueList &rhs)
736{
737    m_values = rhs.m_values;
738}
739
740const ValueList &
741ValueList::operator= (const ValueList &rhs)
742{
743    m_values = rhs.m_values;
744    return *this;
745}
746
747void
748ValueList::PushValue (const Value &value)
749{
750    m_values.push_back (value);
751}
752
753size_t
754ValueList::GetSize()
755{
756    return m_values.size();
757}
758
759Value *
760ValueList::GetValueAtIndex (size_t idx)
761{
762    if (idx < GetSize())
763    {
764        return &(m_values[idx]);
765    }
766    else
767        return NULL;
768}
769
770void
771ValueList::Clear ()
772{
773    m_values.clear();
774}
775
776