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
