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 == 59 static_cast<uint32_t>(m_registers_count[gpr_registers_count] + 60 m_registers_count[fpr_registers_count] + 61 m_registers_count[msa_registers_count])); 62 63 // elf-core yet to support ReadFPR() 64 ProcessSP base = CalculateProcess(); 65 if (base.get()->GetPluginName() == ProcessElfCore::GetPluginNameStatic()) 66 return; 67 } 68 69 RegisterContextPOSIX_mips64::~RegisterContextPOSIX_mips64() {} 70 71 void RegisterContextPOSIX_mips64::Invalidate() {} 72 73 void RegisterContextPOSIX_mips64::InvalidateAllRegisters() {} 74 75 unsigned RegisterContextPOSIX_mips64::GetRegisterOffset(unsigned reg) { 76 assert(reg < m_num_registers && "Invalid register number."); 77 return GetRegisterInfo()[reg].byte_offset; 78 } 79 80 unsigned RegisterContextPOSIX_mips64::GetRegisterSize(unsigned reg) { 81 assert(reg < m_num_registers && "Invalid register number."); 82 return GetRegisterInfo()[reg].byte_size; 83 } 84 85 size_t RegisterContextPOSIX_mips64::GetRegisterCount() { 86 return m_register_info_ap->GetRegisterCount(); 87 } 88 89 size_t RegisterContextPOSIX_mips64::GetGPRSize() { 90 return m_register_info_ap->GetGPRSize(); 91 } 92 93 const RegisterInfo *RegisterContextPOSIX_mips64::GetRegisterInfo() { 94 // Commonly, this method is overridden and g_register_infos is copied and 95 // specialized. 96 // So, use GetRegisterInfo() rather than g_register_infos in this scope. 97 return m_register_info_ap->GetRegisterInfo(); 98 } 99 100 const RegisterInfo * 101 RegisterContextPOSIX_mips64::GetRegisterInfoAtIndex(size_t reg) { 102 if (reg < m_num_registers) 103 return &GetRegisterInfo()[reg]; 104 else 105 return NULL; 106 } 107 108 size_t RegisterContextPOSIX_mips64::GetRegisterSetCount() { 109 ArchSpec target_arch = m_register_info_ap->GetTargetArchitecture(); 110 switch (target_arch.GetTriple().getOS()) { 111 case llvm::Triple::Linux: { 112 if ((target_arch.GetMachine() == llvm::Triple::mipsel) || 113 (target_arch.GetMachine() == llvm::Triple::mips)) { 114 const auto *context = static_cast<const RegisterContextLinux_mips *> 115 (m_register_info_ap.get()); 116 return context->GetRegisterSetCount(); 117 } 118 const auto *context = static_cast<const RegisterContextLinux_mips64 *> 119 (m_register_info_ap.get()); 120 return context->GetRegisterSetCount(); 121 } 122 default: { 123 const auto *context = static_cast<const RegisterContextFreeBSD_mips64 *> 124 (m_register_info_ap.get()); 125 return context->GetRegisterSetCount(); 126 } 127 128 } 129 } 130 131 const RegisterSet *RegisterContextPOSIX_mips64::GetRegisterSet(size_t set) { 132 ArchSpec target_arch = m_register_info_ap->GetTargetArchitecture(); 133 switch (target_arch.GetTriple().getOS()) { 134 case llvm::Triple::Linux: { 135 if ((target_arch.GetMachine() == llvm::Triple::mipsel) || 136 (target_arch.GetMachine() == llvm::Triple::mips)) { 137 const auto *context = static_cast<const RegisterContextLinux_mips *> 138 (m_register_info_ap.get()); 139 return context->GetRegisterSet(set); 140 } 141 const auto *context = static_cast<const RegisterContextLinux_mips64 *> 142 (m_register_info_ap.get()); 143 return context->GetRegisterSet(set); 144 } 145 default: { 146 const auto *context = static_cast<const RegisterContextFreeBSD_mips64 *> 147 (m_register_info_ap.get()); 148 return context->GetRegisterSet(set); 149 } 150 } 151 } 152 153 const char *RegisterContextPOSIX_mips64::GetRegisterName(unsigned reg) { 154 assert(reg < m_num_registers && "Invalid register offset."); 155 return GetRegisterInfo()[reg].name; 156 } 157 158 lldb::ByteOrder RegisterContextPOSIX_mips64::GetByteOrder() { 159 // Get the target process whose privileged thread was used for the register 160 // read. 161 lldb::ByteOrder byte_order = eByteOrderInvalid; 162 Process *process = CalculateProcess().get(); 163 164 if (process) 165 byte_order = process->GetByteOrder(); 166 return byte_order; 167 } 168 169 bool RegisterContextPOSIX_mips64::IsRegisterSetAvailable(size_t set_index) { 170 size_t num_sets = GetRegisterSetCount(); 171 172 return (set_index < num_sets); 173 } 174 175 // Used when parsing DWARF and EH frame information and any other 176 // object file sections that contain register numbers in them. 177 uint32_t RegisterContextPOSIX_mips64::ConvertRegisterKindToRegisterNumber( 178 lldb::RegisterKind kind, uint32_t num) { 179 const uint32_t num_regs = m_num_registers; 180 181 assert(kind < kNumRegisterKinds); 182 for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) { 183 const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx); 184 185 if (reg_info->kinds[kind] == num) 186 return reg_idx; 187 } 188 189 return LLDB_INVALID_REGNUM; 190 } 191