/*
- * 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@
*/
*
* 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();
#include <vm/vm_map.h>
#include <vm/vm_kern.h>
#include <mach-o/mach_header.h>
+#include <string.h> // from libsa
#ifdef __MACHO__
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
*/
#ifdef MACH_BSD
__private_extern__
#endif
-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));
#ifdef XXX_MACH_BSD
__private_extern__
#endif
+/*
+ * 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;
if (kmem_alloc(kernel_map, (vm_offset_t *) &tl, 2*sizeof(struct mach_header *)) != KERN_SUCCESS)
* 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.
*/
#ifdef MACH_BSD
__private_extern__
void *
getsectdatafromheader(
struct mach_header *mhp,
- char *segname,
- char *sectname,
+ const char *segname,
+ const char *sectname,
int *size)
{
const struct section *sp;
void *
getsegdatafromheader(
struct mach_header *mhp,
- char *segname,
+ const char *segname,
int *size)
{
const struct segment_command *sc;
* 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.
*/
#ifdef MACH_BSD
__private_extern__
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));
#ifdef MACH_BSD
__private_extern__
#endif
-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));
4, // align
0, // reloff
0, // nreloc
- 0 // flags
+ 0, // flags
+ 0, // reserved1
+ 0 // reserved2
}
};
#ifdef MACH_BSD
__private_extern__
#endif
-struct segment_command *firstseg(void)
+struct segment_command *
+firstseg(void)
{
return firstsegfromheader(&_mh_execute_header);
}
#ifdef MACH_BSD
__private_extern__
#endif
-struct segment_command *firstsegfromheader(struct mach_header *header)
+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));
#ifdef MACH_BSD
__private_extern__
#endif
-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;
#ifdef MACH_BSD
__private_extern__
#endif
-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));
/*
- * 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.
*/
#ifdef MACH_BSD
__private_extern__
#endif
-struct segment_command *getsegbyname(char *seg_name)
+struct segment_command *
+getsegbyname(const char *seg_name)
{
struct segment_command *this;
/*
* 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.
*/
#ifdef MACH_BSD
__private_extern__
#endif
struct section *
getsectbyname(
- char *segname,
- char *sectname)
+ const char *segname,
+ const char *sectname)
{
return(getsectbynamefromheader(
(struct mach_header *)&_mh_execute_header, segname, sectname));
#ifdef MACH_BSD
__private_extern__
#endif
-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;
#ifdef MACH_BSD
__private_extern__
#endif
-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));
/*
* Create a fake USER seg if a fvmfile_command is present.
+ *
+ * This routine operates against the currently executing kernel only
*/
#ifdef MACH_BSD
__private_extern__
#endif
-struct segment_command *getfakefvmseg(void)
+struct segment_command *
+getfakefvmseg(void)
{
struct segment_command *sgp = getsegbyname("__USER");
struct fvmfile_command *fvp = fvmfilefromheader(&_mh_execute_header);
/*
* Figure out the size the size of the data associated with a
* loaded mach_header.
+ *
+ * This routine operates against the currently executing kernel only
*/
-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;
struct mach_header *mhp)
{
struct segment_command *sgp;
- struct section *sp;
- long i;
+ unsigned long i;
sgp = (struct segment_command *)
((char *)mhp + sizeof(struct mach_header));