|
|
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.