summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
diff options
context:
space:
mode:
authorTamas Berghammer <tberghammer@google.com>2015-05-26 11:58:52 +0000
committerTamas Berghammer <tberghammer@google.com>2015-05-26 11:58:52 +0000
commit068f8a7e2d7ece12cc00726bb2e6df180b217848 (patch)
tree3ac16e6c32a2a44799ad79fa0f141f30c990c66a /lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
parentb2b901c607ae3149b6d3a0c53a45f22e3542fb04 (diff)
downloadbcm5719-llvm-068f8a7e2d7ece12cc00726bb2e6df180b217848.tar.gz
bcm5719-llvm-068f8a7e2d7ece12cc00726bb2e6df180b217848.zip
Move register reading form NativeProcessLinux to NativeRegisterContextLinux*
This change reorganize the register read/write code inside lldb-server on Linux with moving the architecture independent code into a new class called NativeRegisterContextLinux and all of the architecture dependent code into the appropriate NativeRegisterContextLinux_* class. As part of it the compilation of the architecture specific register contexts are only compiled on the specific architecture because they can't be used in other cases. The purpose of this change is to remove a lot of duplicated code from the different register contexts and to remove the architecture dependent codes from the global NativeProcessLinux class. Differential revision: http://reviews.llvm.org/D9935 llvm-svn: 238196
Diffstat (limited to 'lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp')
-rw-r--r--lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp302
1 files changed, 104 insertions, 198 deletions
diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
index 8a4a7ae806f..a7390f58713 100644
--- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
@@ -7,16 +7,18 @@
//
//===----------------------------------------------------------------------===//
+#if defined(__i386__) || defined(__x86_64__)
+
#include "NativeRegisterContextLinux_x86_64.h"
#include "lldb/Core/Log.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"
+#include "lldb/Host/HostInfo.h"
+
+#include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
+#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
using namespace lldb_private;
using namespace lldb_private::process_linux;
@@ -326,12 +328,39 @@ namespace
#define NT_X86_XSTATE 0x202
#endif
+NativeRegisterContextLinux*
+NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(const ArchSpec& target_arch,
+ NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx)
+{
+ return new NativeRegisterContextLinux_x86_64(target_arch, native_thread, concrete_frame_idx);
+}
+
// ----------------------------------------------------------------------------
// NativeRegisterContextLinux_x86_64 members.
// ----------------------------------------------------------------------------
-NativeRegisterContextLinux_x86_64::NativeRegisterContextLinux_x86_64 (NativeThreadProtocol &native_thread, uint32_t concrete_frame_idx, RegisterInfoInterface *reg_info_interface_p) :
- NativeRegisterContextRegisterInfo (native_thread, concrete_frame_idx, reg_info_interface_p),
+static RegisterInfoInterface*
+CreateRegisterInfoInterface(const ArchSpec& target_arch)
+{
+ if (HostInfo::GetArchitecture().GetAddressByteSize() == 4)
+ {
+ // 32-bit hosts run with a RegisterContextLinux_i386 context.
+ return new RegisterContextLinux_i386(target_arch);
+ }
+ else
+ {
+ assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
+ "Register setting path assumes this is a 64-bit host");
+ // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the x86_64 register context.
+ return new RegisterContextLinux_x86_64 (target_arch);
+ }
+}
+
+NativeRegisterContextLinux_x86_64::NativeRegisterContextLinux_x86_64 (const ArchSpec& target_arch,
+ NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx) :
+ NativeRegisterContextLinux (native_thread, concrete_frame_idx, CreateRegisterInfoInterface(target_arch)),
m_fpr_type (eFPRTypeNotValid),
m_fpr (),
m_iovec (),
@@ -340,7 +369,7 @@ NativeRegisterContextLinux_x86_64::NativeRegisterContextLinux_x86_64 (NativeThre
m_gpr_x86_64 ()
{
// Set up data about ranges of valid registers.
- switch (reg_info_interface_p->GetTargetArchitecture ().GetMachine ())
+ switch (target_arch.GetMachine ())
{
case llvm::Triple::x86:
m_reg_info.num_registers = k_num_registers_i386;
@@ -444,32 +473,6 @@ NativeRegisterContextLinux_x86_64::GetRegisterSet (uint32_t set_index) const
}
Error
-NativeRegisterContextLinux_x86_64::ReadRegisterRaw (uint32_t reg_index, RegisterValue &reg_value)
-{
- Error error;
- const RegisterInfo *const reg_info = GetRegisterInfoAtIndex (reg_index);
- if (!reg_info)
- {
- error.SetErrorStringWithFormat ("register %" PRIu32 " not found", reg_index);
- return error;
- }
-
- NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
- if (!process_sp)
- {
- error.SetErrorString ("NativeProcessProtocol is NULL");
- return error;
- }
-
- NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
- return process_p->ReadRegisterValue(m_thread.GetID(),
- reg_info->byte_offset,
- reg_info->name,
- reg_info->byte_size,
- reg_value);
-}
-
-Error
NativeRegisterContextLinux_x86_64::ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value)
{
Error error;
@@ -490,11 +493,9 @@ NativeRegisterContextLinux_x86_64::ReadRegister (const RegisterInfo *reg_info, R
if (IsFPR(reg, GetFPRType()))
{
- if (!ReadFPR())
- {
- error.SetErrorString ("failed to read floating point register");
+ error = ReadFPR();
+ if (error.Fail())
return error;
- }
}
else
{
@@ -581,78 +582,6 @@ NativeRegisterContextLinux_x86_64::ReadRegister (const RegisterInfo *reg_info, R
}
Error
-NativeRegisterContextLinux_x86_64::WriteRegister(const uint32_t reg,
- const RegisterValue &value)
-{
- Error error;
-
- uint32_t reg_to_write = reg;
- RegisterValue value_to_write = value;
-
- // Check if this is a subregister of a full register.
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
- if (reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM))
- {
- RegisterValue full_value;
- uint32_t full_reg = reg_info->invalidate_regs[0];
- const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
-
- // Read the full register.
- error = ReadRegister(full_reg_info, full_value);
- if (error.Fail ())
- return error;
-
- lldb::ByteOrder byte_order = GetByteOrder();
- uint8_t dst[RegisterValue::kMaxRegisterByteSize];
-
- // Get the bytes for the full register.
- const uint32_t dest_size = full_value.GetAsMemoryData (full_reg_info,
- dst,
- sizeof(dst),
- byte_order,
- error);
- if (error.Success() && dest_size)
- {
- uint8_t src[RegisterValue::kMaxRegisterByteSize];
-
- // Get the bytes for the source data.
- const uint32_t src_size = value.GetAsMemoryData (reg_info, src, sizeof(src), byte_order, error);
- if (error.Success() && src_size && (src_size < dest_size))
- {
- // Copy the src bytes to the destination.
- memcpy (dst + (reg_info->byte_offset & 0x1), src, src_size);
- // Set this full register as the value to write.
- value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
- value_to_write.SetType(full_reg_info);
- reg_to_write = full_reg;
- }
- }
- }
-
-
- NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
- if (!process_sp)
- {
- error.SetErrorString ("NativeProcessProtocol is NULL");
- return error;
- }
-
- const RegisterInfo *const register_to_write_info_p = GetRegisterInfoAtIndex (reg_to_write);
- assert (register_to_write_info_p && "register to write does not have valid RegisterInfo");
- if (!register_to_write_info_p)
- {
- error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s failed to get RegisterInfo for write register index %" PRIu32, __FUNCTION__, reg_to_write);
- return error;
- }
-
- NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
- return process_p->WriteRegisterValue(m_thread.GetID(),
- register_to_write_info_p->byte_offset,
- register_to_write_info_p->name,
- value_to_write);
-}
-
-Error
NativeRegisterContextLinux_x86_64::WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value)
{
assert (reg_info && "reg_info is null");
@@ -662,7 +591,7 @@ NativeRegisterContextLinux_x86_64::WriteRegister (const RegisterInfo *reg_info,
return Error ("no lldb regnum for %s", reg_info && reg_info->name ? reg_info->name : "<unknown register>");
if (IsGPR(reg_index))
- return WriteRegister(reg_index, reg_value);
+ return WriteRegisterRaw(reg_index, reg_value);
if (IsFPR(reg_index, GetFPRType()))
{
@@ -710,15 +639,16 @@ NativeRegisterContextLinux_x86_64::WriteRegister (const RegisterInfo *reg_info,
}
}
- if (WriteFPR())
+ Error error = WriteFPR();
+ if (error.Fail())
+ return error;
+
+ if (IsAVX(reg_index))
{
- if (IsAVX(reg_index))
- {
- if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))
- return Error ("CopyYMMtoXSTATE() failed");
- }
- return Error ();
+ if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))
+ return Error ("CopyYMMtoXSTATE() failed");
}
+ return Error ();
}
return Error ("failed - register wasn't recognized to be a GPR or an FPR, write strategy unknown");
}
@@ -735,17 +665,13 @@ NativeRegisterContextLinux_x86_64::ReadAllRegisterValues (lldb::DataBufferSP &da
return error;
}
- if (!ReadGPR ())
- {
- error.SetErrorString ("ReadGPR() failed");
+ error = ReadGPR();
+ if (error.Fail())
return error;
- }
- if (!ReadFPR ())
- {
- error.SetErrorString ("ReadFPR() failed");
+ error = ReadFPR();
+ if (error.Fail())
return error;
- }
uint8_t *dst = data_sp->GetBytes ();
if (dst == nullptr)
@@ -810,11 +736,9 @@ NativeRegisterContextLinux_x86_64::WriteAllRegisterValues (const lldb::DataBuffe
}
::memcpy (&m_gpr_x86_64, src, GetRegisterInfoInterface ().GetGPRSize ());
- if (!WriteGPR ())
- {
- error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s WriteGPR() failed", __FUNCTION__);
+ error = WriteGPR();
+ if (error.Fail())
return error;
- }
src += GetRegisterInfoInterface ().GetGPRSize ();
if (GetFPRType () == eFPRTypeFXSAVE)
@@ -822,11 +746,9 @@ NativeRegisterContextLinux_x86_64::WriteAllRegisterValues (const lldb::DataBuffe
else if (GetFPRType () == eFPRTypeXSAVE)
::memcpy (&m_fpr.xstate.xsave, src, sizeof(m_fpr.xstate.xsave));
- if (!WriteFPR ())
- {
- error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s WriteFPR() failed", __FUNCTION__);
+ error = WriteFPR();
+ if (error.Fail())
return error;
- }
if (GetFPRType() == eFPRTypeXSAVE)
{
@@ -860,24 +782,6 @@ NativeRegisterContextLinux_x86_64::IsRegisterSetAvailable (uint32_t set_index) c
return (set_index < num_sets);
}
-lldb::ByteOrder
-NativeRegisterContextLinux_x86_64::GetByteOrder() const
-{
- // Get the target process whose privileged thread was used for the register read.
- lldb::ByteOrder byte_order = lldb::eByteOrderInvalid;
-
- NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
- if (!process_sp)
- return byte_order;
-
- if (!process_sp->GetByteOrder (byte_order))
- {
- // FIXME log here
- }
-
- return byte_order;
-}
-
bool
NativeRegisterContextLinux_x86_64::IsGPR(uint32_t reg_index) const
{
@@ -894,7 +798,7 @@ NativeRegisterContextLinux_x86_64::GetFPRType () const
// Try and see if AVX register retrieval works.
m_fpr_type = eFPRTypeXSAVE;
- if (!const_cast<NativeRegisterContextLinux_x86_64*> (this)->ReadFPR ())
+ if (const_cast<NativeRegisterContextLinux_x86_64*>(this)->ReadFPR().Fail())
{
// Fall back to general floating point with no AVX support.
m_fpr_type = eFPRTypeFXSAVE;
@@ -920,20 +824,19 @@ NativeRegisterContextLinux_x86_64::IsFPR(uint32_t reg_index, FPRType fpr_type) c
return generic_fpr;
}
-bool
+Error
NativeRegisterContextLinux_x86_64::WriteFPR()
{
- NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
- if (!process_sp)
- return false;
- NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
-
- if (GetFPRType() == eFPRTypeFXSAVE)
- return process_p->WriteFPR (m_thread.GetID (), &m_fpr.xstate.fxsave, sizeof (m_fpr.xstate.fxsave)).Success();
-
- if (GetFPRType() == eFPRTypeXSAVE)
- return process_p->WriteRegisterSet (m_thread.GetID (), &m_iovec, sizeof (m_fpr.xstate.xsave), NT_X86_XSTATE).Success();
- return false;
+ const FPRType fpr_type = GetFPRType ();
+ switch (fpr_type)
+ {
+ case FPRType::eFPRTypeFXSAVE:
+ return NativeRegisterContextLinux::WriteFPR();
+ case FPRType::eFPRTypeXSAVE:
+ return WriteRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave), NT_X86_XSTATE);
+ default:
+ return Error("Unrecognized FPR type");
+ }
}
bool
@@ -1003,48 +906,49 @@ NativeRegisterContextLinux_x86_64::CopyYMMtoXSTATE(uint32_t reg, lldb::ByteOrder
return false; // unsupported or invalid byte order
}
-bool
-NativeRegisterContextLinux_x86_64::ReadFPR ()
+void*
+NativeRegisterContextLinux_x86_64::GetFPRBuffer()
{
- NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
- if (!process_sp)
- return false;
- NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
-
const FPRType fpr_type = GetFPRType ();
switch (fpr_type)
{
case FPRType::eFPRTypeFXSAVE:
- return process_p->ReadFPR (m_thread.GetID (), &m_fpr.xstate.fxsave, sizeof (m_fpr.xstate.fxsave)).Success();
-
+ return &m_fpr.xstate.fxsave;
case FPRType::eFPRTypeXSAVE:
- return process_p->ReadRegisterSet (m_thread.GetID (), &m_iovec, sizeof (m_fpr.xstate.xsave), NT_X86_XSTATE).Success();
-
+ return &m_iovec;
default:
- return false;
+ return nullptr;
}
}
-bool
-NativeRegisterContextLinux_x86_64::ReadGPR()
+size_t
+NativeRegisterContextLinux_x86_64::GetFPRSize()
{
- NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
- if (!process_sp)
- return false;
- NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
-
- return process_p->ReadGPR (m_thread.GetID (), &m_gpr_x86_64, GetRegisterInfoInterface ().GetGPRSize ()).Success();
+ const FPRType fpr_type = GetFPRType ();
+ switch (fpr_type)
+ {
+ case FPRType::eFPRTypeFXSAVE:
+ return sizeof(m_fpr.xstate.fxsave);
+ case FPRType::eFPRTypeXSAVE:
+ return sizeof(m_iovec);
+ default:
+ return 0;
+ }
}
-bool
-NativeRegisterContextLinux_x86_64::WriteGPR()
+Error
+NativeRegisterContextLinux_x86_64::ReadFPR ()
{
- NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
- if (!process_sp)
- return false;
- NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
-
- return process_p->WriteGPR (m_thread.GetID (), &m_gpr_x86_64, GetRegisterInfoInterface ().GetGPRSize ()).Success();
+ const FPRType fpr_type = GetFPRType ();
+ switch (fpr_type)
+ {
+ case FPRType::eFPRTypeFXSAVE:
+ return NativeRegisterContextLinux::ReadFPR();
+ case FPRType::eFPRTypeXSAVE:
+ return ReadRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave), NT_X86_XSTATE);
+ default:
+ return Error("Unrecognized FPR type");
+ }
}
Error
@@ -1148,10 +1052,10 @@ NativeRegisterContextLinux_x86_64::SetHardwareWatchpointWithIndex(
control_bits |= enable_bit | rw_bits | size_bits;
- error = WriteRegister(m_reg_info.first_dr + wp_index, RegisterValue(addr));
+ error = WriteRegisterRaw(m_reg_info.first_dr + wp_index, RegisterValue(addr));
if (error.Fail()) return error;
- error = WriteRegister(m_reg_info.first_dr + 7, RegisterValue(control_bits));
+ error = WriteRegisterRaw(m_reg_info.first_dr + 7, RegisterValue(control_bits));
if (error.Fail()) return error;
error.Clear();
@@ -1172,7 +1076,7 @@ NativeRegisterContextLinux_x86_64::ClearHardwareWatchpoint(uint32_t wp_index)
if (error.Fail()) return false;
uint64_t bit_mask = 1 << wp_index;
uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask;
- error = WriteRegister(m_reg_info.first_dr + 6, RegisterValue(status_bits));
+ error = WriteRegisterRaw(m_reg_info.first_dr + 6, RegisterValue(status_bits));
if (error.Fail()) return false;
// for watchpoints 0, 1, 2, or 3, respectively,
@@ -1182,7 +1086,7 @@ NativeRegisterContextLinux_x86_64::ClearHardwareWatchpoint(uint32_t wp_index)
if (error.Fail()) return false;
bit_mask = (0x3 << (2 * wp_index)) | (0xF << (16 + 4 * wp_index));
uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
- return WriteRegister(m_reg_info.first_dr + 7, RegisterValue(control_bits)).Success();
+ return WriteRegisterRaw(m_reg_info.first_dr + 7, RegisterValue(control_bits)).Success();
}
Error
@@ -1195,7 +1099,7 @@ NativeRegisterContextLinux_x86_64::ClearAllHardwareWatchpoints()
if (error.Fail()) return error;
uint64_t bit_mask = 0xF;
uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask;
- error = WriteRegister(m_reg_info.first_dr + 6, RegisterValue(status_bits));
+ error = WriteRegisterRaw(m_reg_info.first_dr + 6, RegisterValue(status_bits));
if (error.Fail()) return error;
// clear bits {0-7,16-31} of the debug control register (DR7)
@@ -1203,7 +1107,7 @@ NativeRegisterContextLinux_x86_64::ClearAllHardwareWatchpoints()
if (error.Fail()) return error;
bit_mask = 0xFF | (0xFFFF << 16);
uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
- return WriteRegister(m_reg_info.first_dr + 7, RegisterValue(control_bits));
+ return WriteRegisterRaw(m_reg_info.first_dr + 7, RegisterValue(control_bits));
}
uint32_t
@@ -1248,3 +1152,5 @@ NativeRegisterContextLinux_x86_64::NumSupportedHardwareWatchpoints ()
// Available debug address registers: dr0, dr1, dr2, dr3
return 4;
}
+
+#endif // defined(__i386__) || defined(__x86_64__)
OpenPOWER on IntegriCloud