]>
git.saurik.com Git - apple/xnu.git/blob - bsd/kern/kern_panicinfo.c
2 * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
23 #include <sys/param.h>
24 #include <sys/fcntl.h>
25 #include <sys/malloc.h>
26 #include <sys/namei.h>
29 #include <sys/sysctl.h>
30 #include <sys/vnode.h>
33 #include <mach/kern_return.h>
35 /* prototypes not exported by osfmk. */
36 extern void kmem_free(vm_map_t
, vm_offset_t
, vm_size_t
);
37 extern kern_return_t
kmem_alloc_wired(vm_map_t
, vm_offset_t
*, vm_size_t
);
41 static off_t imagesizelimit
= (4 * 4096);
43 /* Information about the current panic image */
44 static int image_bits
= 32; /* Bitdepth */
46 static char *image_pathname
= NULL
; /* path to it */
47 static size_t image_pathlen
= 0; /* and the length of the pathname */
49 static vm_offset_t image_ptr
= NULL
; /* the image itself */
50 static off_t image_size
= 0; /* and the imagesize */
53 __private_extern__
void
54 get_panicimage(vm_offset_t
*imageptr
, vm_size_t
*imagesize
, int *imagebits
)
56 *imageptr
= image_ptr
;
57 *imagesize
= image_size
;
58 *imagebits
= image_bits
;
76 struct pcred
*pcred
= p
->p_cred
;
77 struct ucred
*cred
= pcred
->pc_ucred
;
81 NDINIT(&nd
, LOOKUP
, FOLLOW
, UIO_SYSSPACE
, imname
, p
);
82 error
= vn_open(&nd
, FREAD
, S_IRUSR
);
87 if (vp
->v_type
!= VREG
) {
92 /* get the file size */
93 error
= VOP_GETATTR(vp
, &vattr
, cred
, p
);
97 /* validate the file size */
98 if (vattr
.va_size
> sizelimit
) {
103 /* allocate kernel wired memory */
104 kret
= kmem_alloc_wired(kernel_map
, &iobuf
,
105 (vm_size_t
)vattr
.va_size
);
106 if (kret
!= KERN_SUCCESS
) {
112 case KERN_RESOURCE_SHORTAGE
:
115 case KERN_PROTECTION_FAILURE
:
122 /* read the file in the kernel buffer */
123 error
= vn_rdwr(UIO_READ
, vp
, (caddr_t
)iobuf
, (int)vattr
.va_size
,
124 (off_t
)0, UIO_SYSSPACE
, IO_NODELOCKED
|IO_UNIT
,
127 (void)kmem_free(kernel_map
, iobuf
, (vm_size_t
)vattr
.va_size
);
132 * return the image to the caller
133 * freeing this memory is callers responsibility
136 *filesize
= (off_t
)vattr
.va_size
;
139 VOP_UNLOCK(vp
, 0, p
);
140 error1
= vn_close(vp
, FREAD
, cred
, p
);
146 __private_extern__
int
147 sysctl_dopanicinfo(name
, namelen
, oldp
, oldlenp
, newp
, newlen
, p
)
157 int bitdepth
= 32; /* default is 32 bits */
160 /* all sysctl names at this level are terminal */
162 return (ENOTDIR
); /* overloaded */
167 case KERN_PANICINFO_MAXSIZE
:
168 if (newp
!= NULL
&& (error
= suser(p
->p_ucred
, &p
->p_acflag
)))
170 error
= sysctl_quad(oldp
, oldlenp
, newp
, newlen
, &imagesizelimit
);
173 case KERN_PANICINFO_IMAGE16
:
175 /* and fall through */
176 case KERN_PANICINFO_IMAGE32
:
177 /* allocate a buffer for the image pathname */
178 MALLOC_ZONE(imname
, char *, MAXPATHLEN
, M_NAMEI
, M_WAITOK
);
181 bcopy(image_pathname
, imname
, image_pathlen
);
182 imname
[image_pathlen
] = '\0';
185 error
= sysctl_string(oldp
, oldlenp
, newp
, newlen
,
187 if (newp
&& !error
) {
188 char *tmpstr
, *oldstr
;
195 len
= strlen(imname
);
196 oldstr
= image_pathname
;
198 error
= panicimage_from_file(imname
, imagesizelimit
,
199 &image
, &filesize
, p
);
203 /* release the old image */
209 /* remember the new one */
211 image_bits
= bitdepth
; /* new bith depth */
212 image_size
= filesize
; /* new imagesize */
215 kmem_free(kernel_map
, oimage
, osize
);
217 /* save the new name */
218 MALLOC(tmpstr
, char *, len
+1, M_TEMP
, M_WAITOK
);
219 bcopy(imname
, tmpstr
, len
);
222 image_pathname
= tmpstr
; /* new pathname */
223 image_pathlen
= len
; /* new pathname length */
225 /* free the old name */
226 FREE(oldstr
, M_TEMP
);
229 FREE_ZONE(imname
, MAXPATHLEN
, M_NAMEI
);