Home | History | Annotate | Download | only in Utility
      1 //===-- RegisterContextMemory.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 "RegisterContextMemory.h"
     11 
     12 // C Includes
     13 // C++ Includes
     14 // Other libraries and framework includes
     15 // Project includes
     16 #include "DynamicRegisterInfo.h"
     17 #include "lldb/Core/DataBufferHeap.h"
     18 #include "lldb/Core/Error.h"
     19 #include "lldb/Core/RegisterValue.h"
     20 #include "lldb/Target/Process.h"
     21 #include "lldb/Target/Thread.h"
     22 
     23 using namespace lldb;
     24 using namespace lldb_private;
     25 
     26 //----------------------------------------------------------------------
     27 // RegisterContextMemory constructor
     28 //----------------------------------------------------------------------
     29 RegisterContextMemory::RegisterContextMemory
     30 (
     31     Thread &thread,
     32     uint32_t concrete_frame_idx,
     33     DynamicRegisterInfo &reg_infos,
     34     addr_t reg_data_addr
     35 ) :
     36     RegisterContext (thread, concrete_frame_idx),
     37     m_reg_infos (reg_infos),
     38     m_reg_valid (),
     39     m_reg_data (),
     40     m_reg_data_addr (reg_data_addr)
     41 {
     42     // Resize our vector of bools to contain one bool for every register.
     43     // We will use these boolean values to know when a register value
     44     // is valid in m_reg_data.
     45     const size_t num_regs = reg_infos.GetNumRegisters();
     46     assert (num_regs > 0);
     47     m_reg_valid.resize (num_regs);
     48 
     49     // Make a heap based buffer that is big enough to store all registers
     50     DataBufferSP reg_data_sp(new DataBufferHeap (reg_infos.GetRegisterDataByteSize(), 0));
     51     m_reg_data.SetData (reg_data_sp);
     52 }
     53 
     54 //----------------------------------------------------------------------
     55 // Destructor
     56 //----------------------------------------------------------------------
     57 RegisterContextMemory::~RegisterContextMemory()
     58 {
     59 }
     60 
     61 void
     62 RegisterContextMemory::InvalidateAllRegisters ()
     63 {
     64     if (m_reg_data_addr != LLDB_INVALID_ADDRESS)
     65         SetAllRegisterValid (false);
     66 }
     67 
     68 void
     69 RegisterContextMemory::SetAllRegisterValid (bool b)
     70 {
     71     std::vector<bool>::iterator pos, end = m_reg_valid.end();
     72     for (pos = m_reg_valid.begin(); pos != end; ++pos)
     73         *pos = b;
     74 }
     75 
     76 size_t
     77 RegisterContextMemory::GetRegisterCount ()
     78 {
     79     return m_reg_infos.GetNumRegisters ();
     80 }
     81 
     82 const RegisterInfo *
     83 RegisterContextMemory::GetRegisterInfoAtIndex (size_t reg)
     84 {
     85     return m_reg_infos.GetRegisterInfoAtIndex (reg);
     86 }
     87 
     88 size_t
     89 RegisterContextMemory::GetRegisterSetCount ()
     90 {
     91     return m_reg_infos.GetNumRegisterSets ();
     92 }
     93 
     94 const RegisterSet *
     95 RegisterContextMemory::GetRegisterSet (size_t reg_set)
     96 {
     97     return m_reg_infos.GetRegisterSet (reg_set);
     98 }
     99 
    100 uint32_t
    101 RegisterContextMemory::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num)
    102 {
    103     return m_reg_infos.ConvertRegisterKindToRegisterNumber (kind, num);
    104 }
    105 
    106 bool
    107 RegisterContextMemory::ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value)
    108 {
    109     const uint32_t reg_num = reg_info->kinds[eRegisterKindLLDB];
    110     if (!m_reg_valid[reg_num])
    111     {
    112         if (!ReadAllRegisterValues(m_reg_data.GetSharedDataBuffer ()))
    113             return false;
    114     }
    115     const bool partial_data_ok = false;
    116     return reg_value.SetValueFromData(reg_info, m_reg_data, reg_info->byte_offset, partial_data_ok).Success();
    117 }
    118 
    119 bool
    120 RegisterContextMemory::WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value)
    121 {
    122     if (m_reg_data_addr != LLDB_INVALID_ADDRESS)
    123     {
    124         const uint32_t reg_num = reg_info->kinds[eRegisterKindLLDB];
    125         addr_t reg_addr = m_reg_data_addr + reg_info->byte_offset;
    126         Error error (WriteRegisterValueToMemory(reg_info, reg_addr, reg_info->byte_size, reg_value));
    127         m_reg_valid[reg_num] = false;
    128         return error.Success();
    129     }
    130     return false;
    131 }
    132 
    133 bool
    134 RegisterContextMemory::ReadAllRegisterValues (DataBufferSP &data_sp)
    135 {
    136     if (m_reg_data_addr != LLDB_INVALID_ADDRESS)
    137     {
    138         ProcessSP process_sp (CalculateProcess());
    139         if (process_sp)
    140         {
    141             Error error;
    142             if (process_sp->ReadMemory(m_reg_data_addr, data_sp->GetBytes(), data_sp->GetByteSize(), error) == data_sp->GetByteSize())
    143             {
    144                 SetAllRegisterValid (true);
    145                 return true;
    146             }
    147         }
    148     }
    149     return false;
    150 }
    151 
    152 bool
    153 RegisterContextMemory::WriteAllRegisterValues (const DataBufferSP &data_sp)
    154 {
    155     if (m_reg_data_addr != LLDB_INVALID_ADDRESS)
    156     {
    157         ProcessSP process_sp (CalculateProcess());
    158         if (process_sp)
    159         {
    160             Error error;
    161             SetAllRegisterValid (false);
    162             if (process_sp->WriteMemory(m_reg_data_addr, data_sp->GetBytes(), data_sp->GetByteSize(), error) == data_sp->GetByteSize())
    163                 return true;
    164         }
    165     }
    166     return false;
    167 }
    168 
    169 void
    170 RegisterContextMemory::SetAllRegisterData  (const lldb::DataBufferSP &data_sp)
    171 {
    172     m_reg_data.SetData(data_sp);
    173     SetAllRegisterValid (true);
    174 }
    175