Author: chaoren
Date: Wed Apr  1 15:40:34 2015
New Revision: 233837

URL: http://llvm.org/viewvc/llvm-project?rev=233837&view=rev
Log:
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

Modified:
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp
    lldb/trunk/source/Plugins/Process/Utility/RegisterInfos_x86_64.h

Modified: 
lldb/trunk/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp?rev=233837&r1=233836&r2=233837&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp 
(original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp 
Wed Apr  1 15:40:34 2015
@@ -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.

Modified: 
lldb/trunk/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp?rev=233837&r1=233836&r2=233837&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp 
(original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp 
Wed Apr  1 15:40:34 2015
@@ -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.
 //---------------------------------------------------------------------------

Modified: lldb/trunk/source/Plugins/Process/Utility/RegisterInfos_x86_64.h
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterInfos_x86_64.h?rev=233837&r1=233836&r2=233837&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterInfos_x86_64.h (original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterInfos_x86_64.h Wed Apr  1 
15:40:34 2015
@@ -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)                                              
 \


_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits

Reply via email to