1 //===-- RegisterContextPOSIX_arm.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 <cstring> 11 #include <errno.h> 12 #include <stdint.h> 13 14 #include "lldb/Core/DataBufferHeap.h" 15 #include "lldb/Core/DataExtractor.h" 16 #include "lldb/Core/RegisterValue.h" 17 #include "lldb/Core/Scalar.h" 18 #include "lldb/Target/Target.h" 19 #include "lldb/Target/Thread.h" 20 #include "lldb/Host/Endian.h" 21 #include "llvm/Support/Compiler.h" 22 23 #include "RegisterContextPOSIX_arm.h" 24 #include "Plugins/Process/elf-core/ProcessElfCore.h" 25 26 using namespace lldb; 27 using namespace lldb_private; 28 29 // arm general purpose registers. 30 const uint32_t g_gpr_regnums_arm[] = 31 { 32 gpr_r0_arm, 33 gpr_r1_arm, 34 gpr_r2_arm, 35 gpr_r3_arm, 36 gpr_r4_arm, 37 gpr_r5_arm, 38 gpr_r6_arm, 39 gpr_r7_arm, 40 gpr_r8_arm, 41 gpr_r9_arm, 42 gpr_r10_arm, 43 gpr_r11_arm, 44 gpr_r12_arm, 45 gpr_sp_arm, 46 gpr_lr_arm, 47 gpr_pc_arm, 48 gpr_cpsr_arm, 49 LLDB_INVALID_REGNUM // register sets need to end with this flag 50 51 }; 52 static_assert(((sizeof g_gpr_regnums_arm / sizeof g_gpr_regnums_arm[0]) - 1) == k_num_gpr_registers_arm, \ 53 "g_gpr_regnums_arm has wrong number of register infos"); 54 55 // arm floating point registers. 56 static const uint32_t g_fpu_regnums_arm[] = 57 { 58 fpu_s0_arm, 59 fpu_s1_arm, 60 fpu_s2_arm, 61 fpu_s3_arm, 62 fpu_s4_arm, 63 fpu_s5_arm, 64 fpu_s6_arm, 65 fpu_s7_arm, 66 fpu_s8_arm, 67 fpu_s9_arm, 68 fpu_s10_arm, 69 fpu_s11_arm, 70 fpu_s12_arm, 71 fpu_s13_arm, 72 fpu_s14_arm, 73 fpu_s15_arm, 74 fpu_s16_arm, 75 fpu_s17_arm, 76 fpu_s18_arm, 77 fpu_s19_arm, 78 fpu_s20_arm, 79 fpu_s21_arm, 80 fpu_s22_arm, 81 fpu_s23_arm, 82 fpu_s24_arm, 83 fpu_s25_arm, 84 fpu_s26_arm, 85 fpu_s27_arm, 86 fpu_s28_arm, 87 fpu_s29_arm, 88 fpu_s30_arm, 89 fpu_s31_arm, 90 fpu_fpscr_arm, 91 fpu_d0_arm, 92 fpu_d1_arm, 93 fpu_d2_arm, 94 fpu_d3_arm, 95 fpu_d4_arm, 96 fpu_d5_arm, 97 fpu_d6_arm, 98 fpu_d7_arm, 99 fpu_d8_arm, 100 fpu_d9_arm, 101 fpu_d10_arm, 102 fpu_d11_arm, 103 fpu_d12_arm, 104 fpu_d13_arm, 105 fpu_d14_arm, 106 fpu_d15_arm, 107 fpu_d16_arm, 108 fpu_d17_arm, 109 fpu_d18_arm, 110 fpu_d19_arm, 111 fpu_d20_arm, 112 fpu_d21_arm, 113 fpu_d22_arm, 114 fpu_d23_arm, 115 fpu_d24_arm, 116 fpu_d25_arm, 117 fpu_d26_arm, 118 fpu_d27_arm, 119 fpu_d28_arm, 120 fpu_d29_arm, 121 fpu_d30_arm, 122 fpu_d31_arm, 123 fpu_q0_arm, 124 fpu_q1_arm, 125 fpu_q2_arm, 126 fpu_q3_arm, 127 fpu_q4_arm, 128 fpu_q5_arm, 129 fpu_q6_arm, 130 fpu_q7_arm, 131 fpu_q8_arm, 132 fpu_q9_arm, 133 fpu_q10_arm, 134 fpu_q11_arm, 135 fpu_q12_arm, 136 fpu_q13_arm, 137 fpu_q14_arm, 138 fpu_q15_arm, 139 LLDB_INVALID_REGNUM // register sets need to end with this flag 140 141 }; 142 static_assert(((sizeof g_fpu_regnums_arm / sizeof g_fpu_regnums_arm[0]) - 1) == k_num_fpr_registers_arm, \ 143 "g_fpu_regnums_arm has wrong number of register infos"); 144 145 // Number of register sets provided by this context. 146 enum 147 { 148 k_num_register_sets = 2 149 }; 150 151 // Register sets for arm. 152 static const lldb_private::RegisterSet 153 g_reg_sets_arm[k_num_register_sets] = 154 { 155 { "General Purpose Registers", "gpr", k_num_gpr_registers_arm, g_gpr_regnums_arm }, 156 { "Floating Point Registers", "fpu", k_num_fpr_registers_arm, g_fpu_regnums_arm } 157 }; 158 159 bool RegisterContextPOSIX_arm::IsGPR(unsigned reg) 160 { 161 return reg <= m_reg_info.last_gpr; // GPR's come first. 162 } 163 164 bool RegisterContextPOSIX_arm::IsFPR(unsigned reg) 165 { 166 return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr); 167 } 168 169 RegisterContextPOSIX_arm::RegisterContextPOSIX_arm(lldb_private::Thread &thread, 170 uint32_t concrete_frame_idx, 171 lldb_private::RegisterInfoInterface *register_info) 172 : lldb_private::RegisterContext(thread, concrete_frame_idx) 173 { 174 m_register_info_ap.reset(register_info); 175 176 switch (register_info->m_target_arch.GetMachine()) 177 { 178 case llvm::Triple::arm: 179 m_reg_info.num_registers = k_num_registers_arm; 180 m_reg_info.num_gpr_registers = k_num_gpr_registers_arm; 181 m_reg_info.num_fpr_registers = k_num_fpr_registers_arm; 182 m_reg_info.last_gpr = k_last_gpr_arm; 183 m_reg_info.first_fpr = k_first_fpr_arm; 184 m_reg_info.last_fpr = k_last_fpr_arm; 185 m_reg_info.first_fpr_v = fpu_s0_arm; 186 m_reg_info.last_fpr_v = fpu_s31_arm; 187 m_reg_info.gpr_flags = gpr_cpsr_arm; 188 break; 189 default: 190 assert(false && "Unhandled target architecture."); 191 break; 192 } 193 194 ::memset(&m_fpr, 0, sizeof m_fpr); 195 196 // elf-core yet to support ReadFPR() 197 lldb::ProcessSP base = CalculateProcess(); 198 if (base.get()->GetPluginName() == ProcessElfCore::GetPluginNameStatic()) 199 return; 200 } 201 202 RegisterContextPOSIX_arm::~RegisterContextPOSIX_arm() 203 { 204 } 205 206 void 207 RegisterContextPOSIX_arm::Invalidate() 208 { 209 } 210 211 void 212 RegisterContextPOSIX_arm::InvalidateAllRegisters() 213 { 214 } 215 216 unsigned 217 RegisterContextPOSIX_arm::GetRegisterOffset(unsigned reg) 218 { 219 assert(reg < m_reg_info.num_registers && "Invalid register number."); 220 return GetRegisterInfo()[reg].byte_offset; 221 } 222 223 unsigned 224 RegisterContextPOSIX_arm::GetRegisterSize(unsigned reg) 225 { 226 assert(reg < m_reg_info.num_registers && "Invalid register number."); 227 return GetRegisterInfo()[reg].byte_size; 228 } 229 230 size_t 231 RegisterContextPOSIX_arm::GetRegisterCount() 232 { 233 size_t num_registers = m_reg_info.num_gpr_registers + m_reg_info.num_fpr_registers; 234 return num_registers; 235 } 236 237 size_t 238 RegisterContextPOSIX_arm::GetGPRSize() 239 { 240 return m_register_info_ap->GetGPRSize (); 241 } 242 243 const lldb_private::RegisterInfo * 244 RegisterContextPOSIX_arm::GetRegisterInfo() 245 { 246 // Commonly, this method is overridden and g_register_infos is copied and specialized. 247 // So, use GetRegisterInfo() rather than g_register_infos in this scope. 248 return m_register_info_ap->GetRegisterInfo (); 249 } 250 251 const lldb_private::RegisterInfo * 252 RegisterContextPOSIX_arm::GetRegisterInfoAtIndex(size_t reg) 253 { 254 if (reg < m_reg_info.num_registers) 255 return &GetRegisterInfo()[reg]; 256 else 257 return NULL; 258 } 259 260 size_t 261 RegisterContextPOSIX_arm::GetRegisterSetCount() 262 { 263 size_t sets = 0; 264 for (size_t set = 0; set < k_num_register_sets; ++set) 265 { 266 if (IsRegisterSetAvailable(set)) 267 ++sets; 268 } 269 270 return sets; 271 } 272 273 const lldb_private::RegisterSet * 274 RegisterContextPOSIX_arm::GetRegisterSet(size_t set) 275 { 276 if (IsRegisterSetAvailable(set)) 277 { 278 switch (m_register_info_ap->m_target_arch.GetMachine()) 279 { 280 case llvm::Triple::arm: 281 return &g_reg_sets_arm[set]; 282 default: 283 assert(false && "Unhandled target architecture."); 284 return NULL; 285 } 286 } 287 return NULL; 288 } 289 290 const char * 291 RegisterContextPOSIX_arm::GetRegisterName(unsigned reg) 292 { 293 assert(reg < m_reg_info.num_registers && "Invalid register offset."); 294 return GetRegisterInfo()[reg].name; 295 } 296 297 lldb::ByteOrder 298 RegisterContextPOSIX_arm::GetByteOrder() 299 { 300 // Get the target process whose privileged thread was used for the register read. 301 lldb::ByteOrder byte_order = lldb::eByteOrderInvalid; 302 lldb_private::Process *process = CalculateProcess().get(); 303 304 if (process) 305 byte_order = process->GetByteOrder(); 306 return byte_order; 307 } 308 309 bool 310 RegisterContextPOSIX_arm::IsRegisterSetAvailable(size_t set_index) 311 { 312 return set_index < k_num_register_sets; 313 } 314 315 316 // Used when parsing DWARF and EH frame information and any other 317 // object file sections that contain register numbers in them. 318 uint32_t 319 RegisterContextPOSIX_arm::ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, 320 uint32_t num) 321 { 322 const uint32_t num_regs = GetRegisterCount(); 323 324 assert (kind < lldb::kNumRegisterKinds); 325 for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) 326 { 327 const lldb_private::RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg_idx); 328 329 if (reg_info->kinds[kind] == num) 330 return reg_idx; 331 } 332 333 return LLDB_INVALID_REGNUM; 334 } 335 336