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/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_mips64.h"
24 #include "Plugins/Process/elf-core/ProcessElfCore.h"
25
26 using namespace lldb_private;
27 using namespace lldb;
28
29 static const
30 uint32_t g_gpr_regnums[] =
31 {
32 gpr_zero_mips64,
33 gpr_r1_mips64,
34 gpr_r2_mips64,
35 gpr_r3_mips64,
36 gpr_r4_mips64,
37 gpr_r5_mips64,
38 gpr_r6_mips64,
39 gpr_r7_mips64,
40 gpr_r8_mips64,
41 gpr_r9_mips64,
42 gpr_r10_mips64,
43 gpr_r11_mips64,
44 gpr_r12_mips64,
45 gpr_r13_mips64,
46 gpr_r14_mips64,
47 gpr_r15_mips64,
48 gpr_r16_mips64,
49 gpr_r17_mips64,
50 gpr_r18_mips64,
51 gpr_r19_mips64,
52 gpr_r20_mips64,
53 gpr_r21_mips64,
54 gpr_r22_mips64,
55 gpr_r23_mips64,
56 gpr_r24_mips64,
57 gpr_r25_mips64,
58 gpr_r26_mips64,
59 gpr_r27_mips64,
60 gpr_gp_mips64,
61 gpr_sp_mips64,
62 gpr_r30_mips64,
63 gpr_ra_mips64,
64 gpr_sr_mips64,
65 gpr_mullo_mips64,
66 gpr_mulhi_mips64,
67 gpr_badvaddr_mips64,
68 gpr_cause_mips64,
69 gpr_pc_mips64,
70 gpr_ic_mips64,
71 gpr_dummy_mips64
72 };
73
74 // Number of register sets provided by this context.
75 enum
76 {
77 k_num_register_sets = 1
78 };
79
80 static const RegisterSet
81 g_reg_sets_mips64[k_num_register_sets] =
82 {
83 { "General Purpose Registers", "gpr", k_num_gpr_registers_mips64, g_gpr_regnums },
84 };
85
IsGPR(unsigned reg)86 bool RegisterContextPOSIX_mips64::IsGPR(unsigned reg)
87 {
88 return reg <= k_num_gpr_registers_mips64; // GPR's come first.
89 }
90
91 bool
IsFPR(unsigned reg)92 RegisterContextPOSIX_mips64::IsFPR(unsigned reg)
93 {
94 // XXX
95 return false;
96 }
97
RegisterContextPOSIX_mips64(Thread & thread,uint32_t concrete_frame_idx,RegisterInfoInterface * register_info)98 RegisterContextPOSIX_mips64::RegisterContextPOSIX_mips64(Thread &thread,
99 uint32_t concrete_frame_idx,
100 RegisterInfoInterface *register_info)
101 : RegisterContext(thread, concrete_frame_idx)
102 {
103 m_register_info_ap.reset(register_info);
104
105 // elf-core yet to support ReadFPR()
106 ProcessSP base = CalculateProcess();
107 if (base.get()->GetPluginName() == ProcessElfCore::GetPluginNameStatic())
108 return;
109 }
110
~RegisterContextPOSIX_mips64()111 RegisterContextPOSIX_mips64::~RegisterContextPOSIX_mips64()
112 {
113 }
114
115 void
Invalidate()116 RegisterContextPOSIX_mips64::Invalidate()
117 {
118 }
119
120 void
InvalidateAllRegisters()121 RegisterContextPOSIX_mips64::InvalidateAllRegisters()
122 {
123 }
124
125 unsigned
GetRegisterOffset(unsigned reg)126 RegisterContextPOSIX_mips64::GetRegisterOffset(unsigned reg)
127 {
128 assert(reg < k_num_registers_mips64 && "Invalid register number.");
129 return GetRegisterInfo()[reg].byte_offset;
130 }
131
132 unsigned
GetRegisterSize(unsigned reg)133 RegisterContextPOSIX_mips64::GetRegisterSize(unsigned reg)
134 {
135 assert(reg < k_num_registers_mips64 && "Invalid register number.");
136 return GetRegisterInfo()[reg].byte_size;
137 }
138
139 size_t
GetRegisterCount()140 RegisterContextPOSIX_mips64::GetRegisterCount()
141 {
142 size_t num_registers = k_num_registers_mips64;
143 return num_registers;
144 }
145
146 size_t
GetGPRSize()147 RegisterContextPOSIX_mips64::GetGPRSize()
148 {
149 return m_register_info_ap->GetGPRSize();
150 }
151
152 const RegisterInfo *
GetRegisterInfo()153 RegisterContextPOSIX_mips64::GetRegisterInfo()
154 {
155 // Commonly, this method is overridden and g_register_infos is copied and specialized.
156 // So, use GetRegisterInfo() rather than g_register_infos in this scope.
157 return m_register_info_ap->GetRegisterInfo ();
158 }
159
160 const RegisterInfo *
GetRegisterInfoAtIndex(size_t reg)161 RegisterContextPOSIX_mips64::GetRegisterInfoAtIndex(size_t reg)
162 {
163 if (reg < k_num_registers_mips64)
164 return &GetRegisterInfo()[reg];
165 else
166 return NULL;
167 }
168
169 size_t
GetRegisterSetCount()170 RegisterContextPOSIX_mips64::GetRegisterSetCount()
171 {
172 size_t sets = 0;
173 for (size_t set = 0; set < k_num_register_sets; ++set)
174 {
175 if (IsRegisterSetAvailable(set))
176 ++sets;
177 }
178
179 return sets;
180 }
181
182 const RegisterSet *
GetRegisterSet(size_t set)183 RegisterContextPOSIX_mips64::GetRegisterSet(size_t set)
184 {
185 if (IsRegisterSetAvailable(set))
186 return &g_reg_sets_mips64[set];
187 else
188 return NULL;
189 }
190
191 const char *
GetRegisterName(unsigned reg)192 RegisterContextPOSIX_mips64::GetRegisterName(unsigned reg)
193 {
194 assert(reg < k_num_registers_mips64 && "Invalid register offset.");
195 return GetRegisterInfo()[reg].name;
196 }
197
198 lldb::ByteOrder
GetByteOrder()199 RegisterContextPOSIX_mips64::GetByteOrder()
200 {
201 // Get the target process whose privileged thread was used for the register read.
202 lldb::ByteOrder byte_order = eByteOrderInvalid;
203 Process *process = CalculateProcess().get();
204
205 if (process)
206 byte_order = process->GetByteOrder();
207 return byte_order;
208 }
209
210 bool
IsRegisterSetAvailable(size_t set_index)211 RegisterContextPOSIX_mips64::IsRegisterSetAvailable(size_t set_index)
212 {
213 size_t num_sets = k_num_register_sets;
214
215 return (set_index < num_sets);
216 }
217
218 // Used when parsing DWARF and EH frame information and any other
219 // object file sections that contain register numbers in them.
220 uint32_t
ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,uint32_t num)221 RegisterContextPOSIX_mips64::ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
222 uint32_t num)
223 {
224 const uint32_t num_regs = GetRegisterCount();
225
226 assert (kind < kNumRegisterKinds);
227 for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx)
228 {
229 const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg_idx);
230
231 if (reg_info->kinds[kind] == num)
232 return reg_idx;
233 }
234
235 return LLDB_INVALID_REGNUM;
236 }
237
238