|
|
1.1 ! root 1: /* ! 2: * linux/kernel/math/ea.c ! 3: * ! 4: * (C) 1991 Linus Torvalds ! 5: */ ! 6: ! 7: /* ! 8: * Calculate the effective address. ! 9: */ ! 10: ! 11: #include <stddef.h> ! 12: ! 13: #include <linux/math_emu.h> ! 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 = &EAX; ! 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,1<<(SIGILL-1)); ! 88: } ! 89: I387.foo = offset; ! 90: I387.fos = 0x17; ! 91: return offset + (char *) *tmp; ! 92: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.