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