1 //===-- RegisterContextPOSIX_mips64.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/RegisterValue.h" 15 #include "lldb/Core/Scalar.h" 16 #include "lldb/Target/Target.h" 17 #include "lldb/Target/Thread.h" 18 #include "lldb/Utility/DataBufferHeap.h" 19 #include "lldb/Utility/DataExtractor.h" 20 #include "lldb/Utility/Endian.h" 21 #include "llvm/Support/Compiler.h" 22 23 #include "Plugins/Process/elf-core/ProcessElfCore.h" 24 #include "RegisterContextPOSIX_mips64.h" 25 #include "RegisterContextFreeBSD_mips64.h" 26 #include "RegisterContextLinux_mips64.h" 27 #include "RegisterContextLinux_mips.h" 28 29 using namespace lldb_private; 30 using namespace lldb; 31 32 bool RegisterContextPOSIX_mips64::IsGPR(unsigned reg) { 33 return reg < m_registers_count[gpr_registers_count]; // GPR's come first. 34 } 35 36 bool RegisterContextPOSIX_mips64::IsFPR(unsigned reg) { 37 int set = GetRegisterSetCount(); 38 if (set > 1) 39 return reg < (m_registers_count[fpr_registers_count] 40 + m_registers_count[gpr_registers_count]); 41 return false; 42 } 43 44 RegisterContextPOSIX_mips64::RegisterContextPOSIX_mips64( 45 Thread &thread, uint32_t concrete_frame_idx, 46 RegisterInfoInterface *register_info) 47 : RegisterContext(thread, concrete_frame_idx) { 48 m_register_info_ap.reset(register_info); 49 m_num_registers = GetRegisterCount(); 50 int set = GetRegisterSetCount(); 51 52 const RegisterSet *reg_set_ptr; 53 for(int i = 0; i < set; ++i) { 54 reg_set_ptr = GetRegisterSet(i); 55 m_registers_count[i] = reg_set_ptr->num_registers; 56 } 57 58 assert(m_num_registers == m_registers_count[gpr_registers_count] + 59 m_registers_count[fpr_registers_count] + 60 m_registers_count[msa_registers_count]); 61 62 // elf-core yet to support ReadFPR() 63 ProcessSP base = CalculateProcess(); 64 if (base.get()->GetPluginName() == ProcessElfCore::GetPluginNameStatic()) 65 return; 66 } 67 68 RegisterContextPOSIX_mips64::~RegisterContextPOSIX_mips64() {} 69 70 void RegisterContextPOSIX_mips64::Invalidate() {} 71 72 void RegisterContextPOSIX_mips64::InvalidateAllRegisters() {} 73 74 unsigned RegisterContextPOSIX_mips64::GetRegisterOffset(unsigned reg) { 75 assert(reg < m_num_registers && "Invalid register number."); 76 return GetRegisterInfo()[reg].byte_offset; 77 } 78 79 unsigned RegisterContextPOSIX_mips64::GetRegisterSize(unsigned reg) { 80 assert(reg < m_num_registers && "Invalid register number."); 81 return GetRegisterInfo()[reg].byte_size; 82 } 83 84 size_t RegisterContextPOSIX_mips64::GetRegisterCount() { 85 return m_register_info_ap->GetRegisterCount(); 86 } 87 88 size_t RegisterContextPOSIX_mips64::GetGPRSize() { 89 return m_register_info_ap->GetGPRSize(); 90 } 91 92 const RegisterInfo *RegisterContextPOSIX_mips64::GetRegisterInfo() { 93 // Commonly, this method is overridden and g_register_infos is copied and 94 // specialized. 95 // So, use GetRegisterInfo() rather than g_register_infos in this scope. 96 return m_register_info_ap->GetRegisterInfo(); 97 } 98 99 const RegisterInfo * 100 RegisterContextPOSIX_mips64::GetRegisterInfoAtIndex(size_t reg) { 101 if (reg < m_num_registers) 102 return &GetRegisterInfo()[reg]; 103 else 104 return NULL; 105 } 106 107 size_t RegisterContextPOSIX_mips64::GetRegisterSetCount() { 108 ArchSpec target_arch = m_register_info_ap->GetTargetArchitecture(); 109 switch (target_arch.GetTriple().getOS()) { 110 case llvm::Triple::Linux: { 111 if ((target_arch.GetMachine() == llvm::Triple::mipsel) || 112 (target_arch.GetMachine() == llvm::Triple::mips)) { 113 const auto *context = static_cast<const RegisterContextLinux_mips *> 114 (m_register_info_ap.get()); 115 return context->GetRegisterSetCount(); 116 } 117 const auto *context = static_cast<const RegisterContextLinux_mips64 *> 118 (m_register_info_ap.get()); 119 return context->GetRegisterSetCount(); 120 } 121 default: { 122 const auto *context = static_cast<const RegisterContextFreeBSD_mips64 *> 123 (m_register_info_ap.get()); 124 return context->GetRegisterSetCount(); 125 } 126 127 } 128 } 129 130 const RegisterSet *RegisterContextPOSIX_mips64::GetRegisterSet(size_t set) { 131 ArchSpec target_arch = m_register_info_ap->GetTargetArchitecture(); 132 switch (target_arch.GetTriple().getOS()) { 133 case llvm::Triple::Linux: { 134 if ((target_arch.GetMachine() == llvm::Triple::mipsel) || 135 (target_arch.GetMachine() == llvm::Triple::mips)) { 136 const auto *context = static_cast<const RegisterContextLinux_mips *> 137 (m_register_info_ap.get()); 138 return context->GetRegisterSet(set); 139 } 140 const auto *context = static_cast<const RegisterContextLinux_mips64 *> 141 (m_register_info_ap.get()); 142 return context->GetRegisterSet(set); 143 } 144 default: { 145 const auto *context = static_cast<const RegisterContextFreeBSD_mips64 *> 146 (m_register_info_ap.get()); 147 return context->GetRegisterSet(set); 148 } 149 } 150 } 151 152 const char *RegisterContextPOSIX_mips64::GetRegisterName(unsigned reg) { 153 assert(reg < m_num_registers && "Invalid register offset."); 154 return GetRegisterInfo()[reg].name; 155 } 156 157 lldb::ByteOrder RegisterContextPOSIX_mips64::GetByteOrder() { 158 // Get the target process whose privileged thread was used for the register 159 // read. 160 lldb::ByteOrder byte_order = eByteOrderInvalid; 161 Process *process = CalculateProcess().get(); 162 163 if (process) 164 byte_order = process->GetByteOrder(); 165 return byte_order; 166 } 167 168 bool RegisterContextPOSIX_mips64::IsRegisterSetAvailable(size_t set_index) { 169 size_t num_sets = GetRegisterSetCount(); 170 171 return (set_index < num_sets); 172 } 173 174 // Used when parsing DWARF and EH frame information and any other 175 // object file sections that contain register numbers in them. 176 uint32_t RegisterContextPOSIX_mips64::ConvertRegisterKindToRegisterNumber( 177 lldb::RegisterKind kind, uint32_t num) { 178 const uint32_t num_regs = m_num_registers; 179 180 assert(kind < kNumRegisterKinds); 181 for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) { 182 const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx); 183 184 if (reg_info->kinds[kind] == num) 185 return reg_idx; 186 } 187 188 return LLDB_INVALID_REGNUM; 189 } 190