Annotation of XNU/bsd/kern/kern_symfile.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             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.
        !            11:  * 
        !            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
        !            18:  * under the License.
        !            19:  * 
        !            20:  * @APPLE_LICENSE_HEADER_END@
        !            21:  */
        !            22: /* Copyright (c) 1998 Apple Computer, Inc.  All rights reserved.
        !            23:  *
        !            24:  *     File:   bsd/kern/kern_symfile.c
        !            25:  *
        !            26:  *     This file contains creates a dummy symbol file for mach_kernel based on
        !            27:  *      the symbol table information passed by the SecondaryLoader/PlatformExpert.
        !            28:  *      This allows us to correctly link other executables (drivers, etc) against the 
        !            29:  *      the kernel in cases where the kernel image on the root device does not match
        !            30:  *      the live kernel. This can occur during net-booting where the actual kernel
        !            31:  *      image is obtained from the network via tftp rather than the root
        !            32:  *      device.
        !            33:  *
        !            34:  *      If a symbol table is available, then the file /mach.sym will be created
        !            35:  *      containing a Mach Header and a LC_SYMTAB load command followed by the
        !            36:  *      the symbol table data for mach_kernel.
        !            37:  *
        !            38:  * HISTORY
        !            39:  * 
        !            40:  *     .
        !            41:  */
        !            42: 
        !            43: #import <mach/vm_param.h>
        !            44: 
        !            45: #include <sys/param.h>
        !            46: #include <sys/systm.h>
        !            47: #include <sys/signalvar.h>
        !            48: #include <sys/resourcevar.h>
        !            49: #include <sys/namei.h>
        !            50: #include <sys/vnode.h>
        !            51: #include <sys/proc.h>
        !            52: #include <sys/timeb.h>
        !            53: #include <sys/times.h>
        !            54: #include <sys/buf.h>
        !            55: #include <sys/acct.h>
        !            56: #include <sys/file.h>
        !            57: #include <sys/uio.h>
        !            58: #include <sys/kernel.h>
        !            59: #include <sys/stat.h>
        !            60: 
        !            61: #include <mach-o/loader.h>
        !            62: #include <mach-o/nlist.h>
        !            63: 
        !            64: #include <vm/vm_kern.h>
        !            65: 
        !            66: extern unsigned char   rootdevice[];
        !            67: extern vm_size_t       page_size;
        !            68: 
        !            69: 
        !            70: int kernel_symfile_opened = 0;
        !            71: int error_code = 0;
        !            72: 
        !            73: extern int  IODTGetLoaderInfo(  char *key, void **infoAddr, int *infoSize );
        !            74: extern void IODTFreeLoaderInfo( char *key, void *infoAddr, int infoSize );
        !            75: 
        !            76: /*
        !            77:  * 
        !            78:  */
        !            79: int get_kernel_symfile( struct proc *p, char **symfile )
        !            80: {
        !            81:     if ( kernel_symfile_opened == 0 )
        !            82:     {
        !            83:         kernel_symfile_opened = 1;
        !            84:         error_code = output_kernel_symbols( p );
        !            85:     }
        !            86:     if ( error_code == 0 ) *symfile = "\\mach.sym";
        !            87: 
        !            88:     return error_code;
        !            89: }
        !            90: 
        !            91: /*
        !            92:  * 
        !            93:  */
        !            94: int output_kernel_symbols( register struct proc *p )
        !            95: {
        !            96:        register struct vnode           *vp;
        !            97:        register struct pcred           *pcred = p->p_cred;
        !            98:        register struct ucred           *cred = pcred->pc_ucred;
        !            99:        struct nameidata                nd;
        !           100:        struct vattr                    vattr;
        !           101:        struct mach_header              *orig_mh, *mh;
        !           102:         struct load_command            *lc;
        !           103:         struct segment_command         *sg;
        !           104:         struct section                 *se;
        !           105:        struct symtab_command           *sc, *sc0;
        !           106:         struct nlist                    *nl;
        !           107:        vm_size_t                       orig_mhsize, sc0_size;
        !           108:         vm_offset_t                    header;
        !           109:         vm_size_t                      header_size;
        !           110:        int                             error, error1;
        !           111:         int                            i, j;
        !           112:         int                            symfoffset, symsize;
        !           113:         int                             rc_mh, rc_sc;
        !           114: 
        !           115:         error = EFAULT;
        !           116: 
        !           117:         vp       = NULL;
        !           118:         header   = NULL;
        !           119:         orig_mh  = NULL;
        !           120:         sc0      = NULL;
        !           121:         
        !           122:         rc_mh = IODTGetLoaderInfo( "Kernel-__HEADER", (void **)&orig_mh, &orig_mhsize );
        !           123:         rc_sc = IODTGetLoaderInfo( "Kernel-__SYMTAB", (void **)&sc0, &sc0_size );
        !           124:         
        !           125:         if ( rc_mh != 0 || orig_mh == 0 || orig_mhsize < sizeof(struct mach_header) )    goto out;
        !           126:         if ( rc_sc != 0 || sc0 == 0     || sc0_size    < sizeof(struct symtab_command) ) goto out;
        !           127: 
        !           128:        if ( pcred->p_svuid != pcred->p_ruid || pcred->p_svgid != pcred->p_rgid ) goto out;
        !           129: 
        !           130:         if ( rootdevice[0] == 'e' && rootdevice[1] == 'n' ) goto out;
        !           131: 
        !           132:        NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, "mach.sym", p);
        !           133:        if( (error = vn_open(&nd, O_CREAT | FWRITE, S_IRUSR | S_IRGRP | S_IROTH )) != 0 ) goto out;
        !           134: 
        !           135:        vp = nd.ni_vp;
        !           136:        
        !           137:        /* Don't dump to non-regular files or files with links. */
        !           138:         error = EFAULT;
        !           139:        if (vp->v_type != VREG || VOP_GETATTR(vp, &vattr, cred, p) || vattr.va_nlink != 1) goto out;
        !           140: 
        !           141:        VATTR_NULL(&vattr);
        !           142:        vattr.va_size = 0;
        !           143:        VOP_LEASE(vp, p, cred, LEASE_WRITE);
        !           144:        VOP_SETATTR(vp, &vattr, cred, p);
        !           145:        p->p_acflag |= ACORE;
        !           146: 
        !           147:        header_size =   sizeof(struct mach_header) 
        !           148:                       + sizeof(struct segment_command)
        !           149:                       + sizeof(struct section)
        !           150:                       + sizeof(struct symtab_command);
        !           151: 
        !           152:        (void) kmem_alloc_wired( kernel_map,
        !           153:                                (vm_offset_t *)&header,
        !           154:                                (vm_size_t)header_size);
        !           155: 
        !           156:         if ( header == NULL ) goto out;
        !           157: 
        !           158:         bzero( (void *)header, header_size );
        !           159: 
        !           160:        /*
        !           161:         *      Set up Mach-O header.
        !           162:         */
        !           163:        mh = (struct mach_header *) header;
        !           164:        mh->magic = orig_mh->magic;
        !           165:        mh->cputype = orig_mh->cputype;
        !           166:        mh->cpusubtype = orig_mh->cpusubtype;
        !           167:        mh->filetype = orig_mh->filetype;
        !           168:        mh->ncmds = 2;
        !           169:        mh->sizeofcmds = header_size - sizeof(struct mach_header);
        !           170: 
        !           171:        /*
        !           172:         *      Setup a dummy LC_SEGMENT command to force page alignment of  sections.
        !           173:         */
        !           174:         sg = (struct segment_command *)(mh+1);
        !           175:         sg->cmd      = LC_SEGMENT;
        !           176:         sg->cmdsize  = sizeof(struct segment_command) + sizeof(struct section);
        !           177:         strcpy( sg->segname, SEG_DATA );
        !           178:         sg->vmaddr   = 0;
        !           179:         sg->vmsize   = 0x1000;
        !           180:         sg->fileoff  = 0;
        !           181:         sg->filesize = 0;
        !           182:         sg->maxprot  = 0;
        !           183:         sg->initprot = 0;
        !           184:         sg->nsects   = 1;
        !           185:         sg->flags    = 0;
        !           186: 
        !           187:        /*
        !           188:         *      Set up alignment section.
        !           189:         */
        !           190:         for ( j=page_size-1, i=0; j; i++, j >>= 1 )
        !           191:           ;
        !           192: 
        !           193:         se = (struct section *)(sg+1);
        !           194:         strcpy( se->sectname, SECT_BSS );
        !           195:         strcpy( se->segname, sg->segname );
        !           196:         se->addr  = 0;
        !           197:         se->size  = 0;
        !           198:         se->align = i;
        !           199:         se->flags = S_ZEROFILL;
        !           200: 
        !           201:         symfoffset = round_page(header_size);
        !           202: 
        !           203:        /*
        !           204:         *      Set up LC_SYMTAB command
        !           205:         */
        !           206:        sc          = (struct symtab_command *)(se+1);
        !           207:        sc->cmd     = LC_SYMTAB;
        !           208:        sc->cmdsize = sizeof(struct symtab_command);
        !           209:         sc->symoff  = symfoffset;
        !           210:         sc->nsyms   = sc0->nsyms;
        !           211:         sc->strsize = sc0->strsize;
        !           212:         sc->stroff =  symfoffset + sc->nsyms * sizeof(struct nlist);    
        !           213: 
        !           214:         symsize = sc->nsyms * sizeof(struct nlist) + sc->strsize;
        !           215: 
        !           216:         nl = (struct nlist *)(sc0+1);
        !           217:         for (i = 0; i < sc->nsyms; i++, nl++ )
        !           218:         {
        !           219:             if ( (nl->n_type & N_TYPE) == N_SECT )
        !           220:             {
        !           221:                 nl->n_sect = NO_SECT;
        !           222:                 nl->n_type = (nl->n_type & ~N_TYPE) | N_ABS;
        !           223:             }
        !           224:         }
        !           225: 
        !           226:        /*
        !           227:         *      Write out the load commands at the beginning of the
        !           228:         *      file.
        !           229:         */
        !           230:        error = vn_rdwr(UIO_WRITE, vp, (caddr_t)mh, header_size, (off_t)0,
        !           231:                        UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred, (int *) 0, p);
        !           232:         if ( error != 0 ) goto out;
        !           233:         
        !           234:         /*
        !           235:          *     Write out kernel symbols
        !           236:          */
        !           237:        error = vn_rdwr(UIO_WRITE, vp, (caddr_t)(sc0+1), symsize, symfoffset,
        !           238:                        UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred, (int *) 0, p);
        !           239:         if ( error != 0 ) goto out;
        !           240: 
        !           241: out:
        !           242:         if ( header != 0 ) kmem_free(kernel_map, header, header_size);
        !           243:         if ( orig_mh != 0 ) IODTFreeLoaderInfo( "Kernel-__HEADER", (void *)orig_mh, round_page(orig_mhsize) );
        !           244:         if ( sc0     != 0 ) IODTFreeLoaderInfo( "Kernel-__SYMTAB", (void *)sc0,     round_page(sc0_size) );        
        !           245:   
        !           246:         if ( vp != 0 )
        !           247:         {
        !           248:            VOP_UNLOCK(vp, 0, p);
        !           249:            error1 = vn_close(vp, FWRITE, cred, p);
        !           250:            if (error == 0) error = error1;
        !           251:         }
        !           252: 
        !           253:        return(error);
        !           254: }

unix.superglobalmegacorp.com

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