1 //===-- RegisterContextPOSIX_arm.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_arm.h"
24 #include "Plugins/Process/elf-core/ProcessElfCore.h"
25 
26 using namespace lldb;
27 using namespace lldb_private;
28 
29 // arm general purpose registers.
30 const uint32_t g_gpr_regnums_arm[] =
31 {
32     gpr_r0_arm,
33     gpr_r1_arm,
34     gpr_r2_arm,
35     gpr_r3_arm,
36     gpr_r4_arm,
37     gpr_r5_arm,
38     gpr_r6_arm,
39     gpr_r7_arm,
40     gpr_r8_arm,
41     gpr_r9_arm,
42     gpr_r10_arm,
43     gpr_r11_arm,
44     gpr_r12_arm,
45     gpr_sp_arm,
46     gpr_lr_arm,
47     gpr_pc_arm,
48     gpr_cpsr_arm,
49     LLDB_INVALID_REGNUM // register sets need to end with this flag
50 
51 };
52 static_assert(((sizeof g_gpr_regnums_arm / sizeof g_gpr_regnums_arm[0]) - 1) == k_num_gpr_registers_arm, \
53               "g_gpr_regnums_arm has wrong number of register infos");
54 
55 // arm floating point registers.
56 static const uint32_t g_fpu_regnums_arm[] =
57 {
58     fpu_s0_arm,
59     fpu_s1_arm,
60     fpu_s2_arm,
61     fpu_s3_arm,
62     fpu_s4_arm,
63     fpu_s5_arm,
64     fpu_s6_arm,
65     fpu_s7_arm,
66     fpu_s8_arm,
67     fpu_s9_arm,
68     fpu_s10_arm,
69     fpu_s11_arm,
70     fpu_s12_arm,
71     fpu_s13_arm,
72     fpu_s14_arm,
73     fpu_s15_arm,
74     fpu_s16_arm,
75     fpu_s17_arm,
76     fpu_s18_arm,
77     fpu_s19_arm,
78     fpu_s20_arm,
79     fpu_s21_arm,
80     fpu_s22_arm,
81     fpu_s23_arm,
82     fpu_s24_arm,
83     fpu_s25_arm,
84     fpu_s26_arm,
85     fpu_s27_arm,
86     fpu_s28_arm,
87     fpu_s29_arm,
88     fpu_s30_arm,
89     fpu_s31_arm,
90     fpu_fpscr_arm,
91     LLDB_INVALID_REGNUM // register sets need to end with this flag
92 
93 };
94 static_assert(((sizeof g_fpu_regnums_arm / sizeof g_fpu_regnums_arm[0]) - 1) == k_num_fpr_registers_arm, \
95               "g_fpu_regnums_arm has wrong number of register infos");
96 
97 // Number of register sets provided by this context.
98 enum
99 {
100     k_num_register_sets = 2
101 };
102 
103 // Register sets for arm.
104 static const lldb_private::RegisterSet
105 g_reg_sets_arm[k_num_register_sets] =
106 {
107     { "General Purpose Registers",  "gpr", k_num_gpr_registers_arm, g_gpr_regnums_arm },
108     { "Floating Point Registers",   "fpu", k_num_fpr_registers_arm, g_fpu_regnums_arm }
109 };
110 
111 bool RegisterContextPOSIX_arm::IsGPR(unsigned reg)
112 {
113     return reg <= m_reg_info.last_gpr;   // GPR's come first.
114 }
115 
116 bool RegisterContextPOSIX_arm::IsFPR(unsigned reg)
117 {
118     return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
119 }
120 
121 RegisterContextPOSIX_arm::RegisterContextPOSIX_arm(lldb_private::Thread &thread,
122                                                        uint32_t concrete_frame_idx,
123                                                        lldb_private::RegisterInfoInterface *register_info)
124     : lldb_private::RegisterContext(thread, concrete_frame_idx)
125 {
126     m_register_info_ap.reset(register_info);
127 
128     switch (register_info->m_target_arch.GetMachine())
129     {
130         case llvm::Triple::arm:
131             m_reg_info.num_registers     = k_num_registers_arm;
132             m_reg_info.num_gpr_registers = k_num_gpr_registers_arm;
133             m_reg_info.num_fpr_registers = k_num_fpr_registers_arm;
134             m_reg_info.last_gpr          = k_last_gpr_arm;
135             m_reg_info.first_fpr         = k_first_fpr_arm;
136             m_reg_info.last_fpr          = k_last_fpr_arm;
137             m_reg_info.first_fpr_v       = fpu_s0_arm;
138             m_reg_info.last_fpr_v        = fpu_s31_arm;
139             m_reg_info.gpr_flags         = gpr_cpsr_arm;
140             break;
141         default:
142             assert(false && "Unhandled target architecture.");
143             break;
144     }
145 
146     ::memset(&m_fpr, 0, sizeof m_fpr);
147 
148     // elf-core yet to support ReadFPR()
149     lldb::ProcessSP base = CalculateProcess();
150     if (base.get()->GetPluginName() ==  ProcessElfCore::GetPluginNameStatic())
151         return;
152 }
153 
154 RegisterContextPOSIX_arm::~RegisterContextPOSIX_arm()
155 {
156 }
157 
158 void
159 RegisterContextPOSIX_arm::Invalidate()
160 {
161 }
162 
163 void
164 RegisterContextPOSIX_arm::InvalidateAllRegisters()
165 {
166 }
167 
168 unsigned
169 RegisterContextPOSIX_arm::GetRegisterOffset(unsigned reg)
170 {
171     assert(reg < m_reg_info.num_registers && "Invalid register number.");
172     return GetRegisterInfo()[reg].byte_offset;
173 }
174 
175 unsigned
176 RegisterContextPOSIX_arm::GetRegisterSize(unsigned reg)
177 {
178     assert(reg < m_reg_info.num_registers && "Invalid register number.");
179     return GetRegisterInfo()[reg].byte_size;
180 }
181 
182 size_t
183 RegisterContextPOSIX_arm::GetRegisterCount()
184 {
185     size_t num_registers = m_reg_info.num_gpr_registers + m_reg_info.num_fpr_registers;
186     return num_registers;
187 }
188 
189 size_t
190 RegisterContextPOSIX_arm::GetGPRSize()
191 {
192     return m_register_info_ap->GetGPRSize ();
193 }
194 
195 const lldb_private::RegisterInfo *
196 RegisterContextPOSIX_arm::GetRegisterInfo()
197 {
198     // Commonly, this method is overridden and g_register_infos is copied and specialized.
199     // So, use GetRegisterInfo() rather than g_register_infos in this scope.
200     return m_register_info_ap->GetRegisterInfo ();
201 }
202 
203 const lldb_private::RegisterInfo *
204 RegisterContextPOSIX_arm::GetRegisterInfoAtIndex(size_t reg)
205 {
206     if (reg < m_reg_info.num_registers)
207         return &GetRegisterInfo()[reg];
208     else
209         return NULL;
210 }
211 
212 size_t
213 RegisterContextPOSIX_arm::GetRegisterSetCount()
214 {
215     size_t sets = 0;
216     for (size_t set = 0; set < k_num_register_sets; ++set)
217     {
218         if (IsRegisterSetAvailable(set))
219             ++sets;
220     }
221 
222     return sets;
223 }
224 
225 const lldb_private::RegisterSet *
226 RegisterContextPOSIX_arm::GetRegisterSet(size_t set)
227 {
228     if (IsRegisterSetAvailable(set))
229     {
230         switch (m_register_info_ap->m_target_arch.GetMachine())
231         {
232             case llvm::Triple::arm:
233                 return &g_reg_sets_arm[set];
234             default:
235                 assert(false && "Unhandled target architecture.");
236                 return NULL;
237         }
238     }
239     return NULL;
240 }
241 
242 const char *
243 RegisterContextPOSIX_arm::GetRegisterName(unsigned reg)
244 {
245     assert(reg < m_reg_info.num_registers && "Invalid register offset.");
246     return GetRegisterInfo()[reg].name;
247 }
248 
249 lldb::ByteOrder
250 RegisterContextPOSIX_arm::GetByteOrder()
251 {
252     // Get the target process whose privileged thread was used for the register read.
253     lldb::ByteOrder byte_order = lldb::eByteOrderInvalid;
254     lldb_private::Process *process = CalculateProcess().get();
255 
256     if (process)
257         byte_order = process->GetByteOrder();
258     return byte_order;
259 }
260 
261 bool
262 RegisterContextPOSIX_arm::IsRegisterSetAvailable(size_t set_index)
263 {
264     return set_index < k_num_register_sets;
265 }
266 
267 
268 // Used when parsing DWARF and EH frame information and any other
269 // object file sections that contain register numbers in them.
270 uint32_t
271 RegisterContextPOSIX_arm::ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
272                                                                 uint32_t num)
273 {
274     const uint32_t num_regs = GetRegisterCount();
275 
276     assert (kind < lldb::kNumRegisterKinds);
277     for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx)
278     {
279         const lldb_private::RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg_idx);
280 
281         if (reg_info->kinds[kind] == num)
282             return reg_idx;
283     }
284 
285     return LLDB_INVALID_REGNUM;
286 }
287 
288