forked from OSchip/llvm-project
Fix issue where GPR and FPR registers have overlapping byte offsets.
Summary: The implementation of GDBRemoteRegisterContext relies on byte offsets to cache register values. GPR, FPR, etc. should start on different offsets. This is correctly done in debugserver (in DNBArchImplX86_64.cpp), but not on Linux or FreeBSD (in RegisterInfos_x86_64.h). Test Plan: `register read st0` no longer overwrites `rbp` on Linux with LLGS. Reviewers: sivachandra, jingham, emaste, ovyalov, clayborg Reviewed By: clayborg Subscribers: emaste, lldb-commits Differential Revision: http://reviews.llvm.org/D8685 llvm-svn: 233837
This commit is contained in:
parent
1346717068
commit
4ced470a31
|
@ -46,19 +46,21 @@ typedef struct _GPR
|
|||
uint64_t ss;
|
||||
} GPR;
|
||||
|
||||
struct dbreg {
|
||||
uint64_t dr[16]; /* debug registers */
|
||||
/* Index 0-3: debug address registers */
|
||||
/* Index 4-5: reserved */
|
||||
/* Index 6: debug status */
|
||||
/* Index 7: debug control */
|
||||
/* Index 8-15: reserved */
|
||||
struct DBG {
|
||||
uint64_t dr[16]; /* debug registers */
|
||||
/* Index 0-3: debug address registers */
|
||||
/* Index 4-5: reserved */
|
||||
/* Index 6: debug status */
|
||||
/* Index 7: debug control */
|
||||
/* Index 8-15: reserved */
|
||||
};
|
||||
|
||||
#define DR_SIZE sizeof(uint64_t)
|
||||
#define DR_OFFSET(reg_index) \
|
||||
(LLVM_EXTENSION offsetof(dbreg, dr[reg_index]))
|
||||
|
||||
struct UserArea
|
||||
{
|
||||
GPR gpr;
|
||||
FPR fpr;
|
||||
DBG dbg;
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include RegisterInfos_x86_64 to declare our g_register_infos_x86_64 structure.
|
||||
|
|
|
@ -46,12 +46,16 @@ typedef struct _GPR
|
|||
uint64_t gs;
|
||||
} GPR;
|
||||
|
||||
struct DBG {
|
||||
uint64_t dr[8];
|
||||
};
|
||||
|
||||
struct UserArea
|
||||
{
|
||||
GPR gpr; // General purpose registers.
|
||||
int32_t fpvalid; // True if FPU is being used.
|
||||
int32_t pad0;
|
||||
FXSAVE i387; // General purpose floating point registers (see FPR for extended register sets).
|
||||
FXSAVE fpr; // General purpose floating point registers (see FPR for extended register sets).
|
||||
uint64_t tsize; // Text segment size.
|
||||
uint64_t dsize; // Data segment size.
|
||||
uint64_t ssize; // Stack segment size.
|
||||
|
@ -64,15 +68,11 @@ struct UserArea
|
|||
FXSAVE* fpstate; // Location of FPR's.
|
||||
uint64_t magic; // Identifier for core dumps.
|
||||
char u_comm[32]; // Command causing core dump.
|
||||
uint64_t u_debugreg[8]; // Debug registers (DR0 - DR7).
|
||||
DBG dbg; // Debug registers.
|
||||
uint64_t error_code; // CPU error code.
|
||||
uint64_t fault_address; // Control register CR3.
|
||||
};
|
||||
|
||||
#define DR_SIZE sizeof(((UserArea*)NULL)->u_debugreg[0])
|
||||
#define DR_OFFSET(reg_index) \
|
||||
(LLVM_EXTENSION offsetof(UserArea, u_debugreg[reg_index]))
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include RegisterInfos_x86_64 to declare our g_register_infos_x86_64 structure.
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
|
@ -16,12 +16,20 @@
|
|||
|
||||
// Computes the offset of the given FPR in the extended data area.
|
||||
#define FPR_OFFSET(regname) \
|
||||
(LLVM_EXTENSION offsetof(FPR, xstate) + \
|
||||
(LLVM_EXTENSION offsetof(UserArea, fpr) + \
|
||||
LLVM_EXTENSION offsetof(FPR, xstate) + \
|
||||
LLVM_EXTENSION offsetof(FXSAVE, regname))
|
||||
|
||||
// Computes the offset of the YMM register assembled from register halves.
|
||||
#define YMM_OFFSET(regname) \
|
||||
(LLVM_EXTENSION offsetof(YMM, regname))
|
||||
#define YMM_OFFSET(reg_index) \
|
||||
(LLVM_EXTENSION offsetof(UserArea, fpr) + \
|
||||
LLVM_EXTENSION offsetof(FPR, xstate) + \
|
||||
LLVM_EXTENSION offsetof(XSAVE, ymmh[reg_index]) + \
|
||||
(32 * reg_index))
|
||||
|
||||
#define DR_OFFSET(reg_index) \
|
||||
(LLVM_EXTENSION offsetof(UserArea, dbg) + \
|
||||
LLVM_EXTENSION offsetof(DBG, dr[reg_index]))
|
||||
|
||||
#ifdef DECLARE_REGISTER_INFOS_X86_64_STRUCT
|
||||
|
||||
|
@ -37,6 +45,8 @@
|
|||
// Number of bytes needed to represent a YMM register.
|
||||
#define YMM_SIZE sizeof(YMMReg)
|
||||
|
||||
#define DR_SIZE sizeof(((DBG*)NULL)->dr[0])
|
||||
|
||||
// RegisterKind: GCC, DWARF, Generic, GDB, LLDB
|
||||
|
||||
// Note that the size and offset will be updated by platform-specific classes.
|
||||
|
@ -67,7 +77,7 @@
|
|||
NULL, NULL }
|
||||
|
||||
#define DEFINE_YMM(reg, i) \
|
||||
{ #reg#i, NULL, YMM_SIZE, LLVM_EXTENSION YMM_OFFSET(reg[i]), \
|
||||
{ #reg#i, NULL, YMM_SIZE, LLVM_EXTENSION YMM_OFFSET(i), \
|
||||
eEncodingVector, eFormatVectorOfUInt8, \
|
||||
{ gcc_dwarf_##reg##i##h_x86_64, gcc_dwarf_##reg##i##h_x86_64, LLDB_INVALID_REGNUM, gdb_##reg##i##h_x86_64, lldb_##reg##i##_x86_64 }, \
|
||||
NULL, NULL }
|
||||
|
@ -298,7 +308,7 @@ do {
|
|||
|
||||
#define UPDATE_YMM_INFO(reg, i) \
|
||||
do { \
|
||||
g_register_infos[lldb_##reg##i##_i386].byte_offset = YMM_OFFSET(reg[i]); \
|
||||
g_register_infos[lldb_##reg##i##_i386].byte_offset = YMM_OFFSET(i); \
|
||||
} while(false);
|
||||
|
||||
#define UPDATE_DR_INFO(reg_index) \
|
||||
|
|
Loading…
Reference in New Issue