X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/d7e50217d7adf6e52786a38bcaa4cd698cb9a79e..378393581903b274cb7a4d18e0d978071a6b592d:/bsd/kern/mach_header.c diff --git a/bsd/kern/mach_header.c b/bsd/kern/mach_header.c index 2510daa92..9071eaa48 100644 --- a/bsd/kern/mach_header.c +++ b/bsd/kern/mach_header.c @@ -1,24 +1,21 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * - * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. * * @APPLE_LICENSE_HEADER_END@ */ @@ -27,6 +24,14 @@ * * Functions for accessing mach-o headers. * + * NOTE: This file supports only 32 bit mach headers at the present + * time; it's primary use is by kld, and all externally + * referenced routines at the present time operate against + * the 32 bit mach header _mh_execute_header, which is the + * header for the currently executing kernel. Adding support + * for 64 bit kernels is possible, but is not necessary at the + * present time. + * * HISTORY * 27-MAR-97 Umesh Vaishampayan (umeshv@NeXT.com) * Added getsegdatafromheader(); @@ -38,26 +43,22 @@ #if !defined(KERNEL_PRELOAD) #include +#include // from libsa extern struct mach_header _mh_execute_header; -struct section *getsectbynamefromheader( - struct mach_header *header, - char *seg_name, - char *sect_name); -struct segment_command *getsegbynamefromheader( - struct mach_header *header, - char *seg_name); - /* * return the last address (first avail) + * + * This routine operates against the currently executing kernel only */ -vm_offset_t getlastaddr(void) +vm_offset_t +getlastaddr(void) { struct segment_command *sgp; vm_offset_t last_addr = 0; struct mach_header *header = &_mh_execute_header; - int i; + unsigned long i; sgp = (struct segment_command *) ((char *)header + sizeof(struct mach_header)); @@ -72,10 +73,12 @@ vm_offset_t getlastaddr(void) } #if FIXME /* [ */ +/* + * This routine operates against the currently executing kernel only + */ struct mach_header ** getmachheaders(void) { - extern struct mach_header _mh_execute_header; struct mach_header **tl; tl = (struct mach_header **)malloc(2*sizeof(struct mach_header *)); tl[0] = &_mh_execute_header; @@ -89,12 +92,14 @@ getmachheaders(void) * named segment if it exist in the mach header passed to it. Also it returns * the size of the section data indirectly through the pointer size. Otherwise * it returns zero for the pointer and the size. + * + * This routine can operate against any 32 bit mach header. */ void * getsectdatafromheader( struct mach_header *mhp, - char *segname, - char *sectname, + const char *segname, + const char *sectname, int *size) { const struct section *sp; @@ -115,11 +120,13 @@ getsectdatafromheader( * if it exist in the mach header passed to it. Also it returns * the size of the segment data indirectly through the pointer size. * Otherwise it returns zero for the pointer and the size. + * + * This routine can operate against any 32 bit mach header. */ void * getsegdatafromheader( - struct mach_header *mhp, - char *segname, + struct mach_header *mhp, + const char *segname, int *size) { const struct segment_command *sc; @@ -139,16 +146,18 @@ getsegdatafromheader( * This routine returns the section structure for the named section in the * named segment for the mach_header pointer passed to it if it exist. * Otherwise it returns zero. + * + * This routine can operate against any 32 bit mach header. */ struct section * getsectbynamefromheader( struct mach_header *mhp, - char *segname, - char *sectname) + const char *segname, + const char *sectname) { struct segment_command *sgp; struct section *sp; - long i, j; + unsigned long i, j; sgp = (struct segment_command *) ((char *)mhp + sizeof(struct mach_header)); @@ -173,12 +182,16 @@ getsectbynamefromheader( return((struct section *)0); } -struct segment_command *getsegbynamefromheader( +/* + * This routine can operate against any 32 bit mach header. + */ +struct segment_command * +getsegbynamefromheader( struct mach_header *header, - char *seg_name) + const char *seg_name) { struct segment_command *sgp; - int i; + unsigned long i; sgp = (struct segment_command *) ((char *)header + sizeof(struct mach_header)); @@ -224,7 +237,9 @@ static struct { 4, // align 0, // reloff 0, // nreloc - 0 // flags + 0, // flags + 0, // reserved1 + 0 // reserved2 } }; @@ -235,16 +250,25 @@ static vm_offset_t getsizeofmacho(struct mach_header *header); /* * Return the first segment_command in the header. + * + * This routine operates against the currently executing kernel only */ -struct segment_command *firstseg(void) +struct segment_command * +firstseg(void) { return firstsegfromheader(&_mh_execute_header); } -struct segment_command *firstsegfromheader(struct mach_header *header) +/* + * This routine can operate against any 32 bit mach header, and returns a + * pointer to a 32 bit segment_command structure from the file prefixed by + * the header it is passed as its argument. + */ +struct segment_command * +firstsegfromheader(struct mach_header *header) { struct segment_command *sgp; - int i; + unsigned long i; sgp = (struct segment_command *) ((char *)header + sizeof(struct mach_header)); @@ -256,7 +280,14 @@ struct segment_command *firstsegfromheader(struct mach_header *header) return (struct segment_command *)0; } -struct segment_command *nextseg(struct segment_command *sgp) +/* + * This routine operates against a 32 bit mach segment_command structure + * pointer from the currently executing kernel only, to obtain the + * sequentially next segment_command structure in the currently executing + * kernel + */ +struct segment_command * +nextseg(struct segment_command *sgp) { struct segment_command *this; @@ -272,12 +303,18 @@ struct segment_command *nextseg(struct segment_command *sgp) return this; } -struct segment_command *nextsegfromheader( +/* + * This routine operates against any 32 bit mach segment_command structure + * pointer and the provided 32 bit header, to obtain the sequentially next + * segment_command structure in that header. + */ +struct segment_command * +nextsegfromheader( struct mach_header *header, struct segment_command *seg) { struct segment_command *sgp; - int i; + unsigned long i; sgp = (struct segment_command *) ((char *)header + sizeof(struct mach_header)); @@ -302,9 +339,11 @@ struct segment_command *nextsegfromheader( /* - * Return the address of the named Mach-O segment, or NULL. + * Return the address of the named Mach-O segment from the currently + * executing 32 bit kernel, or NULL. */ -struct segment_command *getsegbyname(char *seg_name) +struct segment_command * +getsegbyname(const char *seg_name) { struct segment_command *this; @@ -322,42 +361,60 @@ struct segment_command *getsegbyname(char *seg_name) /* * This routine returns the a pointer the section structure of the named - * section in the named segment if it exist in the mach executable it is - * linked into. Otherwise it returns zero. + * section in the named segment if it exists in the currently executing + * kernel, which it is presumed to be linked into. Otherwise it returns NULL. */ struct section * getsectbyname( - char *segname, - char *sectname) + const char *segname, + const char *sectname) { return(getsectbynamefromheader( (struct mach_header *)&_mh_execute_header, segname, sectname)); } -struct section *firstsect(struct segment_command *sgp) +/* + * This routine can operate against any 32 bit segment_command structure to + * return the first 32 bit section immediately following that structure. If + * there are no sections associated with the segment_command structure, it + * returns NULL. + */ +struct section * +firstsect(struct segment_command *sgp) { - struct section *sp; - if (!sgp || sgp->nsects == 0) return (struct section *)0; return (struct section *)(sgp+1); } -struct section *nextsect(struct segment_command *sgp, struct section *sp) +/* + * This routine can operate against any 32 bit segment_command structure and + * 32 bit section to return the next consecutive 32 bit section immediately + * following the 32 bit section provided. If there are no sections following + * the provided section, it returns NULL. + */ +struct section * +nextsect(struct segment_command *sgp, struct section *sp) { struct section *fsp = firstsect(sgp); - if (sp - fsp >= sgp->nsects-1) + if (((unsigned long)(sp - fsp) + 1) >= sgp->nsects) return (struct section *)0; return sp+1; } -static struct fvmfile_command *fvmfilefromheader(struct mach_header *header) +/* + * This routine can operate against any 32 bit mach header to return the + * first occurring 32 bit fvmfile_command section. If one is not present, + * it returns NULL. + */ +static struct fvmfile_command * +fvmfilefromheader(struct mach_header *header) { struct fvmfile_command *fvp; - int i; + unsigned long i; fvp = (struct fvmfile_command *) ((char *)header + sizeof(struct mach_header)); @@ -371,8 +428,11 @@ static struct fvmfile_command *fvmfilefromheader(struct mach_header *header) /* * Create a fake USER seg if a fvmfile_command is present. + * + * This routine operates against the currently executing kernel only */ -struct segment_command *getfakefvmseg(void) +struct segment_command * +getfakefvmseg(void) { struct segment_command *sgp = getsegbyname("__USER"); struct fvmfile_command *fvp = fvmfilefromheader(&_mh_execute_header); @@ -398,17 +458,21 @@ struct segment_command *getfakefvmseg(void) #if DEBUG printf("fake fvm seg __USER/\"%s\" at 0x%x, size 0x%x\n", sp->sectname, sp->addr, sp->size); -#endif DEBUG +#endif /* DEBUG */ + + return sgp; } /* * Figure out the size the size of the data associated with a * loaded mach_header. + * + * This routine can operate against any 32 bit mach header. */ -static vm_offset_t getsizeofmacho(struct mach_header *header) +static vm_offset_t +getsizeofmacho(struct mach_header *header) { struct segment_command *sgp; - struct section *sp; vm_offset_t last_addr; last_addr = 0;