RegisterContextPOSIX_powerpc.cpp revision 280031
1110386Sbenno//===-- RegisterContextPOSIX_powerpc.cpp -------------------------*- C++ -*-===//
2110386Sbenno//
3110386Sbenno//                     The LLVM Compiler Infrastructure
4110386Sbenno//
5110386Sbenno// This file is distributed under the University of Illinois Open Source
6110386Sbenno// License. See LICENSE.TXT for details.
7110386Sbenno//
8110386Sbenno//===----------------------------------------------------------------------===//
9110386Sbenno
10110386Sbenno#include <cstring>
11110386Sbenno#include <errno.h>
12110386Sbenno#include <stdint.h>
13110386Sbenno
14110386Sbenno#include "lldb/Core/DataBufferHeap.h"
15110386Sbenno#include "lldb/Core/DataExtractor.h"
16110386Sbenno#include "lldb/Core/RegisterValue.h"
17110386Sbenno#include "lldb/Core/Scalar.h"
18110386Sbenno#include "lldb/Target/Target.h"
19110386Sbenno#include "lldb/Target/Thread.h"
20110386Sbenno#include "lldb/Host/Endian.h"
21110386Sbenno#include "llvm/Support/Compiler.h"
22110386Sbenno
23110386Sbenno#include "RegisterContextPOSIX_powerpc.h"
24110386Sbenno#include "Plugins/Process/elf-core/ProcessElfCore.h"
25110386Sbenno
26110386Sbennousing namespace lldb_private;
27110386Sbennousing namespace lldb;
28110386Sbenno
29110386Sbennostatic const
30110386Sbennouint32_t g_gpr_regnums[] =
31110386Sbenno{
32110386Sbenno    gpr_r0_powerpc,
33110386Sbenno    gpr_r1_powerpc,
34110386Sbenno    gpr_r2_powerpc,
35110386Sbenno    gpr_r3_powerpc,
36110386Sbenno    gpr_r4_powerpc,
37110386Sbenno    gpr_r5_powerpc,
38110386Sbenno    gpr_r6_powerpc,
39110386Sbenno    gpr_r7_powerpc,
40110386Sbenno    gpr_r8_powerpc,
41110386Sbenno    gpr_r9_powerpc,
42110386Sbenno    gpr_r10_powerpc,
43110386Sbenno    gpr_r11_powerpc,
44110386Sbenno    gpr_r12_powerpc,
45110386Sbenno    gpr_r13_powerpc,
46110386Sbenno    gpr_r14_powerpc,
47110386Sbenno    gpr_r15_powerpc,
48110386Sbenno    gpr_r16_powerpc,
49110386Sbenno    gpr_r17_powerpc,
50110386Sbenno    gpr_r18_powerpc,
51110386Sbenno    gpr_r19_powerpc,
52110386Sbenno    gpr_r20_powerpc,
53110386Sbenno    gpr_r21_powerpc,
54110386Sbenno    gpr_r22_powerpc,
55110386Sbenno    gpr_r23_powerpc,
56110386Sbenno    gpr_r24_powerpc,
57110386Sbenno    gpr_r25_powerpc,
58110386Sbenno    gpr_r26_powerpc,
59110386Sbenno    gpr_r27_powerpc,
60110386Sbenno    gpr_r28_powerpc,
61110386Sbenno    gpr_r29_powerpc,
62110386Sbenno    gpr_r30_powerpc,
63110386Sbenno    gpr_r31_powerpc,
64110386Sbenno    gpr_lr_powerpc,
65110386Sbenno    gpr_cr_powerpc,
66110386Sbenno    gpr_xer_powerpc,
67110386Sbenno    gpr_ctr_powerpc,
68110386Sbenno    gpr_pc_powerpc,
69110386Sbenno};
70110386Sbenno
71110386Sbennostatic const
72110386Sbennouint32_t g_fpr_regnums[] =
73110386Sbenno{
74110386Sbenno    fpr_f0_powerpc,
75110386Sbenno    fpr_f1_powerpc,
76110386Sbenno    fpr_f2_powerpc,
77110386Sbenno    fpr_f3_powerpc,
78110386Sbenno    fpr_f4_powerpc,
79110386Sbenno    fpr_f5_powerpc,
80110386Sbenno    fpr_f6_powerpc,
81110386Sbenno    fpr_f7_powerpc,
82110386Sbenno    fpr_f8_powerpc,
83110386Sbenno    fpr_f9_powerpc,
84110386Sbenno    fpr_f10_powerpc,
85110386Sbenno    fpr_f11_powerpc,
86110386Sbenno    fpr_f12_powerpc,
87110386Sbenno    fpr_f13_powerpc,
88110386Sbenno    fpr_f14_powerpc,
89110386Sbenno    fpr_f15_powerpc,
90110386Sbenno    fpr_f16_powerpc,
91110386Sbenno    fpr_f17_powerpc,
92110386Sbenno    fpr_f18_powerpc,
93110386Sbenno    fpr_f19_powerpc,
94110386Sbenno    fpr_f20_powerpc,
95125615Sgrehan    fpr_f21_powerpc,
96110386Sbenno    fpr_f22_powerpc,
97110386Sbenno    fpr_f23_powerpc,
98110386Sbenno    fpr_f24_powerpc,
99110386Sbenno    fpr_f25_powerpc,
100110386Sbenno    fpr_f26_powerpc,
101110386Sbenno    fpr_f27_powerpc,
102110386Sbenno    fpr_f28_powerpc,
103110386Sbenno    fpr_f29_powerpc,
104110386Sbenno    fpr_f30_powerpc,
105110386Sbenno    fpr_f31_powerpc,
106110386Sbenno    fpr_fpscr_powerpc,
107110386Sbenno};
108110386Sbenno
109110386Sbenno// Number of register sets provided by this context.
110110386Sbennoenum
111110386Sbenno{
112110386Sbenno    k_num_register_sets = 2
113110386Sbenno};
114110386Sbenno
115110386Sbennostatic const RegisterSet
116110386Sbennog_reg_sets_powerpc[k_num_register_sets] =
117110386Sbenno{
118110386Sbenno    { "General Purpose Registers",  "gpr", k_num_gpr_registers_powerpc, g_gpr_regnums },
119110386Sbenno    { "Floating Point Registers",  "fpr", k_num_fpr_registers_powerpc, g_fpr_regnums },
120110386Sbenno};
121110386Sbenno
122110386Sbennobool RegisterContextPOSIX_powerpc::IsGPR(unsigned reg)
123110386Sbenno{
124110386Sbenno    return reg <= k_num_gpr_registers_powerpc;   // GPR's come first.
125110386Sbenno}
126110386Sbenno
127110386Sbennobool
128110386SbennoRegisterContextPOSIX_powerpc::IsFPR(unsigned reg)
129110386Sbenno{
130110386Sbenno    // XXX
131110386Sbenno    return (reg >= k_first_fpr) && (reg <= k_last_fpr);
132110386Sbenno}
133110386Sbenno
134110386SbennoRegisterContextPOSIX_powerpc::RegisterContextPOSIX_powerpc(Thread &thread,
135110386Sbenno                                               uint32_t concrete_frame_idx,
136110386Sbenno                                               RegisterInfoInterface *register_info)
137110386Sbenno    : RegisterContext(thread, concrete_frame_idx)
138110386Sbenno{
139110386Sbenno    m_register_info_ap.reset(register_info);
140110386Sbenno
141110386Sbenno    // elf-core yet to support ReadFPR()
142110386Sbenno    ProcessSP base = CalculateProcess();
143110386Sbenno    if (base.get()->GetPluginName() ==  ProcessElfCore::GetPluginNameStatic())
144110386Sbenno        return;
145110386Sbenno}
146110386Sbenno
147110386SbennoRegisterContextPOSIX_powerpc::~RegisterContextPOSIX_powerpc()
148110386Sbenno{
149110386Sbenno}
150110386Sbenno
151110386Sbennovoid
152110386SbennoRegisterContextPOSIX_powerpc::Invalidate()
153110386Sbenno{
154110386Sbenno}
155110386Sbenno
156110386Sbennovoid
157110386SbennoRegisterContextPOSIX_powerpc::InvalidateAllRegisters()
158110386Sbenno{
159110386Sbenno}
160110386Sbenno
161110386Sbennounsigned
162110386SbennoRegisterContextPOSIX_powerpc::GetRegisterOffset(unsigned reg)
163110386Sbenno{
164110386Sbenno    assert(reg < k_num_registers_powerpc && "Invalid register number.");
165110386Sbenno    return GetRegisterInfo()[reg].byte_offset;
166110386Sbenno}
167110386Sbenno
168110386Sbennounsigned
169110386SbennoRegisterContextPOSIX_powerpc::GetRegisterSize(unsigned reg)
170110386Sbenno{
171110386Sbenno    assert(reg < k_num_registers_powerpc && "Invalid register number.");
172110386Sbenno    return GetRegisterInfo()[reg].byte_size;
173110386Sbenno}
174110386Sbenno
175110386Sbennosize_t
176110386SbennoRegisterContextPOSIX_powerpc::GetRegisterCount()
177125615Sgrehan{
178110386Sbenno    size_t num_registers = k_num_registers_powerpc;
179110386Sbenno    return num_registers;
180110386Sbenno}
181110386Sbenno
182110386Sbennosize_t
183110386SbennoRegisterContextPOSIX_powerpc::GetGPRSize()
184110386Sbenno{
185110386Sbenno    return m_register_info_ap->GetGPRSize();
186110386Sbenno}
187110386Sbenno
188110386Sbennoconst RegisterInfo *
189110386SbennoRegisterContextPOSIX_powerpc::GetRegisterInfo()
190110386Sbenno{
191110386Sbenno    // Commonly, this method is overridden and g_register_infos is copied and specialized.
192110386Sbenno    // So, use GetRegisterInfo() rather than g_register_infos in this scope.
193110386Sbenno    return m_register_info_ap->GetRegisterInfo ();
194110386Sbenno}
195110386Sbenno
196110386Sbennoconst RegisterInfo *
197110386SbennoRegisterContextPOSIX_powerpc::GetRegisterInfoAtIndex(size_t reg)
198110386Sbenno{
199110386Sbenno    if (reg < k_num_registers_powerpc)
200110386Sbenno        return &GetRegisterInfo()[reg];
201110386Sbenno    else
202110386Sbenno        return NULL;
203110386Sbenno}
204110386Sbenno
205110386Sbennosize_t
206110386SbennoRegisterContextPOSIX_powerpc::GetRegisterSetCount()
207110386Sbenno{
208110386Sbenno    size_t sets = 0;
209110386Sbenno    for (size_t set = 0; set < k_num_register_sets; ++set)
210110386Sbenno    {
211110386Sbenno        if (IsRegisterSetAvailable(set))
212110386Sbenno            ++sets;
213110386Sbenno    }
214110386Sbenno
215125615Sgrehan    return sets;
216110386Sbenno}
217110386Sbenno
218110386Sbennoconst RegisterSet *
219110386SbennoRegisterContextPOSIX_powerpc::GetRegisterSet(size_t set)
220110386Sbenno{
221110386Sbenno    if (IsRegisterSetAvailable(set))
222110386Sbenno        return &g_reg_sets_powerpc[set];
223110386Sbenno    else
224110386Sbenno        return NULL;
225110386Sbenno}
226110386Sbenno
227110386Sbennoconst char *
228110386SbennoRegisterContextPOSIX_powerpc::GetRegisterName(unsigned reg)
229110386Sbenno{
230125615Sgrehan    assert(reg < k_num_registers_powerpc && "Invalid register offset.");
231110386Sbenno    return GetRegisterInfo()[reg].name;
232110386Sbenno}
233110386Sbenno
234110386Sbennolldb::ByteOrder
235110386SbennoRegisterContextPOSIX_powerpc::GetByteOrder()
236110386Sbenno{
237110386Sbenno    // Get the target process whose privileged thread was used for the register read.
238110386Sbenno    lldb::ByteOrder byte_order = eByteOrderInvalid;
239110386Sbenno    Process *process = CalculateProcess().get();
240110386Sbenno
241110386Sbenno    if (process)
242110386Sbenno        byte_order = process->GetByteOrder();
243110386Sbenno    return byte_order;
244110386Sbenno}
245110386Sbenno
246110386Sbennobool
247110386SbennoRegisterContextPOSIX_powerpc::IsRegisterSetAvailable(size_t set_index)
248110386Sbenno{
249110386Sbenno    size_t num_sets = k_num_register_sets;
250110386Sbenno
251110386Sbenno    return (set_index < num_sets);
252120460Sgrehan}
253110386Sbenno
254110386Sbenno// Used when parsing DWARF and EH frame information and any other
255110386Sbenno// object file sections that contain register numbers in them.
256110386Sbennouint32_t
257110386SbennoRegisterContextPOSIX_powerpc::ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
258110386Sbenno                                                                 uint32_t num)
259110386Sbenno{
260110386Sbenno    const uint32_t num_regs = GetRegisterCount();
261110386Sbenno
262110386Sbenno    assert (kind < kNumRegisterKinds);
263110386Sbenno    for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx)
264110386Sbenno    {
265110386Sbenno        const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg_idx);
266110386Sbenno
267110386Sbenno        if (reg_info->kinds[kind] == num)
268110386Sbenno            return reg_idx;
269110386Sbenno    }
270110386Sbenno
271110386Sbenno    return LLDB_INVALID_REGNUM;
272110386Sbenno}
273110386Sbenno
274110386Sbenno