This source file includes following definitions.
- sib
- get_address
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 #include <linux/stddef.h>
21
22 #include <asm/segment.h>
23
24 #include "fpu_system.h"
25 #include "exception.h"
26 #include "fpu_emu.h"
27
28 static int reg_offset[] = {
29 offsetof(struct info,___eax),
30 offsetof(struct info,___ecx),
31 offsetof(struct info,___edx),
32 offsetof(struct info,___ebx),
33 offsetof(struct info,___esp),
34 offsetof(struct info,___ebp),
35 offsetof(struct info,___esi),
36 offsetof(struct info,___edi)
37 };
38
39 #define REG_(x) (*(long *)(reg_offset[(x)]+(char *) FPU_info))
40
41
42 void *FPU_data_address;
43
44
45
46 static void *sib(int mod)
47 {
48 unsigned char ss,index,base;
49 long offset;
50
51 RE_ENTRANT_CHECK_OFF
52 base = get_fs_byte((char *) FPU_EIP);
53 RE_ENTRANT_CHECK_ON
54 FPU_EIP++;
55 ss = base >> 6;
56 index = (base >> 3) & 7;
57 base &= 7;
58
59 if ((mod == 0) && (base == 5))
60 offset = 0;
61 else
62 offset = REG_(base);
63
64 if (index == 4)
65 {
66
67
68 if ( ss )
69 EXCEPTION(EX_Invalid);
70 }
71 else
72 {
73 offset += (REG_(index)) << ss;
74 }
75
76 if (mod == 1)
77 {
78
79 RE_ENTRANT_CHECK_OFF
80 offset += (signed char) get_fs_byte((char *) FPU_EIP);
81 RE_ENTRANT_CHECK_ON
82 FPU_EIP++;
83 }
84 else if (mod == 2 || base == 5)
85 {
86
87 RE_ENTRANT_CHECK_OFF
88 offset += (signed) get_fs_long((unsigned long *) FPU_EIP);
89 RE_ENTRANT_CHECK_ON
90 FPU_EIP += 4;
91 }
92
93 return (void *) offset;
94 }
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114 void get_address(unsigned char FPU_modrm)
115 {
116 unsigned char mod;
117 long *cpu_reg_ptr;
118 int offset = 0;
119
120 mod = (FPU_modrm >> 6) & 3;
121
122 if (FPU_rm == 4 && mod != 3)
123 {
124 FPU_data_address = sib(mod);
125 return;
126 }
127
128 cpu_reg_ptr = & REG_(FPU_rm);
129 switch (mod)
130 {
131 case 0:
132 if (FPU_rm == 5)
133 {
134
135 RE_ENTRANT_CHECK_OFF
136 offset = get_fs_long((unsigned long *) FPU_EIP);
137 RE_ENTRANT_CHECK_ON
138 FPU_EIP += 4;
139 FPU_data_address = (void *) offset;
140 return;
141 }
142 else
143 {
144 FPU_data_address = (void *)*cpu_reg_ptr;
145
146 return;
147 }
148 case 1:
149
150 RE_ENTRANT_CHECK_OFF
151 offset = (signed char) get_fs_byte((char *) FPU_EIP);
152 RE_ENTRANT_CHECK_ON
153 FPU_EIP++;
154 break;
155 case 2:
156
157 RE_ENTRANT_CHECK_OFF
158 offset = (signed) get_fs_long((unsigned long *) FPU_EIP);
159 RE_ENTRANT_CHECK_ON
160 FPU_EIP += 4;
161 break;
162 case 3:
163
164 EXCEPTION(EX_Invalid);
165 }
166
167 FPU_data_address = offset + (char *)*cpu_reg_ptr;
168 }