diff options
author | Ed Maste <emaste@freebsd.org> | 2013-10-10 00:59:47 +0000 |
---|---|---|
committer | Ed Maste <emaste@freebsd.org> | 2013-10-10 00:59:47 +0000 |
commit | b73f844be3be4bd71ffbe0e91e778810a1647b8e (patch) | |
tree | 3c74410c79efc7e18eb6b80160523cb09cae2515 | |
parent | e65ab9e80eec0e56235bd74c6d487e5a89f66146 (diff) | |
download | bcm5719-llvm-b73f844be3be4bd71ffbe0e91e778810a1647b8e.tar.gz bcm5719-llvm-b73f844be3be4bd71ffbe0e91e778810a1647b8e.zip |
POSIX RegisterContext for mips64
Based on the POSIX x86_64 register context. This is sufficient for opening
a mips64 (big endian) core file. Subsequent changes will connect the
disassembler, dynamic loader support, ABI, etc.
Review: http://llvm-reviews.chandlerc.com/D1873
llvm-svn: 192335
14 files changed, 795 insertions, 3 deletions
diff --git a/lldb/include/lldb/Core/ArchSpec.h b/lldb/include/lldb/Core/ArchSpec.h index 5957ffd3d5d..7f2fd77a093 100644 --- a/lldb/include/lldb/Core/ArchSpec.h +++ b/lldb/include/lldb/Core/ArchSpec.h @@ -62,6 +62,8 @@ public: eCore_thumbv7m, eCore_thumbv7em, + eCore_mips64, + eCore_ppc_generic, eCore_ppc_ppc601, eCore_ppc_ppc602, diff --git a/lldb/source/Core/ArchSpec.cpp b/lldb/source/Core/ArchSpec.cpp index 36d46ad54e9..f2eb3751a4b 100644 --- a/lldb/source/Core/ArchSpec.cpp +++ b/lldb/source/Core/ArchSpec.cpp @@ -76,7 +76,8 @@ static const CoreDefinition g_core_definitions[ArchSpec::kNumCores] = { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb , ArchSpec::eCore_thumbv7k , "thumbv7k" }, { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb , ArchSpec::eCore_thumbv7m , "thumbv7m" }, { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb , ArchSpec::eCore_thumbv7em , "thumbv7em" }, - + + { eByteOrderBig , 8, 4, 4, llvm::Triple::mips64 , ArchSpec::eCore_mips64 , "mips64" }, { eByteOrderBig , 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_generic , "ppc" }, { eByteOrderBig , 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc601 , "ppc601" }, @@ -233,7 +234,8 @@ static const ArchDefinitionEntry g_elf_arch_entries[] = { ArchSpec::eCore_ppc64_generic , llvm::ELF::EM_PPC64 , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // PowerPC64 { ArchSpec::eCore_arm_generic , llvm::ELF::EM_ARM , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // ARM { ArchSpec::eCore_sparc9_generic , llvm::ELF::EM_SPARCV9, LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // SPARC V9 - { ArchSpec::eCore_x86_64_x86_64 , llvm::ELF::EM_X86_64 , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu } // AMD64 + { ArchSpec::eCore_x86_64_x86_64 , llvm::ELF::EM_X86_64 , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // AMD64 + { ArchSpec::eCore_mips64 , llvm::ELF::EM_MIPS , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu } // MIPS }; static const ArchDefinition g_elf_arch_def = { diff --git a/lldb/source/Plugins/Process/POSIX/CMakeLists.txt b/lldb/source/Plugins/Process/POSIX/CMakeLists.txt index 48c44770c9c..02cb180f106 100644 --- a/lldb/source/Plugins/Process/POSIX/CMakeLists.txt +++ b/lldb/source/Plugins/Process/POSIX/CMakeLists.txt @@ -10,9 +10,11 @@ add_lldb_library(lldbPluginProcessPOSIX ProcessMessage.cpp ProcessPOSIX.cpp ProcessPOSIXLog.cpp + RegisterContextPOSIX_mips64.cpp RegisterContextPOSIX_x86.cpp RegisterContextPOSIXProcessMonitor_x86.cpp RegisterContextFreeBSD_i386.cpp + RegisterContextFreeBSD_mips64.cpp RegisterContextFreeBSD_x86_64.cpp RegisterContextLinux_i386.cpp RegisterContextLinux_x86_64.cpp diff --git a/lldb/source/Plugins/Process/POSIX/RegisterContextFreeBSD_mips64.cpp b/lldb/source/Plugins/Process/POSIX/RegisterContextFreeBSD_mips64.cpp new file mode 100644 index 00000000000..4714251fd2d --- /dev/null +++ b/lldb/source/Plugins/Process/POSIX/RegisterContextFreeBSD_mips64.cpp @@ -0,0 +1,90 @@ +//===-- RegisterContextFreeBSD_mips64.cpp ----------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===---------------------------------------------------------------------===// + +#include <vector> +#include "RegisterContextPOSIX_mips64.h" +#include "RegisterContextFreeBSD_mips64.h" + +using namespace lldb_private; +using namespace lldb; + +// http://svnweb.freebsd.org/base/head/sys/mips/include/regnum.h +typedef struct _GPR +{ + uint64_t zero; + uint64_t r1; + uint64_t r2; + uint64_t r3; + uint64_t r4; + uint64_t r5; + uint64_t r6; + uint64_t r7; + uint64_t r8; + uint64_t r9; + uint64_t r10; + uint64_t r11; + uint64_t r12; + uint64_t r13; + uint64_t r14; + uint64_t r15; + uint64_t r16; + uint64_t r17; + uint64_t r18; + uint64_t r19; + uint64_t r20; + uint64_t r21; + uint64_t r22; + uint64_t r23; + uint64_t r24; + uint64_t r25; + uint64_t r26; + uint64_t r27; + uint64_t gp; + uint64_t sp; + uint64_t r30; + uint64_t ra; + uint64_t sr; + uint64_t mullo; + uint64_t mulhi; + uint64_t badvaddr; + uint64_t cause; + uint64_t pc; + uint64_t ic; + uint64_t dummy; +} GPR; + +//--------------------------------------------------------------------------- +// Include RegisterInfos_mips64 to declare our g_register_infos_mips64 structure. +//--------------------------------------------------------------------------- +#define DECLARE_REGISTER_INFOS_MIPS64_STRUCT +#include "RegisterInfos_mips64.h" +#undef DECLARE_REGISTER_INFOS_MIPS64_STRUCT + +RegisterContextFreeBSD_mips64::RegisterContextFreeBSD_mips64(const ArchSpec &target_arch) : + RegisterInfoInterface(target_arch) +{ +} + +RegisterContextFreeBSD_mips64::~RegisterContextFreeBSD_mips64() +{ +} + +size_t +RegisterContextFreeBSD_mips64::GetGPRSize() +{ + return sizeof(GPR); +} + +const RegisterInfo * +RegisterContextFreeBSD_mips64::GetRegisterInfo() +{ + assert (m_target_arch.GetCore() == ArchSpec::eCore_mips64); + return g_register_infos_mips64; +} + diff --git a/lldb/source/Plugins/Process/POSIX/RegisterContextFreeBSD_mips64.h b/lldb/source/Plugins/Process/POSIX/RegisterContextFreeBSD_mips64.h new file mode 100644 index 00000000000..9ee76795534 --- /dev/null +++ b/lldb/source/Plugins/Process/POSIX/RegisterContextFreeBSD_mips64.h @@ -0,0 +1,29 @@ +//===-- RegisterContextFreeBSD_mips64.h -------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_RegisterContextFreeBSD_mips64_H_ +#define liblldb_RegisterContextFreeBSD_mips64_H_ + +#include "RegisterContextPOSIX.h" + +class RegisterContextFreeBSD_mips64: + public RegisterInfoInterface +{ +public: + RegisterContextFreeBSD_mips64(const lldb_private::ArchSpec &target_arch); + virtual ~RegisterContextFreeBSD_mips64(); + + size_t + GetGPRSize(); + + const lldb_private::RegisterInfo * + GetRegisterInfo(); +}; + +#endif diff --git a/lldb/source/Plugins/Process/POSIX/RegisterContextPOSIX_mips64.cpp b/lldb/source/Plugins/Process/POSIX/RegisterContextPOSIX_mips64.cpp new file mode 100644 index 00000000000..45c99aec165 --- /dev/null +++ b/lldb/source/Plugins/Process/POSIX/RegisterContextPOSIX_mips64.cpp @@ -0,0 +1,238 @@ +//===-- RegisterContextPOSIX_mips64.cpp -------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include <cstring> +#include <errno.h> +#include <stdint.h> + +#include "lldb/Core/DataBufferHeap.h" +#include "lldb/Core/DataExtractor.h" +#include "lldb/Core/RegisterValue.h" +#include "lldb/Core/Scalar.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Host/Endian.h" +#include "llvm/Support/Compiler.h" + +#include "ProcessPOSIX.h" +#include "RegisterContextPOSIX_mips64.h" +#include "Plugins/Process/elf-core/ProcessElfCore.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. +} + +bool +RegisterContextPOSIX_mips64::IsFPR(unsigned reg) +{ + // XXX + return false; +} + +RegisterContextPOSIX_mips64::RegisterContextPOSIX_mips64(Thread &thread, + uint32_t concrete_frame_idx, + RegisterInfoInterface *register_info) + : RegisterContext(thread, concrete_frame_idx) +{ + m_register_info_ap.reset(register_info); + + // elf-core yet to support ReadFPR() + ProcessSP base = CalculateProcess(); + if (base.get()->GetPluginName() == ProcessElfCore::GetPluginNameStatic()) + return; +} + +RegisterContextPOSIX_mips64::~RegisterContextPOSIX_mips64() +{ +} + +void +RegisterContextPOSIX_mips64::Invalidate() +{ +} + +void +RegisterContextPOSIX_mips64::InvalidateAllRegisters() +{ +} + +unsigned +RegisterContextPOSIX_mips64::GetRegisterOffset(unsigned reg) +{ + assert(reg < k_num_registers_mips64 && "Invalid register number."); + return GetRegisterInfo()[reg].byte_offset; +} + +unsigned +RegisterContextPOSIX_mips64::GetRegisterSize(unsigned reg) +{ + assert(reg < k_num_registers_mips64 && "Invalid register number."); + return GetRegisterInfo()[reg].byte_size; +} + +size_t +RegisterContextPOSIX_mips64::GetRegisterCount() +{ + size_t num_registers = k_num_registers_mips64; + return num_registers; +} + +size_t +RegisterContextPOSIX_mips64::GetGPRSize() +{ + return m_register_info_ap->GetGPRSize(); +} + +const RegisterInfo * +RegisterContextPOSIX_mips64::GetRegisterInfo() +{ + // Commonly, this method is overridden and g_register_infos is copied and specialized. + // So, use GetRegisterInfo() rather than g_register_infos in this scope. + return m_register_info_ap->GetRegisterInfo (); +} + +const RegisterInfo * +RegisterContextPOSIX_mips64::GetRegisterInfoAtIndex(size_t reg) +{ + if (reg < k_num_registers_mips64) + 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; + } + + return sets; +} + +const RegisterSet * +RegisterContextPOSIX_mips64::GetRegisterSet(size_t set) +{ + if (IsRegisterSetAvailable(set)) + return &g_reg_sets_mips64[set]; + else + return NULL; +} + +const char * +RegisterContextPOSIX_mips64::GetRegisterName(unsigned reg) +{ + assert(reg < k_num_registers_mips64 && "Invalid register offset."); + return GetRegisterInfo()[reg].name; +} + +lldb::ByteOrder +RegisterContextPOSIX_mips64::GetByteOrder() +{ + // Get the target process whose privileged thread was used for the register read. + lldb::ByteOrder byte_order = eByteOrderInvalid; + Process *process = CalculateProcess().get(); + + if (process) + byte_order = process->GetByteOrder(); + return byte_order; +} + +bool +RegisterContextPOSIX_mips64::IsRegisterSetAvailable(size_t set_index) +{ + size_t num_sets = k_num_register_sets; + + return (set_index < num_sets); +} + +// Used when parsing DWARF and EH frame information and any other +// object file sections that contain register numbers in them. +uint32_t +RegisterContextPOSIX_mips64::ConvertRegisterKindToRegisterNumber(uint32_t kind, + uint32_t num) +{ + const uint32_t num_regs = GetRegisterCount(); + + assert (kind < kNumRegisterKinds); + for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) + { + const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg_idx); + + if (reg_info->kinds[kind] == num) + return reg_idx; + } + + return LLDB_INVALID_REGNUM; +} + diff --git a/lldb/source/Plugins/Process/POSIX/RegisterContextPOSIX_mips64.h b/lldb/source/Plugins/Process/POSIX/RegisterContextPOSIX_mips64.h new file mode 100644 index 00000000000..aaadc014738 --- /dev/null +++ b/lldb/source/Plugins/Process/POSIX/RegisterContextPOSIX_mips64.h @@ -0,0 +1,138 @@ +//===-- RegisterContextPOSIX_mips64.h ---------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_RegisterContextPOSIX_mips64_H_ +#define liblldb_RegisterContextPOSIX_mips64_H_ + +#include "lldb/Core/Log.h" +#include "RegisterContextPOSIX.h" +#include "RegisterContext_mips64.h" + +class ProcessMonitor; + +// --------------------------------------------------------------------------- +// Internal codes for all mips64 registers. +// --------------------------------------------------------------------------- +enum +{ + k_first_gpr_mips64, + gpr_zero_mips64 = k_first_gpr_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, + + k_num_registers_mips64, + k_num_gpr_registers_mips64 = k_num_registers_mips64 +}; + +class RegisterContextPOSIX_mips64 + : public lldb_private::RegisterContext +{ +public: + RegisterContextPOSIX_mips64 (lldb_private::Thread &thread, + uint32_t concrete_frame_idx, + RegisterInfoInterface *register_info); + + ~RegisterContextPOSIX_mips64(); + + void + Invalidate(); + + void + InvalidateAllRegisters(); + + size_t + GetRegisterCount(); + + virtual size_t + GetGPRSize(); + + virtual unsigned + GetRegisterSize(unsigned reg); + + virtual unsigned + GetRegisterOffset(unsigned reg); + + const lldb_private::RegisterInfo * + GetRegisterInfoAtIndex(size_t reg); + + size_t + GetRegisterSetCount(); + + const lldb_private::RegisterSet * + GetRegisterSet(size_t set); + + const char * + GetRegisterName(unsigned reg); + + uint32_t + ConvertRegisterKindToRegisterNumber(uint32_t kind, uint32_t num); + +protected: + uint64_t m_gpr[k_num_gpr_registers_mips64]; // general purpose registers. + std::unique_ptr<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. + virtual bool + IsRegisterSetAvailable(size_t set_index); + + virtual const lldb_private::RegisterInfo * + GetRegisterInfo(); + + bool + IsGPR(unsigned reg); + + bool + IsFPR(unsigned reg); + + lldb::ByteOrder GetByteOrder(); + + virtual bool ReadGPR() = 0; + virtual bool ReadFPR() = 0; + virtual bool WriteGPR() = 0; + virtual bool WriteFPR() = 0; +}; + +#endif // #ifndef liblldb_RegisterContextPOSIX_mips64_H_ diff --git a/lldb/source/Plugins/Process/POSIX/RegisterContext_mips64.h b/lldb/source/Plugins/Process/POSIX/RegisterContext_mips64.h new file mode 100644 index 00000000000..dfd473d7cbe --- /dev/null +++ b/lldb/source/Plugins/Process/POSIX/RegisterContext_mips64.h @@ -0,0 +1,104 @@ +//===-- RegisterContext_mips64.h --------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_RegisterContext_mips64_H_ +#define liblldb_RegisterContext_mips64_H_ + +// GCC and DWARF Register numbers (eRegisterKindGCC & eRegisterKindDWARF) +enum +{ + // GP Registers + gcc_dwarf_zero_mips64 = 0, + gcc_dwarf_r1_mips64, + gcc_dwarf_r2_mips64, + gcc_dwarf_r3_mips64, + gcc_dwarf_r4_mips64, + gcc_dwarf_r5_mips64, + gcc_dwarf_r6_mips64, + gcc_dwarf_r7_mips64, + gcc_dwarf_r8_mips64, + gcc_dwarf_r9_mips64, + gcc_dwarf_r10_mips64, + gcc_dwarf_r11_mips64, + gcc_dwarf_r12_mips64, + gcc_dwarf_r13_mips64, + gcc_dwarf_r14_mips64, + gcc_dwarf_r15_mips64, + gcc_dwarf_r16_mips64, + gcc_dwarf_r17_mips64, + gcc_dwarf_r18_mips64, + gcc_dwarf_r19_mips64, + gcc_dwarf_r20_mips64, + gcc_dwarf_r21_mips64, + gcc_dwarf_r22_mips64, + gcc_dwarf_r23_mips64, + gcc_dwarf_r24_mips64, + gcc_dwarf_r25_mips64, + gcc_dwarf_r26_mips64, + gcc_dwarf_r27_mips64, + gcc_dwarf_gp_mips64, + gcc_dwarf_sp_mips64, + gcc_dwarf_r30_mips64, + gcc_dwarf_ra_mips64, + gcc_dwarf_sr_mips64, + gcc_dwarf_lo_mips64, + gcc_dwarf_hi_mips64, + gcc_dwarf_bad_mips64, + gcc_dwarf_cause_mips64, + gcc_dwarf_pc_mips64, + gcc_dwarf_ic_mips64, + gcc_dwarf_dummy_mips64 +}; + +// GDB Register numbers (eRegisterKindGDB) +enum +{ + gdb_zero_mips64 = 0, + gdb_r1_mips64, + gdb_r2_mips64, + gdb_r3_mips64, + gdb_r4_mips64, + gdb_r5_mips64, + gdb_r6_mips64, + gdb_r7_mips64, + gdb_r8_mips64, + gdb_r9_mips64, + gdb_r10_mips64, + gdb_r11_mips64, + gdb_r12_mips64, + gdb_r13_mips64, + gdb_r14_mips64, + gdb_r15_mips64, + gdb_r16_mips64, + gdb_r17_mips64, + gdb_r18_mips64, + gdb_r19_mips64, + gdb_r20_mips64, + gdb_r21_mips64, + gdb_r22_mips64, + gdb_r23_mips64, + gdb_r24_mips64, + gdb_r25_mips64, + gdb_r26_mips64, + gdb_r27_mips64, + gdb_gp_mips64, + gdb_sp_mips64, + gdb_r30_mips64, + gdb_ra_mips64, + gdb_sr_mips64, + gdb_lo_mips64, + gdb_hi_mips64, + gdb_bad_mips64, + gdb_cause_mips64, + gdb_pc_mips64, + gdb_ic_mips64, + gdb_dummy_mips64 +}; + +#endif // liblldb_RegisterContext_mips64_H_ diff --git a/lldb/source/Plugins/Process/POSIX/RegisterInfos_mips64.h b/lldb/source/Plugins/Process/POSIX/RegisterInfos_mips64.h new file mode 100644 index 00000000000..13526e3680b --- /dev/null +++ b/lldb/source/Plugins/Process/POSIX/RegisterInfos_mips64.h @@ -0,0 +1,74 @@ +//===-- RegisterInfos_mips64.h ---------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===---------------------------------------------------------------------===// + +// Computes the offset of the given GPR in the user data area. +#define GPR_OFFSET(regname) \ + (offsetof(GPR, regname)) + +#ifdef DECLARE_REGISTER_INFOS_MIPS64_STRUCT + +// Note that the size and offset will be updated by platform-specific classes. +#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \ + { #reg, alt, sizeof(GPR::reg), GPR_OFFSET(reg), eEncodingUint, \ + eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg##_mips64 }, NULL, NULL } + +static RegisterInfo +g_register_infos_mips64[] = +{ + // General purpose registers. GCC, DWARF, Generic, GDB + DEFINE_GPR(zero, "r0", gcc_dwarf_zero_mips64, gcc_dwarf_zero_mips64, LLDB_INVALID_REGNUM, gdb_zero_mips64), + DEFINE_GPR(r1, NULL, gcc_dwarf_r1_mips64, gcc_dwarf_r1_mips64, LLDB_INVALID_REGNUM, gdb_r1_mips64), + DEFINE_GPR(r2, NULL, gcc_dwarf_r2_mips64, gcc_dwarf_r2_mips64, LLDB_INVALID_REGNUM, gdb_r2_mips64), + DEFINE_GPR(r3, NULL, gcc_dwarf_r3_mips64, gcc_dwarf_r3_mips64, LLDB_INVALID_REGNUM, gdb_r3_mips64), + DEFINE_GPR(r4, NULL, gcc_dwarf_r4_mips64, gcc_dwarf_r4_mips64, LLDB_INVALID_REGNUM, gdb_r4_mips64), + DEFINE_GPR(r5, NULL, gcc_dwarf_r5_mips64, gcc_dwarf_r5_mips64, LLDB_INVALID_REGNUM, gdb_r5_mips64), + DEFINE_GPR(r6, NULL, gcc_dwarf_r6_mips64, gcc_dwarf_r6_mips64, LLDB_INVALID_REGNUM, gdb_r6_mips64), + DEFINE_GPR(r7, NULL, gcc_dwarf_r7_mips64, gcc_dwarf_r7_mips64, LLDB_INVALID_REGNUM, gdb_r7_mips64), + DEFINE_GPR(r8, NULL, gcc_dwarf_r8_mips64, gcc_dwarf_r8_mips64, LLDB_INVALID_REGNUM, gdb_r8_mips64), + DEFINE_GPR(r9, NULL, gcc_dwarf_r9_mips64, gcc_dwarf_r9_mips64, LLDB_INVALID_REGNUM, gdb_r9_mips64), + DEFINE_GPR(r10, NULL, gcc_dwarf_r10_mips64, gcc_dwarf_r10_mips64, LLDB_INVALID_REGNUM, gdb_r10_mips64), + DEFINE_GPR(r11, NULL, gcc_dwarf_r11_mips64, gcc_dwarf_r11_mips64, LLDB_INVALID_REGNUM, gdb_r11_mips64), + DEFINE_GPR(r12, NULL, gcc_dwarf_r12_mips64, gcc_dwarf_r12_mips64, LLDB_INVALID_REGNUM, gdb_r12_mips64), + DEFINE_GPR(r13, NULL, gcc_dwarf_r13_mips64, gcc_dwarf_r13_mips64, LLDB_INVALID_REGNUM, gdb_r13_mips64), + DEFINE_GPR(r14, NULL, gcc_dwarf_r14_mips64, gcc_dwarf_r14_mips64, LLDB_INVALID_REGNUM, gdb_r14_mips64), + DEFINE_GPR(r15, NULL, gcc_dwarf_r15_mips64, gcc_dwarf_r15_mips64, LLDB_INVALID_REGNUM, gdb_r15_mips64), + DEFINE_GPR(r16, NULL, gcc_dwarf_r16_mips64, gcc_dwarf_r16_mips64, LLDB_INVALID_REGNUM, gdb_r16_mips64), + DEFINE_GPR(r17, NULL, gcc_dwarf_r17_mips64, gcc_dwarf_r17_mips64, LLDB_INVALID_REGNUM, gdb_r17_mips64), + DEFINE_GPR(r18, NULL, gcc_dwarf_r18_mips64, gcc_dwarf_r18_mips64, LLDB_INVALID_REGNUM, gdb_r18_mips64), + DEFINE_GPR(r19, NULL, gcc_dwarf_r19_mips64, gcc_dwarf_r19_mips64, LLDB_INVALID_REGNUM, gdb_r19_mips64), + DEFINE_GPR(r20, NULL, gcc_dwarf_r20_mips64, gcc_dwarf_r20_mips64, LLDB_INVALID_REGNUM, gdb_r20_mips64), + DEFINE_GPR(r21, NULL, gcc_dwarf_r21_mips64, gcc_dwarf_r21_mips64, LLDB_INVALID_REGNUM, gdb_r21_mips64), + DEFINE_GPR(r22, NULL, gcc_dwarf_r22_mips64, gcc_dwarf_r22_mips64, LLDB_INVALID_REGNUM, gdb_r22_mips64), + DEFINE_GPR(r23, NULL, gcc_dwarf_r23_mips64, gcc_dwarf_r23_mips64, LLDB_INVALID_REGNUM, gdb_r23_mips64), + DEFINE_GPR(r24, NULL, gcc_dwarf_r24_mips64, gcc_dwarf_r24_mips64, LLDB_INVALID_REGNUM, gdb_r24_mips64), + DEFINE_GPR(r25, NULL, gcc_dwarf_r25_mips64, gcc_dwarf_r25_mips64, LLDB_INVALID_REGNUM, gdb_r25_mips64), + DEFINE_GPR(r26, NULL, gcc_dwarf_r26_mips64, gcc_dwarf_r26_mips64, LLDB_INVALID_REGNUM, gdb_r26_mips64), + DEFINE_GPR(r27, NULL, gcc_dwarf_r27_mips64, gcc_dwarf_r27_mips64, LLDB_INVALID_REGNUM, gdb_r27_mips64), + DEFINE_GPR(gp, "r28", gcc_dwarf_gp_mips64, gcc_dwarf_gp_mips64, LLDB_INVALID_REGNUM, gdb_gp_mips64), + DEFINE_GPR(sp, "r29", gcc_dwarf_sp_mips64, gcc_dwarf_sp_mips64, LLDB_REGNUM_GENERIC_SP, gdb_sp_mips64), + DEFINE_GPR(r30, NULL, gcc_dwarf_r30_mips64, gcc_dwarf_r30_mips64, LLDB_INVALID_REGNUM, gdb_r30_mips64), + DEFINE_GPR(ra, "r31", gcc_dwarf_ra_mips64, gcc_dwarf_ra_mips64, LLDB_INVALID_REGNUM, gdb_ra_mips64), + DEFINE_GPR(sr, NULL, gcc_dwarf_sr_mips64, gcc_dwarf_sr_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(mullo, NULL, gcc_dwarf_lo_mips64, gcc_dwarf_lo_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(mulhi, NULL, gcc_dwarf_hi_mips64, gcc_dwarf_hi_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(badvaddr, NULL, gcc_dwarf_bad_mips64, gcc_dwarf_bad_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(cause, NULL, gcc_dwarf_cause_mips64, gcc_dwarf_cause_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(pc, "pc", gcc_dwarf_pc_mips64, gcc_dwarf_pc_mips64, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM), + DEFINE_GPR(ic, NULL, gcc_dwarf_ic_mips64, gcc_dwarf_ic_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(dummy, NULL, gcc_dwarf_dummy_mips64, gcc_dwarf_dummy_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), +}; +static_assert((sizeof(g_register_infos_mips64) / sizeof(g_register_infos_mips64[0])) == k_num_registers_mips64, + "g_register_infos_mips64 has wrong number of register infos"); + +#undef DEFINE_GPR + +#endif // DECLARE_REGISTER_INFOS_MIPS64_STRUCT + +#undef GPR_OFFSET + diff --git a/lldb/source/Plugins/Process/elf-core/CMakeLists.txt b/lldb/source/Plugins/Process/elf-core/CMakeLists.txt index 44cf02b523f..29c30186347 100644 --- a/lldb/source/Plugins/Process/elf-core/CMakeLists.txt +++ b/lldb/source/Plugins/Process/elf-core/CMakeLists.txt @@ -5,5 +5,6 @@ set(LLVM_NO_RTTI 1) add_lldb_library(lldbPluginProcessElfCore ProcessElfCore.cpp ThreadElfCore.cpp + RegisterContextPOSIXCore_mips64.cpp RegisterContextPOSIXCore_x86_64.cpp ) diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp index dd553ce36c8..995c9569496 100644 --- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp +++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp @@ -441,7 +441,8 @@ ParseFreeBSDPrStatus(ThreadData *thread_data, DataExtractor &data, ArchSpec &arch) { lldb::offset_t offset = 0; - bool have_padding = (arch.GetMachine() == llvm::Triple::x86_64); + bool have_padding = (arch.GetMachine() == llvm::Triple::mips64 || + arch.GetMachine() == llvm::Triple::x86_64); int pr_version = data.GetU32(&offset); Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS)); diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp new file mode 100644 index 00000000000..b95a51130ca --- /dev/null +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp @@ -0,0 +1,94 @@ +//===-- RegisterContextCorePOSIX_mips64.cpp ---------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Core/DataExtractor.h" +#include "lldb/Core/RegisterValue.h" +#include "lldb/Target/Thread.h" +#include "RegisterContextPOSIX.h" +#include "RegisterContextPOSIXCore_mips64.h" + +using namespace lldb_private; + +RegisterContextCorePOSIX_mips64::RegisterContextCorePOSIX_mips64(Thread &thread, + RegisterInfoInterface *register_info, + const DataExtractor &gpregset, + const DataExtractor &fpregset) + : RegisterContextPOSIX_mips64(thread, 0, register_info) +{ + size_t i; + lldb::offset_t offset = 0; + + for (i = 0; i < k_num_gpr_registers_mips64; i++) + { + m_reg[i] = gpregset.GetU64(&offset); + } +} + +RegisterContextCorePOSIX_mips64::~RegisterContextCorePOSIX_mips64() +{ +} + +bool +RegisterContextCorePOSIX_mips64::ReadGPR() +{ + return true; +} + +bool +RegisterContextCorePOSIX_mips64::ReadFPR() +{ + return false; +} + +bool +RegisterContextCorePOSIX_mips64::WriteGPR() +{ + assert(0); + return false; +} + +bool +RegisterContextCorePOSIX_mips64::WriteFPR() +{ + assert(0); + return false; +} + +bool +RegisterContextCorePOSIX_mips64::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value) +{ + int reg_num = reg_info->byte_offset / 8; + assert(reg_num < k_num_gpr_registers_mips64); + value = m_reg[reg_num]; + return true; +} + +bool +RegisterContextCorePOSIX_mips64::ReadAllRegisterValues(lldb::DataBufferSP &data_sp) +{ + return false; +} + +bool +RegisterContextCorePOSIX_mips64::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value) +{ + return false; +} + +bool +RegisterContextCorePOSIX_mips64::WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) +{ + return false; +} + +bool +RegisterContextCorePOSIX_mips64::HardwareSingleStep(bool enable) +{ + return false; +} diff --git a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp index 9929a0119bb..3bda86dc0f7 100644 --- a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp +++ b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp @@ -17,7 +17,9 @@ #include "ThreadElfCore.h" #include "ProcessElfCore.h" #include "RegisterContextLinux_x86_64.h" +#include "RegisterContextFreeBSD_mips64.h" #include "RegisterContextFreeBSD_x86_64.h" +#include "RegisterContextPOSIXCore_mips64.h" #include "RegisterContextPOSIXCore_x86_64.h" using namespace lldb; @@ -85,6 +87,20 @@ ThreadElfCore::CreateRegisterContextForFrame (StackFrame *frame) ArchSpec arch = process->GetArchitecture(); switch (arch.GetMachine()) { + case llvm::Triple::mips64: + switch (arch.GetTriple().getOS()) + { + case llvm::Triple::FreeBSD: + m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64 (*this, new RegisterContextFreeBSD_mips64(arch), m_gpregset_data, m_fpregset_data)); + break; + default: + if (log) + log->Printf ("elf-core::%s:: OS(%d) not supported", + __FUNCTION__, arch.GetTriple().getOS()); + assert (false && "OS not supported"); + break; + } + break; case llvm::Triple::x86_64: switch (arch.GetTriple().getOS()) { diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp index dde5755efd6..0ef91e8a650 100644 --- a/lldb/source/Target/Thread.cpp +++ b/lldb/source/Target/Thread.cpp @@ -2017,6 +2017,7 @@ Thread::GetUnwinder () case llvm::Triple::x86: case llvm::Triple::arm: case llvm::Triple::thumb: + case llvm::Triple::mips64: m_unwinder_ap.reset (new UnwindLLDB (*this)); break; |