1 //===-- RegisterContext.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 // C Includes 11 // C++ Includes 12 // Other libraries and framework includes 13 // Project includes 14 #include "lldb/Target/RegisterContext.h" 15 #include "lldb/Core/DataExtractor.h" 16 #include "lldb/Core/Scalar.h" 17 #include "lldb/Target/ExecutionContext.h" 18 #include "lldb/Target/StackFrame.h" 19 #include "lldb/Target/Process.h" 20 #include "lldb/Target/Thread.h" 21 22 using namespace lldb; 23 using namespace lldb_private; 24 25 RegisterContext::RegisterContext (Thread &thread, uint32_t concrete_frame_idx) : 26 m_thread (thread), 27 m_concrete_frame_idx (concrete_frame_idx), 28 m_stop_id (thread.GetProcess().GetStopID()) 29 { 30 } 31 32 //---------------------------------------------------------------------- 33 // Destructor 34 //---------------------------------------------------------------------- 35 RegisterContext::~RegisterContext() 36 { 37 } 38 39 void 40 RegisterContext::InvalidateIfNeeded (bool force) 41 { 42 const uint32_t this_stop_id = GetStopID(); 43 const uint32_t process_stop_id = m_thread.GetProcess().GetStopID(); 44 if (force || process_stop_id != this_stop_id) 45 { 46 InvalidateAllRegisters (); 47 SetStopID (process_stop_id); 48 } 49 } 50 51 52 const RegisterInfo * 53 RegisterContext::GetRegisterInfoByName (const char *reg_name, uint32_t start_idx) 54 { 55 if (reg_name && reg_name[0]) 56 { 57 const uint32_t num_registers = GetRegisterCount(); 58 for (uint32_t reg = start_idx; reg < num_registers; ++reg) 59 { 60 const RegisterInfo * reg_info = GetRegisterInfoAtIndex(reg); 61 62 if ((reg_info->name != NULL && ::strcasecmp (reg_info->name, reg_name) == 0) || 63 (reg_info->alt_name != NULL && ::strcasecmp (reg_info->alt_name, reg_name) == 0)) 64 { 65 return reg_info; 66 } 67 } 68 } 69 return NULL; 70 } 71 72 const char * 73 RegisterContext::GetRegisterName (uint32_t reg) 74 { 75 const RegisterInfo * reg_info = GetRegisterInfoAtIndex(reg); 76 if (reg_info) 77 return reg_info->name; 78 return NULL; 79 } 80 81 uint64_t 82 RegisterContext::GetPC(uint64_t fail_value) 83 { 84 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); 85 return ReadRegisterAsUnsigned (reg, fail_value); 86 } 87 88 bool 89 RegisterContext::SetPC(uint64_t pc) 90 { 91 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); 92 bool success = WriteRegisterFromUnsigned (reg, pc); 93 if (success) 94 { 95 StackFrameSP frame_sp(m_thread.GetFrameWithConcreteFrameIndex (m_concrete_frame_idx)); 96 if (frame_sp) 97 frame_sp->ChangePC(pc); 98 else 99 m_thread.ClearStackFrames (); 100 } 101 return success; 102 } 103 104 uint64_t 105 RegisterContext::GetSP(uint64_t fail_value) 106 { 107 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); 108 return ReadRegisterAsUnsigned (reg, fail_value); 109 } 110 111 bool 112 RegisterContext::SetSP(uint64_t sp) 113 { 114 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); 115 return WriteRegisterFromUnsigned (reg, sp); 116 } 117 118 uint64_t 119 RegisterContext::GetFP(uint64_t fail_value) 120 { 121 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP); 122 return ReadRegisterAsUnsigned (reg, fail_value); 123 } 124 125 bool 126 RegisterContext::SetFP(uint64_t fp) 127 { 128 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP); 129 return WriteRegisterFromUnsigned (reg, fp); 130 } 131 132 uint64_t 133 RegisterContext::GetReturnAddress (uint64_t fail_value) 134 { 135 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA); 136 return ReadRegisterAsUnsigned (reg, fail_value); 137 } 138 139 uint64_t 140 RegisterContext::GetFlags (uint64_t fail_value) 141 { 142 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS); 143 return ReadRegisterAsUnsigned (reg, fail_value); 144 } 145 146 147 uint64_t 148 RegisterContext::ReadRegisterAsUnsigned (uint32_t reg, uint64_t fail_value) 149 { 150 if (reg != LLDB_INVALID_REGNUM) 151 { 152 Scalar value; 153 if (ReadRegisterValue (reg, value)) 154 return value.GetRawBits64(fail_value); 155 } 156 return fail_value; 157 } 158 159 bool 160 RegisterContext::WriteRegisterFromUnsigned (uint32_t reg, uint64_t uval) 161 { 162 if (reg == LLDB_INVALID_REGNUM) 163 return false; 164 Scalar value(uval); 165 return WriteRegisterValue (reg, value); 166 } 167 168 lldb::tid_t 169 RegisterContext::GetThreadID() const 170 { 171 return m_thread.GetID(); 172 } 173 174 uint32_t 175 RegisterContext::NumSupportedHardwareBreakpoints () 176 { 177 return 0; 178 } 179 180 uint32_t 181 RegisterContext::SetHardwareBreakpoint (lldb::addr_t addr, size_t size) 182 { 183 return LLDB_INVALID_INDEX32; 184 } 185 186 bool 187 RegisterContext::ClearHardwareBreakpoint (uint32_t hw_idx) 188 { 189 return false; 190 } 191 192 193 uint32_t 194 RegisterContext::NumSupportedHardwareWatchpoints () 195 { 196 return 0; 197 } 198 199 uint32_t 200 RegisterContext::SetHardwareWatchpoint (lldb::addr_t addr, size_t size, bool read, bool write) 201 { 202 return LLDB_INVALID_INDEX32; 203 } 204 205 bool 206 RegisterContext::ClearHardwareWatchpoint (uint32_t hw_index) 207 { 208 return false; 209 } 210 211 bool 212 RegisterContext::HardwareSingleStep (bool enable) 213 { 214 return false; 215 } 216 217 Target * 218 RegisterContext::CalculateTarget () 219 { 220 return m_thread.CalculateTarget(); 221 } 222 223 224 Process * 225 RegisterContext::CalculateProcess () 226 { 227 return m_thread.CalculateProcess (); 228 } 229 230 Thread * 231 RegisterContext::CalculateThread () 232 { 233 return &m_thread; 234 } 235 236 StackFrame * 237 RegisterContext::CalculateStackFrame () 238 { 239 // Register contexts might belong to many frames if we have inlined 240 // functions inside a frame since all inlined functions share the 241 // same registers, so we can't definitively say which frame we come from... 242 return NULL; 243 } 244 245 void 246 RegisterContext::CalculateExecutionContext (ExecutionContext &exe_ctx) 247 { 248 m_thread.CalculateExecutionContext (exe_ctx); 249 } 250 251 252 bool 253 RegisterContext::ConvertBetweenRegisterKinds (int source_rk, uint32_t source_regnum, int target_rk, uint32_t& target_regnum) 254 { 255 const uint32_t num_registers = GetRegisterCount(); 256 for (uint32_t reg = 0; reg < num_registers; ++reg) 257 { 258 const RegisterInfo * reg_info = GetRegisterInfoAtIndex (reg); 259 260 if (reg_info->kinds[source_rk] == source_regnum) 261 { 262 target_regnum = reg_info->kinds[target_rk]; 263 if (target_regnum == LLDB_INVALID_REGNUM) 264 { 265 return false; 266 } 267 else 268 { 269 return true; 270 } 271 } 272 } 273 return false; 274 } 275 276 bool 277 RegisterContext::ReadRegisterValue (uint32_t reg, Scalar &value) 278 { 279 DataExtractor data; 280 if (!ReadRegisterBytes (reg, data)) 281 return false; 282 283 const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg); 284 uint32_t offset = 0; 285 switch (reg_info->encoding) 286 { 287 case eEncodingUint: 288 switch (reg_info->byte_size) 289 { 290 case 1: 291 { 292 value = data.GetU8 (&offset); 293 return true; 294 } 295 case 2: 296 { 297 value = data.GetU16 (&offset); 298 return true; 299 } 300 case 4: 301 { 302 value = data.GetU32 (&offset); 303 return true; 304 } 305 case 8: 306 { 307 value = data.GetU64 (&offset); 308 return true; 309 } 310 } 311 break; 312 case eEncodingSint: 313 switch (reg_info->byte_size) 314 { 315 case 1: 316 { 317 int8_t v; 318 if (data.ExtractBytes (0, sizeof (int8_t), eByteOrderHost, &v) != sizeof (int8_t)) 319 return false; 320 value = v; 321 return true; 322 } 323 case 2: 324 { 325 int16_t v; 326 if (data.ExtractBytes (0, sizeof (int16_t), eByteOrderHost, &v) != sizeof (int16_t)) 327 return false; 328 value = v; 329 return true; 330 } 331 case 4: 332 { 333 int32_t v; 334 if (data.ExtractBytes (0, sizeof (int32_t), eByteOrderHost, &v) != sizeof (int32_t)) 335 return false; 336 value = v; 337 return true; 338 } 339 case 8: 340 { 341 int64_t v; 342 if (data.ExtractBytes (0, sizeof (int64_t), eByteOrderHost, &v) != sizeof (int64_t)) 343 return false; 344 value = v; 345 return true; 346 } 347 } 348 break; 349 case eEncodingIEEE754: 350 switch (reg_info->byte_size) 351 { 352 case sizeof (float): 353 { 354 float v; 355 if (data.ExtractBytes (0, sizeof (float), eByteOrderHost, &v) != sizeof (float)) 356 return false; 357 value = v; 358 return true; 359 } 360 case sizeof (double): 361 { 362 double v; 363 if (data.ExtractBytes (0, sizeof (double), eByteOrderHost, &v) != sizeof (double)) 364 return false; 365 value = v; 366 return true; 367 } 368 case sizeof (long double): 369 { 370 double v; 371 if (data.ExtractBytes (0, sizeof (long double), eByteOrderHost, &v) != sizeof (long double)) 372 return false; 373 value = v; 374 return true; 375 } 376 } 377 break; 378 } 379 return false; 380 } 381 382 bool 383 RegisterContext::WriteRegisterValue (uint32_t reg, const Scalar &value) 384 { 385 DataExtractor data; 386 if (!value.IsValid()) 387 return false; 388 if (!value.GetData (data)) 389 return false; 390 391 return WriteRegisterBytes (reg, data); 392 } 393