]>
git.saurik.com Git - apple/xnu.git/blob - bsd/kern/kern_panicinfo.c
db92fb59a747e2c43a2d6efc0d68b3de1598ecb4
2 * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
26 #include <sys/param.h>
27 #include <sys/fcntl.h>
28 #include <sys/malloc.h>
29 #include <sys/namei.h>
32 #include <sys/sysctl.h>
33 #include <sys/vnode.h>
36 #include <mach/kern_return.h>
38 /* prototypes not exported by osfmk. */
39 extern void kmem_free(vm_map_t
, vm_offset_t
, vm_size_t
);
40 extern kern_return_t
kmem_alloc_wired(vm_map_t
, vm_offset_t
*, vm_size_t
);
44 static off_t imagesizelimit
= (4 * 4096);
46 /* Information about the current panic image */
47 static int image_bits
= 32; /* Bitdepth */
49 static char *image_pathname
= NULL
; /* path to it */
50 static size_t image_pathlen
= 0; /* and the length of the pathname */
52 static vm_offset_t image_ptr
= NULL
; /* the image itself */
53 static off_t image_size
= 0; /* and the imagesize */
56 __private_extern__
void
57 get_panicimage(vm_offset_t
*imageptr
, vm_size_t
*imagesize
, int *imagebits
)
59 *imageptr
= image_ptr
;
60 *imagesize
= image_size
;
61 *imagebits
= image_bits
;
79 struct pcred
*pcred
= p
->p_cred
;
80 struct ucred
*cred
= pcred
->pc_ucred
;
84 NDINIT(&nd
, LOOKUP
, FOLLOW
, UIO_SYSSPACE
, imname
, p
);
85 error
= vn_open(&nd
, FREAD
, S_IRUSR
);
90 if (vp
->v_type
!= VREG
) {
95 /* get the file size */
96 error
= VOP_GETATTR(vp
, &vattr
, cred
, p
);
100 /* validate the file size */
101 if (vattr
.va_size
> sizelimit
) {
106 /* allocate kernel wired memory */
107 kret
= kmem_alloc_wired(kernel_map
, &iobuf
,
108 (vm_size_t
)vattr
.va_size
);
109 if (kret
!= KERN_SUCCESS
) {
115 case KERN_RESOURCE_SHORTAGE
:
118 case KERN_PROTECTION_FAILURE
:
125 /* read the file in the kernel buffer */
126 error
= vn_rdwr(UIO_READ
, vp
, (caddr_t
)iobuf
, (int)vattr
.va_size
,
127 (off_t
)0, UIO_SYSSPACE
, IO_NODELOCKED
|IO_UNIT
,
130 (void)kmem_free(kernel_map
, iobuf
, (vm_size_t
)vattr
.va_size
);
135 * return the image to the caller
136 * freeing this memory is callers responsibility
139 *filesize
= (off_t
)vattr
.va_size
;
142 VOP_UNLOCK(vp
, 0, p
);
143 error1
= vn_close(vp
, FREAD
, cred
, p
);
149 __private_extern__
int
150 sysctl_dopanicinfo(name
, namelen
, oldp
, oldlenp
, newp
, newlen
, p
)
160 int bitdepth
= 32; /* default is 32 bits */
163 /* all sysctl names at this level are terminal */
165 return (ENOTDIR
); /* overloaded */
170 case KERN_PANICINFO_MAXSIZE
:
171 if (newp
!= NULL
&& (error
= suser(p
->p_ucred
, &p
->p_acflag
)))
173 error
= sysctl_quad(oldp
, oldlenp
, newp
, newlen
, &imagesizelimit
);
176 case KERN_PANICINFO_IMAGE16
:
178 /* and fall through */
179 case KERN_PANICINFO_IMAGE32
:
180 /* allocate a buffer for the image pathname */
181 MALLOC_ZONE(imname
, char *, MAXPATHLEN
, M_NAMEI
, M_WAITOK
);
184 bcopy(image_pathname
, imname
, image_pathlen
);
185 imname
[image_pathlen
] = '\0';
188 error
= sysctl_string(oldp
, oldlenp
, newp
, newlen
,
190 if (newp
&& !error
) {
191 char *tmpstr
, *oldstr
;
198 len
= strlen(imname
);
199 oldstr
= image_pathname
;
201 error
= panicimage_from_file(imname
, imagesizelimit
,
202 &image
, &filesize
, p
);
206 /* release the old image */
212 /* remember the new one */
214 image_bits
= bitdepth
; /* new bith depth */
215 image_size
= filesize
; /* new imagesize */
218 kmem_free(kernel_map
, oimage
, osize
);
220 /* save the new name */
221 MALLOC(tmpstr
, char *, len
+1, M_TEMP
, M_WAITOK
);
222 bcopy(imname
, tmpstr
, len
);
225 image_pathname
= tmpstr
; /* new pathname */
226 image_pathlen
= len
; /* new pathname length */
228 /* free the old name */
229 FREE(oldstr
, M_TEMP
);
232 FREE_ZONE(imname
, MAXPATHLEN
, M_NAMEI
);