瀏覽代碼

x86: use generic register names in struct user_regs_struct

Switch struct user_regs_struct (defined in <asm/user.h>, which is no
longer exported to userspace) to using register names without e- or
r-prefixes for both 32 and 64 bit x86.  This is intended as a
preliminary step in unifying this code between architectures.

Also, be a bit more strict in truncating 32-bit "extended" segment
register values to 16 bits.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
H. Peter Anvin 17 年之前
父節點
當前提交
153d5f2e57
共有 4 個文件被更改,包括 68 次插入36 次删除
  1. 18 17
      arch/x86/kernel/process_32.c
  2. 2 2
      arch/x86/kernel/ptrace_64.c
  3. 17 7
      include/asm-x86/user_32.h
  4. 31 10
      include/asm-x86/user_64.h

+ 18 - 17
arch/x86/kernel/process_32.c

@@ -523,6 +523,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
 void dump_thread(struct pt_regs * regs, struct user * dump)
 void dump_thread(struct pt_regs * regs, struct user * dump)
 {
 {
 	int i;
 	int i;
+	u16 gs;
 
 
 /* changed the size calculations - should hopefully work better. lbt */
 /* changed the size calculations - should hopefully work better. lbt */
 	dump->magic = CMAGIC;
 	dump->magic = CMAGIC;
@@ -538,23 +539,23 @@ void dump_thread(struct pt_regs * regs, struct user * dump)
 	if (dump->start_stack < TASK_SIZE)
 	if (dump->start_stack < TASK_SIZE)
 		dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT;
 		dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT;
 
 
-	dump->regs.ebx = regs->bx;
-	dump->regs.ecx = regs->cx;
-	dump->regs.edx = regs->dx;
-	dump->regs.esi = regs->si;
-	dump->regs.edi = regs->di;
-	dump->regs.ebp = regs->bp;
-	dump->regs.eax = regs->ax;
-	dump->regs.ds = regs->ds;
-	dump->regs.es = regs->es;
-	dump->regs.fs = regs->fs;
-	savesegment(gs,dump->regs.gs);
-	dump->regs.orig_eax = regs->orig_ax;
-	dump->regs.eip = regs->ip;
-	dump->regs.cs = regs->cs;
-	dump->regs.eflags = regs->flags;
-	dump->regs.esp = regs->sp;
-	dump->regs.ss = regs->ss;
+	dump->regs.bx = regs->bx;
+	dump->regs.cx = regs->cx;
+	dump->regs.dx = regs->dx;
+	dump->regs.si = regs->si;
+	dump->regs.di = regs->di;
+	dump->regs.bp = regs->bp;
+	dump->regs.ax = regs->ax;
+	dump->regs.ds = (u16)regs->ds;
+	dump->regs.es = (u16)regs->es;
+	dump->regs.fs = (u16)regs->fs;
+	savesegment(gs,gs);
+	dump->regs.orig_ax = regs->orig_ax;
+	dump->regs.ip = regs->ip;
+	dump->regs.cs = (u16)regs->cs;
+	dump->regs.flags = regs->flags;
+	dump->regs.sp = regs->sp;
+	dump->regs.ss = (u16)regs->ss;
 
 
 	dump->u_fpvalid = dump_fpu (regs, &dump->i387);
 	dump->u_fpvalid = dump_fpu (regs, &dump->i387);
 }
 }

+ 2 - 2
arch/x86/kernel/ptrace_64.c

@@ -108,7 +108,7 @@ static int putreg(struct task_struct *child,
 			if (child->thread.gs != value)
 			if (child->thread.gs != value)
 				return do_arch_prctl(child, ARCH_SET_GS, value);
 				return do_arch_prctl(child, ARCH_SET_GS, value);
 			return 0;
 			return 0;
-		case offsetof(struct user_regs_struct, eflags):
+		case offsetof(struct user_regs_struct,flags):
 			value &= FLAG_MASK;
 			value &= FLAG_MASK;
 			/*
 			/*
 			 * If the user value contains TF, mark that
 			 * If the user value contains TF, mark that
@@ -164,7 +164,7 @@ static unsigned long getreg(struct task_struct *child, unsigned long regno)
 			if (child->thread.gsindex != GS_TLS_SEL)
 			if (child->thread.gsindex != GS_TLS_SEL)
 				return 0;
 				return 0;
 			return get_desc_base(&child->thread.tls_array[GS_TLS]);
 			return get_desc_base(&child->thread.tls_array[GS_TLS]);
-		case offsetof(struct user_regs_struct, eflags):
+		case offsetof(struct user_regs_struct, flags):
 			/*
 			/*
 			 * If the debugger set TF, hide it from the readout.
 			 * If the debugger set TF, hide it from the readout.
 			 */
 			 */

+ 17 - 7
include/asm-x86/user_32.h

@@ -75,13 +75,23 @@ struct user_fxsr_struct {
  * doesn't use the extra segment registers)
  * doesn't use the extra segment registers)
  */
  */
 struct user_regs_struct {
 struct user_regs_struct {
-	long ebx, ecx, edx, esi, edi, ebp, eax;
-	unsigned short ds, __ds, es, __es;
-	unsigned short fs, __fs, gs, __gs;
-	long orig_eax, eip;
-	unsigned short cs, __cs;
-	long eflags, esp;
-	unsigned short ss, __ss;
+	unsigned long	bx;
+	unsigned long	cx;
+	unsigned long	dx;
+	unsigned long	si;
+	unsigned long	di;
+	unsigned long	bp;
+	unsigned long	ax;
+	unsigned long	ds;
+	unsigned long	es;
+	unsigned long	fs;
+	unsigned long	gs;
+	unsigned long	orig_ax;
+	unsigned long	ip;
+	unsigned long	cs;
+	unsigned long	flags;
+	unsigned long	sp;
+	unsigned long	ss;
 };
 };
 
 
 /* When the kernel dumps core, it starts by dumping the user struct -
 /* When the kernel dumps core, it starts by dumping the user struct -

+ 31 - 10
include/asm-x86/user_64.h

@@ -40,13 +40,13 @@
  * and both the standard and SIMD floating point data can be accessed via
  * and both the standard and SIMD floating point data can be accessed via
  * the new ptrace requests.  In either case, changes to the FPU environment
  * the new ptrace requests.  In either case, changes to the FPU environment
  * will be reflected in the task's state as expected.
  * will be reflected in the task's state as expected.
- * 
+ *
  * x86-64 support by Andi Kleen.
  * x86-64 support by Andi Kleen.
  */
  */
 
 
 /* This matches the 64bit FXSAVE format as defined by AMD. It is the same
 /* This matches the 64bit FXSAVE format as defined by AMD. It is the same
    as the 32bit format defined by Intel, except that the selector:offset pairs for
    as the 32bit format defined by Intel, except that the selector:offset pairs for
-   data and eip are replaced with flat 64bit pointers. */ 
+   data and eip are replaced with flat 64bit pointers. */
 struct user_i387_struct {
 struct user_i387_struct {
 	unsigned short	cwd;
 	unsigned short	cwd;
 	unsigned short	swd;
 	unsigned short	swd;
@@ -65,13 +65,34 @@ struct user_i387_struct {
  * Segment register layout in coredumps.
  * Segment register layout in coredumps.
  */
  */
 struct user_regs_struct {
 struct user_regs_struct {
-	unsigned long r15,r14,r13,r12,rbp,rbx,r11,r10;
-	unsigned long r9,r8,rax,rcx,rdx,rsi,rdi,orig_rax;
-	unsigned long rip,cs,eflags;
-	unsigned long rsp,ss;
-  	unsigned long fs_base, gs_base;
-	unsigned long ds,es,fs,gs; 
-}; 
+	unsigned long	r15;
+	unsigned long	r14;
+	unsigned long	r13;
+	unsigned long	r12;
+	unsigned long	bp;
+	unsigned long	bx;
+	unsigned long	r11;
+	unsigned long	r10;
+	unsigned long	r9;
+	unsigned long	r8;
+	unsigned long	ax;
+	unsigned long	cx;
+	unsigned long	dx;
+	unsigned long	si;
+	unsigned long	di;
+	unsigned long	orig_ax;
+	unsigned long	ip;
+	unsigned long	cs;
+	unsigned long	flags;
+	unsigned long	sp;
+	unsigned long	ss;
+	unsigned long	fs_base;
+	unsigned long	gs_base;
+	unsigned long	ds;
+	unsigned long	es;
+	unsigned long	fs;
+	unsigned long	gs;
+};
 
 
 /* When the kernel dumps core, it starts by dumping the user struct -
 /* When the kernel dumps core, it starts by dumping the user struct -
    this will be used by gdb to figure out where the data and stack segments
    this will be used by gdb to figure out where the data and stack segments
@@ -94,7 +115,7 @@ struct user{
 				   This is actually the bottom of the stack,
 				   This is actually the bottom of the stack,
 				   the top of the stack is always found in the
 				   the top of the stack is always found in the
 				   esp register.  */
 				   esp register.  */
-  long int signal;     		/* Signal that caused the core dump. */
+  long int signal;		/* Signal that caused the core dump. */
   int reserved;			/* No longer used */
   int reserved;			/* No longer used */
   int pad1;
   int pad1;
   struct user_pt_regs * u_ar0;	/* Used by gdb to help find the values for */
   struct user_pt_regs * u_ar0;	/* Used by gdb to help find the values for */