X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/0b4e3aa066abc0728aacb4bbeb86f53f9737156e..b36670cedae0009469e8ee117453de831de64a6b:/bsd/kern/kern_symfile.c diff --git a/bsd/kern/kern_symfile.c b/bsd/kern/kern_symfile.c index f4607b9d3..ed56bd1cd 100644 --- a/bsd/kern/kern_symfile.c +++ b/bsd/kern/kern_symfile.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -23,17 +23,22 @@ * * File: bsd/kern/kern_symfile.c * - * This file contains creates a dummy symbol file for mach_kernel based on - * the symbol table information passed by the SecondaryLoader/PlatformExpert. - * This allows us to correctly link other executables (drivers, etc) against the - * the kernel in cases where the kernel image on the root device does not match - * the live kernel. This can occur during net-booting where the actual kernel - * image is obtained from the network via tftp rather than the root - * device. + * This file contains creates a dummy symbol file for mach_kernel + * based on the symbol table information passed by the + * SecondaryLoader/PlatformExpert. This allows us to correctly + * link other executables (drivers, etc) against the the kernel in + * cases where the kernel image on the root device does not match + * the live kernel. This can occur during net-booting where the + * actual kernel image is obtained from the network via tftp rather + * than the root device. * - * If a symbol table is available, then the file /mach.sym will be created - * containing a Mach Header and a LC_SYMTAB load command followed by the - * the symbol table data for mach_kernel. + * If a symbol table is available, then the file /mach.sym will be + * created containing a Mach Header and a LC_SYMTAB load command + * followed by the the symbol table data for mach_kernel. + * + * NOTE: This file supports only 32 bit kernels at the present time; + * adding support for 64 bit kernels is possible, but is not + * necessary at the present time. * * HISTORY * @@ -47,21 +52,25 @@ #include #include #include -#include -#include +#include +#include +#include #include #include -#include #include -#include +#include #include #include #include +#include +#include #include #include +#include #include +#include extern unsigned char rootdevice[]; extern struct mach_header _mh_execute_header; @@ -73,15 +82,15 @@ extern int IODTGetLoaderInfo(char *key, void **infoAddr, int *infoSize); extern void IODTFreeLoaderInfo(char *key, void *infoAddr, int infoSize); /* - * + * Can only operate against currently running 32 bit mach_kernel */ -static int output_kernel_symbols(struct proc *p) +static int +output_kernel_symbols(struct proc *p) { struct vnode *vp; - struct pcred *pcred = p->p_cred; - struct ucred *cred = pcred->pc_ucred; - struct nameidata nd; - struct vattr vattr; + kauth_cred_t cred = p->p_ucred; /* XXX */ + struct vnode_attr va; + struct vfs_context context; struct load_command *cmd; struct mach_header *orig_mh, *mh; struct segment_command *orig_ds, *orig_ts, *orig_le, *sg; @@ -90,9 +99,9 @@ static int output_kernel_symbols(struct proc *p) struct nlist *sym; vm_size_t orig_mhsize, orig_st_size; vm_offset_t header; - vm_size_t header_size; + vm_size_t header_size = 0; /* out: protected by header */ int error, error1; - int i, j; + unsigned int i, j; caddr_t addr; vm_offset_t offset; int rc_mh, rc_sc; @@ -107,38 +116,39 @@ static int output_kernel_symbols(struct proc *p) // Dispose of unnecessary gumf, the booter doesn't need to load these rc_mh = IODTGetLoaderInfo("Kernel-__HEADER", (void **)&orig_mh, &orig_mhsize); - if (rc_mh && orig_mh) + if (rc_mh == 0 && orig_mh) IODTFreeLoaderInfo("Kernel-__HEADER", - (void *)orig_mh, round_page(orig_mhsize)); + (void *)orig_mh, round_page_32(orig_mhsize)); rc_sc = IODTGetLoaderInfo("Kernel-__SYMTAB", (void **) &orig_st, &orig_st_size); - if (rc_sc && orig_st) + if (rc_sc == 0 && orig_st) IODTFreeLoaderInfo("Kernel-__SYMTAB", - (void *)orig_st, round_page(orig_st_size)); + (void *)orig_st, round_page_32(orig_st_size)); - if (pcred->p_svuid != pcred->p_ruid || pcred->p_svgid != pcred->p_rgid) + if (cred->cr_svuid != cred->cr_ruid || cred->cr_svgid != cred->cr_rgid) goto out; // Check to see if the root is 'e' or 'n', is this a test for network? if (rootdevice[0] == 'e' && rootdevice[1] == 'n') goto out; - NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, "mach.sym", p); - if((error = vn_open(&nd, O_CREAT | FWRITE, S_IRUSR | S_IRGRP | S_IROTH))) goto out; + context.vc_proc = p; + context.vc_ucred = cred; + + if ((error = vnode_open("mach.sym", (O_CREAT | FWRITE), (S_IRUSR | S_IRGRP | S_IROTH), 0, &vp, &context))) + goto out; - vp = nd.ni_vp; - /* Don't dump to non-regular files or files with links. */ error = EFAULT; - if (vp->v_type != VREG || VOP_GETATTR(vp, &vattr, cred, p) - || vattr.va_nlink != 1) + VATTR_INIT(&va); + VATTR_WANTED(&va, va_nlink); + if ((vp->v_type != VREG) || vnode_getattr(vp, &va, &context) || (va.va_nlink != 1)) goto out; - VATTR_NULL(&vattr); - vattr.va_size = 0; - VOP_LEASE(vp, p, cred, LEASE_WRITE); - VOP_SETATTR(vp, &vattr, cred, p); + VATTR_INIT(&va); /* better to do it here than waste more stack in vnode_getsize */ + VATTR_SET(&va, va_data_size, 0); + vnode_setattr(vp, &va, &context); p->p_acflag |= ACORE; // If the file type is MH_EXECUTE then this must be a kernel @@ -149,14 +159,14 @@ static int output_kernel_symbols(struct proc *p) cmd = (struct load_command *) &orig_mh[1]; for (i = 0; i < orig_mh->ncmds; i++) { if (cmd->cmd == LC_SEGMENT) { - struct segment_command *sg = (struct segment_command *) cmd; + struct segment_command *orig_sg = (struct segment_command *) cmd; - if (!strcmp(SEG_TEXT, sg->segname)) - orig_ts = sg; - else if (!strcmp(SEG_DATA, sg->segname)) - orig_ds = sg; - else if (!strcmp(SEG_LINKEDIT, sg->segname)) - orig_le = sg; + if (!strcmp(SEG_TEXT, orig_sg->segname)) + orig_ts = orig_sg; + else if (!strcmp(SEG_DATA, orig_sg->segname)) + orig_ds = orig_sg; + else if (!strcmp(SEG_LINKEDIT, orig_sg->segname)) + orig_le = orig_sg; } else if (cmd->cmd == LC_SYMTAB) orig_st = (struct symtab_command *) cmd; @@ -183,7 +193,7 @@ static int output_kernel_symbols(struct proc *p) + orig_ds->cmdsize + sizeof(struct symtab_command); - (void) kmem_alloc_wired(kernel_map, + (void) kmem_alloc(kernel_map, (vm_offset_t *) &header, (vm_size_t) header_size); if (header) @@ -234,7 +244,7 @@ static int output_kernel_symbols(struct proc *p) const_text = se; } } - offset = round_page((vm_address_t) offset); + offset = round_page(offset); // Now copy of the __DATA segment load command, the image need // not be stored to disk nobody needs it, yet! @@ -285,7 +295,7 @@ static int output_kernel_symbols(struct proc *p) * Write out the load commands at the beginning of the file. */ error = vn_rdwr(UIO_WRITE, vp, (caddr_t) mh, header_size, (off_t) 0, - UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred, (int *) 0, p); + UIO_SYSSPACE32, IO_NODELOCKED|IO_UNIT, cred, (int *) 0, p); if (error) goto out; @@ -294,7 +304,7 @@ static int output_kernel_symbols(struct proc *p) */ error = vn_rdwr(UIO_WRITE, vp, (caddr_t) const_text->addr, const_text->size, const_text->offset, - UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred, (int *) 0, p); + UIO_SYSSPACE32, IO_NODELOCKED|IO_UNIT, cred, (int *) 0, p); if (error) goto out; @@ -304,17 +314,13 @@ static int output_kernel_symbols(struct proc *p) offset = st->nsyms * sizeof(struct nlist) + st->strsize; // symtab size error = vn_rdwr(UIO_WRITE, vp, (caddr_t) orig_le->vmaddr, offset, st->symoff, - UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred, (int *) 0, p); - if (error) - goto out; - + UIO_SYSSPACE32, IO_NODELOCKED|IO_UNIT, cred, (int *) 0, p); out: if (header) kmem_free(kernel_map, header, header_size); if (vp) { - VOP_UNLOCK(vp, 0, p); - error1 = vn_close(vp, FWRITE, cred, p); + error1 = vnode_close(vp, FWRITE, &context); if (!error) error = error1; } @@ -334,3 +340,4 @@ int get_kernel_symfile(struct proc *p, char **symfile) return error_code; } +