|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24:
25: #import <kern/lock.h>
26: #import <bsd/machine/cpu.h>
27: #import <vm/vm_kern.h>
28: #import <machine/spl.h>
29: #import <kern/clock.h>
30: #import <kdebug.h>
31: #import <kern/kdebug.h>
32: #import <kern/kdebug_private.h>
33: #import <bsd/sys/errno.h>
34: #import <bsd/sys/param.h> /* for splhigh */
35: #import <bsd/sys/proc.h>
36: #import <bsd/sys/vm.h>
37: #import <bsd/sys/sysctl.h>
38:
39: /* kd_buf kd_buffer[kd_bufsize/sizeof(kd_buf)]; */
40: kd_buf * kd_bufptr;
41: unsigned int kd_buftomem=0;
42: kd_buf * kd_buffer=0;
43: kd_buf * kd_buflast;
44: kd_buf * kd_readlast;
45: unsigned int nkdbufs = 8192;
46: unsigned int kd_bufsize = 0;
47: unsigned int kdebug_flags = 0;
48: unsigned int kdebug_enable=0;
49: unsigned int kdebug_nolog=1;
50: unsigned int kdlog_beg=0;
51: unsigned int kdlog_end=0;
52:
53: extern tvalspec_t get_timebase(void);
54:
55: struct kdebug_args {
56: int code;
57: int arg1;
58: int arg2;
59: int arg3;
60: int arg4;
61: int arg5;
62: };
63:
64: syscall_kdebug(p, uap, retval)
65: struct proc *p;
66: struct kdebug_args *uap;
67: register_t *retval;
68: {
69: if (kdebug_nolog)
70: return(EINVAL);
71:
72: kernel_debug(uap->code, uap->arg1, uap->arg2, uap->arg3, uap->arg4, uap->arg5);
73: return(0);
74: }
75:
76:
77: void
78: kernel_debug(debugid, arg1, arg2, arg3, arg4, arg5)
79: unsigned int debugid, arg1, arg2, arg3, arg4, arg5;
80: {
81: kd_buf * kd;
82:
83: if (kdebug_nolog ||
84: ((kdebug_flags & KDBG_RANGECHECK) &&
85: ((debugid < kdlog_beg) ||(debugid > kdlog_end))))
86: return;
87: kd = kd_bufptr;
88: kd->debugid= debugid;
89: kd->arg1 = arg1;
90: kd->arg2 = arg2;
91: kd->arg3 = arg3;
92: kd->arg4 = arg4;
93: kd->arg5 = (unsigned int)current_thread();
94: kd->timestamp = get_timebase();
95: kd_bufptr++;
96: if(kdebug_flags & KDBG_NOWRAP) {
97: if (kd_bufptr >= kd_buflast)
98: kdebug_nolog = 1 ;
99: } else {
100: if ( kd_bufptr >= kd_buflast)
101: { kd_bufptr = kd_buffer;
102: kdebug_flags |= KDBG_WRAPPED;
103: }
104: }
105: }
106:
107:
108: kdbg_bootstrap()
109: {
110: kd_bufsize = nkdbufs * sizeof(kd_buf);
111: if (kmem_alloc(kernel_map, &kd_buftomem ,(vm_size_t)kd_bufsize) == KERN_SUCCESS)
112: kd_buffer = (kd_buf *) kd_buftomem;
113: else kd_buffer= (kd_buf *) 0;
114: kdebug_flags &= ~KDBG_WRAPPED;
115: if (kd_buffer) {
116: kdebug_flags |= (KDBG_INIT | KDBG_BUFINIT);
117: kd_bufptr = kd_buffer;
118: kd_buflast = &kd_bufptr[nkdbufs];
119: kd_readlast = kd_bufptr;
120: return(0);
121: } else {
122: kd_bufsize=0;
123: kdebug_flags &= ~(KDBG_INIT | KDBG_BUFINIT);
124: return(EINVAL);
125: }
126:
127: }
128:
129: kdbg_reinit()
130: {
131: int x;
132: int ret=0;
133: x= splhigh();
134: if ((kdebug_flags & KDBG_INIT) && (kdebug_flags & KDBG_BUFINIT) && kd_bufsize && kd_buffer)
135: kmem_free(kernel_map,kd_buffer,kd_bufsize);
136: ret= kdbg_bootstrap();
137: splx(x);
138: return(ret);
139: }
140:
141: kdbg_clear()
142: {
143: int x;
144: x=splhigh();
145: kdebug_flags &= ~KDBG_BUFINIT;
146: kmem_free(kernel_map,kd_buffer,kd_bufsize);
147: kd_buffer = (kd_buf *)0;
148: kd_bufsize = 0;
149: kdebug_enable = 0;
150: kdebug_nolog = 1;
151: splx(x);
152: }
153:
154: kdbg_setreg(kd_regtype * kdr)
155: {
156: int i,j, ret=0;
157: unsigned int val_1, val_2, val;
158: switch (kdr->type) {
159:
160: case KDBG_CLASSTYPE :
161: val_1 = (kdr->value1 & 0xff);
162: val_2 = val_1 + 1;
163: kdlog_beg = (val_1<<24);
164: kdlog_end = (val_2<<24);
165: kdebug_flags &= (unsigned int)~KDBG_CKTYPES;
166: kdebug_flags |= (KDBG_RANGECHECK | KDBG_CLASSTYPE);
167: break;
168: case KDBG_SUBCLSTYPE :
169: val_1 = (kdr->value1 & 0xff);
170: val_2 = (kdr->value2 & 0xff);
171: val = val_2 + 1;
172: kdlog_beg = ((val_1<<24) | (val_2 << 16));
173: kdlog_end = ((val_1<<24) | (val << 16));
174: kdebug_flags &= (unsigned int)~KDBG_CKTYPES;
175: kdebug_flags |= (KDBG_RANGECHECK | KDBG_SUBCLSTYPE);
176: break;
177: case KDBG_RANGETYPE :
178: kdlog_beg = (kdr->value1);
179: kdlog_end = (kdr->value2);
180: kdebug_flags &= (unsigned int)~KDBG_CKTYPES;
181: kdebug_flags |= (KDBG_RANGECHECK | KDBG_RANGETYPE);
182: break;
183: case KDBG_TYPENONE :
184: kdebug_flags &= (unsigned int)~KDBG_CKTYPES;
185: kdlog_beg = 0;
186: kdlog_end = 0;
187: break;
188: default :
189: ret = EINVAL;
190: break;
191: }
192: return(ret);
193: }
194:
195: kdbg_getreg(kd_regtype * kdr)
196: {
197: int i,j, ret=0;
198: unsigned int val_1, val_2, val;
199: #if 0
200: switch (kdr->type) {
201: case KDBG_CLASSTYPE :
202: val_1 = (kdr->value1 & 0xff);
203: val_2 = val_1 + 1;
204: kdlog_beg = (val_1<<24);
205: kdlog_end = (val_2<<24);
206: kdebug_flags &= (unsigned int)~KDBG_CKTYPES;
207: kdebug_flags |= (KDBG_RANGECHECK | KDBG_CLASSTYPE);
208: break;
209: case KDBG_SUBCLSTYPE :
210: val_1 = (kdr->value1 & 0xff);
211: val_2 = (kdr->value2 & 0xff);
212: val = val_2 + 1;
213: kdlog_beg = ((val_1<<24) | (val_2 << 16));
214: kdlog_end = ((val_1<<24) | (val << 16));
215: kdebug_flags &= (unsigned int)~KDBG_CKTYPES;
216: kdebug_flags |= (KDBG_RANGECHECK | KDBG_SUBCLSTYPE);
217: break;
218: case KDBG_RANGETYPE :
219: kdlog_beg = (kdr->value1);
220: kdlog_end = (kdr->value2);
221: kdebug_flags &= (unsigned int)~KDBG_CKTYPES;
222: kdebug_flags |= (KDBG_RANGECHECK | KDBG_RANGETYPE);
223: break;
224: case KDBG_TYPENONE :
225: kdebug_flags &= (unsigned int)~KDBG_CKTYPES;
226: kdlog_beg = 0;
227: kdlog_end = 0;
228: break;
229: default :
230: ret = EINVAL;
231: break;
232: }
233: #endif /* 0 */
234: return(EINVAL);
235: }
236:
237: kdbg_control(name, namelen, where, sizep)
238: int *name;
239: u_int namelen;
240: char *where;
241: size_t *sizep;
242: {
243: int ret=0;
244: int size=*sizep;
245: unsigned int value = name[1];
246: kd_regtype kd_Reg;
247: int kd_val[3];
248:
249: switch(name[0]) {
250: case KERN_KDEFLAGS:
251: value &= KDBG_USERFLAGS;
252: kdebug_flags |= value;
253: break;
254: case KERN_KDDFLAGS:
255: value &= KDBG_USERFLAGS;
256: kdebug_flags &= ~value;
257: break;
258: case KERN_KDENABLE:
259: kdebug_enable=(value)?1:0;
260: kdebug_nolog = (value)?0:1;;
261: break;
262: case KERN_KDSETBUF:
263: if (value <= (KDBG_MAXBUFSIZE))
264: nkdbufs = value;
265: else ret= EINVAL;
266: break;
267: case KERN_KDGETBUF:
268: if(size < sizeof(kd_val)) {
269: ret=EINVAL;
270: break;
271: }
272: kd_val[0] = nkdbufs;
273: kd_val[1] = kdebug_nolog;
274: kd_val[2] = kdebug_flags;
275: if(copyout (&kd_val, where, sizeof(kd_val))) {
276: ret=EINVAL;
277: }
278: break;
279: case KERN_KDSETUP:
280: ret=kdbg_reinit();
281: break;
282: case KERN_KDREMOVE:
283: kdbg_clear();
284: break;
285: case KERN_KDSETREG:
286: if(size < sizeof(kd_regtype)) {
287: ret=EINVAL;
288: break;
289: }
290: if (copyin(where, &kd_Reg, sizeof(kd_regtype))) {
291: ret= EINVAL;
292: break;
293: }
294: ret = kdbg_setreg(&kd_Reg);
295: break;
296: case KERN_KDGETREG:
297: if(size < sizeof(kd_regtype)) {
298: ret = EINVAL;
299: break;
300: }
301: ret = kdbg_getreg(&kd_Reg);
302: if (copyout(&kd_Reg, where, sizeof(kd_regtype))){
303: ret=EINVAL;
304: }
305: break;
306: case KERN_KDREADTR:
307: ret = kdbg_read(where, sizep);
308: break;
309: default:
310: ret= EINVAL;
311: }
312: return(ret);
313: }
314:
315:
316: kdbg_read(kd_buf * buffer, size_t *number)
317: {
318: int x,i;
319: kd_buf *start;
320: int ret=0;
321: int avail=*number;
322: int count=0;
323:
324: count = avail/sizeof(kd_buf);
325: if (count) {
326: if ((kdebug_flags & KDBG_BUFINIT) && kd_bufsize && kd_buffer) {
327: if (count > nkdbufs) count = nkdbufs;
328: x= splhigh();
329: if (kdebug_flags & KDBG_WRAPPED)
330: { kd_readlast = kd_bufptr+1;
331: if (kd_readlast > kd_buflast)
332: kd_readlast = kd_buffer;
333: kdebug_flags &= ~KDBG_WRAPPED;
334: }
335: for (i = 0 ; i < count ; i++ ) {
336: if (kd_readlast == kd_bufptr) break;
337: if(copyout(kd_readlast,buffer,sizeof(kd_buf))) {
338: ret=EINVAL;
339: break;
340: }
341: kd_readlast++;
342: buffer ++;
343: if (kd_readlast >= kd_buflast)
344: kd_readlast = kd_buffer;
345: }
346: splx(x);
347: *number = i;
348: } else ret = EINVAL;
349: } else ret=EINVAL;
350:
351: return (ret);
352: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.