Home | History | Annotate | Download | only in gdb-remote
      1 //===-- GDBRemoteRegisterContext.h ------------------------------*- 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 #ifndef lldb_GDBRemoteRegisterContext_h_
     11 #define lldb_GDBRemoteRegisterContext_h_
     12 
     13 // C Includes
     14 // C++ Includes
     15 #include <vector>
     16 
     17 // Other libraries and framework includes
     18 // Project includes
     19 #include "lldb/lldb-private.h"
     20 #include "lldb/lldb-enumerations.h"
     21 #include "lldb/Core/ConstString.h"
     22 #include "lldb/Core/DataExtractor.h"
     23 #include "lldb/Target/RegisterContext.h"
     24 #include "GDBRemoteCommunicationClient.h"
     25 
     26 class ThreadGDBRemote;
     27 class ProcessGDBRemote;
     28 class StringExtractor;
     29 
     30 class GDBRemoteDynamicRegisterInfo
     31 {
     32 public:
     33     GDBRemoteDynamicRegisterInfo () :
     34         m_regs (),
     35         m_sets (),
     36         m_set_reg_nums (),
     37         m_reg_names (),
     38         m_reg_alt_names (),
     39         m_set_names (),
     40         m_reg_data_byte_size (0)
     41     {
     42     }
     43 
     44     ~GDBRemoteDynamicRegisterInfo ()
     45     {
     46     }
     47 
     48     void
     49     AddRegister (lldb_private::RegisterInfo reg_info,
     50                  lldb_private::ConstString &reg_name,
     51                  lldb_private::ConstString &reg_alt_name,
     52                  lldb_private::ConstString &set_name)
     53     {
     54         const uint32_t reg_num = (uint32_t)m_regs.size();
     55         m_reg_names.push_back (reg_name);
     56         m_reg_alt_names.push_back (reg_alt_name);
     57         reg_info.name = reg_name.AsCString();
     58         assert (reg_info.name);
     59         reg_info.alt_name = reg_alt_name.AsCString(NULL);
     60         uint32_t i;
     61         if (reg_info.value_regs)
     62         {
     63             for (i=0; reg_info.value_regs[i] != LLDB_INVALID_REGNUM; ++i)
     64                 m_value_regs_map[reg_num].push_back(reg_info.value_regs[i]);
     65             m_value_regs_map[reg_num].push_back(LLDB_INVALID_REGNUM);
     66             reg_info.value_regs = m_value_regs_map[reg_num].data();
     67         }
     68         if (reg_info.invalidate_regs)
     69         {
     70             for (i=0; reg_info.invalidate_regs[i] != LLDB_INVALID_REGNUM; ++i)
     71                 m_invalidate_regs_map[reg_num].push_back(reg_info.invalidate_regs[i]);
     72             m_invalidate_regs_map[reg_num].push_back(LLDB_INVALID_REGNUM);
     73             reg_info.invalidate_regs = m_invalidate_regs_map[reg_num].data();
     74         }
     75         m_regs.push_back (reg_info);
     76         uint32_t set = GetRegisterSetIndexByName (set_name);
     77         assert (set < m_sets.size());
     78         assert (set < m_set_reg_nums.size());
     79         assert (set < m_set_names.size());
     80         m_set_reg_nums[set].push_back(reg_num);
     81         size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size;
     82         if (m_reg_data_byte_size < end_reg_offset)
     83             m_reg_data_byte_size = end_reg_offset;
     84     }
     85 
     86     void
     87     Finalize ()
     88     {
     89         for (uint32_t set = 0; set < m_sets.size(); ++set)
     90         {
     91             assert (m_sets.size() == m_set_reg_nums.size());
     92             m_sets[set].num_registers = m_set_reg_nums[set].size();
     93             m_sets[set].registers = &m_set_reg_nums[set][0];
     94         }
     95     }
     96 
     97     size_t
     98     GetNumRegisters() const
     99     {
    100         return m_regs.size();
    101     }
    102 
    103     size_t
    104     GetNumRegisterSets() const
    105     {
    106         return m_sets.size();
    107     }
    108 
    109     size_t
    110     GetRegisterDataByteSize() const
    111     {
    112         return m_reg_data_byte_size;
    113     }
    114 
    115     const lldb_private::RegisterInfo *
    116     GetRegisterInfoAtIndex (uint32_t i) const
    117     {
    118         if (i < m_regs.size())
    119             return &m_regs[i];
    120         return NULL;
    121     }
    122 
    123     const lldb_private::RegisterSet *
    124     GetRegisterSet (uint32_t i) const
    125     {
    126         if (i < m_sets.size())
    127             return &m_sets[i];
    128         return NULL;
    129     }
    130 
    131     uint32_t
    132     GetRegisterSetIndexByName (lldb_private::ConstString &set_name)
    133     {
    134         name_collection::iterator pos, end = m_set_names.end();
    135         for (pos = m_set_names.begin(); pos != end; ++pos)
    136         {
    137             if (*pos == set_name)
    138                 return static_cast<uint32_t>(std::distance (m_set_names.begin(), pos));
    139         }
    140 
    141         m_set_names.push_back(set_name);
    142         m_set_reg_nums.resize(m_set_reg_nums.size()+1);
    143         lldb_private::RegisterSet new_set = { set_name.AsCString(), NULL, 0, NULL };
    144         m_sets.push_back (new_set);
    145         return static_cast<uint32_t>(m_sets.size() - 1);
    146     }
    147 
    148     uint32_t
    149     ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num) const
    150     {
    151         reg_collection::const_iterator pos, end = m_regs.end();
    152         for (pos = m_regs.begin(); pos != end; ++pos)
    153         {
    154             if (pos->kinds[kind] == num)
    155                 return static_cast<uint32_t>(std::distance (m_regs.begin(), pos));
    156         }
    157 
    158         return LLDB_INVALID_REGNUM;
    159     }
    160     void
    161     Clear()
    162     {
    163         m_regs.clear();
    164         m_sets.clear();
    165         m_set_reg_nums.clear();
    166         m_reg_names.clear();
    167         m_reg_alt_names.clear();
    168         m_set_names.clear();
    169     }
    170 
    171     void
    172     HardcodeARMRegisters(bool from_scratch);
    173 
    174 protected:
    175     //------------------------------------------------------------------
    176     // Classes that inherit from GDBRemoteRegisterContext can see and modify these
    177     //------------------------------------------------------------------
    178     typedef std::vector <lldb_private::RegisterInfo> reg_collection;
    179     typedef std::vector <lldb_private::RegisterSet> set_collection;
    180     typedef std::vector <uint32_t> reg_num_collection;
    181     typedef std::vector <reg_num_collection> set_reg_num_collection;
    182     typedef std::vector <lldb_private::ConstString> name_collection;
    183     typedef std::map<uint32_t, reg_num_collection> reg_to_regs_map;
    184 
    185     reg_collection m_regs;
    186     set_collection m_sets;
    187     set_reg_num_collection m_set_reg_nums;
    188     name_collection m_reg_names;
    189     name_collection m_reg_alt_names;
    190     name_collection m_set_names;
    191     reg_to_regs_map m_value_regs_map;
    192     reg_to_regs_map m_invalidate_regs_map;
    193     size_t m_reg_data_byte_size;   // The number of bytes required to store all registers
    194 };
    195 
    196 class GDBRemoteRegisterContext : public lldb_private::RegisterContext
    197 {
    198 public:
    199     //------------------------------------------------------------------
    200     // Constructors and Destructors
    201     //------------------------------------------------------------------
    202     GDBRemoteRegisterContext (ThreadGDBRemote &thread,
    203                               uint32_t concrete_frame_idx,
    204                               GDBRemoteDynamicRegisterInfo &reg_info,
    205                               bool read_all_at_once);
    206 
    207     virtual
    208     ~GDBRemoteRegisterContext ();
    209 
    210     //------------------------------------------------------------------
    211     // Subclasses must override these functions
    212     //------------------------------------------------------------------
    213     virtual void
    214     InvalidateAllRegisters ();
    215 
    216     virtual size_t
    217     GetRegisterCount ();
    218 
    219     virtual const lldb_private::RegisterInfo *
    220     GetRegisterInfoAtIndex (size_t reg);
    221 
    222     virtual size_t
    223     GetRegisterSetCount ();
    224 
    225     virtual const lldb_private::RegisterSet *
    226     GetRegisterSet (size_t reg_set);
    227 
    228     virtual bool
    229     ReadRegister (const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value);
    230 
    231     virtual bool
    232     WriteRegister (const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value);
    233 
    234     virtual bool
    235     ReadAllRegisterValues (lldb::DataBufferSP &data_sp);
    236 
    237     virtual bool
    238     WriteAllRegisterValues (const lldb::DataBufferSP &data_sp);
    239 
    240     virtual uint32_t
    241     ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num);
    242 
    243 protected:
    244     friend class ThreadGDBRemote;
    245 
    246     bool
    247     ReadRegisterBytes (const lldb_private::RegisterInfo *reg_info,
    248                        lldb_private::DataExtractor &data);
    249 
    250     bool
    251     WriteRegisterBytes (const lldb_private::RegisterInfo *reg_info,
    252                         lldb_private::DataExtractor &data,
    253                         uint32_t data_offset);
    254 
    255     bool
    256     PrivateSetRegisterValue (uint32_t reg, StringExtractor &response);
    257 
    258     void
    259     SetAllRegisterValid (bool b);
    260 
    261     bool
    262     GetRegisterIsValid (uint32_t reg) const
    263     {
    264 #if defined (LLDB_CONFIGURATION_DEBUG)
    265         assert (reg < m_reg_valid.size());
    266 #endif
    267         if (reg < m_reg_valid.size())
    268             return m_reg_valid[reg];
    269         return false;
    270     }
    271 
    272     void
    273     SetRegisterIsValid (const lldb_private::RegisterInfo *reg_info, bool valid)
    274     {
    275         if (reg_info)
    276             return SetRegisterIsValid (reg_info->kinds[lldb::eRegisterKindLLDB], valid);
    277     }
    278 
    279     void
    280     SetRegisterIsValid (uint32_t reg, bool valid)
    281     {
    282 #if defined (LLDB_CONFIGURATION_DEBUG)
    283         assert (reg < m_reg_valid.size());
    284 #endif
    285         if (reg < m_reg_valid.size())
    286             m_reg_valid[reg] = valid;
    287     }
    288 
    289     void
    290     SyncThreadState(lldb_private::Process *process);  // Assumes the sequence mutex has already been acquired.
    291 
    292     GDBRemoteDynamicRegisterInfo &m_reg_info;
    293     std::vector<bool> m_reg_valid;
    294     lldb_private::DataExtractor m_reg_data;
    295     bool m_read_all_at_once;
    296 
    297 private:
    298     // Helper function for ReadRegisterBytes().
    299     bool GetPrimordialRegister(const lldb_private::RegisterInfo *reg_info,
    300                                GDBRemoteCommunicationClient &gdb_comm);
    301     // Helper function for WriteRegisterBytes().
    302     bool SetPrimordialRegister(const lldb_private::RegisterInfo *reg_info,
    303                                GDBRemoteCommunicationClient &gdb_comm);
    304 
    305     //------------------------------------------------------------------
    306     // For GDBRemoteRegisterContext only
    307     //------------------------------------------------------------------
    308     DISALLOW_COPY_AND_ASSIGN (GDBRemoteRegisterContext);
    309 };
    310 
    311 #endif  // lldb_GDBRemoteRegisterContext_h_
    312