Annotation of kernel/bsd/kern/kern_symfile.c, revision 1.1.1.1

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: /* Copyright (c) 1998 Apple Computer, Inc.  All rights reserved.
                     26:  *
                     27:  *     File:   bsd/kern/kern_symfile.c
                     28:  *
                     29:  *     This file contains creates a dummy symbol file for mach_kernel based on
                     30:  *      the symbol table information passed by the SecondaryLoader/PlatformExpert.
                     31:  *      This allows us to correctly link other executables (drivers, etc) against the 
                     32:  *      the kernel in cases where the kernel image on the root device does not match
                     33:  *      the live kernel. This can occur during net-booting where the actual kernel
                     34:  *      image is obtained from the network via tftp rather than the root
                     35:  *      device.
                     36:  *
                     37:  *      If a symbol table is available, then the file /mach.sym will be created
                     38:  *      containing a Mach Header and a LC_SYMTAB load command followed by the
                     39:  *      the symbol table data for mach_kernel.
                     40:  *
                     41:  * HISTORY
                     42:  * 
                     43:  *     .
                     44:  */
                     45: #import <cputypes.h>
                     46: #import <mach_host.h>
                     47: 
                     48: #import <mach/vm_param.h>
                     49: 
                     50: #import <machine/cpu.h>
                     51: 
                     52: #include <sys/param.h>
                     53: #include <sys/systm.h>
                     54: #include <sys/signalvar.h>
                     55: #include <sys/resourcevar.h>
                     56: #include <sys/namei.h>
                     57: #include <sys/vnode.h>
                     58: #include <sys/proc.h>
                     59: #include <sys/timeb.h>
                     60: #include <sys/times.h>
                     61: #include <sys/buf.h>
                     62: #include <sys/acct.h>
                     63: #include <sys/file.h>
                     64: #include <sys/uio.h>
                     65: #include <sys/kernel.h>
                     66: #include <sys/stat.h>
                     67: 
                     68: #import <mach-o/loader.h>
                     69: #import <mach-o/nlist.h>
                     70: #import <vm/vm_kern.h>
                     71: 
                     72: void                   *symbol_table_addr;                     // Initialized by PlatformExpert.
                     73: extern unsigned char   rootdevice[];
                     74: 
                     75: /*
                     76:  * 
                     77:  */
                     78: int output_kernel_symbols( register struct proc *p )
                     79: {
                     80:        register struct vnode           *vp;
                     81:        register struct pcred           *pcred = p->p_cred;
                     82:        register struct ucred           *cred = pcred->pc_ucred;
                     83:        struct nameidata                nd;
                     84:        struct vattr                    vattr;
                     85:        int                             command_size, header_size;
                     86:        int                             hoffset, foffset;
                     87:        vm_offset_t                     header;
                     88:        struct machine_slot             *ms;
                     89:        struct mach_header              *mh;
                     90:        struct symtab_command           *sc, *sc0;
                     91:         struct nlist                    *nl;
                     92:        vm_size_t                       size;
                     93:        int                             error, error1;
                     94:         int                            i;
                     95: 
                     96:         if ( symbol_table_addr == NULL )
                     97:                 return (EFAULT);
                     98: 
                     99:        if ( pcred->p_svuid != pcred->p_ruid || pcred->p_svgid != pcred->p_rgid )
                    100:                return (EFAULT);
                    101: 
                    102:         if ( rootdevice[0] == 'e' || rootdevice[1] == 'n' )
                    103:                 return (EROFS);
                    104: 
                    105:        NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, "mach.sym", p);
                    106:        if( (error = vn_open(&nd, O_CREAT | FWRITE, S_IRUSR | S_IRGRP | S_IROTH )) != 0 )
                    107:                return (error);
                    108:        vp = nd.ni_vp;
                    109:        
                    110:        /* Don't dump to non-regular files or files with links. */
                    111:        if (vp->v_type != VREG ||
                    112:            VOP_GETATTR(vp, &vattr, cred, p) || vattr.va_nlink != 1) {
                    113:                error = EFAULT;
                    114:                goto out;
                    115:        }
                    116: 
                    117:        VATTR_NULL(&vattr);
                    118:        vattr.va_size = 0;
                    119:        VOP_LEASE(vp, p, cred, LEASE_WRITE);
                    120:        VOP_SETATTR(vp, &vattr, cred, p);
                    121:        p->p_acflag |= ACORE;
                    122: 
                    123:        command_size = sizeof(struct symtab_command);
                    124:        header_size = command_size + sizeof(struct mach_header);
                    125: 
                    126:        (void) kmem_alloc_wired(kernel_map,
                    127:                                    (vm_offset_t *)&header,
                    128:                                    (vm_size_t)header_size);
                    129: 
                    130:        /*
                    131:         *      Set up Mach-O header.
                    132:         */
                    133:        mh = (struct mach_header *) header;
                    134:        ms = &machine_slot[cpu_number()];
                    135:        mh->magic = MH_MAGIC;
                    136:        mh->cputype = ms->cpu_type;
                    137:        mh->cpusubtype = ms->cpu_subtype;
                    138:        mh->filetype = MH_CORE;
                    139:        mh->ncmds = 1;
                    140:        mh->sizeofcmds = command_size;
                    141: 
                    142:        hoffset = sizeof(struct mach_header);   /* offset into header */
                    143:        foffset = round_page(header_size);      /* offset into file */
                    144: 
                    145:        /*
                    146:         *      Fill in segment command structure.
                    147:         */
                    148:         sc0         = (struct symtab_command *)  symbol_table_addr;
                    149:        sc          = (struct symtab_command *) (header + hoffset);
                    150:        sc->cmd     = LC_SYMTAB;
                    151:        sc->cmdsize = sizeof(struct symtab_command);
                    152:         sc->symoff  = foffset;
                    153:         sc->nsyms   = sc0->nsyms;
                    154:         sc->strsize = sc0->strsize;
                    155:         sc->stroff =  foffset + sc->nsyms * sizeof(struct nlist);    
                    156: 
                    157:         size = sc->nsyms * sizeof(struct nlist) + sc->strsize;
                    158: 
                    159:         nl = (struct nlist *)(sc0+1);
                    160:         for (i = 0; i < sc->nsyms; i++, nl++ )
                    161:         {
                    162:             if ( (nl->n_type & N_TYPE) == N_SECT )
                    163:             {
                    164:                 nl->n_sect = NO_SECT;
                    165:                 nl->n_type = (nl->n_type & ~N_TYPE) | N_ABS;
                    166:             }
                    167:         }
                    168: 
                    169:        /*
                    170:         *      Write out the Mach header at the beginning of the
                    171:         *      file.
                    172:         */
                    173:        error = vn_rdwr(UIO_WRITE, vp, (caddr_t)header, header_size, (off_t)0,
                    174:                        UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred, (int *) 0, p);
                    175: 
                    176:         /*
                    177:          *     Write out kernel symbols
                    178:          */
                    179:         if ( !error )
                    180:         {
                    181:            error = vn_rdwr(UIO_WRITE, vp, (caddr_t)(sc0+1), size, foffset,
                    182:                            UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred, (int *) 0, p);
                    183: 
                    184:         }
                    185: 
                    186:        kmem_free(kernel_map, header, header_size);
                    187: out:
                    188:        VOP_UNLOCK(vp, 0, p);
                    189:        error1 = vn_close(vp, FWRITE, cred, p);
                    190:        if (error == 0)
                    191:                error = error1;
                    192:        return(error);
                    193: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.