patch-2.1.4 linux/arch/i386/math-emu/get_address.c
Next file: linux/arch/i386/math-emu/load_store.c
Previous file: linux/arch/i386/math-emu/fpu_entry.c
Back to the patch index
Back to the overall index
- Lines: 138
- Date:
Tue Oct 15 10:44:40 1996
- Orig file:
v2.1.3/linux/arch/i386/math-emu/get_address.c
- Orig date:
Fri Aug 19 08:54:01 1994
diff -u --recursive --new-file v2.1.3/linux/arch/i386/math-emu/get_address.c linux/arch/i386/math-emu/get_address.c
@@ -56,12 +56,16 @@
#define VM86_REG_(x) (*(unsigned short *) \
(reg_offset_vm86[((unsigned)x)]+(char *) FPU_info))
+/* These are dummy, fs and gs are not saved on the stack. */
+#define ___FS ___ds
+#define ___GS ___ds
+
static int reg_offset_pm[] = {
offsetof(struct info,___cs),
offsetof(struct info,___ds),
offsetof(struct info,___es),
- offsetof(struct info,___fs),
- offsetof(struct info,___gs),
+ offsetof(struct info,___FS),
+ offsetof(struct info,___GS),
offsetof(struct info,___ss),
offsetof(struct info,___ds)
};
@@ -78,7 +82,7 @@
RE_ENTRANT_CHECK_OFF;
FPU_code_verify_area(1);
- base = get_fs_byte((char *) (*fpu_eip)); /* The SIB byte */
+ get_user(base, (unsigned char *) (*fpu_eip)); /* The SIB byte */
RE_ENTRANT_CHECK_ON;
(*fpu_eip)++;
ss = base >> 6;
@@ -105,18 +109,22 @@
if (mod == 1)
{
/* 8 bit signed displacement */
+ long displacement;
RE_ENTRANT_CHECK_OFF;
FPU_code_verify_area(1);
- offset += (signed char) get_fs_byte((char *) (*fpu_eip));
+ get_user(displacement, (signed char *) (*fpu_eip));
+ offset += displacement;
RE_ENTRANT_CHECK_ON;
(*fpu_eip)++;
}
else if (mod == 2 || base == 5) /* The second condition also has mod==0 */
{
/* 32 bit displacement */
+ long displacement;
RE_ENTRANT_CHECK_OFF;
FPU_code_verify_area(4);
- offset += (signed) get_fs_long((unsigned long *) (*fpu_eip));
+ get_user(displacement, (signed long *) (*fpu_eip));
+ offset += displacement;
RE_ENTRANT_CHECK_ON;
(*fpu_eip) += 4;
}
@@ -149,7 +157,9 @@
unsigned long base_address, limit, address, seg_top;
segment--;
+
#ifdef PARANOID
+ /* segment is unsigned, so this also detects if segment was 0: */
if ( segment > PREFIX_SS_ )
{
EXCEPTION(EX_INTERNAL|0x132);
@@ -157,7 +167,19 @@
}
#endif PARANOID
- *selector = PM_REG_(segment);
+ switch ( segment )
+ {
+ /* fs and gs aren't used by the kernel, so they still have their
+ user-space values. */
+ case PREFIX_FS_-1:
+ __asm__("mov %%fs,%0":"=r" (*selector));
+ break;
+ case PREFIX_GS_-1:
+ __asm__("mov %%gs,%0":"=r" (*selector));
+ break;
+ default:
+ *selector = PM_REG_(segment);
+ }
descriptor = LDT_DESCRIPTOR(PM_REG_(segment));
base_address = SEG_BASE_ADDR(descriptor);
@@ -248,7 +270,7 @@
/* Special case: disp32 */
RE_ENTRANT_CHECK_OFF;
FPU_code_verify_area(4);
- address = get_fs_long((unsigned long *) (*fpu_eip));
+ get_user(address, (unsigned long *) (*fpu_eip));
(*fpu_eip) += 4;
RE_ENTRANT_CHECK_ON;
addr->offset = address;
@@ -265,7 +287,7 @@
/* 8 bit signed displacement */
RE_ENTRANT_CHECK_OFF;
FPU_code_verify_area(1);
- address = (signed char) get_fs_byte((char *) (*fpu_eip));
+ get_user(address, (signed char *) (*fpu_eip));
RE_ENTRANT_CHECK_ON;
(*fpu_eip)++;
break;
@@ -273,7 +295,7 @@
/* 32 bit displacement */
RE_ENTRANT_CHECK_OFF;
FPU_code_verify_area(4);
- address = (signed) get_fs_long((unsigned long *) (*fpu_eip));
+ get_user(address, (long *) (*fpu_eip));
(*fpu_eip) += 4;
RE_ENTRANT_CHECK_ON;
break;
@@ -336,7 +358,7 @@
/* Special case: disp16 */
RE_ENTRANT_CHECK_OFF;
FPU_code_verify_area(2);
- address = (unsigned short)get_fs_word((unsigned short *) (*fpu_eip));
+ get_user(address, (unsigned short *) (*fpu_eip));
(*fpu_eip) += 2;
RE_ENTRANT_CHECK_ON;
goto add_segment;
@@ -346,7 +368,7 @@
/* 8 bit signed displacement */
RE_ENTRANT_CHECK_OFF;
FPU_code_verify_area(1);
- address = (signed char) get_fs_byte((signed char *) (*fpu_eip));
+ get_user(address, (signed char *) (*fpu_eip));
RE_ENTRANT_CHECK_ON;
(*fpu_eip)++;
break;
@@ -354,7 +376,7 @@
/* 16 bit displacement */
RE_ENTRANT_CHECK_OFF;
FPU_code_verify_area(2);
- address = (unsigned) get_fs_word((unsigned short *) (*fpu_eip));
+ get_user(address, (unsigned short *) (*fpu_eip));
(*fpu_eip) += 2;
RE_ENTRANT_CHECK_ON;
break;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov