forked from OSchip/llvm-project
Implement initial Altivec support
Summary: This adds the register plumbing, as well as register reading in FreeBSD core dumps. Further work on the POSIX/FreeBSD ProcessMonitor is required in order to support ptrace access to these registers. Reviewers: tfiala, emaste Reviewed By: emaste Subscribers: emaste, lldb-commits Differential Revision: http://reviews.llvm.org/D7039 llvm-svn: 228278
This commit is contained in:
parent
b07ee8ded9
commit
f9ec0d1ea5
|
@ -685,9 +685,7 @@ ABISysV_ppc::GetReturnValueObjectSimple (Thread &thread,
|
||||||
if (byte_size > 0)
|
if (byte_size > 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
const RegisterInfo *altivec_reg = reg_ctx->GetRegisterInfoByName("v0", 0);
|
const RegisterInfo *altivec_reg = reg_ctx->GetRegisterInfoByName("v2", 0);
|
||||||
if (altivec_reg == NULL)
|
|
||||||
altivec_reg = reg_ctx->GetRegisterInfoByName("mm0", 0);
|
|
||||||
if (altivec_reg)
|
if (altivec_reg)
|
||||||
{
|
{
|
||||||
if (byte_size <= altivec_reg->byte_size)
|
if (byte_size <= altivec_reg->byte_size)
|
||||||
|
|
|
@ -685,9 +685,7 @@ ABISysV_ppc64::GetReturnValueObjectSimple (Thread &thread,
|
||||||
if (byte_size > 0)
|
if (byte_size > 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
const RegisterInfo *altivec_reg = reg_ctx->GetRegisterInfoByName("v0", 0);
|
const RegisterInfo *altivec_reg = reg_ctx->GetRegisterInfoByName("v2", 0);
|
||||||
if (altivec_reg == NULL)
|
|
||||||
altivec_reg = reg_ctx->GetRegisterInfoByName("mm0", 0);
|
|
||||||
if (altivec_reg)
|
if (altivec_reg)
|
||||||
{
|
{
|
||||||
if (byte_size <= altivec_reg->byte_size)
|
if (byte_size <= altivec_reg->byte_size)
|
||||||
|
|
|
@ -49,6 +49,13 @@ RegisterContextPOSIXProcessMonitor_powerpc::ReadFPR()
|
||||||
return monitor.ReadFPR(m_thread.GetID(), &m_fpr_powerpc, sizeof(m_fpr_powerpc));
|
return monitor.ReadFPR(m_thread.GetID(), &m_fpr_powerpc, sizeof(m_fpr_powerpc));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
RegisterContextPOSIXProcessMonitor_powerpc::ReadVMX()
|
||||||
|
{
|
||||||
|
// XXX: Need a way to read/write process VMX registers with ptrace.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
RegisterContextPOSIXProcessMonitor_powerpc::WriteGPR()
|
RegisterContextPOSIXProcessMonitor_powerpc::WriteGPR()
|
||||||
{
|
{
|
||||||
|
@ -63,6 +70,13 @@ RegisterContextPOSIXProcessMonitor_powerpc::WriteFPR()
|
||||||
return monitor.WriteFPR(m_thread.GetID(), &m_fpr_powerpc, sizeof(m_fpr_powerpc));
|
return monitor.WriteFPR(m_thread.GetID(), &m_fpr_powerpc, sizeof(m_fpr_powerpc));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
RegisterContextPOSIXProcessMonitor_powerpc::WriteVMX()
|
||||||
|
{
|
||||||
|
// XXX: Need a way to read/write process VMX registers with ptrace.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
RegisterContextPOSIXProcessMonitor_powerpc::ReadRegister(const unsigned reg,
|
RegisterContextPOSIXProcessMonitor_powerpc::ReadRegister(const unsigned reg,
|
||||||
RegisterValue &value)
|
RegisterValue &value)
|
||||||
|
|
|
@ -22,18 +22,27 @@ public:
|
||||||
lldb_private::RegisterInfoInterface *register_info);
|
lldb_private::RegisterInfoInterface *register_info);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
bool
|
||||||
|
IsVMX();
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ReadGPR();
|
ReadGPR();
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ReadFPR();
|
ReadFPR();
|
||||||
|
|
||||||
|
bool
|
||||||
|
ReadVMX();
|
||||||
|
|
||||||
bool
|
bool
|
||||||
WriteGPR();
|
WriteGPR();
|
||||||
|
|
||||||
bool
|
bool
|
||||||
WriteFPR();
|
WriteFPR();
|
||||||
|
|
||||||
|
bool
|
||||||
|
WriteVMX();
|
||||||
|
|
||||||
// lldb_private::RegisterContext
|
// lldb_private::RegisterContext
|
||||||
bool
|
bool
|
||||||
ReadRegister(const unsigned reg, lldb_private::RegisterValue &value);
|
ReadRegister(const unsigned reg, lldb_private::RegisterValue &value);
|
||||||
|
|
|
@ -134,6 +134,45 @@ typedef struct _FPR
|
||||||
uint64_t fpscr;
|
uint64_t fpscr;
|
||||||
} FPR;
|
} FPR;
|
||||||
|
|
||||||
|
typedef struct _VMX
|
||||||
|
{
|
||||||
|
uint32_t v0[4];
|
||||||
|
uint32_t v1[4];
|
||||||
|
uint32_t v2[4];
|
||||||
|
uint32_t v3[4];
|
||||||
|
uint32_t v4[4];
|
||||||
|
uint32_t v5[4];
|
||||||
|
uint32_t v6[4];
|
||||||
|
uint32_t v7[4];
|
||||||
|
uint32_t v8[4];
|
||||||
|
uint32_t v9[4];
|
||||||
|
uint32_t v10[4];
|
||||||
|
uint32_t v11[4];
|
||||||
|
uint32_t v12[4];
|
||||||
|
uint32_t v13[4];
|
||||||
|
uint32_t v14[4];
|
||||||
|
uint32_t v15[4];
|
||||||
|
uint32_t v16[4];
|
||||||
|
uint32_t v17[4];
|
||||||
|
uint32_t v18[4];
|
||||||
|
uint32_t v19[4];
|
||||||
|
uint32_t v20[4];
|
||||||
|
uint32_t v21[4];
|
||||||
|
uint32_t v22[4];
|
||||||
|
uint32_t v23[4];
|
||||||
|
uint32_t v24[4];
|
||||||
|
uint32_t v25[4];
|
||||||
|
uint32_t v26[4];
|
||||||
|
uint32_t v27[4];
|
||||||
|
uint32_t v28[4];
|
||||||
|
uint32_t v29[4];
|
||||||
|
uint32_t v30[4];
|
||||||
|
uint32_t v31[4];
|
||||||
|
uint32_t pad[2];
|
||||||
|
uint32_t vrsave;
|
||||||
|
uint32_t vscr;
|
||||||
|
} VMX;
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
// Include RegisterInfos_powerpc to declare our g_register_infos_powerpc structure.
|
// Include RegisterInfos_powerpc to declare our g_register_infos_powerpc structure.
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
|
@ -106,10 +106,49 @@ uint32_t g_fpr_regnums[] =
|
||||||
fpr_fpscr_powerpc,
|
fpr_fpscr_powerpc,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const
|
||||||
|
uint32_t g_vmx_regnums[] =
|
||||||
|
{
|
||||||
|
vmx_v0_powerpc,
|
||||||
|
vmx_v1_powerpc,
|
||||||
|
vmx_v2_powerpc,
|
||||||
|
vmx_v3_powerpc,
|
||||||
|
vmx_v4_powerpc,
|
||||||
|
vmx_v5_powerpc,
|
||||||
|
vmx_v6_powerpc,
|
||||||
|
vmx_v7_powerpc,
|
||||||
|
vmx_v8_powerpc,
|
||||||
|
vmx_v9_powerpc,
|
||||||
|
vmx_v10_powerpc,
|
||||||
|
vmx_v11_powerpc,
|
||||||
|
vmx_v12_powerpc,
|
||||||
|
vmx_v13_powerpc,
|
||||||
|
vmx_v14_powerpc,
|
||||||
|
vmx_v15_powerpc,
|
||||||
|
vmx_v16_powerpc,
|
||||||
|
vmx_v17_powerpc,
|
||||||
|
vmx_v18_powerpc,
|
||||||
|
vmx_v19_powerpc,
|
||||||
|
vmx_v20_powerpc,
|
||||||
|
vmx_v21_powerpc,
|
||||||
|
vmx_v22_powerpc,
|
||||||
|
vmx_v23_powerpc,
|
||||||
|
vmx_v24_powerpc,
|
||||||
|
vmx_v25_powerpc,
|
||||||
|
vmx_v26_powerpc,
|
||||||
|
vmx_v27_powerpc,
|
||||||
|
vmx_v28_powerpc,
|
||||||
|
vmx_v29_powerpc,
|
||||||
|
vmx_v30_powerpc,
|
||||||
|
vmx_v31_powerpc,
|
||||||
|
vmx_vrsave_powerpc,
|
||||||
|
vmx_vscr_powerpc,
|
||||||
|
};
|
||||||
|
|
||||||
// Number of register sets provided by this context.
|
// Number of register sets provided by this context.
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
k_num_register_sets = 2
|
k_num_register_sets = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
static const RegisterSet
|
static const RegisterSet
|
||||||
|
@ -117,6 +156,7 @@ g_reg_sets_powerpc[k_num_register_sets] =
|
||||||
{
|
{
|
||||||
{ "General Purpose Registers", "gpr", k_num_gpr_registers_powerpc, g_gpr_regnums },
|
{ "General Purpose Registers", "gpr", k_num_gpr_registers_powerpc, g_gpr_regnums },
|
||||||
{ "Floating Point Registers", "fpr", k_num_fpr_registers_powerpc, g_fpr_regnums },
|
{ "Floating Point Registers", "fpr", k_num_fpr_registers_powerpc, g_fpr_regnums },
|
||||||
|
{ "Altivec/VMX Registers", "vmx", k_num_vmx_registers_powerpc, g_vmx_regnums },
|
||||||
};
|
};
|
||||||
|
|
||||||
bool RegisterContextPOSIX_powerpc::IsGPR(unsigned reg)
|
bool RegisterContextPOSIX_powerpc::IsGPR(unsigned reg)
|
||||||
|
@ -127,10 +167,15 @@ bool RegisterContextPOSIX_powerpc::IsGPR(unsigned reg)
|
||||||
bool
|
bool
|
||||||
RegisterContextPOSIX_powerpc::IsFPR(unsigned reg)
|
RegisterContextPOSIX_powerpc::IsFPR(unsigned reg)
|
||||||
{
|
{
|
||||||
// XXX
|
|
||||||
return (reg >= k_first_fpr) && (reg <= k_last_fpr);
|
return (reg >= k_first_fpr) && (reg <= k_last_fpr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
RegisterContextPOSIX_powerpc::IsVMX(unsigned reg)
|
||||||
|
{
|
||||||
|
return (reg >= k_first_vmx) && (reg <= k_last_vmx);
|
||||||
|
}
|
||||||
|
|
||||||
RegisterContextPOSIX_powerpc::RegisterContextPOSIX_powerpc(Thread &thread,
|
RegisterContextPOSIX_powerpc::RegisterContextPOSIX_powerpc(Thread &thread,
|
||||||
uint32_t concrete_frame_idx,
|
uint32_t concrete_frame_idx,
|
||||||
RegisterInfoInterface *register_info)
|
RegisterInfoInterface *register_info)
|
||||||
|
|
|
@ -97,9 +97,47 @@ enum
|
||||||
fpr_fpscr_powerpc,
|
fpr_fpscr_powerpc,
|
||||||
k_last_fpr = fpr_fpscr_powerpc,
|
k_last_fpr = fpr_fpscr_powerpc,
|
||||||
|
|
||||||
|
k_first_vmx,
|
||||||
|
vmx_v0_powerpc = k_first_vmx,
|
||||||
|
vmx_v1_powerpc,
|
||||||
|
vmx_v2_powerpc,
|
||||||
|
vmx_v3_powerpc,
|
||||||
|
vmx_v4_powerpc,
|
||||||
|
vmx_v5_powerpc,
|
||||||
|
vmx_v6_powerpc,
|
||||||
|
vmx_v7_powerpc,
|
||||||
|
vmx_v8_powerpc,
|
||||||
|
vmx_v9_powerpc,
|
||||||
|
vmx_v10_powerpc,
|
||||||
|
vmx_v11_powerpc,
|
||||||
|
vmx_v12_powerpc,
|
||||||
|
vmx_v13_powerpc,
|
||||||
|
vmx_v14_powerpc,
|
||||||
|
vmx_v15_powerpc,
|
||||||
|
vmx_v16_powerpc,
|
||||||
|
vmx_v17_powerpc,
|
||||||
|
vmx_v18_powerpc,
|
||||||
|
vmx_v19_powerpc,
|
||||||
|
vmx_v20_powerpc,
|
||||||
|
vmx_v21_powerpc,
|
||||||
|
vmx_v22_powerpc,
|
||||||
|
vmx_v23_powerpc,
|
||||||
|
vmx_v24_powerpc,
|
||||||
|
vmx_v25_powerpc,
|
||||||
|
vmx_v26_powerpc,
|
||||||
|
vmx_v27_powerpc,
|
||||||
|
vmx_v28_powerpc,
|
||||||
|
vmx_v29_powerpc,
|
||||||
|
vmx_v30_powerpc,
|
||||||
|
vmx_v31_powerpc,
|
||||||
|
vmx_vrsave_powerpc,
|
||||||
|
vmx_vscr_powerpc,
|
||||||
|
k_last_vmx = vmx_vscr_powerpc,
|
||||||
|
|
||||||
k_num_registers_powerpc,
|
k_num_registers_powerpc,
|
||||||
k_num_gpr_registers_powerpc = k_last_gpr_powerpc - k_first_gpr_powerpc + 1,
|
k_num_gpr_registers_powerpc = k_last_gpr_powerpc - k_first_gpr_powerpc + 1,
|
||||||
k_num_fpr_registers_powerpc = k_last_fpr - k_first_fpr + 1,
|
k_num_fpr_registers_powerpc = k_last_fpr - k_first_fpr + 1,
|
||||||
|
k_num_vmx_registers_powerpc = k_last_vmx - k_first_vmx + 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
class RegisterContextPOSIX_powerpc
|
class RegisterContextPOSIX_powerpc
|
||||||
|
@ -148,6 +186,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
uint64_t m_gpr_powerpc[k_num_gpr_registers_powerpc]; // general purpose registers.
|
uint64_t m_gpr_powerpc[k_num_gpr_registers_powerpc]; // general purpose registers.
|
||||||
uint64_t m_fpr_powerpc[k_num_fpr_registers_powerpc]; // floating point registers.
|
uint64_t m_fpr_powerpc[k_num_fpr_registers_powerpc]; // floating point registers.
|
||||||
|
uint32_t m_vmx_powerpc[k_num_vmx_registers_powerpc][4];
|
||||||
std::unique_ptr<lldb_private::RegisterInfoInterface> m_register_info_ap; // Register Info Interface (FreeBSD or Linux)
|
std::unique_ptr<lldb_private::RegisterInfoInterface> m_register_info_ap; // Register Info Interface (FreeBSD or Linux)
|
||||||
|
|
||||||
// Determines if an extended register set is supported on the processor running the inferior process.
|
// Determines if an extended register set is supported on the processor running the inferior process.
|
||||||
|
@ -163,12 +202,17 @@ protected:
|
||||||
bool
|
bool
|
||||||
IsFPR(unsigned reg);
|
IsFPR(unsigned reg);
|
||||||
|
|
||||||
|
bool
|
||||||
|
IsVMX(unsigned reg);
|
||||||
|
|
||||||
lldb::ByteOrder GetByteOrder();
|
lldb::ByteOrder GetByteOrder();
|
||||||
|
|
||||||
virtual bool ReadGPR() = 0;
|
virtual bool ReadGPR() = 0;
|
||||||
virtual bool ReadFPR() = 0;
|
virtual bool ReadFPR() = 0;
|
||||||
|
virtual bool ReadVMX() = 0;
|
||||||
virtual bool WriteGPR() = 0;
|
virtual bool WriteGPR() = 0;
|
||||||
virtual bool WriteFPR() = 0;
|
virtual bool WriteFPR() = 0;
|
||||||
|
virtual bool WriteVMX() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // #ifndef liblldb_RegisterContextPOSIX_powerpc_H_
|
#endif // #ifndef liblldb_RegisterContextPOSIX_powerpc_H_
|
||||||
|
|
|
@ -79,10 +79,45 @@ enum
|
||||||
gcc_dwarf_f31_powerpc,
|
gcc_dwarf_f31_powerpc,
|
||||||
gcc_dwarf_cr_powerpc,
|
gcc_dwarf_cr_powerpc,
|
||||||
gcc_dwarf_fpscr_powerpc,
|
gcc_dwarf_fpscr_powerpc,
|
||||||
|
gcc_dwarf_msr_powerpc,
|
||||||
|
gcc_dwarf_vscr_powerpc,
|
||||||
gcc_dwarf_xer_powerpc = 101,
|
gcc_dwarf_xer_powerpc = 101,
|
||||||
gcc_dwarf_lr_powerpc = 108,
|
gcc_dwarf_lr_powerpc = 108,
|
||||||
gcc_dwarf_ctr_powerpc,
|
gcc_dwarf_ctr_powerpc,
|
||||||
gcc_dwarf_pc_powerpc,
|
gcc_dwarf_pc_powerpc,
|
||||||
|
gcc_dwarf_vrsave_powerpc = 356,
|
||||||
|
gcc_dwarf_v0_powerpc = 1124,
|
||||||
|
gcc_dwarf_v1_powerpc,
|
||||||
|
gcc_dwarf_v2_powerpc,
|
||||||
|
gcc_dwarf_v3_powerpc,
|
||||||
|
gcc_dwarf_v4_powerpc,
|
||||||
|
gcc_dwarf_v5_powerpc,
|
||||||
|
gcc_dwarf_v6_powerpc,
|
||||||
|
gcc_dwarf_v7_powerpc,
|
||||||
|
gcc_dwarf_v8_powerpc,
|
||||||
|
gcc_dwarf_v9_powerpc,
|
||||||
|
gcc_dwarf_v10_powerpc,
|
||||||
|
gcc_dwarf_v11_powerpc,
|
||||||
|
gcc_dwarf_v12_powerpc,
|
||||||
|
gcc_dwarf_v13_powerpc,
|
||||||
|
gcc_dwarf_v14_powerpc,
|
||||||
|
gcc_dwarf_v15_powerpc,
|
||||||
|
gcc_dwarf_v16_powerpc,
|
||||||
|
gcc_dwarf_v17_powerpc,
|
||||||
|
gcc_dwarf_v18_powerpc,
|
||||||
|
gcc_dwarf_v19_powerpc,
|
||||||
|
gcc_dwarf_v20_powerpc,
|
||||||
|
gcc_dwarf_v21_powerpc,
|
||||||
|
gcc_dwarf_v22_powerpc,
|
||||||
|
gcc_dwarf_v23_powerpc,
|
||||||
|
gcc_dwarf_v24_powerpc,
|
||||||
|
gcc_dwarf_v25_powerpc,
|
||||||
|
gcc_dwarf_v26_powerpc,
|
||||||
|
gcc_dwarf_v27_powerpc,
|
||||||
|
gcc_dwarf_v28_powerpc,
|
||||||
|
gcc_dwarf_v29_powerpc,
|
||||||
|
gcc_dwarf_v30_powerpc,
|
||||||
|
gcc_dwarf_v31_powerpc,
|
||||||
};
|
};
|
||||||
|
|
||||||
// GDB Register numbers (eRegisterKindGDB)
|
// GDB Register numbers (eRegisterKindGDB)
|
||||||
|
@ -152,12 +187,46 @@ enum
|
||||||
gdb_f29_powerpc,
|
gdb_f29_powerpc,
|
||||||
gdb_f30_powerpc,
|
gdb_f30_powerpc,
|
||||||
gdb_f31_powerpc,
|
gdb_f31_powerpc,
|
||||||
gdb_cr_powerpc,
|
|
||||||
gdb_fpscr_powerpc,
|
|
||||||
gdb_xer_powerpc = 101,
|
|
||||||
gdb_lr_powerpc = 108,
|
|
||||||
gdb_ctr_powerpc,
|
|
||||||
gdb_pc_powerpc,
|
gdb_pc_powerpc,
|
||||||
|
gdb_cr_powerpc = 66,
|
||||||
|
gdb_lr_powerpc,
|
||||||
|
gdb_ctr_powerpc,
|
||||||
|
gdb_xer_powerpc,
|
||||||
|
gdb_fpscr_powerpc,
|
||||||
|
gdb_v0_powerpc = 106,
|
||||||
|
gdb_v1_powerpc,
|
||||||
|
gdb_v2_powerpc,
|
||||||
|
gdb_v3_powerpc,
|
||||||
|
gdb_v4_powerpc,
|
||||||
|
gdb_v5_powerpc,
|
||||||
|
gdb_v6_powerpc,
|
||||||
|
gdb_v7_powerpc,
|
||||||
|
gdb_v8_powerpc,
|
||||||
|
gdb_v9_powerpc,
|
||||||
|
gdb_v10_powerpc,
|
||||||
|
gdb_v11_powerpc,
|
||||||
|
gdb_v12_powerpc,
|
||||||
|
gdb_v13_powerpc,
|
||||||
|
gdb_v14_powerpc,
|
||||||
|
gdb_v15_powerpc,
|
||||||
|
gdb_v16_powerpc,
|
||||||
|
gdb_v17_powerpc,
|
||||||
|
gdb_v18_powerpc,
|
||||||
|
gdb_v19_powerpc,
|
||||||
|
gdb_v20_powerpc,
|
||||||
|
gdb_v21_powerpc,
|
||||||
|
gdb_v22_powerpc,
|
||||||
|
gdb_v23_powerpc,
|
||||||
|
gdb_v24_powerpc,
|
||||||
|
gdb_v25_powerpc,
|
||||||
|
gdb_v26_powerpc,
|
||||||
|
gdb_v27_powerpc,
|
||||||
|
gdb_v28_powerpc,
|
||||||
|
gdb_v29_powerpc,
|
||||||
|
gdb_v30_powerpc,
|
||||||
|
gdb_v31_powerpc,
|
||||||
|
gdb_vscr_powerpc,
|
||||||
|
gdb_vrsave_powerpc,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // liblldb_RegisterContext_powerpc_H_
|
#endif // liblldb_RegisterContext_powerpc_H_
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
(offsetof(GPR, regname))
|
(offsetof(GPR, regname))
|
||||||
#define FPR_OFFSET(regname) \
|
#define FPR_OFFSET(regname) \
|
||||||
(offsetof(FPR, regname))
|
(offsetof(FPR, regname))
|
||||||
|
#define VMX_OFFSET(regname) \
|
||||||
|
(offsetof(VMX, regname))
|
||||||
#define GPR_SIZE(regname) \
|
#define GPR_SIZE(regname) \
|
||||||
(sizeof(((GPR*)NULL)->regname))
|
(sizeof(((GPR*)NULL)->regname))
|
||||||
|
|
||||||
|
@ -26,6 +28,9 @@
|
||||||
#define DEFINE_FPR(reg, lldb_kind) \
|
#define DEFINE_FPR(reg, lldb_kind) \
|
||||||
{ #reg, NULL, 8, FPR_OFFSET(reg), eEncodingIEEE754, \
|
{ #reg, NULL, 8, FPR_OFFSET(reg), eEncodingIEEE754, \
|
||||||
eFormatFloat, { gcc_dwarf_##reg##_powerpc, gcc_dwarf_##reg##_powerpc, lldb_kind, gdb_##reg##_powerpc, fpr_##reg##_powerpc }, NULL, NULL }
|
eFormatFloat, { gcc_dwarf_##reg##_powerpc, gcc_dwarf_##reg##_powerpc, lldb_kind, gdb_##reg##_powerpc, fpr_##reg##_powerpc }, NULL, NULL }
|
||||||
|
#define DEFINE_VMX(reg, lldb_kind) \
|
||||||
|
{ #reg, NULL, 16, VMX_OFFSET(reg), eEncodingVector, \
|
||||||
|
eFormatVectorOfUInt32, { gcc_dwarf_##reg##_powerpc, gcc_dwarf_##reg##_powerpc, lldb_kind, gdb_##reg##_powerpc, vmx_##reg##_powerpc }, NULL, NULL }
|
||||||
|
|
||||||
// General purpose registers. GCC, DWARF, Generic, GDB
|
// General purpose registers. GCC, DWARF, Generic, GDB
|
||||||
#define POWERPC_REGS \
|
#define POWERPC_REGS \
|
||||||
|
@ -98,7 +103,42 @@
|
||||||
DEFINE_FPR(f29, LLDB_INVALID_REGNUM), \
|
DEFINE_FPR(f29, LLDB_INVALID_REGNUM), \
|
||||||
DEFINE_FPR(f30, LLDB_INVALID_REGNUM), \
|
DEFINE_FPR(f30, LLDB_INVALID_REGNUM), \
|
||||||
DEFINE_FPR(f31, LLDB_INVALID_REGNUM), \
|
DEFINE_FPR(f31, LLDB_INVALID_REGNUM), \
|
||||||
{ "fpscr", NULL, 8, FPR_OFFSET(fpscr), eEncodingUint, eFormatHex, { gcc_dwarf_fpscr_powerpc, gcc_dwarf_fpscr_powerpc, LLDB_INVALID_REGNUM, gdb_fpscr_powerpc, fpr_fpscr_powerpc }, NULL, NULL },
|
{ "fpscr", NULL, 8, FPR_OFFSET(fpscr), eEncodingUint, eFormatHex, { gcc_dwarf_fpscr_powerpc, gcc_dwarf_fpscr_powerpc, LLDB_INVALID_REGNUM, gdb_fpscr_powerpc, fpr_fpscr_powerpc }, NULL, NULL }, \
|
||||||
|
DEFINE_VMX(v0, LLDB_INVALID_REGNUM), \
|
||||||
|
DEFINE_VMX(v1, LLDB_INVALID_REGNUM), \
|
||||||
|
DEFINE_VMX(v2, LLDB_INVALID_REGNUM), \
|
||||||
|
DEFINE_VMX(v3, LLDB_INVALID_REGNUM), \
|
||||||
|
DEFINE_VMX(v4, LLDB_INVALID_REGNUM), \
|
||||||
|
DEFINE_VMX(v5, LLDB_INVALID_REGNUM), \
|
||||||
|
DEFINE_VMX(v6, LLDB_INVALID_REGNUM), \
|
||||||
|
DEFINE_VMX(v7, LLDB_INVALID_REGNUM), \
|
||||||
|
DEFINE_VMX(v8, LLDB_INVALID_REGNUM), \
|
||||||
|
DEFINE_VMX(v9, LLDB_INVALID_REGNUM), \
|
||||||
|
DEFINE_VMX(v10, LLDB_INVALID_REGNUM), \
|
||||||
|
DEFINE_VMX(v11, LLDB_INVALID_REGNUM), \
|
||||||
|
DEFINE_VMX(v12, LLDB_INVALID_REGNUM), \
|
||||||
|
DEFINE_VMX(v13, LLDB_INVALID_REGNUM), \
|
||||||
|
DEFINE_VMX(v14, LLDB_INVALID_REGNUM), \
|
||||||
|
DEFINE_VMX(v15, LLDB_INVALID_REGNUM), \
|
||||||
|
DEFINE_VMX(v16, LLDB_INVALID_REGNUM), \
|
||||||
|
DEFINE_VMX(v17, LLDB_INVALID_REGNUM), \
|
||||||
|
DEFINE_VMX(v18, LLDB_INVALID_REGNUM), \
|
||||||
|
DEFINE_VMX(v19, LLDB_INVALID_REGNUM), \
|
||||||
|
DEFINE_VMX(v20, LLDB_INVALID_REGNUM), \
|
||||||
|
DEFINE_VMX(v21, LLDB_INVALID_REGNUM), \
|
||||||
|
DEFINE_VMX(v22, LLDB_INVALID_REGNUM), \
|
||||||
|
DEFINE_VMX(v23, LLDB_INVALID_REGNUM), \
|
||||||
|
DEFINE_VMX(v24, LLDB_INVALID_REGNUM), \
|
||||||
|
DEFINE_VMX(v25, LLDB_INVALID_REGNUM), \
|
||||||
|
DEFINE_VMX(v26, LLDB_INVALID_REGNUM), \
|
||||||
|
DEFINE_VMX(v27, LLDB_INVALID_REGNUM), \
|
||||||
|
DEFINE_VMX(v28, LLDB_INVALID_REGNUM), \
|
||||||
|
DEFINE_VMX(v29, LLDB_INVALID_REGNUM), \
|
||||||
|
DEFINE_VMX(v30, LLDB_INVALID_REGNUM), \
|
||||||
|
DEFINE_VMX(v31, LLDB_INVALID_REGNUM), \
|
||||||
|
{ "vrsave", NULL, 4, VMX_OFFSET(vrsave), eEncodingUint, eFormatHex, { gcc_dwarf_vrsave_powerpc, gcc_dwarf_vrsave_powerpc, LLDB_INVALID_REGNUM, gdb_vrsave_powerpc, vmx_vrsave_powerpc }, NULL, NULL }, \
|
||||||
|
{ "vscr", NULL, 4, VMX_OFFSET(vscr), eEncodingUint, eFormatHex, { gcc_dwarf_vscr_powerpc, gcc_dwarf_vscr_powerpc, LLDB_INVALID_REGNUM, gdb_vscr_powerpc, vmx_vscr_powerpc }, NULL, NULL },
|
||||||
|
|
||||||
static RegisterInfo
|
static RegisterInfo
|
||||||
g_register_infos_powerpc64[] =
|
g_register_infos_powerpc64[] =
|
||||||
{
|
{
|
||||||
|
|
|
@ -412,7 +412,8 @@ enum {
|
||||||
NT_FPREGSET,
|
NT_FPREGSET,
|
||||||
NT_PRPSINFO,
|
NT_PRPSINFO,
|
||||||
NT_THRMISC = 7,
|
NT_THRMISC = 7,
|
||||||
NT_PROCSTAT_AUXV = 16
|
NT_PROCSTAT_AUXV = 16,
|
||||||
|
NT_PPC_VMX = 0x100
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -538,6 +539,9 @@ ProcessElfCore::ParseThreadContextsFromNoteSegment(const elf::ELFProgramHeader *
|
||||||
// FIXME: FreeBSD sticks an int at the beginning of the note
|
// FIXME: FreeBSD sticks an int at the beginning of the note
|
||||||
m_auxv = DataExtractor(segment_data, note_start + 4, note_size - 4);
|
m_auxv = DataExtractor(segment_data, note_start + 4, note_size - 4);
|
||||||
break;
|
break;
|
||||||
|
case FREEBSD::NT_PPC_VMX:
|
||||||
|
thread_data->vregset = note_data;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,8 @@ using namespace lldb_private;
|
||||||
RegisterContextCorePOSIX_powerpc::RegisterContextCorePOSIX_powerpc(Thread &thread,
|
RegisterContextCorePOSIX_powerpc::RegisterContextCorePOSIX_powerpc(Thread &thread,
|
||||||
RegisterInfoInterface *register_info,
|
RegisterInfoInterface *register_info,
|
||||||
const DataExtractor &gpregset,
|
const DataExtractor &gpregset,
|
||||||
const DataExtractor &fpregset)
|
const DataExtractor &fpregset,
|
||||||
|
const DataExtractor &vregset)
|
||||||
: RegisterContextPOSIX_powerpc(thread, 0, register_info)
|
: RegisterContextPOSIX_powerpc(thread, 0, register_info)
|
||||||
{
|
{
|
||||||
m_gpr_buffer.reset(new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
|
m_gpr_buffer.reset(new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
|
||||||
|
@ -27,6 +28,9 @@ RegisterContextCorePOSIX_powerpc::RegisterContextCorePOSIX_powerpc(Thread &threa
|
||||||
m_fpr_buffer.reset(new DataBufferHeap(fpregset.GetDataStart(), fpregset.GetByteSize()));
|
m_fpr_buffer.reset(new DataBufferHeap(fpregset.GetDataStart(), fpregset.GetByteSize()));
|
||||||
m_fpr.SetData(m_fpr_buffer);
|
m_fpr.SetData(m_fpr_buffer);
|
||||||
m_fpr.SetByteOrder(fpregset.GetByteOrder());
|
m_fpr.SetByteOrder(fpregset.GetByteOrder());
|
||||||
|
m_vec_buffer.reset(new DataBufferHeap(vregset.GetDataStart(), vregset.GetByteSize()));
|
||||||
|
m_vec.SetData(m_vec_buffer);
|
||||||
|
m_vec.SetByteOrder(fpregset.GetByteOrder());
|
||||||
}
|
}
|
||||||
|
|
||||||
RegisterContextCorePOSIX_powerpc::~RegisterContextCorePOSIX_powerpc()
|
RegisterContextCorePOSIX_powerpc::~RegisterContextCorePOSIX_powerpc()
|
||||||
|
@ -45,6 +49,12 @@ RegisterContextCorePOSIX_powerpc::ReadFPR()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
RegisterContextCorePOSIX_powerpc::ReadVMX()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
RegisterContextCorePOSIX_powerpc::WriteGPR()
|
RegisterContextCorePOSIX_powerpc::WriteGPR()
|
||||||
{
|
{
|
||||||
|
@ -59,17 +69,32 @@ RegisterContextCorePOSIX_powerpc::WriteFPR()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
RegisterContextCorePOSIX_powerpc::WriteVMX()
|
||||||
|
{
|
||||||
|
assert(0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
RegisterContextCorePOSIX_powerpc::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
|
RegisterContextCorePOSIX_powerpc::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
|
||||||
{
|
{
|
||||||
lldb::offset_t offset = reg_info->byte_offset;
|
lldb::offset_t offset = reg_info->byte_offset;
|
||||||
if (reg_info->name[0] == 'f') {
|
if (IsFPR(reg_info->kinds[lldb::eRegisterKindLLDB])) {
|
||||||
uint64_t v = m_fpr.GetMaxU64(&offset, reg_info->byte_size);
|
uint64_t v = m_fpr.GetMaxU64(&offset, reg_info->byte_size);
|
||||||
if (offset == reg_info->byte_offset + reg_info->byte_size)
|
if (offset == reg_info->byte_offset + reg_info->byte_size)
|
||||||
{
|
{
|
||||||
value = v;
|
value = v;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
} else if (IsVMX(reg_info->kinds[lldb::eRegisterKindLLDB])) {
|
||||||
|
uint32_t v[4];
|
||||||
|
offset = m_vec.CopyData(offset, reg_info->byte_size, &v);
|
||||||
|
if (offset == reg_info->byte_size)
|
||||||
|
{
|
||||||
|
value.SetBytes(v, reg_info->byte_size, m_vec.GetByteOrder());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
|
uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
|
||||||
if (offset == reg_info->byte_offset + reg_info->byte_size)
|
if (offset == reg_info->byte_offset + reg_info->byte_size)
|
||||||
|
|
|
@ -20,7 +20,8 @@ public:
|
||||||
RegisterContextCorePOSIX_powerpc (lldb_private::Thread &thread,
|
RegisterContextCorePOSIX_powerpc (lldb_private::Thread &thread,
|
||||||
lldb_private::RegisterInfoInterface *register_info,
|
lldb_private::RegisterInfoInterface *register_info,
|
||||||
const lldb_private::DataExtractor &gpregset,
|
const lldb_private::DataExtractor &gpregset,
|
||||||
const lldb_private::DataExtractor &fpregset);
|
const lldb_private::DataExtractor &fpregset,
|
||||||
|
const lldb_private::DataExtractor &vregset);
|
||||||
|
|
||||||
~RegisterContextCorePOSIX_powerpc();
|
~RegisterContextCorePOSIX_powerpc();
|
||||||
|
|
||||||
|
@ -46,17 +47,25 @@ protected:
|
||||||
bool
|
bool
|
||||||
ReadFPR();
|
ReadFPR();
|
||||||
|
|
||||||
|
bool
|
||||||
|
ReadVMX();
|
||||||
|
|
||||||
bool
|
bool
|
||||||
WriteGPR();
|
WriteGPR();
|
||||||
|
|
||||||
bool
|
bool
|
||||||
WriteFPR();
|
WriteFPR();
|
||||||
|
|
||||||
|
bool
|
||||||
|
WriteVMX();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
lldb::DataBufferSP m_gpr_buffer;
|
lldb::DataBufferSP m_gpr_buffer;
|
||||||
lldb::DataBufferSP m_fpr_buffer;
|
lldb::DataBufferSP m_fpr_buffer;
|
||||||
|
lldb::DataBufferSP m_vec_buffer;
|
||||||
lldb_private::DataExtractor m_gpr;
|
lldb_private::DataExtractor m_gpr;
|
||||||
lldb_private::DataExtractor m_fpr;
|
lldb_private::DataExtractor m_fpr;
|
||||||
|
lldb_private::DataExtractor m_vec;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // #ifndef liblldb_RegisterContextCorePOSIX_powerpc_H_
|
#endif // #ifndef liblldb_RegisterContextCorePOSIX_powerpc_H_
|
||||||
|
|
|
@ -38,7 +38,8 @@ ThreadElfCore::ThreadElfCore (Process &process, tid_t tid,
|
||||||
m_thread_reg_ctx_sp (),
|
m_thread_reg_ctx_sp (),
|
||||||
m_signo(td.signo),
|
m_signo(td.signo),
|
||||||
m_gpregset_data(td.gpregset),
|
m_gpregset_data(td.gpregset),
|
||||||
m_fpregset_data(td.fpregset)
|
m_fpregset_data(td.fpregset),
|
||||||
|
m_vregset_data(td.vregset)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,7 +149,7 @@ ThreadElfCore::CreateRegisterContextForFrame (StackFrame *frame)
|
||||||
break;
|
break;
|
||||||
case llvm::Triple::ppc:
|
case llvm::Triple::ppc:
|
||||||
case llvm::Triple::ppc64:
|
case llvm::Triple::ppc64:
|
||||||
m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_powerpc (*this, reg_interface, m_gpregset_data, m_fpregset_data));
|
m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_powerpc (*this, reg_interface, m_gpregset_data, m_fpregset_data, m_vregset_data));
|
||||||
break;
|
break;
|
||||||
case llvm::Triple::x86:
|
case llvm::Triple::x86:
|
||||||
case llvm::Triple::x86_64:
|
case llvm::Triple::x86_64:
|
||||||
|
|
|
@ -111,6 +111,7 @@ struct ThreadData
|
||||||
{
|
{
|
||||||
lldb_private::DataExtractor gpregset;
|
lldb_private::DataExtractor gpregset;
|
||||||
lldb_private::DataExtractor fpregset;
|
lldb_private::DataExtractor fpregset;
|
||||||
|
lldb_private::DataExtractor vregset;
|
||||||
int signo;
|
int signo;
|
||||||
std::string name;
|
std::string name;
|
||||||
};
|
};
|
||||||
|
@ -170,6 +171,7 @@ protected:
|
||||||
|
|
||||||
lldb_private::DataExtractor m_gpregset_data;
|
lldb_private::DataExtractor m_gpregset_data;
|
||||||
lldb_private::DataExtractor m_fpregset_data;
|
lldb_private::DataExtractor m_fpregset_data;
|
||||||
|
lldb_private::DataExtractor m_vregset_data;
|
||||||
|
|
||||||
virtual bool CalculateStopInfo();
|
virtual bool CalculateStopInfo();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue