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: GDBRemoteDynamicRegisterInfo()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 ~GDBRemoteDynamicRegisterInfo()44 ~GDBRemoteDynamicRegisterInfo () 45 { 46 } 47 48 void AddRegister(lldb_private::RegisterInfo reg_info,lldb_private::ConstString & reg_name,lldb_private::ConstString & reg_alt_name,lldb_private::ConstString & set_name)49 AddRegister (lldb_private::RegisterInfo reg_info, 50 lldb_private::ConstString ®_name, 51 lldb_private::ConstString ®_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 Finalize()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 GetNumRegisters()98 GetNumRegisters() const 99 { 100 return m_regs.size(); 101 } 102 103 size_t GetNumRegisterSets()104 GetNumRegisterSets() const 105 { 106 return m_sets.size(); 107 } 108 109 size_t GetRegisterDataByteSize()110 GetRegisterDataByteSize() const 111 { 112 return m_reg_data_byte_size; 113 } 114 115 const lldb_private::RegisterInfo * GetRegisterInfoAtIndex(uint32_t i)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 * GetRegisterSet(uint32_t i)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 GetRegisterSetIndexByName(lldb_private::ConstString & set_name)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 ConvertRegisterKindToRegisterNumber(uint32_t kind,uint32_t num)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 Clear()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 ®_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 GetRegisterIsValid(uint32_t reg)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 SetRegisterIsValid(const lldb_private::RegisterInfo * reg_info,bool valid)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 SetRegisterIsValid(uint32_t reg,bool valid)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