[LLDB][MIPS] Core Dump Support.

Reviewers: labath, emaste

Subscribers: jaydeep, bhushan, lldb-commits, slthakur

Differential Revision: https://reviews.llvm.org/D30457

llvm-svn: 299200
This commit is contained in:
Nitesh Jain 2017-03-31 11:14:02 +00:00
parent 706c520558
commit b8dbd32375
15 changed files with 443 additions and 245 deletions

View File

@ -1380,7 +1380,7 @@ static bool cores_match(const ArchSpec::Core core1, const ArchSpec::Core core2,
if (core2 >= ArchSpec::kCore_mips32el_first &&
core2 <= ArchSpec::kCore_mips32el_last)
return true;
try_inverse = false;
try_inverse = true;
}
break;

View File

@ -11,6 +11,7 @@
#define liblldb_RegisterContextPOSIXProcessMonitor_mips64_H_
#include "Plugins/Process/Utility/RegisterContextPOSIX_mips64.h"
#include "Plugin/Process/Utility/lldb-mips-freebsd-register-enums.h"
#include "RegisterContextPOSIX.h"
class RegisterContextPOSIXProcessMonitor_mips64
@ -72,6 +73,8 @@ protected:
uint32_t NumSupportedHardwareWatchpoints();
private:
uint64_t
m_gpr_mips64[k_num_gpr_registers_mips64]; // general purpose registers.
ProcessMonitor &GetMonitor();
};

View File

@ -80,152 +80,6 @@ struct pt_watch_regs default_watch_regs;
using namespace lldb_private;
using namespace lldb_private::process_linux;
// ----------------------------------------------------------------------------
// Private namespace.
// ----------------------------------------------------------------------------
namespace {
// mips general purpose registers.
const uint32_t g_gp_regnums_mips[] = {
gpr_zero_mips, gpr_r1_mips, gpr_r2_mips, gpr_r3_mips,
gpr_r4_mips, gpr_r5_mips, gpr_r6_mips, gpr_r7_mips,
gpr_r8_mips, gpr_r9_mips, gpr_r10_mips, gpr_r11_mips,
gpr_r12_mips, gpr_r13_mips, gpr_r14_mips, gpr_r15_mips,
gpr_r16_mips, gpr_r17_mips, gpr_r18_mips, gpr_r19_mips,
gpr_r20_mips, gpr_r21_mips, gpr_r22_mips, gpr_r23_mips,
gpr_r24_mips, gpr_r25_mips, gpr_r26_mips, gpr_r27_mips,
gpr_gp_mips, gpr_sp_mips, gpr_r30_mips, gpr_ra_mips,
gpr_sr_mips, gpr_mullo_mips, gpr_mulhi_mips, gpr_badvaddr_mips,
gpr_cause_mips, gpr_pc_mips, gpr_config5_mips,
LLDB_INVALID_REGNUM // register sets need to end with this flag
};
static_assert((sizeof(g_gp_regnums_mips) / sizeof(g_gp_regnums_mips[0])) - 1 ==
k_num_gpr_registers_mips,
"g_gp_regnums_mips has wrong number of register infos");
// mips floating point registers.
const uint32_t g_fp_regnums_mips[] = {
fpr_f0_mips, fpr_f1_mips, fpr_f2_mips, fpr_f3_mips,
fpr_f4_mips, fpr_f5_mips, fpr_f6_mips, fpr_f7_mips,
fpr_f8_mips, fpr_f9_mips, fpr_f10_mips, fpr_f11_mips,
fpr_f12_mips, fpr_f13_mips, fpr_f14_mips, fpr_f15_mips,
fpr_f16_mips, fpr_f17_mips, fpr_f18_mips, fpr_f19_mips,
fpr_f20_mips, fpr_f21_mips, fpr_f22_mips, fpr_f23_mips,
fpr_f24_mips, fpr_f25_mips, fpr_f26_mips, fpr_f27_mips,
fpr_f28_mips, fpr_f29_mips, fpr_f30_mips, fpr_f31_mips,
fpr_fcsr_mips, fpr_fir_mips, fpr_config5_mips,
LLDB_INVALID_REGNUM // register sets need to end with this flag
};
static_assert((sizeof(g_fp_regnums_mips) / sizeof(g_fp_regnums_mips[0])) - 1 ==
k_num_fpr_registers_mips,
"g_fp_regnums_mips has wrong number of register infos");
// mips MSA registers.
const uint32_t g_msa_regnums_mips[] = {
msa_w0_mips, msa_w1_mips, msa_w2_mips, msa_w3_mips,
msa_w4_mips, msa_w5_mips, msa_w6_mips, msa_w7_mips,
msa_w8_mips, msa_w9_mips, msa_w10_mips, msa_w11_mips,
msa_w12_mips, msa_w13_mips, msa_w14_mips, msa_w15_mips,
msa_w16_mips, msa_w17_mips, msa_w18_mips, msa_w19_mips,
msa_w20_mips, msa_w21_mips, msa_w22_mips, msa_w23_mips,
msa_w24_mips, msa_w25_mips, msa_w26_mips, msa_w27_mips,
msa_w28_mips, msa_w29_mips, msa_w30_mips, msa_w31_mips,
msa_fcsr_mips, msa_fir_mips, msa_mcsr_mips, msa_mir_mips,
msa_config5_mips,
LLDB_INVALID_REGNUM // register sets need to end with this flag
};
static_assert((sizeof(g_msa_regnums_mips) / sizeof(g_msa_regnums_mips[0])) -
1 ==
k_num_msa_registers_mips,
"g_msa_regnums_mips has wrong number of register infos");
// mips64 general purpose registers.
const uint32_t g_gp_regnums_mips64[] = {
gpr_zero_mips64, gpr_r1_mips64, gpr_r2_mips64,
gpr_r3_mips64, gpr_r4_mips64, gpr_r5_mips64,
gpr_r6_mips64, gpr_r7_mips64, gpr_r8_mips64,
gpr_r9_mips64, gpr_r10_mips64, gpr_r11_mips64,
gpr_r12_mips64, gpr_r13_mips64, gpr_r14_mips64,
gpr_r15_mips64, gpr_r16_mips64, gpr_r17_mips64,
gpr_r18_mips64, gpr_r19_mips64, gpr_r20_mips64,
gpr_r21_mips64, gpr_r22_mips64, gpr_r23_mips64,
gpr_r24_mips64, gpr_r25_mips64, gpr_r26_mips64,
gpr_r27_mips64, gpr_gp_mips64, gpr_sp_mips64,
gpr_r30_mips64, gpr_ra_mips64, gpr_sr_mips64,
gpr_mullo_mips64, gpr_mulhi_mips64, gpr_badvaddr_mips64,
gpr_cause_mips64, gpr_pc_mips64, gpr_config5_mips64,
LLDB_INVALID_REGNUM // register sets need to end with this flag
};
static_assert((sizeof(g_gp_regnums_mips64) / sizeof(g_gp_regnums_mips64[0])) -
1 ==
k_num_gpr_registers_mips64,
"g_gp_regnums_mips64 has wrong number of register infos");
// mips64 floating point registers.
const uint32_t g_fp_regnums_mips64[] = {
fpr_f0_mips64, fpr_f1_mips64, fpr_f2_mips64, fpr_f3_mips64,
fpr_f4_mips64, fpr_f5_mips64, fpr_f6_mips64, fpr_f7_mips64,
fpr_f8_mips64, fpr_f9_mips64, fpr_f10_mips64, fpr_f11_mips64,
fpr_f12_mips64, fpr_f13_mips64, fpr_f14_mips64, fpr_f15_mips64,
fpr_f16_mips64, fpr_f17_mips64, fpr_f18_mips64, fpr_f19_mips64,
fpr_f20_mips64, fpr_f21_mips64, fpr_f22_mips64, fpr_f23_mips64,
fpr_f24_mips64, fpr_f25_mips64, fpr_f26_mips64, fpr_f27_mips64,
fpr_f28_mips64, fpr_f29_mips64, fpr_f30_mips64, fpr_f31_mips64,
fpr_fcsr_mips64, fpr_fir_mips64, fpr_config5_mips64,
LLDB_INVALID_REGNUM // register sets need to end with this flag
};
static_assert((sizeof(g_fp_regnums_mips64) / sizeof(g_fp_regnums_mips64[0])) -
1 ==
k_num_fpr_registers_mips64,
"g_fp_regnums_mips64 has wrong number of register infos");
// mips64 MSA registers.
const uint32_t g_msa_regnums_mips64[] = {
msa_w0_mips64, msa_w1_mips64, msa_w2_mips64, msa_w3_mips64,
msa_w4_mips64, msa_w5_mips64, msa_w6_mips64, msa_w7_mips64,
msa_w8_mips64, msa_w9_mips64, msa_w10_mips64, msa_w11_mips64,
msa_w12_mips64, msa_w13_mips64, msa_w14_mips64, msa_w15_mips64,
msa_w16_mips64, msa_w17_mips64, msa_w18_mips64, msa_w19_mips64,
msa_w20_mips64, msa_w21_mips64, msa_w22_mips64, msa_w23_mips64,
msa_w24_mips64, msa_w25_mips64, msa_w26_mips64, msa_w27_mips64,
msa_w28_mips64, msa_w29_mips64, msa_w30_mips64, msa_w31_mips64,
msa_fcsr_mips64, msa_fir_mips64, msa_mcsr_mips64, msa_mir_mips64,
msa_config5_mips64,
LLDB_INVALID_REGNUM // register sets need to end with this flag
};
static_assert((sizeof(g_msa_regnums_mips64) / sizeof(g_msa_regnums_mips64[0])) -
1 ==
k_num_msa_registers_mips64,
"g_msa_regnums_mips64 has wrong number of register infos");
// Number of register sets provided by this context.
enum { k_num_register_sets = 3 };
// Register sets for mips.
static const RegisterSet g_reg_sets_mips[k_num_register_sets] = {
{"General Purpose Registers", "gpr", k_num_gpr_registers_mips,
g_gp_regnums_mips},
{"Floating Point Registers", "fpu", k_num_fpr_registers_mips,
g_fp_regnums_mips},
{"MSA Registers", "msa", k_num_msa_registers_mips, g_msa_regnums_mips}};
// Register sets for mips64.
static const RegisterSet g_reg_sets_mips64[k_num_register_sets] = {
{"General Purpose Registers", "gpr", k_num_gpr_registers_mips64,
g_gp_regnums_mips64},
{"Floating Point Registers", "fpu", k_num_fpr_registers_mips64,
g_fp_regnums_mips64},
{"MSA Registers", "msa", k_num_msa_registers_mips64, g_msa_regnums_mips64},
};
} // end of anonymous namespace
NativeRegisterContextLinux *
NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
@ -244,15 +98,12 @@ NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
static RegisterInfoInterface *
CreateRegisterInfoInterface(const ArchSpec &target_arch) {
if (HostInfo::GetArchitecture().GetAddressByteSize() == 4) {
if ((target_arch.GetMachine() == llvm::Triple::mips) ||
(target_arch.GetMachine() == llvm::Triple::mipsel)) {
// 32-bit hosts run with a RegisterContextLinux_mips context.
return new RegisterContextLinux_mips(
target_arch, NativeRegisterContextLinux_mips64::IsMSAAvailable());
} else {
assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
"Register setting path assumes this is a 64-bit host");
// mips64 hosts know how to work with 64-bit and 32-bit EXEs using the
// mips64 register context.
return new RegisterContextLinux_mips64(
target_arch, NativeRegisterContextLinux_mips64::IsMSAAvailable());
}
@ -307,7 +158,22 @@ NativeRegisterContextLinux_mips64::NativeRegisterContextLinux_mips64(
}
uint32_t NativeRegisterContextLinux_mips64::GetRegisterSetCount() const {
return k_num_register_sets;
switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
case llvm::Triple::mips64:
case llvm::Triple::mips64el: {
const auto context = static_cast<const RegisterContextLinux_mips64 &>
(GetRegisterInfoInterface());
return context.GetRegisterSetCount();
}
case llvm::Triple::mips:
case llvm::Triple::mipsel: {
const auto context = static_cast<const RegisterContextLinux_mips &>
(GetRegisterInfoInterface());
return context.GetRegisterSetCount();
}
default:
llvm_unreachable("Unhandled target architecture.");
}
}
lldb::addr_t NativeRegisterContextLinux_mips64::GetPCfromBreakpointLocation(
@ -357,16 +223,22 @@ lldb::addr_t NativeRegisterContextLinux_mips64::GetPCfromBreakpointLocation(
const RegisterSet *
NativeRegisterContextLinux_mips64::GetRegisterSet(uint32_t set_index) const {
if (set_index >= k_num_register_sets)
if (set_index >= GetRegisterSetCount())
return nullptr;
switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
case llvm::Triple::mips64:
case llvm::Triple::mips64el:
return &g_reg_sets_mips64[set_index];
case llvm::Triple::mips64el: {
const auto context = static_cast<const RegisterContextLinux_mips64 &>
(GetRegisterInfoInterface());
return context.GetRegisterSet(set_index);
}
case llvm::Triple::mips:
case llvm::Triple::mipsel:
return &g_reg_sets_mips[set_index];
case llvm::Triple::mipsel: {
const auto context = static_cast<const RegisterContextLinux_mips &>
(GetRegisterInfoInterface());
return context.GetRegisterSet(set_index);
}
default:
llvm_unreachable("Unhandled target architecture.");
}

View File

@ -9,11 +9,33 @@
#include "RegisterContextFreeBSD_mips64.h"
#include "RegisterContextPOSIX_mips64.h"
#include "lldb-mips-freebsd-register-enums.h"
#include <vector>
using namespace lldb_private;
using namespace lldb;
static const uint32_t g_gpr_regnums[] = {
gpr_zero_mips64, gpr_r1_mips64, gpr_r2_mips64, gpr_r3_mips64,
gpr_r4_mips64, gpr_r5_mips64, gpr_r6_mips64, gpr_r7_mips64,
gpr_r8_mips64, gpr_r9_mips64, gpr_r10_mips64, gpr_r11_mips64,
gpr_r12_mips64, gpr_r13_mips64, gpr_r14_mips64, gpr_r15_mips64,
gpr_r16_mips64, gpr_r17_mips64, gpr_r18_mips64, gpr_r19_mips64,
gpr_r20_mips64, gpr_r21_mips64, gpr_r22_mips64, gpr_r23_mips64,
gpr_r24_mips64, gpr_r25_mips64, gpr_r26_mips64, gpr_r27_mips64,
gpr_gp_mips64, gpr_sp_mips64, gpr_r30_mips64, gpr_ra_mips64,
gpr_sr_mips64, gpr_mullo_mips64, gpr_mulhi_mips64, gpr_badvaddr_mips64,
gpr_cause_mips64, gpr_pc_mips64, gpr_ic_mips64, gpr_dummy_mips64};
// Number of register sets provided by this context.
constexpr size_t k_num_register_sets = 1;
static const RegisterSet g_reg_sets_mips64[k_num_register_sets] = {
{"General Purpose Registers", "gpr", k_num_gpr_registers_mips64,
g_gpr_regnums},
};
// http://svnweb.freebsd.org/base/head/sys/mips/include/regnum.h
typedef struct _GPR {
uint64_t zero;
@ -74,6 +96,19 @@ size_t RegisterContextFreeBSD_mips64::GetGPRSize() const {
return sizeof(GPR_freebsd_mips);
}
const RegisterSet *
RegisterContextFreeBSD_mips64::GetRegisterSet(size_t set) const {
// Check if RegisterSet is available
if (set < k_num_register_sets)
return &g_reg_sets_mips64[set];
return nullptr;
}
size_t
RegisterContextFreeBSD_mips64::GetRegisterSetCount() const {
return k_num_register_sets;
}
const RegisterInfo *RegisterContextFreeBSD_mips64::GetRegisterInfo() const {
assert(m_target_arch.GetCore() == ArchSpec::eCore_mips64);
return g_register_infos_mips64;

View File

@ -19,6 +19,10 @@ public:
size_t GetGPRSize() const override;
const lldb_private::RegisterSet *GetRegisterSet(size_t set) const;
size_t GetRegisterSetCount() const;
const lldb_private::RegisterInfo *GetRegisterInfo() const override;
uint32_t GetRegisterCount() const override;

View File

@ -29,6 +29,73 @@ using namespace lldb;
#include "RegisterInfos_mips.h"
#undef DECLARE_REGISTER_INFOS_MIPS_STRUCT
// mips general purpose registers.
const uint32_t g_gp_regnums_mips[] = {
gpr_zero_mips, gpr_r1_mips, gpr_r2_mips, gpr_r3_mips,
gpr_r4_mips, gpr_r5_mips, gpr_r6_mips, gpr_r7_mips,
gpr_r8_mips, gpr_r9_mips, gpr_r10_mips, gpr_r11_mips,
gpr_r12_mips, gpr_r13_mips, gpr_r14_mips, gpr_r15_mips,
gpr_r16_mips, gpr_r17_mips, gpr_r18_mips, gpr_r19_mips,
gpr_r20_mips, gpr_r21_mips, gpr_r22_mips, gpr_r23_mips,
gpr_r24_mips, gpr_r25_mips, gpr_r26_mips, gpr_r27_mips,
gpr_gp_mips, gpr_sp_mips, gpr_r30_mips, gpr_ra_mips,
gpr_sr_mips, gpr_mullo_mips, gpr_mulhi_mips, gpr_badvaddr_mips,
gpr_cause_mips, gpr_pc_mips, gpr_config5_mips,
LLDB_INVALID_REGNUM // register sets need to end with this flag
};
static_assert((sizeof(g_gp_regnums_mips) / sizeof(g_gp_regnums_mips[0])) - 1 ==
k_num_gpr_registers_mips,
"g_gp_regnums_mips has wrong number of register infos");
// mips floating point registers.
const uint32_t g_fp_regnums_mips[] = {
fpr_f0_mips, fpr_f1_mips, fpr_f2_mips, fpr_f3_mips,
fpr_f4_mips, fpr_f5_mips, fpr_f6_mips, fpr_f7_mips,
fpr_f8_mips, fpr_f9_mips, fpr_f10_mips, fpr_f11_mips,
fpr_f12_mips, fpr_f13_mips, fpr_f14_mips, fpr_f15_mips,
fpr_f16_mips, fpr_f17_mips, fpr_f18_mips, fpr_f19_mips,
fpr_f20_mips, fpr_f21_mips, fpr_f22_mips, fpr_f23_mips,
fpr_f24_mips, fpr_f25_mips, fpr_f26_mips, fpr_f27_mips,
fpr_f28_mips, fpr_f29_mips, fpr_f30_mips, fpr_f31_mips,
fpr_fcsr_mips, fpr_fir_mips, fpr_config5_mips,
LLDB_INVALID_REGNUM // register sets need to end with this flag
};
static_assert((sizeof(g_fp_regnums_mips) / sizeof(g_fp_regnums_mips[0])) - 1 ==
k_num_fpr_registers_mips,
"g_fp_regnums_mips has wrong number of register infos");
// mips MSA registers.
const uint32_t g_msa_regnums_mips[] = {
msa_w0_mips, msa_w1_mips, msa_w2_mips, msa_w3_mips,
msa_w4_mips, msa_w5_mips, msa_w6_mips, msa_w7_mips,
msa_w8_mips, msa_w9_mips, msa_w10_mips, msa_w11_mips,
msa_w12_mips, msa_w13_mips, msa_w14_mips, msa_w15_mips,
msa_w16_mips, msa_w17_mips, msa_w18_mips, msa_w19_mips,
msa_w20_mips, msa_w21_mips, msa_w22_mips, msa_w23_mips,
msa_w24_mips, msa_w25_mips, msa_w26_mips, msa_w27_mips,
msa_w28_mips, msa_w29_mips, msa_w30_mips, msa_w31_mips,
msa_fcsr_mips, msa_fir_mips, msa_mcsr_mips, msa_mir_mips,
msa_config5_mips,
LLDB_INVALID_REGNUM // register sets need to end with this flag
};
static_assert((sizeof(g_msa_regnums_mips) / sizeof(g_msa_regnums_mips[0])) -
1 ==
k_num_msa_registers_mips,
"g_msa_regnums_mips has wrong number of register infos");
// Number of register sets provided by this context.
constexpr size_t k_num_register_sets = 3;
// Register sets for mips.
static const RegisterSet g_reg_sets_mips[k_num_register_sets] = {
{"General Purpose Registers", "gpr", k_num_gpr_registers_mips,
g_gp_regnums_mips},
{"Floating Point Registers", "fpu", k_num_fpr_registers_mips,
g_fp_regnums_mips},
{"MSA Registers", "msa", k_num_msa_registers_mips, g_msa_regnums_mips}};
uint32_t GetUserRegisterInfoCount(bool msa_present) {
if (msa_present)
return static_cast<uint32_t>(k_num_user_registers_mips);
@ -56,6 +123,25 @@ const RegisterInfo *RegisterContextLinux_mips::GetRegisterInfo() const {
}
}
const RegisterSet *
RegisterContextLinux_mips::GetRegisterSet(size_t set) const {
if (set >= k_num_register_sets)
return nullptr;
switch (m_target_arch.GetMachine()) {
case llvm::Triple::mips:
case llvm::Triple::mipsel:
return &g_reg_sets_mips[set];
default:
assert(false && "Unhandled target architecture.");
return nullptr;
}
}
size_t
RegisterContextLinux_mips::GetRegisterSetCount() const {
return k_num_register_sets;
}
uint32_t RegisterContextLinux_mips::GetRegisterCount() const {
return static_cast<uint32_t>(sizeof(g_register_infos_mips) /
sizeof(g_register_infos_mips[0]));

View File

@ -22,6 +22,10 @@ public:
const lldb_private::RegisterInfo *GetRegisterInfo() const override;
const lldb_private::RegisterSet *GetRegisterSet(size_t set) const;
size_t GetRegisterSetCount() const;
uint32_t GetRegisterCount() const override;
uint32_t GetUserRegisterCount() const override;

View File

@ -7,7 +7,6 @@
//
//===---------------------------------------------------------------------===//
#if defined(__mips__)
#include <stddef.h>
#include <vector>
@ -41,6 +40,101 @@ using namespace lldb_private;
#include "RegisterInfos_mips.h"
#undef DECLARE_REGISTER_INFOS_MIPS_STRUCT
// mips64 general purpose registers.
const uint32_t g_gp_regnums_mips64[] = {
gpr_zero_mips64, gpr_r1_mips64, gpr_r2_mips64,
gpr_r3_mips64, gpr_r4_mips64, gpr_r5_mips64,
gpr_r6_mips64, gpr_r7_mips64, gpr_r8_mips64,
gpr_r9_mips64, gpr_r10_mips64, gpr_r11_mips64,
gpr_r12_mips64, gpr_r13_mips64, gpr_r14_mips64,
gpr_r15_mips64, gpr_r16_mips64, gpr_r17_mips64,
gpr_r18_mips64, gpr_r19_mips64, gpr_r20_mips64,
gpr_r21_mips64, gpr_r22_mips64, gpr_r23_mips64,
gpr_r24_mips64, gpr_r25_mips64, gpr_r26_mips64,
gpr_r27_mips64, gpr_gp_mips64, gpr_sp_mips64,
gpr_r30_mips64, gpr_ra_mips64, gpr_sr_mips64,
gpr_mullo_mips64, gpr_mulhi_mips64, gpr_badvaddr_mips64,
gpr_cause_mips64, gpr_pc_mips64, gpr_config5_mips64,
LLDB_INVALID_REGNUM // register sets need to end with this flag
};
static_assert((sizeof(g_gp_regnums_mips64) / sizeof(g_gp_regnums_mips64[0])) -
1 ==
k_num_gpr_registers_mips64,
"g_gp_regnums_mips64 has wrong number of register infos");
// mips64 floating point registers.
const uint32_t g_fp_regnums_mips64[] = {
fpr_f0_mips64, fpr_f1_mips64, fpr_f2_mips64, fpr_f3_mips64,
fpr_f4_mips64, fpr_f5_mips64, fpr_f6_mips64, fpr_f7_mips64,
fpr_f8_mips64, fpr_f9_mips64, fpr_f10_mips64, fpr_f11_mips64,
fpr_f12_mips64, fpr_f13_mips64, fpr_f14_mips64, fpr_f15_mips64,
fpr_f16_mips64, fpr_f17_mips64, fpr_f18_mips64, fpr_f19_mips64,
fpr_f20_mips64, fpr_f21_mips64, fpr_f22_mips64, fpr_f23_mips64,
fpr_f24_mips64, fpr_f25_mips64, fpr_f26_mips64, fpr_f27_mips64,
fpr_f28_mips64, fpr_f29_mips64, fpr_f30_mips64, fpr_f31_mips64,
fpr_fcsr_mips64, fpr_fir_mips64, fpr_config5_mips64,
LLDB_INVALID_REGNUM // register sets need to end with this flag
};
static_assert((sizeof(g_fp_regnums_mips64) / sizeof(g_fp_regnums_mips64[0])) -
1 ==
k_num_fpr_registers_mips64,
"g_fp_regnums_mips64 has wrong number of register infos");
// mips64 MSA registers.
const uint32_t g_msa_regnums_mips64[] = {
msa_w0_mips64, msa_w1_mips64, msa_w2_mips64, msa_w3_mips64,
msa_w4_mips64, msa_w5_mips64, msa_w6_mips64, msa_w7_mips64,
msa_w8_mips64, msa_w9_mips64, msa_w10_mips64, msa_w11_mips64,
msa_w12_mips64, msa_w13_mips64, msa_w14_mips64, msa_w15_mips64,
msa_w16_mips64, msa_w17_mips64, msa_w18_mips64, msa_w19_mips64,
msa_w20_mips64, msa_w21_mips64, msa_w22_mips64, msa_w23_mips64,
msa_w24_mips64, msa_w25_mips64, msa_w26_mips64, msa_w27_mips64,
msa_w28_mips64, msa_w29_mips64, msa_w30_mips64, msa_w31_mips64,
msa_fcsr_mips64, msa_fir_mips64, msa_mcsr_mips64, msa_mir_mips64,
msa_config5_mips64,
LLDB_INVALID_REGNUM // register sets need to end with this flag
};
static_assert((sizeof(g_msa_regnums_mips64) / sizeof(g_msa_regnums_mips64[0])) -
1 ==
k_num_msa_registers_mips64,
"g_msa_regnums_mips64 has wrong number of register infos");
// Number of register sets provided by this context.
constexpr size_t k_num_register_sets = 3;
// Register sets for mips64.
static const RegisterSet g_reg_sets_mips64[k_num_register_sets] = {
{"General Purpose Registers", "gpr", k_num_gpr_registers_mips64,
g_gp_regnums_mips64},
{"Floating Point Registers", "fpu", k_num_fpr_registers_mips64,
g_fp_regnums_mips64},
{"MSA Registers", "msa", k_num_msa_registers_mips64, g_msa_regnums_mips64},
};
const RegisterSet *
RegisterContextLinux_mips64::GetRegisterSet(size_t set) const {
if (set >= k_num_register_sets)
return nullptr;
switch (m_target_arch.GetMachine()) {
case llvm::Triple::mips64:
case llvm::Triple::mips64el:
return &g_reg_sets_mips64[set];
default:
assert(false && "Unhandled target architecture.");
return nullptr;
}
return nullptr;
}
size_t
RegisterContextLinux_mips64::GetRegisterSetCount() const {
return k_num_register_sets;
}
static const RegisterInfo *GetRegisterInfoPtr(const ArchSpec &target_arch) {
switch (target_arch.GetMachine()) {
case llvm::Triple::mips64:
@ -116,4 +210,3 @@ uint32_t RegisterContextLinux_mips64::GetUserRegisterCount() const {
return m_user_register_count;
}
#endif

View File

@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
#if defined(__mips__)
#ifndef liblldb_RegisterContextLinux_mips64_H_
#define liblldb_RegisterContextLinux_mips64_H_
@ -24,6 +22,10 @@ public:
const lldb_private::RegisterInfo *GetRegisterInfo() const override;
const lldb_private::RegisterSet *GetRegisterSet(size_t set) const;
size_t GetRegisterSetCount() const;
uint32_t GetRegisterCount() const override;
uint32_t GetUserRegisterCount() const override;
@ -36,4 +38,3 @@ private:
#endif
#endif

View File

@ -22,36 +22,22 @@
#include "Plugins/Process/elf-core/ProcessElfCore.h"
#include "RegisterContextPOSIX_mips64.h"
#include "RegisterContextFreeBSD_mips64.h"
#include "RegisterContextLinux_mips64.h"
#include "RegisterContextLinux_mips.h"
using namespace lldb_private;
using namespace lldb;
static const uint32_t g_gpr_regnums[] = {
gpr_zero_mips64, gpr_r1_mips64, gpr_r2_mips64, gpr_r3_mips64,
gpr_r4_mips64, gpr_r5_mips64, gpr_r6_mips64, gpr_r7_mips64,
gpr_r8_mips64, gpr_r9_mips64, gpr_r10_mips64, gpr_r11_mips64,
gpr_r12_mips64, gpr_r13_mips64, gpr_r14_mips64, gpr_r15_mips64,
gpr_r16_mips64, gpr_r17_mips64, gpr_r18_mips64, gpr_r19_mips64,
gpr_r20_mips64, gpr_r21_mips64, gpr_r22_mips64, gpr_r23_mips64,
gpr_r24_mips64, gpr_r25_mips64, gpr_r26_mips64, gpr_r27_mips64,
gpr_gp_mips64, gpr_sp_mips64, gpr_r30_mips64, gpr_ra_mips64,
gpr_sr_mips64, gpr_mullo_mips64, gpr_mulhi_mips64, gpr_badvaddr_mips64,
gpr_cause_mips64, gpr_pc_mips64, gpr_ic_mips64, gpr_dummy_mips64};
// Number of register sets provided by this context.
enum { k_num_register_sets = 1 };
static const RegisterSet g_reg_sets_mips64[k_num_register_sets] = {
{"General Purpose Registers", "gpr", k_num_gpr_registers_mips64,
g_gpr_regnums},
};
bool RegisterContextPOSIX_mips64::IsGPR(unsigned reg) {
return reg <= k_num_gpr_registers_mips64; // GPR's come first.
return reg < m_registers_count[gpr_registers_count]; // GPR's come first.
}
bool RegisterContextPOSIX_mips64::IsFPR(unsigned reg) {
// XXX
int set = GetRegisterSetCount();
if (set > 1)
return reg < (m_registers_count[fpr_registers_count]
+ m_registers_count[gpr_registers_count]);
return false;
}
@ -60,6 +46,18 @@ RegisterContextPOSIX_mips64::RegisterContextPOSIX_mips64(
RegisterInfoInterface *register_info)
: RegisterContext(thread, concrete_frame_idx) {
m_register_info_ap.reset(register_info);
m_num_registers = GetRegisterCount();
int set = GetRegisterSetCount();
const RegisterSet *reg_set_ptr;
for(int i = 0; i < set; ++i) {
reg_set_ptr = GetRegisterSet(i);
m_registers_count[i] = reg_set_ptr->num_registers;
}
assert(m_num_registers == m_registers_count[gpr_registers_count] +
m_registers_count[fpr_registers_count] +
m_registers_count[msa_registers_count]);
// elf-core yet to support ReadFPR()
ProcessSP base = CalculateProcess();
@ -74,18 +72,17 @@ void RegisterContextPOSIX_mips64::Invalidate() {}
void RegisterContextPOSIX_mips64::InvalidateAllRegisters() {}
unsigned RegisterContextPOSIX_mips64::GetRegisterOffset(unsigned reg) {
assert(reg < k_num_registers_mips64 && "Invalid register number.");
assert(reg < m_num_registers && "Invalid register number.");
return GetRegisterInfo()[reg].byte_offset;
}
unsigned RegisterContextPOSIX_mips64::GetRegisterSize(unsigned reg) {
assert(reg < k_num_registers_mips64 && "Invalid register number.");
assert(reg < m_num_registers && "Invalid register number.");
return GetRegisterInfo()[reg].byte_size;
}
size_t RegisterContextPOSIX_mips64::GetRegisterCount() {
size_t num_registers = k_num_registers_mips64;
return num_registers;
return m_register_info_ap->GetRegisterCount();
}
size_t RegisterContextPOSIX_mips64::GetGPRSize() {
@ -101,31 +98,59 @@ const RegisterInfo *RegisterContextPOSIX_mips64::GetRegisterInfo() {
const RegisterInfo *
RegisterContextPOSIX_mips64::GetRegisterInfoAtIndex(size_t reg) {
if (reg < k_num_registers_mips64)
if (reg < m_num_registers)
return &GetRegisterInfo()[reg];
else
return NULL;
}
size_t RegisterContextPOSIX_mips64::GetRegisterSetCount() {
size_t sets = 0;
for (size_t set = 0; set < k_num_register_sets; ++set) {
if (IsRegisterSetAvailable(set))
++sets;
ArchSpec target_arch = m_register_info_ap->GetTargetArchitecture();
switch (target_arch.GetTriple().getOS()) {
case llvm::Triple::Linux: {
if ((target_arch.GetMachine() == llvm::Triple::mipsel) ||
(target_arch.GetMachine() == llvm::Triple::mips)) {
const auto *context = static_cast<const RegisterContextLinux_mips *>
(m_register_info_ap.get());
return context->GetRegisterSetCount();
}
const auto *context = static_cast<const RegisterContextLinux_mips64 *>
(m_register_info_ap.get());
return context->GetRegisterSetCount();
}
default: {
const auto *context = static_cast<const RegisterContextFreeBSD_mips64 *>
(m_register_info_ap.get());
return context->GetRegisterSetCount();
}
}
return sets;
}
const RegisterSet *RegisterContextPOSIX_mips64::GetRegisterSet(size_t set) {
if (IsRegisterSetAvailable(set))
return &g_reg_sets_mips64[set];
else
return NULL;
ArchSpec target_arch = m_register_info_ap->GetTargetArchitecture();
switch (target_arch.GetTriple().getOS()) {
case llvm::Triple::Linux: {
if ((target_arch.GetMachine() == llvm::Triple::mipsel) ||
(target_arch.GetMachine() == llvm::Triple::mips)) {
const auto *context = static_cast<const RegisterContextLinux_mips *>
(m_register_info_ap.get());
return context->GetRegisterSet(set);
}
const auto *context = static_cast<const RegisterContextLinux_mips64 *>
(m_register_info_ap.get());
return context->GetRegisterSet(set);
}
default: {
const auto *context = static_cast<const RegisterContextFreeBSD_mips64 *>
(m_register_info_ap.get());
return context->GetRegisterSet(set);
}
}
}
const char *RegisterContextPOSIX_mips64::GetRegisterName(unsigned reg) {
assert(reg < k_num_registers_mips64 && "Invalid register offset.");
assert(reg < m_num_registers && "Invalid register offset.");
return GetRegisterInfo()[reg].name;
}
@ -141,7 +166,7 @@ lldb::ByteOrder RegisterContextPOSIX_mips64::GetByteOrder() {
}
bool RegisterContextPOSIX_mips64::IsRegisterSetAvailable(size_t set_index) {
size_t num_sets = k_num_register_sets;
size_t num_sets = GetRegisterSetCount();
return (set_index < num_sets);
}
@ -150,7 +175,7 @@ bool RegisterContextPOSIX_mips64::IsRegisterSetAvailable(size_t set_index) {
// object file sections that contain register numbers in them.
uint32_t RegisterContextPOSIX_mips64::ConvertRegisterKindToRegisterNumber(
lldb::RegisterKind kind, uint32_t num) {
const uint32_t num_regs = GetRegisterCount();
const uint32_t num_regs = m_num_registers;
assert(kind < kNumRegisterKinds);
for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) {

View File

@ -16,7 +16,6 @@
// Project includes
#include "RegisterContext_mips.h"
#include "RegisterInfoInterface.h"
#include "lldb-mips-freebsd-register-enums.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Utility/Log.h"
@ -26,6 +25,14 @@ class ProcessMonitor;
class RegisterContextPOSIX_mips64 : public lldb_private::RegisterContext {
public:
enum Register_count{
gpr_registers_count = 0,
fpr_registers_count,
msa_registers_count,
register_set_count
};
RegisterContextPOSIX_mips64(
lldb_private::Thread &thread, uint32_t concrete_frame_idx,
lldb_private::RegisterInfoInterface *register_info);
@ -56,8 +63,8 @@ public:
uint32_t num) override;
protected:
uint64_t
m_gpr_mips64[k_num_gpr_registers_mips64]; // general purpose registers.
uint32_t m_num_registers;
uint8_t m_registers_count[register_set_count];
std::unique_ptr<lldb_private::RegisterInfoInterface>
m_register_info_ap; // Register Info Interface (FreeBSD or Linux)

View File

@ -22,6 +22,10 @@ RegisterContextCorePOSIX_mips64::RegisterContextCorePOSIX_mips64(
new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
m_gpr.SetData(m_gpr_buffer);
m_gpr.SetByteOrder(gpregset.GetByteOrder());
m_fpr_buffer.reset(
new DataBufferHeap(fpregset.GetDataStart(), fpregset.GetByteSize()));
m_fpr.SetData(m_fpr_buffer);
m_fpr.SetByteOrder(fpregset.GetByteOrder());
}
RegisterContextCorePOSIX_mips64::~RegisterContextCorePOSIX_mips64() {}
@ -42,12 +46,24 @@ bool RegisterContextCorePOSIX_mips64::WriteFPR() {
bool RegisterContextCorePOSIX_mips64::ReadRegister(const RegisterInfo *reg_info,
RegisterValue &value) {
lldb::offset_t offset = reg_info->byte_offset;
uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
if (offset == reg_info->byte_offset + reg_info->byte_size) {
lldb_private::ArchSpec arch = m_register_info_ap->GetTargetArchitecture();
uint64_t v;
if (IsGPR(reg_info->kinds[lldb::eRegisterKindLLDB])) {
if (reg_info->byte_size == 4 && !(arch.GetMachine() == llvm::Triple::mips64el))
// In case of 32bit core file, the register data are placed at 4 byte
// offset.
offset = offset / 2;
v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
value = v;
return true;
}
} else if (IsFPR(reg_info->kinds[lldb::eRegisterKindLLDB])) {
offset = offset - sizeof(GPR_linux_mips);
v =m_fpr.GetMaxU64(&offset, reg_info->byte_size);
value = v;
return true;
}
return false;
}

View File

@ -51,7 +51,9 @@ protected:
private:
lldb::DataBufferSP m_gpr_buffer;
lldb::DataBufferSP m_fpr_buffer;
lldb_private::DataExtractor m_gpr;
lldb_private::DataExtractor m_fpr;
};
#endif // liblldb_RegisterContextCorePOSIX_mips64_h_

View File

@ -18,6 +18,8 @@
#include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h"
#include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h"
#include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h"
#include "Plugins/Process/Utility/RegisterContextLinux_mips64.h"
#include "Plugins/Process/Utility/RegisterContextLinux_mips.h"
#include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
#include "Plugins/Process/Utility/RegisterContextLinux_s390x.h"
#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
@ -132,6 +134,14 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
case llvm::Triple::aarch64:
reg_interface = new RegisterInfoPOSIX_arm64(arch);
break;
case llvm::Triple::mipsel:
case llvm::Triple::mips:
reg_interface = new RegisterContextLinux_mips(arch);
break;
case llvm::Triple::mips64el:
case llvm::Triple::mips64:
reg_interface = new RegisterContextLinux_mips64(arch);
break;
case llvm::Triple::systemz:
reg_interface = new RegisterContextLinux_s390x(arch);
break;
@ -187,7 +197,13 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm(
*this, reg_interface, m_gpregset_data, m_fpregset_data));
break;
case llvm::Triple::mipsel:
case llvm::Triple::mips:
m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64(
*this, reg_interface, m_gpregset_data, m_fpregset_data));
break;
case llvm::Triple::mips64:
case llvm::Triple::mips64el:
m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64(
*this, reg_interface, m_gpregset_data, m_fpregset_data));
break;
@ -233,6 +249,31 @@ ELFLinuxPrStatus::ELFLinuxPrStatus() {
memset(this, 0, sizeof(ELFLinuxPrStatus));
}
size_t ELFLinuxPrStatus::GetSize(lldb_private::ArchSpec &arch) {
constexpr size_t mips_linux_pr_status_size_o32 = 96;
constexpr size_t mips_linux_pr_status_size_n32 = 72;
if (arch.IsMIPS()) {
std::string abi = arch.GetTargetABI();
assert(!abi.empty() && "ABI is not set");
if (!abi.compare("n64"))
return sizeof(ELFLinuxPrStatus);
else if (!abi.compare("o32"))
return mips_linux_pr_status_size_o32;
// N32 ABI
return mips_linux_pr_status_size_n32;
}
switch (arch.GetCore()) {
case lldb_private::ArchSpec::eCore_s390x_generic:
case lldb_private::ArchSpec::eCore_x86_64_x86_64:
return sizeof(ELFLinuxPrStatus);
case lldb_private::ArchSpec::eCore_x86_32_i386:
case lldb_private::ArchSpec::eCore_x86_32_i486:
return 72;
default:
return 0;
}
}
Error ELFLinuxPrStatus::Parse(DataExtractor &data, ArchSpec &arch) {
Error error;
if (GetSize(arch) > data.GetByteSize()) {
@ -282,6 +323,27 @@ ELFLinuxPrPsInfo::ELFLinuxPrPsInfo() {
memset(this, 0, sizeof(ELFLinuxPrPsInfo));
}
size_t ELFLinuxPrPsInfo::GetSize(lldb_private::ArchSpec &arch) {
constexpr size_t mips_linux_pr_psinfo_size_o32_n32 = 128;
if (arch.IsMIPS()) {
uint8_t address_byte_size = arch.GetAddressByteSize();
if (address_byte_size == 8)
return sizeof(ELFLinuxPrPsInfo);
return mips_linux_pr_psinfo_size_o32_n32;
}
switch (arch.GetCore()) {
case lldb_private::ArchSpec::eCore_s390x_generic:
case lldb_private::ArchSpec::eCore_x86_64_x86_64:
return sizeof(ELFLinuxPrPsInfo);
case lldb_private::ArchSpec::eCore_x86_32_i386:
case lldb_private::ArchSpec::eCore_x86_32_i486:
return 124;
default:
return 0;
}
}
Error ELFLinuxPrPsInfo::Parse(DataExtractor &data, ArchSpec &arch) {
Error error;
ByteOrder byteorder = data.GetByteOrder();
@ -305,9 +367,15 @@ Error ELFLinuxPrPsInfo::Parse(DataExtractor &data, ArchSpec &arch) {
pr_flag = data.GetPointer(&offset);
if (arch.IsMIPS()) {
// The pr_uid and pr_gid is always 32 bit irrespective of platforms
pr_uid = data.GetU32(&offset);
pr_gid = data.GetU32(&offset);
} else {
// 16 bit on 32 bit platforms, 32 bit on 64 bit platforms
pr_uid = data.GetMaxU64(&offset, data.GetAddressByteSize() >> 1);
pr_gid = data.GetMaxU64(&offset, data.GetAddressByteSize() >> 1);
}
pr_pid = data.GetU32(&offset);
pr_ppid = data.GetU32(&offset);
@ -330,6 +398,21 @@ Error ELFLinuxPrPsInfo::Parse(DataExtractor &data, ArchSpec &arch) {
//----------------------------------------------------------------
ELFLinuxSigInfo::ELFLinuxSigInfo() { memset(this, 0, sizeof(ELFLinuxSigInfo)); }
size_t ELFLinuxSigInfo::GetSize(const lldb_private::ArchSpec &arch) {
if (arch.IsMIPS())
return sizeof(ELFLinuxSigInfo);
switch (arch.GetCore()) {
case lldb_private::ArchSpec::eCore_x86_64_x86_64:
return sizeof(ELFLinuxSigInfo);
case lldb_private::ArchSpec::eCore_s390x_generic:
case lldb_private::ArchSpec::eCore_x86_32_i386:
case lldb_private::ArchSpec::eCore_x86_32_i486:
return 12;
default:
return 0;
}
}
Error ELFLinuxSigInfo::Parse(DataExtractor &data, const ArchSpec &arch) {
Error error;
if (GetSize(arch) > data.GetByteSize()) {

View File

@ -65,18 +65,7 @@ struct ELFLinuxPrStatus {
// 32 bit - hardcoded because we are reusing the struct, but some of the
// members are smaller -
// so the layout is not the same
static size_t GetSize(lldb_private::ArchSpec &arch) {
switch (arch.GetCore()) {
case lldb_private::ArchSpec::eCore_s390x_generic:
case lldb_private::ArchSpec::eCore_x86_64_x86_64:
return sizeof(ELFLinuxPrStatus);
case lldb_private::ArchSpec::eCore_x86_32_i386:
case lldb_private::ArchSpec::eCore_x86_32_i486:
return 72;
default:
return 0;
}
}
static size_t GetSize(lldb_private::ArchSpec &arch);
};
static_assert(sizeof(ELFLinuxPrStatus) == 112,
@ -97,18 +86,7 @@ struct ELFLinuxSigInfo {
// 32 bit - hardcoded because we are reusing the struct, but some of the
// members are smaller -
// so the layout is not the same
static size_t GetSize(const lldb_private::ArchSpec &arch) {
switch (arch.GetCore()) {
case lldb_private::ArchSpec::eCore_x86_64_x86_64:
return sizeof(ELFLinuxSigInfo);
case lldb_private::ArchSpec::eCore_s390x_generic:
case lldb_private::ArchSpec::eCore_x86_32_i386:
case lldb_private::ArchSpec::eCore_x86_32_i486:
return 12;
default:
return 0;
}
}
static size_t GetSize(const lldb_private::ArchSpec &arch);
};
static_assert(sizeof(ELFLinuxSigInfo) == 12,
@ -143,18 +121,7 @@ struct ELFLinuxPrPsInfo {
// 32 bit - hardcoded because we are reusing the struct, but some of the
// members are smaller -
// so the layout is not the same
static size_t GetSize(lldb_private::ArchSpec &arch) {
switch (arch.GetCore()) {
case lldb_private::ArchSpec::eCore_s390x_generic:
case lldb_private::ArchSpec::eCore_x86_64_x86_64:
return sizeof(ELFLinuxPrPsInfo);
case lldb_private::ArchSpec::eCore_x86_32_i386:
case lldb_private::ArchSpec::eCore_x86_32_i486:
return 124;
default:
return 0;
}
}
static size_t GetSize(lldb_private::ArchSpec &arch);
};
static_assert(sizeof(ELFLinuxPrPsInfo) == 136,