|
@@ -9,6 +9,20 @@
|
|
|
#ifdef __i386__
|
|
#ifdef __i386__
|
|
|
|
|
|
|
|
struct pt_regs {
|
|
struct pt_regs {
|
|
|
|
|
+ /*
|
|
|
|
|
+ * NB: 32-bit x86 CPUs are inconsistent as what happens in the
|
|
|
|
|
+ * following cases (where %seg represents a segment register):
|
|
|
|
|
+ *
|
|
|
|
|
+ * - pushl %seg: some do a 16-bit write and leave the high
|
|
|
|
|
+ * bits alone
|
|
|
|
|
+ * - movl %seg, [mem]: some do a 16-bit write despite the movl
|
|
|
|
|
+ * - IDT entry: some (e.g. 486) will leave the high bits of CS
|
|
|
|
|
+ * and (if applicable) SS undefined.
|
|
|
|
|
+ *
|
|
|
|
|
+ * Fortunately, x86-32 doesn't read the high bits on POP or IRET,
|
|
|
|
|
+ * so we can just treat all of the segment registers as 16-bit
|
|
|
|
|
+ * values.
|
|
|
|
|
+ */
|
|
|
unsigned long bx;
|
|
unsigned long bx;
|
|
|
unsigned long cx;
|
|
unsigned long cx;
|
|
|
unsigned long dx;
|
|
unsigned long dx;
|
|
@@ -16,16 +30,22 @@ struct pt_regs {
|
|
|
unsigned long di;
|
|
unsigned long di;
|
|
|
unsigned long bp;
|
|
unsigned long bp;
|
|
|
unsigned long ax;
|
|
unsigned long ax;
|
|
|
- unsigned long ds;
|
|
|
|
|
- unsigned long es;
|
|
|
|
|
- unsigned long fs;
|
|
|
|
|
- unsigned long gs;
|
|
|
|
|
|
|
+ unsigned short ds;
|
|
|
|
|
+ unsigned short __dsh;
|
|
|
|
|
+ unsigned short es;
|
|
|
|
|
+ unsigned short __esh;
|
|
|
|
|
+ unsigned short fs;
|
|
|
|
|
+ unsigned short __fsh;
|
|
|
|
|
+ unsigned short gs;
|
|
|
|
|
+ unsigned short __gsh;
|
|
|
unsigned long orig_ax;
|
|
unsigned long orig_ax;
|
|
|
unsigned long ip;
|
|
unsigned long ip;
|
|
|
- unsigned long cs;
|
|
|
|
|
|
|
+ unsigned short cs;
|
|
|
|
|
+ unsigned short __csh;
|
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
|
unsigned long sp;
|
|
unsigned long sp;
|
|
|
- unsigned long ss;
|
|
|
|
|
|
|
+ unsigned short ss;
|
|
|
|
|
+ unsigned short __ssh;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
#else /* __i386__ */
|
|
#else /* __i386__ */
|