This source file includes following definitions.
- sib
- ea
1
2
3
4
5
6
7
8
9
10
11 #include <linux/stddef.h>
12 #include <linux/math_emu.h>
13
14 #include <asm/segment.h>
15
16 static int __regoffset[] = {
17 offsetof(struct info,___eax),
18 offsetof(struct info,___ecx),
19 offsetof(struct info,___edx),
20 offsetof(struct info,___ebx),
21 offsetof(struct info,___esp),
22 offsetof(struct info,___ebp),
23 offsetof(struct info,___esi),
24 offsetof(struct info,___edi)
25 };
26
27 #define REG(x) (*(long *)(__regoffset[(x)]+(char *) info))
28
29 static char * sib(struct info * info, int mod)
30 {
31 unsigned char ss,index,base;
32 long offset = 0;
33
34 base = get_fs_byte((char *) EIP);
35 EIP++;
36 ss = base >> 6;
37 index = (base >> 3) & 7;
38 base &= 7;
39 if (index == 4)
40 offset = 0;
41 else
42 offset = REG(index);
43 offset <<= ss;
44 if (mod || base != 5)
45 offset += REG(base);
46 if (mod == 1) {
47 offset += (signed char) get_fs_byte((char *) EIP);
48 EIP++;
49 } else if (mod == 2 || base == 5) {
50 offset += (signed) get_fs_long((unsigned long *) EIP);
51 EIP += 4;
52 }
53 I387.foo = offset;
54 I387.fos = 0x17;
55 return (char *) offset;
56 }
57
58 char * ea(struct info * info, unsigned short code)
59 {
60 unsigned char mod,rm;
61 long * tmp;
62 int offset = 0;
63
64 mod = (code >> 6) & 3;
65 rm = code & 7;
66 if (rm == 4 && mod != 3)
67 return sib(info,mod);
68 if (rm == 5 && !mod) {
69 offset = get_fs_long((unsigned long *) EIP);
70 EIP += 4;
71 I387.foo = offset;
72 I387.fos = 0x17;
73 return (char *) offset;
74 }
75 tmp = & REG(rm);
76 switch (mod) {
77 case 0: offset = 0; break;
78 case 1:
79 offset = (signed char) get_fs_byte((char *) EIP);
80 EIP++;
81 break;
82 case 2:
83 offset = (signed) get_fs_long((unsigned long *) EIP);
84 EIP += 4;
85 break;
86 case 3:
87 math_abort(info,SIGILL);
88 }
89 I387.foo = offset;
90 I387.fos = 0x17;
91 return offset + (char *) *tmp;
92 }