Skip to content

Commit

Permalink
[MIPS] - Register Context for MIPS64
Browse files Browse the repository at this point in the history
Patch by Jaydeep Patil

Summery:
1. Add MIPS variants by parsing e_flags of the ELF
2. Create RegisterInfoInterface and RegisterContext for MIPS64 and MIPS64EL

Reviewers: clayborg

Subscribers: tberghammer, bhushan, mohit.bhakkad, sagar

Differential Revision: http://reviews.llvm.org/D8166

llvm-svn: 232467
  • Loading branch information
Mohit7 committed Mar 17, 2015
1 parent 0828860 commit 3df471c
Show file tree
Hide file tree
Showing 13 changed files with 579 additions and 2 deletions.
3 changes: 2 additions & 1 deletion lldb/include/lldb/Core/ArchSpec.h
Expand Up @@ -65,8 +65,9 @@ class ArchSpec
eCore_arm_arm64,
eCore_arm_armv8,
eCore_arm_aarch64,

eCore_mips64,
eCore_mips64el,

eCore_ppc_generic,
eCore_ppc_ppc601,
Expand Down
4 changes: 3 additions & 1 deletion lldb/source/Core/ArchSpec.cpp
Expand Up @@ -88,6 +88,7 @@ static const CoreDefinition g_core_definitions[] =
{ eByteOrderLittle, 8, 4, 4, llvm::Triple::aarch64, ArchSpec::eCore_arm_aarch64 , "aarch64" },

{ eByteOrderBig , 8, 4, 4, llvm::Triple::mips64 , ArchSpec::eCore_mips64 , "mips64" },
{ eByteOrderLittle, 8, 4, 4, llvm::Triple::mips64el, ArchSpec::eCore_mips64el , "mips64el" },

{ eByteOrderBig , 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_generic , "powerpc" },
{ eByteOrderBig , 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc601 , "ppc601" },
Expand Down Expand Up @@ -266,7 +267,8 @@ static const ArchDefinitionEntry g_elf_arch_entries[] =
{ ArchSpec::eCore_arm_aarch64 , llvm::ELF::EM_AARCH64, LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // ARM64
{ 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_mips64 , llvm::ELF::EM_MIPS , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // MIPS
{ ArchSpec::eCore_mips64 , llvm::ELF::EM_MIPS , llvm::Triple::mips64, 0xFFFFFFFFu, 0xFFFFFFFFu }, // mips64
{ ArchSpec::eCore_mips64el , llvm::ELF::EM_MIPS , llvm::Triple::mips64el, 0xFFFFFFFFu, 0xFFFFFFFFu }, // mips64el
{ ArchSpec::eCore_hexagon_generic , llvm::ELF::EM_HEXAGON, LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // HEXAGON
{ ArchSpec::eCore_kalimba3 , llvm::ELF::EM_CSR_KALIMBA, llvm::Triple::KalimbaSubArch_v3, 0xFFFFFFFFu, 0xFFFFFFFFu }, // KALIMBA
{ ArchSpec::eCore_kalimba4 , llvm::ELF::EM_CSR_KALIMBA, llvm::Triple::KalimbaSubArch_v4, 0xFFFFFFFFu, 0xFFFFFFFFu }, // KALIMBA
Expand Down
1 change: 1 addition & 0 deletions lldb/source/Host/common/HostInfoBase.cpp
Expand Up @@ -414,6 +414,7 @@ HostInfoBase::ComputeHostArchitectureSupport(ArchSpec &arch_32, ArchSpec &arch_6

case llvm::Triple::aarch64:
case llvm::Triple::mips64:
case llvm::Triple::mips64el:
case llvm::Triple::sparcv9:
arch_64.SetTriple(triple);
break;
Expand Down
26 changes: 26 additions & 0 deletions lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
Expand Up @@ -282,9 +282,35 @@ kalimbaVariantFromElfFlags(const elf::elf_word e_flags)
return kal_arch_variant;
}

static uint32_t
mipsVariantFromElfFlags(const elf::elf_word e_flags, uint32_t endian)
{
const uint32_t mips_arch = e_flags & llvm::ELF::EF_MIPS_ARCH;
uint32_t arch_variant = LLDB_INVALID_CPUTYPE;

switch (mips_arch)
{
case llvm::ELF::EF_MIPS_ARCH_64:
if (endian == ELFDATA2LSB)
arch_variant = llvm::Triple::mips64el;
else
arch_variant = llvm::Triple::mips64;
break;

default:
break;
}

return arch_variant;
}

static uint32_t
subTypeFromElfHeader(const elf::ELFHeader& header)
{
if (header.e_machine == llvm::ELF::EM_MIPS)
return mipsVariantFromElfFlags (header.e_flags,
header.e_ident[EI_DATA]);

return
llvm::ELF::EM_CSR_KALIMBA == header.e_machine ?
kalimbaVariantFromElfFlags(header.e_flags) :
Expand Down
1 change: 1 addition & 0 deletions lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp
Expand Up @@ -586,6 +586,7 @@ PlatformLinux::GetSoftwareBreakpointTrapOpcode (Target &target,
}
break;
case llvm::Triple::mips64:
case llvm::Triple::mips64el:
{
static const uint8_t g_hex_opcode[] = { 0x00, 0x00, 0x00, 0x0d };
trap_opcode = g_hex_opcode;
Expand Down
1 change: 1 addition & 0 deletions lldb/source/Plugins/Process/Linux/CMakeLists.txt
Expand Up @@ -9,6 +9,7 @@ add_lldb_library(lldbPluginProcessLinux
NativeProcessLinux.cpp
NativeRegisterContextLinux_arm64.cpp
NativeRegisterContextLinux_x86_64.cpp
NativeRegisterContextLinux_mips64.cpp
NativeThreadLinux.cpp
ProcessLinux.cpp
ProcessMonitor.cpp
Expand Down
7 changes: 7 additions & 0 deletions lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
Expand Up @@ -3179,6 +3179,7 @@ NativeProcessLinux::GetSoftwareBreakpointTrapOpcode (size_t trap_opcode_size_hin
// set per architecture. Need ARM, MIPS support here.
static const uint8_t g_aarch64_opcode[] = { 0x00, 0x00, 0x20, 0xd4 };
static const uint8_t g_i386_opcode [] = { 0xCC };
static const uint8_t g_mips64_opcode[] = { 0x00, 0x00, 0x00, 0x0d };

switch (m_arch.GetMachine ())
{
Expand All @@ -3193,6 +3194,12 @@ NativeProcessLinux::GetSoftwareBreakpointTrapOpcode (size_t trap_opcode_size_hin
actual_opcode_size = sizeof(g_i386_opcode);
return Error ();

case llvm::Triple::mips64:
case llvm::Triple::mips64el:
trap_opcode_bytes = g_mips64_opcode;
actual_opcode_size = sizeof(g_mips64_opcode);
return Error ();

default:
assert(false && "CPU type not supported!");
return Error ("CPU type not supported");
Expand Down
@@ -0,0 +1,213 @@
//===-- NativeRegisterContextLinux_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 "NativeRegisterContextLinux_mips64.h"

#include "lldb/lldb-private-forward.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Host/common/NativeProcessProtocol.h"
#include "lldb/Host/common/NativeThreadProtocol.h"
#include "Plugins/Process/Linux/NativeProcessLinux.h"

using namespace lldb_private;

// ----------------------------------------------------------------------------
// Private namespace.
// ----------------------------------------------------------------------------

namespace
{
// mips64 general purpose registers.
const uint32_t
g_gp_regnums_mips64[] =
{
gp_reg_r0_mips64,
gp_reg_r1_mips64,
gp_reg_r2_mips64,
gp_reg_r3_mips64,
gp_reg_r4_mips64,
gp_reg_r5_mips64,
gp_reg_r6_mips64,
gp_reg_r7_mips64,
gp_reg_r8_mips64,
gp_reg_r9_mips64,
gp_reg_r10_mips64,
gp_reg_r11_mips64,
gp_reg_r12_mips64,
gp_reg_r13_mips64,
gp_reg_r14_mips64,
gp_reg_r15_mips64,
gp_reg_r16_mips64,
gp_reg_r17_mips64,
gp_reg_r18_mips64,
gp_reg_r19_mips64,
gp_reg_r20_mips64,
gp_reg_r21_mips64,
gp_reg_r22_mips64,
gp_reg_r23_mips64,
gp_reg_r24_mips64,
gp_reg_r25_mips64,
gp_reg_r26_mips64,
gp_reg_r27_mips64,
gp_reg_r28_mips64,
gp_reg_r29_mips64,
gp_reg_r30_mips64,
gp_reg_r31_mips64,
gp_reg_mullo_mips64,
gp_reg_mulhi_mips64,
gp_reg_pc_mips64,
gp_reg_badvaddr_mips64,
gp_reg_sr_mips64,
gp_reg_cause_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_gp_reg_mips64,
"g_gp_regnums_mips64 has wrong number of register infos");

// Number of register sets provided by this context.
enum
{
k_num_register_sets = 1
};

// Register sets for mips64.
static const RegisterSet
g_reg_sets_mips64[k_num_register_sets] =
{
{ "General Purpose Registers", "gpr", k_num_gp_reg_mips64, g_gp_regnums_mips64 }
};
}

// ----------------------------------------------------------------------------
// NativeRegisterContextLinux_mips64 members.
// ----------------------------------------------------------------------------

NativeRegisterContextLinux_mips64::NativeRegisterContextLinux_mips64 (NativeThreadProtocol &native_thread,
uint32_t concrete_frame_idx, RegisterInfoInterface *reg_info_interface_p) :
NativeRegisterContextRegisterInfo (native_thread, concrete_frame_idx, reg_info_interface_p)
{
}

uint32_t
NativeRegisterContextLinux_mips64::GetRegisterSetCount () const
{
return k_num_register_sets;
}

const lldb_private::RegisterSet *
NativeRegisterContextLinux_mips64::GetRegisterSet (uint32_t set_index) const
{
if (set_index >= k_num_register_sets)
return nullptr;

switch (GetRegisterInfoInterface ().GetTargetArchitecture ().GetMachine ())
{
case llvm::Triple::mips64:
case llvm::Triple::mips64el:
return &g_reg_sets_mips64[set_index];
default:
assert (false && "Unhandled target architecture.");
return nullptr;
}

return nullptr;
}

lldb_private::Error
NativeRegisterContextLinux_mips64::ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value)
{
Error error;
error.SetErrorString ("MIPS TODO: NativeRegisterContextLinux_mips64::ReadRegister not implemented");
return error;
}

lldb_private::Error
NativeRegisterContextLinux_mips64::WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value)
{
Error error;
error.SetErrorString ("MIPS TODO: NativeRegisterContextLinux_mips64::WriteRegister not implemented");
return error;
}

lldb_private::Error
NativeRegisterContextLinux_mips64::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
{
Error error;
error.SetErrorString ("MIPS TODO: NativeRegisterContextLinux_mips64::ReadAllRegisterValues not implemented");
return error;
}

lldb_private::Error
NativeRegisterContextLinux_mips64::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
{
Error error;
error.SetErrorString ("MIPS TODO: NativeRegisterContextLinux_mips64::WriteAllRegisterValues not implemented");
return error;
}

Error
NativeRegisterContextLinux_mips64::IsWatchpointHit (uint8_t wp_index)
{
Error error;
error.SetErrorString ("MIPS TODO: NativeRegisterContextLinux_mips64::IsWatchpointHit not implemented");
return error;
}

Error
NativeRegisterContextLinux_mips64::IsWatchpointVacant (uint32_t wp_index)
{
Error error;
error.SetErrorString ("MIPS TODO: NativeRegisterContextLinux_mips64::IsWatchpointVacant not implemented");
return error;
}

bool
NativeRegisterContextLinux_mips64::ClearHardwareWatchpoint (uint32_t wp_index)
{
return false;
}

Error
NativeRegisterContextLinux_mips64::ClearAllHardwareWatchpoints ()
{
Error error;
error.SetErrorString ("MIPS TODO: NativeRegisterContextLinux_mips64::ClearAllHardwareWatchpoints not implemented");
return error;
}

Error
NativeRegisterContextLinux_mips64::SetHardwareWatchpointWithIndex (
lldb::addr_t addr, size_t size, uint32_t watch_flags, uint32_t wp_index)
{
Error error;
error.SetErrorString ("MIPS TODO: NativeRegisterContextLinux_mips64::SetHardwareWatchpointWithIndex not implemented");
return error;
}

uint32_t
NativeRegisterContextLinux_mips64::SetHardwareWatchpoint (
lldb::addr_t addr, size_t size, uint32_t watch_flags)
{
return LLDB_INVALID_INDEX32;
}

lldb::addr_t
NativeRegisterContextLinux_mips64::GetWatchpointAddress (uint32_t wp_index)
{
return LLDB_INVALID_ADDRESS;
}

uint32_t
NativeRegisterContextLinux_mips64::NumSupportedHardwareWatchpoints ()
{
return 0;
}

0 comments on commit 3df471c

Please sign in to comment.