Home | History | Annotate | Download | only in Utility
      1 //===-- RegisterContextThreadMemory.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/lldb-private.h"
     11 #include "lldb/Core/Error.h"
     12 #include "lldb/Target/OperatingSystem.h"
     13 #include "lldb/Target/Process.h"
     14 #include "lldb/Target/Thread.h"
     15 
     16 #include "RegisterContextThreadMemory.h"
     17 
     18 using namespace lldb;
     19 using namespace lldb_private;
     20 
     21 RegisterContextThreadMemory::RegisterContextThreadMemory (Thread &thread,
     22                                                           lldb::addr_t register_data_addr) :
     23     RegisterContext (thread, 0),
     24     m_thread_wp (thread.shared_from_this()),
     25     m_reg_ctx_sp (),
     26     m_register_data_addr (register_data_addr),
     27     m_stop_id(0)
     28 {
     29 }
     30 
     31 RegisterContextThreadMemory::~RegisterContextThreadMemory()
     32 {
     33 }
     34 
     35 void
     36 RegisterContextThreadMemory::UpdateRegisterContext ()
     37 {
     38     ThreadSP thread_sp (m_thread_wp.lock());
     39     if (thread_sp)
     40     {
     41         ProcessSP process_sp (thread_sp->GetProcess());
     42 
     43         if (process_sp)
     44         {
     45             const uint32_t stop_id = process_sp->GetModID().GetStopID();
     46             if (m_stop_id != stop_id)
     47             {
     48                 m_stop_id = stop_id;
     49                 m_reg_ctx_sp.reset();
     50             }
     51             if (!m_reg_ctx_sp)
     52             {
     53                 ThreadSP backing_thread_sp (thread_sp->GetBackingThread());
     54                 if (backing_thread_sp)
     55                 {
     56                     m_reg_ctx_sp = backing_thread_sp->GetRegisterContext();
     57                 }
     58                 else
     59                 {
     60                     OperatingSystem *os = process_sp->GetOperatingSystem ();
     61                     if (os->IsOperatingSystemPluginThread (thread_sp))
     62                         m_reg_ctx_sp = os->CreateRegisterContextForThread (thread_sp.get(), LLDB_INVALID_ADDRESS);
     63                 }
     64             }
     65         }
     66         else
     67         {
     68             m_reg_ctx_sp.reset();
     69         }
     70     }
     71     else
     72     {
     73         m_reg_ctx_sp.reset();
     74     }
     75 }
     76 
     77 //------------------------------------------------------------------
     78 // Subclasses must override these functions
     79 //------------------------------------------------------------------
     80 void
     81 RegisterContextThreadMemory::InvalidateAllRegisters ()
     82 {
     83     UpdateRegisterContext ();
     84     if (m_reg_ctx_sp)
     85         m_reg_ctx_sp->InvalidateAllRegisters();
     86 }
     87 
     88 size_t
     89 RegisterContextThreadMemory::GetRegisterCount ()
     90 {
     91     UpdateRegisterContext ();
     92     if (m_reg_ctx_sp)
     93         return m_reg_ctx_sp->GetRegisterCount();
     94     return 0;
     95 }
     96 
     97 const RegisterInfo *
     98 RegisterContextThreadMemory::GetRegisterInfoAtIndex (size_t reg)
     99 {
    100     UpdateRegisterContext ();
    101     if (m_reg_ctx_sp)
    102         return m_reg_ctx_sp->GetRegisterInfoAtIndex(reg);
    103     return NULL;
    104 }
    105 
    106 size_t
    107 RegisterContextThreadMemory::GetRegisterSetCount ()
    108 {
    109     UpdateRegisterContext ();
    110     if (m_reg_ctx_sp)
    111         return m_reg_ctx_sp->GetRegisterSetCount();
    112     return 0;
    113 }
    114 
    115 const RegisterSet *
    116 RegisterContextThreadMemory::GetRegisterSet (size_t reg_set)
    117 {
    118     UpdateRegisterContext ();
    119     if (m_reg_ctx_sp)
    120         return m_reg_ctx_sp->GetRegisterSet(reg_set);
    121     return NULL;
    122 }
    123 
    124 bool
    125 RegisterContextThreadMemory::ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value)
    126 {
    127     UpdateRegisterContext ();
    128     if (m_reg_ctx_sp)
    129         return m_reg_ctx_sp->ReadRegister(reg_info, reg_value);
    130     return false;
    131 }
    132 
    133 bool
    134 RegisterContextThreadMemory::WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value)
    135 {
    136     UpdateRegisterContext ();
    137     if (m_reg_ctx_sp)
    138         return m_reg_ctx_sp->WriteRegister (reg_info, reg_value);
    139     return false;
    140 }
    141 
    142 bool
    143 RegisterContextThreadMemory::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
    144 {
    145     UpdateRegisterContext ();
    146     if (m_reg_ctx_sp)
    147         return m_reg_ctx_sp->ReadAllRegisterValues(data_sp);
    148     return false;
    149 }
    150 
    151 bool
    152 RegisterContextThreadMemory::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
    153 {
    154     UpdateRegisterContext ();
    155     if (m_reg_ctx_sp)
    156         return m_reg_ctx_sp->WriteAllRegisterValues (data_sp);
    157     return false;
    158 }
    159 
    160 bool
    161 RegisterContextThreadMemory::CopyFromRegisterContext (lldb::RegisterContextSP reg_ctx_sp)
    162 {
    163     UpdateRegisterContext ();
    164     if (m_reg_ctx_sp)
    165         return m_reg_ctx_sp->CopyFromRegisterContext(reg_ctx_sp);
    166     return false;
    167 }
    168 
    169 uint32_t
    170 RegisterContextThreadMemory::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num)
    171 {
    172     UpdateRegisterContext ();
    173     if (m_reg_ctx_sp)
    174         return m_reg_ctx_sp->ConvertRegisterKindToRegisterNumber(kind, num);
    175     return false;
    176 }
    177 
    178 uint32_t
    179 RegisterContextThreadMemory::NumSupportedHardwareBreakpoints ()
    180 {
    181     UpdateRegisterContext ();
    182     if (m_reg_ctx_sp)
    183         return m_reg_ctx_sp->NumSupportedHardwareBreakpoints();
    184     return false;
    185 }
    186 
    187 uint32_t
    188 RegisterContextThreadMemory::SetHardwareBreakpoint (lldb::addr_t addr, size_t size)
    189 {
    190     UpdateRegisterContext ();
    191     if (m_reg_ctx_sp)
    192         return m_reg_ctx_sp->SetHardwareBreakpoint(addr, size);
    193     return 0;
    194 }
    195 
    196 bool
    197 RegisterContextThreadMemory::ClearHardwareBreakpoint (uint32_t hw_idx)
    198 {
    199     UpdateRegisterContext ();
    200     if (m_reg_ctx_sp)
    201         return m_reg_ctx_sp->ClearHardwareBreakpoint (hw_idx);
    202     return false;
    203 }
    204 
    205 uint32_t
    206 RegisterContextThreadMemory::NumSupportedHardwareWatchpoints ()
    207 {
    208     UpdateRegisterContext ();
    209     if (m_reg_ctx_sp)
    210         return m_reg_ctx_sp->NumSupportedHardwareWatchpoints();
    211     return 0;
    212 }
    213 
    214 uint32_t
    215 RegisterContextThreadMemory::SetHardwareWatchpoint (lldb::addr_t addr, size_t size, bool read, bool write)
    216 {
    217     UpdateRegisterContext ();
    218     if (m_reg_ctx_sp)
    219         return m_reg_ctx_sp->SetHardwareWatchpoint(addr, size, read, write);
    220     return 0;
    221 }
    222 
    223 bool
    224 RegisterContextThreadMemory::ClearHardwareWatchpoint (uint32_t hw_index)
    225 {
    226     UpdateRegisterContext ();
    227     if (m_reg_ctx_sp)
    228         return m_reg_ctx_sp->ClearHardwareWatchpoint(hw_index);
    229     return false;
    230 }
    231 
    232 bool
    233 RegisterContextThreadMemory::HardwareSingleStep (bool enable)
    234 {
    235     UpdateRegisterContext ();
    236     if (m_reg_ctx_sp)
    237         return m_reg_ctx_sp->HardwareSingleStep(enable);
    238     return false;
    239 }
    240 
    241 Error
    242 RegisterContextThreadMemory::ReadRegisterValueFromMemory (const lldb_private::RegisterInfo *reg_info, lldb::addr_t src_addr, uint32_t src_len, RegisterValue &reg_value)
    243 {
    244     UpdateRegisterContext ();
    245     if (m_reg_ctx_sp)
    246         return m_reg_ctx_sp->ReadRegisterValueFromMemory (reg_info, src_addr, src_len, reg_value);
    247     Error error;
    248     error.SetErrorString("invalid register context");
    249     return error;
    250 }
    251 
    252 Error
    253 RegisterContextThreadMemory::WriteRegisterValueToMemory (const lldb_private::RegisterInfo *reg_info, lldb::addr_t dst_addr, uint32_t dst_len, const RegisterValue &reg_value)
    254 {
    255     UpdateRegisterContext ();
    256     if (m_reg_ctx_sp)
    257         return m_reg_ctx_sp->WriteRegisterValueToMemory (reg_info, dst_addr, dst_len, reg_value);
    258     Error error;
    259     error.SetErrorString("invalid register context");
    260     return error;
    261 }
    262