Home | History | Annotate | Download | only in Core
      1 //===-- ValueObjectRegister.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 
     11 #include "lldb/Core/ValueObjectRegister.h"
     12 
     13 // C Includes
     14 // C++ Includes
     15 // Other libraries and framework includes
     16 // Project includes
     17 #include "lldb/Core/Module.h"
     18 #include "lldb/Symbol/ClangASTType.h"
     19 #include "lldb/Symbol/ClangASTContext.h"
     20 #include "lldb/Symbol/TypeList.h"
     21 #include "lldb/Target/ExecutionContext.h"
     22 #include "lldb/Target/Process.h"
     23 #include "lldb/Target/RegisterContext.h"
     24 #include "lldb/Target/Target.h"
     25 #include "lldb/Target/Thread.h"
     26 
     27 using namespace lldb;
     28 using namespace lldb_private;
     29 
     30 #pragma mark ValueObjectRegisterContext
     31 
     32 ValueObjectRegisterContext::ValueObjectRegisterContext (ValueObject &parent, RegisterContextSP &reg_ctx) :
     33     ValueObject (parent),
     34     m_reg_ctx_sp (reg_ctx)
     35 {
     36     assert (reg_ctx);
     37     m_name.SetCString("Registers");
     38     SetValueIsValid (true);
     39 }
     40 
     41 ValueObjectRegisterContext::~ValueObjectRegisterContext()
     42 {
     43 }
     44 
     45 ClangASTType
     46 ValueObjectRegisterContext::GetClangTypeImpl ()
     47 {
     48     return ClangASTType();
     49 }
     50 
     51 ConstString
     52 ValueObjectRegisterContext::GetTypeName()
     53 {
     54     return ConstString();
     55 }
     56 
     57 ConstString
     58 ValueObjectRegisterContext::GetQualifiedTypeName()
     59 {
     60     return ConstString();
     61 }
     62 
     63 size_t
     64 ValueObjectRegisterContext::CalculateNumChildren()
     65 {
     66     return m_reg_ctx_sp->GetRegisterSetCount();
     67 }
     68 
     69 uint64_t
     70 ValueObjectRegisterContext::GetByteSize()
     71 {
     72     return 0;
     73 }
     74 
     75 bool
     76 ValueObjectRegisterContext::UpdateValue ()
     77 {
     78     m_error.Clear();
     79     ExecutionContext exe_ctx(GetExecutionContextRef());
     80     StackFrame *frame = exe_ctx.GetFramePtr();
     81     if (frame)
     82         m_reg_ctx_sp = frame->GetRegisterContext();
     83     else
     84         m_reg_ctx_sp.reset();
     85 
     86     if (m_reg_ctx_sp.get() == NULL)
     87     {
     88         SetValueIsValid (false);
     89         m_error.SetErrorToGenericError();
     90     }
     91     else
     92         SetValueIsValid (true);
     93 
     94     return m_error.Success();
     95 }
     96 
     97 ValueObject *
     98 ValueObjectRegisterContext::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index)
     99 {
    100     ValueObject *new_valobj = NULL;
    101 
    102     const size_t num_children = GetNumChildren();
    103     if (idx < num_children)
    104     {
    105         ExecutionContext exe_ctx(GetExecutionContextRef());
    106         new_valobj = new ValueObjectRegisterSet(exe_ctx.GetBestExecutionContextScope(), m_reg_ctx_sp, idx);
    107     }
    108 
    109     return new_valobj;
    110 }
    111 
    112 
    113 #pragma mark -
    114 #pragma mark ValueObjectRegisterSet
    115 
    116 ValueObjectSP
    117 ValueObjectRegisterSet::Create (ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_ctx_sp, uint32_t set_idx)
    118 {
    119     return (new ValueObjectRegisterSet (exe_scope, reg_ctx_sp, set_idx))->GetSP();
    120 }
    121 
    122 
    123 ValueObjectRegisterSet::ValueObjectRegisterSet (ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_ctx, uint32_t reg_set_idx) :
    124     ValueObject (exe_scope),
    125     m_reg_ctx_sp (reg_ctx),
    126     m_reg_set (NULL),
    127     m_reg_set_idx (reg_set_idx)
    128 {
    129     assert (reg_ctx);
    130     m_reg_set = reg_ctx->GetRegisterSet(m_reg_set_idx);
    131     if (m_reg_set)
    132     {
    133         m_name.SetCString (m_reg_set->name);
    134     }
    135 }
    136 
    137 ValueObjectRegisterSet::~ValueObjectRegisterSet()
    138 {
    139 }
    140 
    141 ClangASTType
    142 ValueObjectRegisterSet::GetClangTypeImpl ()
    143 {
    144     return ClangASTType();
    145 }
    146 
    147 ConstString
    148 ValueObjectRegisterSet::GetTypeName()
    149 {
    150     return ConstString();
    151 }
    152 
    153 ConstString
    154 ValueObjectRegisterSet::GetQualifiedTypeName()
    155 {
    156     return ConstString();
    157 }
    158 
    159 size_t
    160 ValueObjectRegisterSet::CalculateNumChildren()
    161 {
    162     const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx);
    163     if (reg_set)
    164         return reg_set->num_registers;
    165     return 0;
    166 }
    167 
    168 uint64_t
    169 ValueObjectRegisterSet::GetByteSize()
    170 {
    171     return 0;
    172 }
    173 
    174 bool
    175 ValueObjectRegisterSet::UpdateValue ()
    176 {
    177     m_error.Clear();
    178     SetValueDidChange (false);
    179     ExecutionContext exe_ctx(GetExecutionContextRef());
    180     StackFrame *frame = exe_ctx.GetFramePtr();
    181     if (frame == NULL)
    182         m_reg_ctx_sp.reset();
    183     else
    184     {
    185         m_reg_ctx_sp = frame->GetRegisterContext ();
    186         if (m_reg_ctx_sp)
    187         {
    188             const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet (m_reg_set_idx);
    189             if (reg_set == NULL)
    190                 m_reg_ctx_sp.reset();
    191             else if (m_reg_set != reg_set)
    192             {
    193                 SetValueDidChange (true);
    194                 m_name.SetCString(reg_set->name);
    195             }
    196         }
    197     }
    198     if (m_reg_ctx_sp)
    199     {
    200         SetValueIsValid (true);
    201     }
    202     else
    203     {
    204         SetValueIsValid (false);
    205         m_error.SetErrorToGenericError ();
    206         m_children.Clear();
    207     }
    208     return m_error.Success();
    209 }
    210 
    211 
    212 ValueObject *
    213 ValueObjectRegisterSet::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index)
    214 {
    215     ValueObject *valobj = NULL;
    216     if (m_reg_ctx_sp && m_reg_set)
    217     {
    218         const size_t num_children = GetNumChildren();
    219         if (idx < num_children)
    220             valobj = new ValueObjectRegister(*this, m_reg_ctx_sp, m_reg_set->registers[idx]);
    221     }
    222     return valobj;
    223 }
    224 
    225 lldb::ValueObjectSP
    226 ValueObjectRegisterSet::GetChildMemberWithName (const ConstString &name, bool can_create)
    227 {
    228     ValueObject *valobj = NULL;
    229     if (m_reg_ctx_sp && m_reg_set)
    230     {
    231         const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoByName (name.AsCString());
    232         if (reg_info != NULL)
    233             valobj = new ValueObjectRegister(*this, m_reg_ctx_sp, reg_info->kinds[eRegisterKindLLDB]);
    234     }
    235     if (valobj)
    236         return valobj->GetSP();
    237     else
    238         return ValueObjectSP();
    239 }
    240 
    241 size_t
    242 ValueObjectRegisterSet::GetIndexOfChildWithName (const ConstString &name)
    243 {
    244     if (m_reg_ctx_sp && m_reg_set)
    245     {
    246         const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoByName (name.AsCString());
    247         if (reg_info != NULL)
    248             return reg_info->kinds[eRegisterKindLLDB];
    249     }
    250     return UINT32_MAX;
    251 }
    252 
    253 #pragma mark -
    254 #pragma mark ValueObjectRegister
    255 
    256 void
    257 ValueObjectRegister::ConstructObject (uint32_t reg_num)
    258 {
    259     const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoAtIndex (reg_num);
    260     if (reg_info)
    261     {
    262         m_reg_info = *reg_info;
    263         if (reg_info->name)
    264             m_name.SetCString(reg_info->name);
    265         else if (reg_info->alt_name)
    266             m_name.SetCString(reg_info->alt_name);
    267     }
    268 }
    269 
    270 ValueObjectRegister::ValueObjectRegister (ValueObject &parent, lldb::RegisterContextSP &reg_ctx_sp, uint32_t reg_num) :
    271     ValueObject (parent),
    272     m_reg_ctx_sp (reg_ctx_sp),
    273     m_reg_info (),
    274     m_reg_value (),
    275     m_type_name (),
    276     m_clang_type ()
    277 {
    278     assert (reg_ctx_sp.get());
    279     ConstructObject(reg_num);
    280 }
    281 
    282 ValueObjectSP
    283 ValueObjectRegister::Create (ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_ctx_sp, uint32_t reg_num)
    284 {
    285     return (new ValueObjectRegister (exe_scope, reg_ctx_sp, reg_num))->GetSP();
    286 }
    287 
    288 ValueObjectRegister::ValueObjectRegister (ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_ctx, uint32_t reg_num) :
    289     ValueObject (exe_scope),
    290     m_reg_ctx_sp (reg_ctx),
    291     m_reg_info (),
    292     m_reg_value (),
    293     m_type_name (),
    294     m_clang_type ()
    295 {
    296     assert (reg_ctx);
    297     ConstructObject(reg_num);
    298 }
    299 
    300 ValueObjectRegister::~ValueObjectRegister()
    301 {
    302 }
    303 
    304 ClangASTType
    305 ValueObjectRegister::GetClangTypeImpl ()
    306 {
    307     if (!m_clang_type.IsValid())
    308     {
    309         ExecutionContext exe_ctx (GetExecutionContextRef());
    310         Target *target = exe_ctx.GetTargetPtr();
    311         if (target)
    312         {
    313             Module *exe_module = target->GetExecutableModulePointer();
    314             if (exe_module)
    315             {
    316                 m_clang_type = exe_module->GetClangASTContext().GetBuiltinTypeForEncodingAndBitSize (m_reg_info.encoding,
    317                                                                                                      m_reg_info.byte_size * 8);
    318             }
    319         }
    320     }
    321     return m_clang_type;
    322 }
    323 
    324 ConstString
    325 ValueObjectRegister::GetTypeName()
    326 {
    327     if (m_type_name.IsEmpty())
    328         m_type_name = GetClangType().GetConstTypeName ();
    329     return m_type_name;
    330 }
    331 
    332 size_t
    333 ValueObjectRegister::CalculateNumChildren()
    334 {
    335     return GetClangType().GetNumChildren(true);
    336 }
    337 
    338 uint64_t
    339 ValueObjectRegister::GetByteSize()
    340 {
    341     return m_reg_info.byte_size;
    342 }
    343 
    344 bool
    345 ValueObjectRegister::UpdateValue ()
    346 {
    347     m_error.Clear();
    348     ExecutionContext exe_ctx(GetExecutionContextRef());
    349     StackFrame *frame = exe_ctx.GetFramePtr();
    350     if (frame == NULL)
    351     {
    352         m_reg_ctx_sp.reset();
    353         m_reg_value.Clear();
    354     }
    355 
    356 
    357     if (m_reg_ctx_sp)
    358     {
    359         if (m_reg_ctx_sp->ReadRegister (&m_reg_info, m_reg_value))
    360         {
    361             if (m_reg_value.GetData (m_data))
    362             {
    363                 Process *process = exe_ctx.GetProcessPtr();
    364                 if (process)
    365                     m_data.SetAddressByteSize(process->GetAddressByteSize());
    366                 m_value.SetContext(Value::eContextTypeRegisterInfo, (void *)&m_reg_info);
    367                 m_value.SetValueType(Value::eValueTypeHostAddress);
    368                 m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
    369                 SetValueIsValid (true);
    370                 return true;
    371             }
    372         }
    373     }
    374 
    375     SetValueIsValid (false);
    376     m_error.SetErrorToGenericError ();
    377     return false;
    378 }
    379 
    380 bool
    381 ValueObjectRegister::SetValueFromCString (const char *value_str, Error& error)
    382 {
    383     // The new value will be in the m_data.  Copy that into our register value.
    384     error = m_reg_value.SetValueFromCString (&m_reg_info, value_str);
    385     if (error.Success())
    386     {
    387         if (m_reg_ctx_sp->WriteRegister (&m_reg_info, m_reg_value))
    388         {
    389             SetNeedsUpdate();
    390             return true;
    391         }
    392         else
    393             return false;
    394     }
    395     else
    396         return false;
    397 }
    398 
    399 bool
    400 ValueObjectRegister::SetData (DataExtractor &data, Error &error)
    401 {
    402     error = m_reg_value.SetValueFromData(&m_reg_info, data, 0, false);
    403     if (error.Success())
    404     {
    405         if (m_reg_ctx_sp->WriteRegister (&m_reg_info, m_reg_value))
    406         {
    407             SetNeedsUpdate();
    408             return true;
    409         }
    410         else
    411             return false;
    412     }
    413     else
    414         return false;
    415 }
    416 
    417 bool
    418 ValueObjectRegister::ResolveValue (Scalar &scalar)
    419 {
    420     if (UpdateValueIfNeeded(false)) // make sure that you are up to date before returning anything
    421         return m_reg_value.GetScalarValue(scalar);
    422     return false;
    423 }
    424 
    425 void
    426 ValueObjectRegister::GetExpressionPath (Stream &s, bool qualify_cxx_base_classes, GetExpressionPathFormat epformat)
    427 {
    428     s.Printf("$%s", m_reg_info.name);
    429 }
    430 
    431 
    432