[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 && if (core2 >= ArchSpec::kCore_mips32el_first &&
core2 <= ArchSpec::kCore_mips32el_last) core2 <= ArchSpec::kCore_mips32el_last)
return true; return true;
try_inverse = false; try_inverse = true;
} }
break; break;

View File

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

View File

@ -80,152 +80,6 @@ struct pt_watch_regs default_watch_regs;
using namespace lldb_private; using namespace lldb_private;
using namespace lldb_private::process_linux; 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 *
NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux( NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
const ArchSpec &target_arch, NativeThreadProtocol &native_thread, const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
@ -244,15 +98,12 @@ NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
static RegisterInfoInterface * static RegisterInfoInterface *
CreateRegisterInfoInterface(const ArchSpec &target_arch) { 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. // 32-bit hosts run with a RegisterContextLinux_mips context.
return new RegisterContextLinux_mips( return new RegisterContextLinux_mips(
target_arch, NativeRegisterContextLinux_mips64::IsMSAAvailable()); target_arch, NativeRegisterContextLinux_mips64::IsMSAAvailable());
} else { } 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( return new RegisterContextLinux_mips64(
target_arch, NativeRegisterContextLinux_mips64::IsMSAAvailable()); target_arch, NativeRegisterContextLinux_mips64::IsMSAAvailable());
} }
@ -307,7 +158,22 @@ NativeRegisterContextLinux_mips64::NativeRegisterContextLinux_mips64(
} }
uint32_t NativeRegisterContextLinux_mips64::GetRegisterSetCount() const { 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( lldb::addr_t NativeRegisterContextLinux_mips64::GetPCfromBreakpointLocation(
@ -357,16 +223,22 @@ lldb::addr_t NativeRegisterContextLinux_mips64::GetPCfromBreakpointLocation(
const RegisterSet * const RegisterSet *
NativeRegisterContextLinux_mips64::GetRegisterSet(uint32_t set_index) const { NativeRegisterContextLinux_mips64::GetRegisterSet(uint32_t set_index) const {
if (set_index >= k_num_register_sets) if (set_index >= GetRegisterSetCount())
return nullptr; return nullptr;
switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) { switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
case llvm::Triple::mips64: case llvm::Triple::mips64:
case llvm::Triple::mips64el: case llvm::Triple::mips64el: {
return &g_reg_sets_mips64[set_index]; const auto context = static_cast<const RegisterContextLinux_mips64 &>
(GetRegisterInfoInterface());
return context.GetRegisterSet(set_index);
}
case llvm::Triple::mips: case llvm::Triple::mips:
case llvm::Triple::mipsel: case llvm::Triple::mipsel: {
return &g_reg_sets_mips[set_index]; const auto context = static_cast<const RegisterContextLinux_mips &>
(GetRegisterInfoInterface());
return context.GetRegisterSet(set_index);
}
default: default:
llvm_unreachable("Unhandled target architecture."); llvm_unreachable("Unhandled target architecture.");
} }

View File

@ -9,11 +9,33 @@
#include "RegisterContextFreeBSD_mips64.h" #include "RegisterContextFreeBSD_mips64.h"
#include "RegisterContextPOSIX_mips64.h" #include "RegisterContextPOSIX_mips64.h"
#include "lldb-mips-freebsd-register-enums.h"
#include <vector> #include <vector>
using namespace lldb_private; using namespace lldb_private;
using namespace lldb; 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 // http://svnweb.freebsd.org/base/head/sys/mips/include/regnum.h
typedef struct _GPR { typedef struct _GPR {
uint64_t zero; uint64_t zero;
@ -74,6 +96,19 @@ size_t RegisterContextFreeBSD_mips64::GetGPRSize() const {
return sizeof(GPR_freebsd_mips); 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 { const RegisterInfo *RegisterContextFreeBSD_mips64::GetRegisterInfo() const {
assert(m_target_arch.GetCore() == ArchSpec::eCore_mips64); assert(m_target_arch.GetCore() == ArchSpec::eCore_mips64);
return g_register_infos_mips64; return g_register_infos_mips64;

View File

@ -19,6 +19,10 @@ public:
size_t GetGPRSize() const override; 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; const lldb_private::RegisterInfo *GetRegisterInfo() const override;
uint32_t GetRegisterCount() const override; uint32_t GetRegisterCount() const override;

View File

@ -29,6 +29,73 @@ using namespace lldb;
#include "RegisterInfos_mips.h" #include "RegisterInfos_mips.h"
#undef DECLARE_REGISTER_INFOS_MIPS_STRUCT #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) { uint32_t GetUserRegisterInfoCount(bool msa_present) {
if (msa_present) if (msa_present)
return static_cast<uint32_t>(k_num_user_registers_mips); 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 { uint32_t RegisterContextLinux_mips::GetRegisterCount() const {
return static_cast<uint32_t>(sizeof(g_register_infos_mips) / return static_cast<uint32_t>(sizeof(g_register_infos_mips) /
sizeof(g_register_infos_mips[0])); sizeof(g_register_infos_mips[0]));

View File

@ -22,6 +22,10 @@ public:
const lldb_private::RegisterInfo *GetRegisterInfo() const override; 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 GetRegisterCount() const override;
uint32_t GetUserRegisterCount() const override; uint32_t GetUserRegisterCount() const override;

View File

@ -7,7 +7,6 @@
// //
//===---------------------------------------------------------------------===// //===---------------------------------------------------------------------===//
#if defined(__mips__)
#include <stddef.h> #include <stddef.h>
#include <vector> #include <vector>
@ -41,6 +40,101 @@ using namespace lldb_private;
#include "RegisterInfos_mips.h" #include "RegisterInfos_mips.h"
#undef DECLARE_REGISTER_INFOS_MIPS_STRUCT #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) { static const RegisterInfo *GetRegisterInfoPtr(const ArchSpec &target_arch) {
switch (target_arch.GetMachine()) { switch (target_arch.GetMachine()) {
case llvm::Triple::mips64: case llvm::Triple::mips64:
@ -116,4 +210,3 @@ uint32_t RegisterContextLinux_mips64::GetUserRegisterCount() const {
return m_user_register_count; return m_user_register_count;
} }
#endif

View File

@ -7,8 +7,6 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#if defined(__mips__)
#ifndef liblldb_RegisterContextLinux_mips64_H_ #ifndef liblldb_RegisterContextLinux_mips64_H_
#define liblldb_RegisterContextLinux_mips64_H_ #define liblldb_RegisterContextLinux_mips64_H_
@ -24,6 +22,10 @@ public:
const lldb_private::RegisterInfo *GetRegisterInfo() const override; 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 GetRegisterCount() const override;
uint32_t GetUserRegisterCount() const override; uint32_t GetUserRegisterCount() const override;
@ -36,4 +38,3 @@ private:
#endif #endif
#endif

View File

@ -22,36 +22,22 @@
#include "Plugins/Process/elf-core/ProcessElfCore.h" #include "Plugins/Process/elf-core/ProcessElfCore.h"
#include "RegisterContextPOSIX_mips64.h" #include "RegisterContextPOSIX_mips64.h"
#include "RegisterContextFreeBSD_mips64.h"
#include "RegisterContextLinux_mips64.h"
#include "RegisterContextLinux_mips.h"
using namespace lldb_private; using namespace lldb_private;
using namespace lldb; 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) { 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) { 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; return false;
} }
@ -60,6 +46,18 @@ RegisterContextPOSIX_mips64::RegisterContextPOSIX_mips64(
RegisterInfoInterface *register_info) RegisterInfoInterface *register_info)
: RegisterContext(thread, concrete_frame_idx) { : RegisterContext(thread, concrete_frame_idx) {
m_register_info_ap.reset(register_info); 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() // elf-core yet to support ReadFPR()
ProcessSP base = CalculateProcess(); ProcessSP base = CalculateProcess();
@ -74,18 +72,17 @@ void RegisterContextPOSIX_mips64::Invalidate() {}
void RegisterContextPOSIX_mips64::InvalidateAllRegisters() {} void RegisterContextPOSIX_mips64::InvalidateAllRegisters() {}
unsigned RegisterContextPOSIX_mips64::GetRegisterOffset(unsigned reg) { 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; return GetRegisterInfo()[reg].byte_offset;
} }
unsigned RegisterContextPOSIX_mips64::GetRegisterSize(unsigned reg) { 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; return GetRegisterInfo()[reg].byte_size;
} }
size_t RegisterContextPOSIX_mips64::GetRegisterCount() { size_t RegisterContextPOSIX_mips64::GetRegisterCount() {
size_t num_registers = k_num_registers_mips64; return m_register_info_ap->GetRegisterCount();
return num_registers;
} }
size_t RegisterContextPOSIX_mips64::GetGPRSize() { size_t RegisterContextPOSIX_mips64::GetGPRSize() {
@ -101,31 +98,59 @@ const RegisterInfo *RegisterContextPOSIX_mips64::GetRegisterInfo() {
const RegisterInfo * const RegisterInfo *
RegisterContextPOSIX_mips64::GetRegisterInfoAtIndex(size_t reg) { RegisterContextPOSIX_mips64::GetRegisterInfoAtIndex(size_t reg) {
if (reg < k_num_registers_mips64) if (reg < m_num_registers)
return &GetRegisterInfo()[reg]; return &GetRegisterInfo()[reg];
else else
return NULL; return NULL;
} }
size_t RegisterContextPOSIX_mips64::GetRegisterSetCount() { size_t RegisterContextPOSIX_mips64::GetRegisterSetCount() {
size_t sets = 0; ArchSpec target_arch = m_register_info_ap->GetTargetArchitecture();
for (size_t set = 0; set < k_num_register_sets; ++set) { switch (target_arch.GetTriple().getOS()) {
if (IsRegisterSetAvailable(set)) case llvm::Triple::Linux: {
++sets; 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) { const RegisterSet *RegisterContextPOSIX_mips64::GetRegisterSet(size_t set) {
if (IsRegisterSetAvailable(set)) ArchSpec target_arch = m_register_info_ap->GetTargetArchitecture();
return &g_reg_sets_mips64[set]; switch (target_arch.GetTriple().getOS()) {
else case llvm::Triple::Linux: {
return NULL; 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) { 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; return GetRegisterInfo()[reg].name;
} }
@ -141,7 +166,7 @@ lldb::ByteOrder RegisterContextPOSIX_mips64::GetByteOrder() {
} }
bool RegisterContextPOSIX_mips64::IsRegisterSetAvailable(size_t set_index) { 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); 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. // object file sections that contain register numbers in them.
uint32_t RegisterContextPOSIX_mips64::ConvertRegisterKindToRegisterNumber( uint32_t RegisterContextPOSIX_mips64::ConvertRegisterKindToRegisterNumber(
lldb::RegisterKind kind, uint32_t num) { lldb::RegisterKind kind, uint32_t num) {
const uint32_t num_regs = GetRegisterCount(); const uint32_t num_regs = m_num_registers;
assert(kind < kNumRegisterKinds); assert(kind < kNumRegisterKinds);
for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) { for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) {

View File

@ -16,7 +16,6 @@
// Project includes // Project includes
#include "RegisterContext_mips.h" #include "RegisterContext_mips.h"
#include "RegisterInfoInterface.h" #include "RegisterInfoInterface.h"
#include "lldb-mips-freebsd-register-enums.h"
#include "lldb/Target/RegisterContext.h" #include "lldb/Target/RegisterContext.h"
#include "lldb/Utility/Log.h" #include "lldb/Utility/Log.h"
@ -26,6 +25,14 @@ class ProcessMonitor;
class RegisterContextPOSIX_mips64 : public lldb_private::RegisterContext { class RegisterContextPOSIX_mips64 : public lldb_private::RegisterContext {
public: public:
enum Register_count{
gpr_registers_count = 0,
fpr_registers_count,
msa_registers_count,
register_set_count
};
RegisterContextPOSIX_mips64( RegisterContextPOSIX_mips64(
lldb_private::Thread &thread, uint32_t concrete_frame_idx, lldb_private::Thread &thread, uint32_t concrete_frame_idx,
lldb_private::RegisterInfoInterface *register_info); lldb_private::RegisterInfoInterface *register_info);
@ -56,8 +63,8 @@ public:
uint32_t num) override; uint32_t num) override;
protected: protected:
uint64_t uint32_t m_num_registers;
m_gpr_mips64[k_num_gpr_registers_mips64]; // general purpose registers. uint8_t m_registers_count[register_set_count];
std::unique_ptr<lldb_private::RegisterInfoInterface> std::unique_ptr<lldb_private::RegisterInfoInterface>
m_register_info_ap; // Register Info Interface (FreeBSD or Linux) 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())); new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
m_gpr.SetData(m_gpr_buffer); m_gpr.SetData(m_gpr_buffer);
m_gpr.SetByteOrder(gpregset.GetByteOrder()); 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() {} RegisterContextCorePOSIX_mips64::~RegisterContextCorePOSIX_mips64() {}
@ -42,12 +46,24 @@ bool RegisterContextCorePOSIX_mips64::WriteFPR() {
bool RegisterContextCorePOSIX_mips64::ReadRegister(const RegisterInfo *reg_info, bool RegisterContextCorePOSIX_mips64::ReadRegister(const RegisterInfo *reg_info,
RegisterValue &value) { RegisterValue &value) {
lldb::offset_t offset = reg_info->byte_offset; lldb::offset_t offset = reg_info->byte_offset;
uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size); lldb_private::ArchSpec arch = m_register_info_ap->GetTargetArchitecture();
if (offset == reg_info->byte_offset + reg_info->byte_size) { 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; value = v;
return true; 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; return false;
} }

View File

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

View File

@ -18,6 +18,8 @@
#include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h" #include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h"
#include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h" #include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h"
#include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.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_i386.h"
#include "Plugins/Process/Utility/RegisterContextLinux_s390x.h" #include "Plugins/Process/Utility/RegisterContextLinux_s390x.h"
#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h" #include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
@ -132,6 +134,14 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
case llvm::Triple::aarch64: case llvm::Triple::aarch64:
reg_interface = new RegisterInfoPOSIX_arm64(arch); reg_interface = new RegisterInfoPOSIX_arm64(arch);
break; 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: case llvm::Triple::systemz:
reg_interface = new RegisterContextLinux_s390x(arch); reg_interface = new RegisterContextLinux_s390x(arch);
break; break;
@ -187,7 +197,13 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm( m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm(
*this, reg_interface, m_gpregset_data, m_fpregset_data)); *this, reg_interface, m_gpregset_data, m_fpregset_data));
break; 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::mips64:
case llvm::Triple::mips64el:
m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64( m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64(
*this, reg_interface, m_gpregset_data, m_fpregset_data)); *this, reg_interface, m_gpregset_data, m_fpregset_data));
break; break;
@ -233,6 +249,31 @@ ELFLinuxPrStatus::ELFLinuxPrStatus() {
memset(this, 0, sizeof(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 ELFLinuxPrStatus::Parse(DataExtractor &data, ArchSpec &arch) {
Error error; Error error;
if (GetSize(arch) > data.GetByteSize()) { if (GetSize(arch) > data.GetByteSize()) {
@ -282,6 +323,27 @@ ELFLinuxPrPsInfo::ELFLinuxPrPsInfo() {
memset(this, 0, sizeof(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 ELFLinuxPrPsInfo::Parse(DataExtractor &data, ArchSpec &arch) {
Error error; Error error;
ByteOrder byteorder = data.GetByteOrder(); ByteOrder byteorder = data.GetByteOrder();
@ -305,9 +367,15 @@ Error ELFLinuxPrPsInfo::Parse(DataExtractor &data, ArchSpec &arch) {
pr_flag = data.GetPointer(&offset); 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 // 16 bit on 32 bit platforms, 32 bit on 64 bit platforms
pr_uid = data.GetMaxU64(&offset, data.GetAddressByteSize() >> 1); pr_uid = data.GetMaxU64(&offset, data.GetAddressByteSize() >> 1);
pr_gid = data.GetMaxU64(&offset, data.GetAddressByteSize() >> 1); pr_gid = data.GetMaxU64(&offset, data.GetAddressByteSize() >> 1);
}
pr_pid = data.GetU32(&offset); pr_pid = data.GetU32(&offset);
pr_ppid = 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)); } 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 ELFLinuxSigInfo::Parse(DataExtractor &data, const ArchSpec &arch) {
Error error; Error error;
if (GetSize(arch) > data.GetByteSize()) { 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 // 32 bit - hardcoded because we are reusing the struct, but some of the
// members are smaller - // members are smaller -
// so the layout is not the same // so the layout is not the same
static size_t GetSize(lldb_private::ArchSpec &arch) { 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_assert(sizeof(ELFLinuxPrStatus) == 112, static_assert(sizeof(ELFLinuxPrStatus) == 112,
@ -97,18 +86,7 @@ struct ELFLinuxSigInfo {
// 32 bit - hardcoded because we are reusing the struct, but some of the // 32 bit - hardcoded because we are reusing the struct, but some of the
// members are smaller - // members are smaller -
// so the layout is not the same // so the layout is not the same
static size_t GetSize(const lldb_private::ArchSpec &arch) { 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_assert(sizeof(ELFLinuxSigInfo) == 12, static_assert(sizeof(ELFLinuxSigInfo) == 12,
@ -143,18 +121,7 @@ struct ELFLinuxPrPsInfo {
// 32 bit - hardcoded because we are reusing the struct, but some of the // 32 bit - hardcoded because we are reusing the struct, but some of the
// members are smaller - // members are smaller -
// so the layout is not the same // so the layout is not the same
static size_t GetSize(lldb_private::ArchSpec &arch) { 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_assert(sizeof(ELFLinuxPrPsInfo) == 136, static_assert(sizeof(ELFLinuxPrPsInfo) == 136,