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