Fixing TestRegisters on Linux with LLGS
This patch fixes TestRegisters on Linux with LLGS
Introduce GetUserRegisterCount on RegisterInfoInterface to distinguish
lldb internal registers (e.g.: DR0-DR7) during register counting.
Update GDBRemoteCommunicationServer to skip lldb internal registers on
read/write register and on discover register.
Submitted for Tamas Berghammer
llvm-svn: 226959
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp
index b9b9dca..b38d6cc 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp
@@ -125,3 +125,8 @@
return static_cast<uint32_t> (sizeof (g_register_infos_i386) / sizeof (g_register_infos_i386 [0]));
}
+uint32_t
+RegisterContextLinux_i386::GetUserRegisterCount () const
+{
+ return static_cast<uint32_t> (k_num_user_registers_i386);
+}
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.h b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.h
index f8b21fc..cb71d79 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.h
@@ -26,6 +26,9 @@
uint32_t
GetRegisterCount () const override;
+
+ uint32_t
+ GetUserRegisterCount () const override;
};
#endif
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp
index 74f016bd..5c93ebf 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp
@@ -145,10 +145,26 @@
}
}
+static uint32_t
+GetUserRegisterInfoCount (const ArchSpec &target_arch)
+{
+ switch (target_arch.GetMachine())
+ {
+ case llvm::Triple::x86:
+ return static_cast<uint32_t> (k_num_user_registers_i386);
+ case llvm::Triple::x86_64:
+ return static_cast<uint32_t> (k_num_user_registers_x86_64);
+ default:
+ assert(false && "Unhandled target architecture.");
+ return 0;
+ }
+}
+
RegisterContextLinux_x86_64::RegisterContextLinux_x86_64(const ArchSpec &target_arch) :
lldb_private::RegisterInfoInterface(target_arch),
m_register_info_p (GetRegisterInfoPtr (target_arch)),
- m_register_info_count (GetRegisterInfoCount (target_arch))
+ m_register_info_count (GetRegisterInfoCount (target_arch)),
+ m_user_register_count (GetUserRegisterInfoCount (target_arch))
{
}
@@ -169,3 +185,9 @@
{
return m_register_info_count;
}
+
+uint32_t
+RegisterContextLinux_x86_64::GetUserRegisterCount () const
+{
+ return m_user_register_count;
+}
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h
index 7b68286..0cdfae9 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h
@@ -27,9 +27,13 @@
uint32_t
GetRegisterCount () const override;
+ uint32_t
+ GetUserRegisterCount () const override;
+
private:
const lldb_private::RegisterInfo *m_register_info_p;
uint32_t m_register_info_count;
+ uint32_t m_user_register_count;
};
#endif
diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h b/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h
index 382475f..94cb5cc7 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h
@@ -32,9 +32,20 @@
virtual const lldb_private::RegisterInfo *
GetRegisterInfo () const = 0;
+ // Returns the number of registers including the user registers and the
+ // lldb internal registers also
virtual uint32_t
GetRegisterCount () const = 0;
+ // Returns the number of the user registers (excluding the registers
+ // kept for lldb internal use only). Subclasses should override it if
+ // they belongs to an architecture with lldb internal registers.
+ virtual uint32_t
+ GetUserRegisterCount () const
+ {
+ return GetRegisterCount();
+ }
+
const lldb_private::ArchSpec&
GetTargetArchitecture() const
{ return m_target_arch; }
diff --git a/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h b/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h
index 99fca30..63027b4 100644
--- a/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h
+++ b/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h
@@ -118,7 +118,8 @@
k_num_registers_i386,
k_num_gpr_registers_i386 = k_last_gpr_i386 - k_first_gpr_i386 + 1,
k_num_fpr_registers_i386 = k_last_fpr_i386 - k_first_fpr_i386 + 1,
- k_num_avx_registers_i386 = k_last_avx_i386 - k_first_avx_i386 + 1
+ k_num_avx_registers_i386 = k_last_avx_i386 - k_first_avx_i386 + 1,
+ k_num_user_registers_i386 = k_num_gpr_registers_i386 + k_num_fpr_registers_i386 + k_num_avx_registers_i386,
};
//---------------------------------------------------------------------------
@@ -285,7 +286,8 @@
k_num_registers_x86_64,
k_num_gpr_registers_x86_64 = k_last_gpr_x86_64 - k_first_gpr_x86_64 + 1,
k_num_fpr_registers_x86_64 = k_last_fpr_x86_64 - k_first_fpr_x86_64 + 1,
- k_num_avx_registers_x86_64 = k_last_avx_x86_64 - k_first_avx_x86_64 + 1
+ k_num_avx_registers_x86_64 = k_last_avx_x86_64 - k_first_avx_x86_64 + 1,
+ k_num_user_registers_x86_64 = k_num_gpr_registers_x86_64 + k_num_fpr_registers_x86_64 + k_num_avx_registers_x86_64,
};
}
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
index 8eb4240..c2f1b7b 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
@@ -2995,7 +2995,7 @@
return SendErrorResponse (69);
// Return the end of registers response if we've iterated one past the end of the register set.
- if (reg_index >= reg_context_sp->GetRegisterCount ())
+ if (reg_index >= reg_context_sp->GetUserRegisterCount ())
return SendErrorResponse (69);
const RegisterInfo *reg_info = reg_context_sp->GetRegisterInfoAtIndex(reg_index);
@@ -3196,10 +3196,10 @@
}
// Return the end of registers response if we've iterated one past the end of the register set.
- if (reg_index >= reg_context_sp->GetRegisterCount ())
+ if (reg_index >= reg_context_sp->GetUserRegisterCount ())
{
if (log)
- log->Printf ("GDBRemoteCommunicationServer::%s failed, requested register %" PRIu32 " beyond register count %" PRIu32, __FUNCTION__, reg_index, reg_context_sp->GetRegisterCount ());
+ log->Printf ("GDBRemoteCommunicationServer::%s failed, requested register %" PRIu32 " beyond register count %" PRIu32, __FUNCTION__, reg_index, reg_context_sp->GetUserRegisterCount ());
return SendErrorResponse (0x15);
}
@@ -3305,10 +3305,10 @@
}
// Return the end of registers response if we've iterated one past the end of the register set.
- if (reg_index >= reg_context_sp->GetRegisterCount ())
+ if (reg_index >= reg_context_sp->GetUserRegisterCount ())
{
if (log)
- log->Printf ("GDBRemoteCommunicationServer::%s failed, requested register %" PRIu32 " beyond register count %" PRIu32, __FUNCTION__, reg_index, reg_context_sp->GetRegisterCount ());
+ log->Printf ("GDBRemoteCommunicationServer::%s failed, requested register %" PRIu32 " beyond register count %" PRIu32, __FUNCTION__, reg_index, reg_context_sp->GetUserRegisterCount ());
return SendErrorResponse (0x47);
}