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 "RegisterContextPOSIX_s390x.h" 25 #include "RegisterContext_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 lldb_r0_s390x, lldb_r1_s390x, lldb_r2_s390x, lldb_r3_s390x, 33 lldb_r4_s390x, lldb_r5_s390x, lldb_r6_s390x, lldb_r7_s390x, 34 lldb_r8_s390x, lldb_r9_s390x, lldb_r10_s390x, lldb_r11_s390x, 35 lldb_r12_s390x, lldb_r13_s390x, lldb_r14_s390x, lldb_r15_s390x, 36 lldb_acr0_s390x, lldb_acr1_s390x, lldb_acr2_s390x, lldb_acr3_s390x, 37 lldb_acr4_s390x, lldb_acr5_s390x, lldb_acr6_s390x, lldb_acr7_s390x, 38 lldb_acr8_s390x, lldb_acr9_s390x, lldb_acr10_s390x, lldb_acr11_s390x, 39 lldb_acr12_s390x, lldb_acr13_s390x, lldb_acr14_s390x, lldb_acr15_s390x, 40 lldb_pswm_s390x, lldb_pswa_s390x, 41 LLDB_INVALID_REGNUM // register sets need to end with this flag 42 }; 43 static_assert((sizeof(g_gpr_regnums_s390x) / sizeof(g_gpr_regnums_s390x[0])) - 44 1 == 45 k_num_gpr_registers_s390x, 46 "g_gpr_regnums_s390x has wrong number of register infos"); 47 48 // s390x 64-bit floating point registers. 49 static const uint32_t g_fpu_regnums_s390x[] = { 50 lldb_f0_s390x, lldb_f1_s390x, lldb_f2_s390x, lldb_f3_s390x, 51 lldb_f4_s390x, lldb_f5_s390x, lldb_f6_s390x, lldb_f7_s390x, 52 lldb_f8_s390x, lldb_f9_s390x, lldb_f10_s390x, lldb_f11_s390x, 53 lldb_f12_s390x, lldb_f13_s390x, lldb_f14_s390x, lldb_f15_s390x, 54 lldb_fpc_s390x, 55 LLDB_INVALID_REGNUM // register sets need to end with this flag 56 }; 57 static_assert((sizeof(g_fpu_regnums_s390x) / sizeof(g_fpu_regnums_s390x[0])) - 58 1 == 59 k_num_fpr_registers_s390x, 60 "g_fpu_regnums_s390x has wrong number of register infos"); 61 62 // Number of register sets provided by this context. 63 enum { k_num_register_sets = 2 }; 64 65 // Register sets for s390x 64-bit. 66 static const RegisterSet g_reg_sets_s390x[k_num_register_sets] = { 67 {"General Purpose Registers", "gpr", k_num_gpr_registers_s390x, 68 g_gpr_regnums_s390x}, 69 {"Floating Point Registers", "fpr", k_num_fpr_registers_s390x, 70 g_fpu_regnums_s390x}, 71 }; 72 73 bool RegisterContextPOSIX_s390x::IsGPR(unsigned reg) { 74 return reg <= m_reg_info.last_gpr; // GPRs come first. 75 } 76 77 bool RegisterContextPOSIX_s390x::IsFPR(unsigned reg) { 78 return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr); 79 } 80 81 RegisterContextPOSIX_s390x::RegisterContextPOSIX_s390x( 82 Thread &thread, uint32_t concrete_frame_idx, 83 RegisterInfoInterface *register_info) 84 : RegisterContext(thread, concrete_frame_idx) { 85 m_register_info_ap.reset(register_info); 86 87 switch (register_info->m_target_arch.GetMachine()) { 88 case llvm::Triple::systemz: 89 m_reg_info.num_registers = k_num_registers_s390x; 90 m_reg_info.num_gpr_registers = k_num_gpr_registers_s390x; 91 m_reg_info.num_fpr_registers = k_num_fpr_registers_s390x; 92 m_reg_info.last_gpr = k_last_gpr_s390x; 93 m_reg_info.first_fpr = k_first_fpr_s390x; 94 m_reg_info.last_fpr = k_last_fpr_s390x; 95 break; 96 default: 97 assert(false && "Unhandled target architecture."); 98 break; 99 } 100 } 101 102 RegisterContextPOSIX_s390x::~RegisterContextPOSIX_s390x() {} 103 104 void RegisterContextPOSIX_s390x::Invalidate() {} 105 106 void RegisterContextPOSIX_s390x::InvalidateAllRegisters() {} 107 108 const RegisterInfo *RegisterContextPOSIX_s390x::GetRegisterInfo() { 109 return m_register_info_ap->GetRegisterInfo(); 110 } 111 112 const RegisterInfo * 113 RegisterContextPOSIX_s390x::GetRegisterInfoAtIndex(size_t reg) { 114 if (reg < m_reg_info.num_registers) 115 return &GetRegisterInfo()[reg]; 116 else 117 return NULL; 118 } 119 120 size_t RegisterContextPOSIX_s390x::GetRegisterCount() { 121 return m_reg_info.num_registers; 122 } 123 124 unsigned RegisterContextPOSIX_s390x::GetRegisterOffset(unsigned reg) { 125 assert(reg < m_reg_info.num_registers && "Invalid register number."); 126 return GetRegisterInfo()[reg].byte_offset; 127 } 128 129 unsigned RegisterContextPOSIX_s390x::GetRegisterSize(unsigned reg) { 130 assert(reg < m_reg_info.num_registers && "Invalid register number."); 131 return GetRegisterInfo()[reg].byte_size; 132 } 133 134 const char *RegisterContextPOSIX_s390x::GetRegisterName(unsigned reg) { 135 assert(reg < m_reg_info.num_registers && "Invalid register offset."); 136 return GetRegisterInfo()[reg].name; 137 } 138 139 bool RegisterContextPOSIX_s390x::IsRegisterSetAvailable(size_t set_index) { 140 return set_index < k_num_register_sets; 141 } 142 143 size_t RegisterContextPOSIX_s390x::GetRegisterSetCount() { 144 size_t sets = 0; 145 for (size_t set = 0; set < k_num_register_sets; ++set) { 146 if (IsRegisterSetAvailable(set)) 147 ++sets; 148 } 149 150 return sets; 151 } 152 153 const RegisterSet *RegisterContextPOSIX_s390x::GetRegisterSet(size_t set) { 154 if (IsRegisterSetAvailable(set)) { 155 switch (m_register_info_ap->m_target_arch.GetMachine()) { 156 case llvm::Triple::systemz: 157 return &g_reg_sets_s390x[set]; 158 default: 159 assert(false && "Unhandled target architecture."); 160 return NULL; 161 } 162 } 163 return NULL; 164 } 165 166 lldb::ByteOrder RegisterContextPOSIX_s390x::GetByteOrder() { 167 // Get the target process whose privileged thread was used for the register 168 // read. 169 lldb::ByteOrder byte_order = eByteOrderInvalid; 170 Process *process = CalculateProcess().get(); 171 172 if (process) 173 byte_order = process->GetByteOrder(); 174 return byte_order; 175 } 176 177 // Used when parsing DWARF and EH frame information and any other 178 // object file sections that contain register numbers in them. 179 uint32_t RegisterContextPOSIX_s390x::ConvertRegisterKindToRegisterNumber( 180 lldb::RegisterKind kind, uint32_t num) { 181 const uint32_t num_regs = GetRegisterCount(); 182 183 assert(kind < kNumRegisterKinds); 184 for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) { 185 const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx); 186 187 if (reg_info->kinds[kind] == num) 188 return reg_idx; 189 } 190 191 return LLDB_INVALID_REGNUM; 192 } 193