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 LLDB_INVALID_REGNUM // register sets need to end with this flag 92 93 }; 94 static_assert(((sizeof g_fpu_regnums_arm / sizeof g_fpu_regnums_arm[0]) - 1) == k_num_fpr_registers_arm, \ 95 "g_fpu_regnums_arm has wrong number of register infos"); 96 97 // Number of register sets provided by this context. 98 enum 99 { 100 k_num_register_sets = 2 101 }; 102 103 // Register sets for arm. 104 static const lldb_private::RegisterSet 105 g_reg_sets_arm[k_num_register_sets] = 106 { 107 { "General Purpose Registers", "gpr", k_num_gpr_registers_arm, g_gpr_regnums_arm }, 108 { "Floating Point Registers", "fpu", k_num_fpr_registers_arm, g_fpu_regnums_arm } 109 }; 110 111 bool RegisterContextPOSIX_arm::IsGPR(unsigned reg) 112 { 113 return reg <= m_reg_info.last_gpr; // GPR's come first. 114 } 115 116 bool RegisterContextPOSIX_arm::IsFPR(unsigned reg) 117 { 118 return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr); 119 } 120 121 RegisterContextPOSIX_arm::RegisterContextPOSIX_arm(lldb_private::Thread &thread, 122 uint32_t concrete_frame_idx, 123 lldb_private::RegisterInfoInterface *register_info) 124 : lldb_private::RegisterContext(thread, concrete_frame_idx) 125 { 126 m_register_info_ap.reset(register_info); 127 128 switch (register_info->m_target_arch.GetMachine()) 129 { 130 case llvm::Triple::arm: 131 m_reg_info.num_registers = k_num_registers_arm; 132 m_reg_info.num_gpr_registers = k_num_gpr_registers_arm; 133 m_reg_info.num_fpr_registers = k_num_fpr_registers_arm; 134 m_reg_info.last_gpr = k_last_gpr_arm; 135 m_reg_info.first_fpr = k_first_fpr_arm; 136 m_reg_info.last_fpr = k_last_fpr_arm; 137 m_reg_info.first_fpr_v = fpu_s0_arm; 138 m_reg_info.last_fpr_v = fpu_s31_arm; 139 m_reg_info.gpr_flags = gpr_cpsr_arm; 140 break; 141 default: 142 assert(false && "Unhandled target architecture."); 143 break; 144 } 145 146 ::memset(&m_fpr, 0, sizeof m_fpr); 147 148 // elf-core yet to support ReadFPR() 149 lldb::ProcessSP base = CalculateProcess(); 150 if (base.get()->GetPluginName() == ProcessElfCore::GetPluginNameStatic()) 151 return; 152 } 153 154 RegisterContextPOSIX_arm::~RegisterContextPOSIX_arm() 155 { 156 } 157 158 void 159 RegisterContextPOSIX_arm::Invalidate() 160 { 161 } 162 163 void 164 RegisterContextPOSIX_arm::InvalidateAllRegisters() 165 { 166 } 167 168 unsigned 169 RegisterContextPOSIX_arm::GetRegisterOffset(unsigned reg) 170 { 171 assert(reg < m_reg_info.num_registers && "Invalid register number."); 172 return GetRegisterInfo()[reg].byte_offset; 173 } 174 175 unsigned 176 RegisterContextPOSIX_arm::GetRegisterSize(unsigned reg) 177 { 178 assert(reg < m_reg_info.num_registers && "Invalid register number."); 179 return GetRegisterInfo()[reg].byte_size; 180 } 181 182 size_t 183 RegisterContextPOSIX_arm::GetRegisterCount() 184 { 185 size_t num_registers = m_reg_info.num_gpr_registers + m_reg_info.num_fpr_registers; 186 return num_registers; 187 } 188 189 size_t 190 RegisterContextPOSIX_arm::GetGPRSize() 191 { 192 return m_register_info_ap->GetGPRSize (); 193 } 194 195 const lldb_private::RegisterInfo * 196 RegisterContextPOSIX_arm::GetRegisterInfo() 197 { 198 // Commonly, this method is overridden and g_register_infos is copied and specialized. 199 // So, use GetRegisterInfo() rather than g_register_infos in this scope. 200 return m_register_info_ap->GetRegisterInfo (); 201 } 202 203 const lldb_private::RegisterInfo * 204 RegisterContextPOSIX_arm::GetRegisterInfoAtIndex(size_t reg) 205 { 206 if (reg < m_reg_info.num_registers) 207 return &GetRegisterInfo()[reg]; 208 else 209 return NULL; 210 } 211 212 size_t 213 RegisterContextPOSIX_arm::GetRegisterSetCount() 214 { 215 size_t sets = 0; 216 for (size_t set = 0; set < k_num_register_sets; ++set) 217 { 218 if (IsRegisterSetAvailable(set)) 219 ++sets; 220 } 221 222 return sets; 223 } 224 225 const lldb_private::RegisterSet * 226 RegisterContextPOSIX_arm::GetRegisterSet(size_t set) 227 { 228 if (IsRegisterSetAvailable(set)) 229 { 230 switch (m_register_info_ap->m_target_arch.GetMachine()) 231 { 232 case llvm::Triple::arm: 233 return &g_reg_sets_arm[set]; 234 default: 235 assert(false && "Unhandled target architecture."); 236 return NULL; 237 } 238 } 239 return NULL; 240 } 241 242 const char * 243 RegisterContextPOSIX_arm::GetRegisterName(unsigned reg) 244 { 245 assert(reg < m_reg_info.num_registers && "Invalid register offset."); 246 return GetRegisterInfo()[reg].name; 247 } 248 249 lldb::ByteOrder 250 RegisterContextPOSIX_arm::GetByteOrder() 251 { 252 // Get the target process whose privileged thread was used for the register read. 253 lldb::ByteOrder byte_order = lldb::eByteOrderInvalid; 254 lldb_private::Process *process = CalculateProcess().get(); 255 256 if (process) 257 byte_order = process->GetByteOrder(); 258 return byte_order; 259 } 260 261 bool 262 RegisterContextPOSIX_arm::IsRegisterSetAvailable(size_t set_index) 263 { 264 return set_index < k_num_register_sets; 265 } 266 267 268 // Used when parsing DWARF and EH frame information and any other 269 // object file sections that contain register numbers in them. 270 uint32_t 271 RegisterContextPOSIX_arm::ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, 272 uint32_t num) 273 { 274 const uint32_t num_regs = GetRegisterCount(); 275 276 assert (kind < lldb::kNumRegisterKinds); 277 for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) 278 { 279 const lldb_private::RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg_idx); 280 281 if (reg_info->kinds[kind] == num) 282 return reg_idx; 283 } 284 285 return LLDB_INVALID_REGNUM; 286 } 287 288