|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1995-1994 The University of Utah and ! 3: * the Computer Systems Laboratory at the University of Utah (CSL). ! 4: * All rights reserved. ! 5: * ! 6: * Permission to use, copy, modify and distribute this software is hereby ! 7: * granted provided that (1) source code retains these copyright, permission, ! 8: * and disclaimer notices, and (2) redistributions including binaries ! 9: * reproduce the notices in supporting documentation, and (3) all advertising ! 10: * materials mentioning features or use of this software display the following ! 11: * acknowledgement: ``This product includes software developed by the ! 12: * Computer Systems Laboratory at the University of Utah.'' ! 13: * ! 14: * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS ! 15: * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF ! 16: * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ! 17: * ! 18: * CSL requests users of this software to return to [email protected] any ! 19: * improvements that they make and grant CSL redistribution rights. ! 20: * ! 21: * Author: Bryan Ford, University of Utah CSL ! 22: */ ! 23: ! 24: #include <mach/machine/code16.h> ! 25: #include <mach/machine/vm_types.h> ! 26: ! 27: #include "i16_dos.h" ! 28: #include "config.h" ! 29: ! 30: ! 31: ! 32: /* These aren't static because vcpi and dpmi code need to grab DOS memory ! 33: before we've switched to protected mode and memory has been collected. */ ! 34: vm_offset_t dos_mem_phys_free_mem; ! 35: vm_size_t dos_mem_phys_free_size; ! 36: ! 37: ! 38: CODE32 ! 39: ! 40: void dos_mem_collect(void) ! 41: { ! 42: if (dos_mem_phys_free_mem) ! 43: { ! 44: phys_mem_add(dos_mem_phys_free_mem, dos_mem_phys_free_size); ! 45: dos_mem_phys_free_mem = 0; ! 46: } ! 47: } ! 48: ! 49: CODE16 ! 50: ! 51: void i16_dos_mem_check() ! 52: { ! 53: unsigned short paras = 0xf000; ! 54: int dos_mem_seg; ! 55: ! 56: /* Allocate as big a chunk of memory as we can find. */ ! 57: do ! 58: { ! 59: if (paras == 0) ! 60: return; ! 61: dos_mem_seg = i16_dos_alloc(¶s); ! 62: } ! 63: while (dos_mem_seg < 0); ! 64: ! 65: dos_mem_phys_free_mem = dos_mem_seg << 4; ! 66: dos_mem_phys_free_size = paras << 4; ! 67: ! 68: #ifdef ENABLE_CODE_CHECK ! 69: i16_code_copy(); ! 70: #endif ! 71: } ! 72: ! 73: ! 74: #ifdef ENABLE_CODE_CHECK ! 75: ! 76: /* Big humongo kludge to help in finding random code-trashing bugs. ! 77: We copy the entire text segment upon initialization, ! 78: and then check it later as necessary. */ ! 79: ! 80: #include <mach/machine/proc_reg.h> ! 81: #include "vm_param.h" ! 82: ! 83: extern char etext[], i16_entry_2[]; ! 84: ! 85: static int code_copy_seg; ! 86: ! 87: static int i16_code_copy() ! 88: { ! 89: int text_size = (int)etext & ~0xf; ! 90: int i; ! 91: ! 92: if (dos_mem_phys_free_size < text_size) ! 93: return; ! 94: ! 95: code_copy_seg = dos_mem_phys_free_mem >> 4; ! 96: dos_mem_phys_free_mem += text_size; ! 97: dos_mem_phys_free_size -= text_size; ! 98: ! 99: set_fs(code_copy_seg); ! 100: for (i = 0; i < text_size; i += 4) ! 101: asm volatile(" ! 102: movl (%%ebx),%%eax ! 103: movl %%eax,%%fs:(%%ebx) ! 104: " : : "b" (i) : "eax"); ! 105: } ! 106: ! 107: void i16_code_check(int dummy) ! 108: { ! 109: int text_size = (int)etext & ~0xf; ! 110: int i, old, new; ! 111: int found = 0; ! 112: ! 113: if (!code_copy_seg) ! 114: return; ! 115: ! 116: set_fs(code_copy_seg); ! 117: for (i = (int)i16_entry_2; i < text_size; i += 4) ! 118: { ! 119: asm volatile(" ! 120: movl (%%ebx),%%eax ! 121: movl %%fs:(%%ebx),%%ecx ! 122: " : "=a" (new), "=c" (old) : "b" (i)); ! 123: if (old != new) ! 124: { ! 125: found = 1; ! 126: i16_writehexw(i); ! 127: i16_putchar(' '); ! 128: i16_writehexl(old); ! 129: i16_putchar(' '); ! 130: i16_writehexl(new); ! 131: i16_putchar('\r'); ! 132: i16_putchar('\n'); ! 133: } ! 134: } ! 135: if (found) ! 136: { ! 137: code_copy_seg = 0; ! 138: i16_writehexl((&dummy)[-1]); ! 139: i16_die(" DOS extender code trashed!"); ! 140: } ! 141: } ! 142: ! 143: CODE32 ! 144: ! 145: void code_check(int dummy) ! 146: { ! 147: int text_size = (int)etext & ~0xf; ! 148: unsigned char *new = 0, *old = (void*)phystokv(code_copy_seg*16); ! 149: int found = 0; ! 150: int i; ! 151: ! 152: if (!code_copy_seg) ! 153: return; ! 154: ! 155: for (i = (int)i16_entry_2; (i < text_size) && (found < 10); i++) ! 156: { ! 157: /* In several places we have to self-modify an int instruction, ! 158: or the segment value in an absolute long jmp instruction, ! 159: so ignore any changes preceded by those opcodes. */ ! 160: if ((new[i] != old[i]) ! 161: && (old[i-1] != 0xcd) ! 162: && (old[i-6] != 0xea)) ! 163: { ! 164: if (!found) ! 165: { ! 166: found = 1; ! 167: about_to_die(1); ! 168: } ! 169: printf("%08x addr %04x was %02x now %02x\n", ! 170: (&dummy)[-1], i, old[i], new[i]); ! 171: } ! 172: } ! 173: if (found) ! 174: { ! 175: code_copy_seg = 0; ! 176: die("%08x DOS extender code trashed!", (&dummy)[-1]); ! 177: } ! 178: } ! 179: ! 180: CODE16 ! 181: ! 182: #endif ENABLE_CODE_CHECK
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.