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>
This commit is contained in:
H. Peter Anvin 2008-01-30 13:30:56 +01:00 committed by Ingo Molnar
parent 65ea5b0349
commit 153d5f2e57
4 changed files with 68 additions and 36 deletions

View File

@ -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.bx = regs->bx;
dump->regs.ecx = regs->cx; dump->regs.cx = regs->cx;
dump->regs.edx = regs->dx; dump->regs.dx = regs->dx;
dump->regs.esi = regs->si; dump->regs.si = regs->si;
dump->regs.edi = regs->di; dump->regs.di = regs->di;
dump->regs.ebp = regs->bp; dump->regs.bp = regs->bp;
dump->regs.eax = regs->ax; dump->regs.ax = regs->ax;
dump->regs.ds = regs->ds; dump->regs.ds = (u16)regs->ds;
dump->regs.es = regs->es; dump->regs.es = (u16)regs->es;
dump->regs.fs = regs->fs; dump->regs.fs = (u16)regs->fs;
savesegment(gs,dump->regs.gs); savesegment(gs,gs);
dump->regs.orig_eax = regs->orig_ax; dump->regs.orig_ax = regs->orig_ax;
dump->regs.eip = regs->ip; dump->regs.ip = regs->ip;
dump->regs.cs = regs->cs; dump->regs.cs = (u16)regs->cs;
dump->regs.eflags = regs->flags; dump->regs.flags = regs->flags;
dump->regs.esp = regs->sp; dump->regs.sp = regs->sp;
dump->regs.ss = regs->ss; dump->regs.ss = (u16)regs->ss;
dump->u_fpvalid = dump_fpu (regs, &dump->i387); dump->u_fpvalid = dump_fpu (regs, &dump->i387);
} }

View File

@ -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.
*/ */

View File

@ -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 long bx;
unsigned short ds, __ds, es, __es; unsigned long cx;
unsigned short fs, __fs, gs, __gs; unsigned long dx;
long orig_eax, eip; unsigned long si;
unsigned short cs, __cs; unsigned long di;
long eflags, esp; unsigned long bp;
unsigned short ss, __ss; 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 -

View File

@ -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 r15;
unsigned long r9,r8,rax,rcx,rdx,rsi,rdi,orig_rax; unsigned long r14;
unsigned long rip,cs,eflags; unsigned long r13;
unsigned long rsp,ss; unsigned long r12;
unsigned long fs_base, gs_base; unsigned long bp;
unsigned long ds,es,fs,gs; 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 */