RegisterContextPOSIX_mips64.cpp revision 263363
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
27using namespace lldb_private;
28using namespace lldb;
29
30static const
31uint32_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.
76enum
77{
78    k_num_register_sets = 1
79};
80
81static const RegisterSet
82g_reg_sets_mips64[k_num_register_sets] =
83{
84    { "General Purpose Registers",  "gpr", k_num_gpr_registers_mips64, g_gpr_regnums },
85};
86
87bool RegisterContextPOSIX_mips64::IsGPR(unsigned reg)
88{
89    return reg <= k_num_gpr_registers_mips64;   // GPR's come first.
90}
91
92bool
93RegisterContextPOSIX_mips64::IsFPR(unsigned reg)
94{
95    // XXX
96    return false;
97}
98
99RegisterContextPOSIX_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
112RegisterContextPOSIX_mips64::~RegisterContextPOSIX_mips64()
113{
114}
115
116void
117RegisterContextPOSIX_mips64::Invalidate()
118{
119}
120
121void
122RegisterContextPOSIX_mips64::InvalidateAllRegisters()
123{
124}
125
126unsigned
127RegisterContextPOSIX_mips64::GetRegisterOffset(unsigned reg)
128{
129    assert(reg < k_num_registers_mips64 && "Invalid register number.");
130    return GetRegisterInfo()[reg].byte_offset;
131}
132
133unsigned
134RegisterContextPOSIX_mips64::GetRegisterSize(unsigned reg)
135{
136    assert(reg < k_num_registers_mips64 && "Invalid register number.");
137    return GetRegisterInfo()[reg].byte_size;
138}
139
140size_t
141RegisterContextPOSIX_mips64::GetRegisterCount()
142{
143    size_t num_registers = k_num_registers_mips64;
144    return num_registers;
145}
146
147size_t
148RegisterContextPOSIX_mips64::GetGPRSize()
149{
150    return m_register_info_ap->GetGPRSize();
151}
152
153const RegisterInfo *
154RegisterContextPOSIX_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
161const RegisterInfo *
162RegisterContextPOSIX_mips64::GetRegisterInfoAtIndex(size_t reg)
163{
164    if (reg < k_num_registers_mips64)
165        return &GetRegisterInfo()[reg];
166    else
167        return NULL;
168}
169
170size_t
171RegisterContextPOSIX_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
183const RegisterSet *
184RegisterContextPOSIX_mips64::GetRegisterSet(size_t set)
185{
186    if (IsRegisterSetAvailable(set))
187        return &g_reg_sets_mips64[set];
188    else
189        return NULL;
190}
191
192const char *
193RegisterContextPOSIX_mips64::GetRegisterName(unsigned reg)
194{
195    assert(reg < k_num_registers_mips64 && "Invalid register offset.");
196    return GetRegisterInfo()[reg].name;
197}
198
199lldb::ByteOrder
200RegisterContextPOSIX_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
211bool
212RegisterContextPOSIX_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.
221uint32_t
222RegisterContextPOSIX_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