1 //===-- RegisterContextPOSIX_x86.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/Host/Endian.h" 19 #include "lldb/Target/Process.h" 20 #include "lldb/Target/Target.h" 21 #include "lldb/Target/Thread.h" 22 #include "llvm/Support/Compiler.h" 23 24 #include "RegisterContext_s390x.h" 25 #include "RegisterContextPOSIX_s390x.h" 26 27 using namespace lldb_private; 28 using namespace lldb; 29 30 // s390x 64-bit general purpose registers. 31 static const uint32_t g_gpr_regnums_s390x[] = 32 { 33 lldb_r0_s390x, 34 lldb_r1_s390x, 35 lldb_r2_s390x, 36 lldb_r3_s390x, 37 lldb_r4_s390x, 38 lldb_r5_s390x, 39 lldb_r6_s390x, 40 lldb_r7_s390x, 41 lldb_r8_s390x, 42 lldb_r9_s390x, 43 lldb_r10_s390x, 44 lldb_r11_s390x, 45 lldb_r12_s390x, 46 lldb_r13_s390x, 47 lldb_r14_s390x, 48 lldb_r15_s390x, 49 lldb_acr0_s390x, 50 lldb_acr1_s390x, 51 lldb_acr2_s390x, 52 lldb_acr3_s390x, 53 lldb_acr4_s390x, 54 lldb_acr5_s390x, 55 lldb_acr6_s390x, 56 lldb_acr7_s390x, 57 lldb_acr8_s390x, 58 lldb_acr9_s390x, 59 lldb_acr10_s390x, 60 lldb_acr11_s390x, 61 lldb_acr12_s390x, 62 lldb_acr13_s390x, 63 lldb_acr14_s390x, 64 lldb_acr15_s390x, 65 lldb_pswm_s390x, 66 lldb_pswa_s390x, 67 LLDB_INVALID_REGNUM // register sets need to end with this flag 68 }; 69 static_assert((sizeof(g_gpr_regnums_s390x) / sizeof(g_gpr_regnums_s390x[0])) - 1 == k_num_gpr_registers_s390x, 70 "g_gpr_regnums_s390x has wrong number of register infos"); 71 72 // s390x 64-bit floating point registers. 73 static const uint32_t g_fpu_regnums_s390x[] = 74 { 75 lldb_f0_s390x, 76 lldb_f1_s390x, 77 lldb_f2_s390x, 78 lldb_f3_s390x, 79 lldb_f4_s390x, 80 lldb_f5_s390x, 81 lldb_f6_s390x, 82 lldb_f7_s390x, 83 lldb_f8_s390x, 84 lldb_f9_s390x, 85 lldb_f10_s390x, 86 lldb_f11_s390x, 87 lldb_f12_s390x, 88 lldb_f13_s390x, 89 lldb_f14_s390x, 90 lldb_f15_s390x, 91 lldb_fpc_s390x, 92 LLDB_INVALID_REGNUM // register sets need to end with this flag 93 }; 94 static_assert((sizeof(g_fpu_regnums_s390x) / sizeof(g_fpu_regnums_s390x[0])) - 1 == k_num_fpr_registers_s390x, 95 "g_fpu_regnums_s390x 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 s390x 64-bit. 104 static const RegisterSet g_reg_sets_s390x[k_num_register_sets] = 105 { 106 { "General Purpose Registers", "gpr", k_num_gpr_registers_s390x, g_gpr_regnums_s390x }, 107 { "Floating Point Registers", "fpr", k_num_fpr_registers_s390x, g_fpu_regnums_s390x }, 108 }; 109 110 bool 111 RegisterContextPOSIX_s390x::IsGPR(unsigned reg) 112 { 113 return reg <= m_reg_info.last_gpr; // GPRs come first. 114 } 115 116 bool 117 RegisterContextPOSIX_s390x::IsFPR(unsigned reg) 118 { 119 return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr); 120 } 121 122 RegisterContextPOSIX_s390x::RegisterContextPOSIX_s390x(Thread &thread, uint32_t concrete_frame_idx, 123 RegisterInfoInterface *register_info) 124 : 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::systemz: 131 m_reg_info.num_registers = k_num_registers_s390x; 132 m_reg_info.num_gpr_registers = k_num_gpr_registers_s390x; 133 m_reg_info.num_fpr_registers = k_num_fpr_registers_s390x; 134 m_reg_info.last_gpr = k_last_gpr_s390x; 135 m_reg_info.first_fpr = k_first_fpr_s390x; 136 m_reg_info.last_fpr = k_last_fpr_s390x; 137 break; 138 default: 139 assert(false && "Unhandled target architecture."); 140 break; 141 } 142 } 143 144 RegisterContextPOSIX_s390x::~RegisterContextPOSIX_s390x() 145 { 146 } 147 148 void 149 RegisterContextPOSIX_s390x::Invalidate() 150 { 151 } 152 153 void 154 RegisterContextPOSIX_s390x::InvalidateAllRegisters() 155 { 156 } 157 158 const RegisterInfo * 159 RegisterContextPOSIX_s390x::GetRegisterInfo() 160 { 161 return m_register_info_ap->GetRegisterInfo(); 162 } 163 164 const RegisterInfo * 165 RegisterContextPOSIX_s390x::GetRegisterInfoAtIndex(size_t reg) 166 { 167 if (reg < m_reg_info.num_registers) 168 return &GetRegisterInfo()[reg]; 169 else 170 return NULL; 171 } 172 173 size_t 174 RegisterContextPOSIX_s390x::GetRegisterCount() 175 { 176 return m_reg_info.num_registers; 177 } 178 179 unsigned 180 RegisterContextPOSIX_s390x::GetRegisterOffset(unsigned reg) 181 { 182 assert(reg < m_reg_info.num_registers && "Invalid register number."); 183 return GetRegisterInfo()[reg].byte_offset; 184 } 185 186 unsigned 187 RegisterContextPOSIX_s390x::GetRegisterSize(unsigned reg) 188 { 189 assert(reg < m_reg_info.num_registers && "Invalid register number."); 190 return GetRegisterInfo()[reg].byte_size; 191 } 192 193 const char * 194 RegisterContextPOSIX_s390x::GetRegisterName(unsigned reg) 195 { 196 assert(reg < m_reg_info.num_registers && "Invalid register offset."); 197 return GetRegisterInfo()[reg].name; 198 } 199 200 bool 201 RegisterContextPOSIX_s390x::IsRegisterSetAvailable(size_t set_index) 202 { 203 return set_index < k_num_register_sets; 204 } 205 206 size_t 207 RegisterContextPOSIX_s390x::GetRegisterSetCount() 208 { 209 size_t sets = 0; 210 for (size_t set = 0; set < k_num_register_sets; ++set) 211 { 212 if (IsRegisterSetAvailable(set)) 213 ++sets; 214 } 215 216 return sets; 217 } 218 219 const RegisterSet * 220 RegisterContextPOSIX_s390x::GetRegisterSet(size_t set) 221 { 222 if (IsRegisterSetAvailable(set)) 223 { 224 switch (m_register_info_ap->m_target_arch.GetMachine()) 225 { 226 case llvm::Triple::systemz: 227 return &g_reg_sets_s390x[set]; 228 default: 229 assert(false && "Unhandled target architecture."); 230 return NULL; 231 } 232 } 233 return NULL; 234 } 235 236 lldb::ByteOrder 237 RegisterContextPOSIX_s390x::GetByteOrder() 238 { 239 // Get the target process whose privileged thread was used for the register read. 240 lldb::ByteOrder byte_order = eByteOrderInvalid; 241 Process *process = CalculateProcess().get(); 242 243 if (process) 244 byte_order = process->GetByteOrder(); 245 return byte_order; 246 } 247 248 // Used when parsing DWARF and EH frame information and any other 249 // object file sections that contain register numbers in them. 250 uint32_t 251 RegisterContextPOSIX_s390x::ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) 252 { 253 const uint32_t num_regs = GetRegisterCount(); 254 255 assert(kind < kNumRegisterKinds); 256 for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) 257 { 258 const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx); 259 260 if (reg_info->kinds[kind] == num) 261 return reg_idx; 262 } 263 264 return LLDB_INVALID_REGNUM; 265 } 266