Commit 703a1edc authored by Jason Wessel's avatar Jason Wessel

kgdb, x86_64: fix PS CS SS registers in gdb serial

On x86_64 the gdb serial register structure defines the PS (also known
as eflags), CS and SS registers as 4 bytes entities.

This patch splits the x86_64 regnames enum into a 32 and 64 version to
account for the 32 bit entities in the gdb serial packets.

Also the program counter is properly filled in for the sleeping
threads.
Signed-off-by: default avatarJason Wessel <jason.wessel@windriver.com>
parent 95dbf1db
...@@ -69,6 +69,9 @@ static int gdb_x86vector = -1; ...@@ -69,6 +69,9 @@ static int gdb_x86vector = -1;
*/ */
void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs) void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
{ {
#ifndef CONFIG_X86_32
u32 *gdb_regs32 = (u32 *)gdb_regs;
#endif
gdb_regs[GDB_AX] = regs->ax; gdb_regs[GDB_AX] = regs->ax;
gdb_regs[GDB_BX] = regs->bx; gdb_regs[GDB_BX] = regs->bx;
gdb_regs[GDB_CX] = regs->cx; gdb_regs[GDB_CX] = regs->cx;
...@@ -76,9 +79,9 @@ void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs) ...@@ -76,9 +79,9 @@ void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
gdb_regs[GDB_SI] = regs->si; gdb_regs[GDB_SI] = regs->si;
gdb_regs[GDB_DI] = regs->di; gdb_regs[GDB_DI] = regs->di;
gdb_regs[GDB_BP] = regs->bp; gdb_regs[GDB_BP] = regs->bp;
gdb_regs[GDB_PS] = regs->flags;
gdb_regs[GDB_PC] = regs->ip; gdb_regs[GDB_PC] = regs->ip;
#ifdef CONFIG_X86_32 #ifdef CONFIG_X86_32
gdb_regs[GDB_PS] = regs->flags;
gdb_regs[GDB_DS] = regs->ds; gdb_regs[GDB_DS] = regs->ds;
gdb_regs[GDB_ES] = regs->es; gdb_regs[GDB_ES] = regs->es;
gdb_regs[GDB_CS] = regs->cs; gdb_regs[GDB_CS] = regs->cs;
...@@ -94,6 +97,9 @@ void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs) ...@@ -94,6 +97,9 @@ void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
gdb_regs[GDB_R13] = regs->r13; gdb_regs[GDB_R13] = regs->r13;
gdb_regs[GDB_R14] = regs->r14; gdb_regs[GDB_R14] = regs->r14;
gdb_regs[GDB_R15] = regs->r15; gdb_regs[GDB_R15] = regs->r15;
gdb_regs32[GDB_PS] = regs->flags;
gdb_regs32[GDB_CS] = regs->cs;
gdb_regs32[GDB_SS] = regs->ss;
#endif #endif
gdb_regs[GDB_SP] = regs->sp; gdb_regs[GDB_SP] = regs->sp;
} }
...@@ -112,6 +118,9 @@ void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs) ...@@ -112,6 +118,9 @@ void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
*/ */
void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p) void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
{ {
#ifndef CONFIG_X86_32
u32 *gdb_regs32 = (u32 *)gdb_regs;
#endif
gdb_regs[GDB_AX] = 0; gdb_regs[GDB_AX] = 0;
gdb_regs[GDB_BX] = 0; gdb_regs[GDB_BX] = 0;
gdb_regs[GDB_CX] = 0; gdb_regs[GDB_CX] = 0;
...@@ -129,8 +138,10 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p) ...@@ -129,8 +138,10 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
gdb_regs[GDB_FS] = 0xFFFF; gdb_regs[GDB_FS] = 0xFFFF;
gdb_regs[GDB_GS] = 0xFFFF; gdb_regs[GDB_GS] = 0xFFFF;
#else #else
gdb_regs[GDB_PS] = *(unsigned long *)(p->thread.sp + 8); gdb_regs32[GDB_PS] = *(unsigned long *)(p->thread.sp + 8);
gdb_regs[GDB_PC] = 0; gdb_regs32[GDB_CS] = __KERNEL_CS;
gdb_regs32[GDB_SS] = __KERNEL_DS;
gdb_regs[GDB_PC] = p->thread.ip;
gdb_regs[GDB_R8] = 0; gdb_regs[GDB_R8] = 0;
gdb_regs[GDB_R9] = 0; gdb_regs[GDB_R9] = 0;
gdb_regs[GDB_R10] = 0; gdb_regs[GDB_R10] = 0;
...@@ -153,6 +164,9 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p) ...@@ -153,6 +164,9 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
*/ */
void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs) void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
{ {
#ifndef CONFIG_X86_32
u32 *gdb_regs32 = (u32 *)gdb_regs;
#endif
regs->ax = gdb_regs[GDB_AX]; regs->ax = gdb_regs[GDB_AX];
regs->bx = gdb_regs[GDB_BX]; regs->bx = gdb_regs[GDB_BX];
regs->cx = gdb_regs[GDB_CX]; regs->cx = gdb_regs[GDB_CX];
...@@ -160,9 +174,9 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs) ...@@ -160,9 +174,9 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
regs->si = gdb_regs[GDB_SI]; regs->si = gdb_regs[GDB_SI];
regs->di = gdb_regs[GDB_DI]; regs->di = gdb_regs[GDB_DI];
regs->bp = gdb_regs[GDB_BP]; regs->bp = gdb_regs[GDB_BP];
regs->flags = gdb_regs[GDB_PS];
regs->ip = gdb_regs[GDB_PC]; regs->ip = gdb_regs[GDB_PC];
#ifdef CONFIG_X86_32 #ifdef CONFIG_X86_32
regs->flags = gdb_regs[GDB_PS];
regs->ds = gdb_regs[GDB_DS]; regs->ds = gdb_regs[GDB_DS];
regs->es = gdb_regs[GDB_ES]; regs->es = gdb_regs[GDB_ES];
regs->cs = gdb_regs[GDB_CS]; regs->cs = gdb_regs[GDB_CS];
...@@ -175,6 +189,9 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs) ...@@ -175,6 +189,9 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
regs->r13 = gdb_regs[GDB_R13]; regs->r13 = gdb_regs[GDB_R13];
regs->r14 = gdb_regs[GDB_R14]; regs->r14 = gdb_regs[GDB_R14];
regs->r15 = gdb_regs[GDB_R15]; regs->r15 = gdb_regs[GDB_R15];
regs->flags = gdb_regs32[GDB_PS];
regs->cs = gdb_regs32[GDB_CS];
regs->ss = gdb_regs32[GDB_SS];
#endif #endif
} }
......
...@@ -39,8 +39,9 @@ enum regnames { ...@@ -39,8 +39,9 @@ enum regnames {
GDB_FS, /* 14 */ GDB_FS, /* 14 */
GDB_GS, /* 15 */ GDB_GS, /* 15 */
}; };
#define NUMREGBYTES ((GDB_GS+1)*4)
#else /* ! CONFIG_X86_32 */ #else /* ! CONFIG_X86_32 */
enum regnames { enum regnames64 {
GDB_AX, /* 0 */ GDB_AX, /* 0 */
GDB_BX, /* 1 */ GDB_BX, /* 1 */
GDB_CX, /* 2 */ GDB_CX, /* 2 */
...@@ -58,18 +59,15 @@ enum regnames { ...@@ -58,18 +59,15 @@ enum regnames {
GDB_R14, /* 14 */ GDB_R14, /* 14 */
GDB_R15, /* 15 */ GDB_R15, /* 15 */
GDB_PC, /* 16 */ GDB_PC, /* 16 */
GDB_PS, /* 17 */
}; };
#endif /* CONFIG_X86_32 */
/* enum regnames32 {
* Number of bytes of registers: GDB_PS = 34,
*/ GDB_CS,
#ifdef CONFIG_X86_32 GDB_SS,
# define NUMREGBYTES 64 };
#else #define NUMREGBYTES ((GDB_SS+1)*4)
# define NUMREGBYTES ((GDB_PS+1)*8) #endif /* CONFIG_X86_32 */
#endif
static inline void arch_kgdb_breakpoint(void) static inline void arch_kgdb_breakpoint(void)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment