File:  [Apple Darwin 0.x] / objc / getsecbyname.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 19:13:57 2018 UTC (8 years, 2 months ago) by root
Branches: MAIN, Apple
CVS tags: HEAD, Darwin03, Darwin01
Darwin 0.1 In-kernel Objective-C runtime

/*
 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
 *
 * @APPLE_LICENSE_HEADER_START@
 * 
 * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
 * Reserved.  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 1.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.apple.com/publicsource 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
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * 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@
 */
#include <mach-o/ldsyms.h>
#include <string.h>

/*
 * 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.
 */
const struct section *
getsectbynamefromheader(
    struct mach_header *mhp,
    char *segname,
    char *sectname)
{
	struct segment_command *sgp;
	struct section *sp;
	long i, j;

	sgp = (struct segment_command *)
	      ((char *)mhp + sizeof(struct mach_header));
	for(i = 0; i < mhp->ncmds; i++){
	    if(sgp->cmd == LC_SEGMENT)
		if(strncmp(sgp->segname, segname, sizeof(sgp->segname)) == 0 ||
		   mhp->filetype == MH_OBJECT){
		    sp = (struct section *)((char *)sgp +
			 sizeof(struct segment_command));
		    for(j = 0; j < sgp->nsects; j++){
			if(strncmp(sp->sectname, sectname,
			   sizeof(sp->sectname)) == 0 &&
			   strncmp(sp->segname, segname,
			   sizeof(sp->segname)) == 0)
			    return(sp);
			sp = (struct section *)((char *)sp +
			     sizeof(struct section));
		    }
		}
	    sgp = (struct segment_command *)((char *)sgp + sgp->cmdsize);
	}
	return((struct section *)0);
}


/*
 * 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.  If fSwap == YES (the mach header has been
 * swapped to the endiannes of the current machine, but the segments and
 * sections are different) then the segment and sections are swapped.
 */
const struct section *
getsectbynamefromheaderwithswap(
    struct mach_header *mhp,
    const char *segname,
    const char *sectname, 
    int fSwap)
{
	struct segment_command *sgp;
	struct section *sp;
	long i, j;

	sgp = (struct segment_command *)
	      ((char *)mhp + sizeof(struct mach_header));
	for(i = 0; i < mhp->ncmds; i++){
	    if(sgp->cmd == (fSwap ? NXSwapLong(LC_SEGMENT) : LC_SEGMENT)) {
	    
		if (fSwap) {
#ifdef __LITTLE_ENDIAN__
		    swap_segment_command(sgp, NX_BigEndian);
#else
		    swap_segment_command(sgp, NX_LittleEndian);
#endif __LITTLE_ENDIAN__
		}
	    
		if(strncmp(sgp->segname, segname, sizeof(sgp->segname)) == 0 ||
		   mhp->filetype == MH_OBJECT){
		    sp = (struct section *)((char *)sgp +
			 sizeof(struct segment_command));
		
		    if (fSwap) {
#ifdef __LITTLE_ENDIAN__
			swap_section(sp, sgp->nsects, NX_BigEndian);
#else
			swap_section(sp, sgp->nsects, NX_LittleEndian);
#endif __LITTLE_ENDIAN__
		    }
		
		    for(j = 0; j < sgp->nsects; j++){
			if(strncmp(sp->sectname, sectname,
			   sizeof(sp->sectname)) == 0 &&
			   strncmp(sp->segname, segname,
			   sizeof(sp->segname)) == 0)
			    return(sp);
			sp = (struct section *)((char *)sp +
			     sizeof(struct section));
		    }
		}
		sgp = (struct segment_command *)((char *)sgp + sgp->cmdsize);
	    } else {
		sgp = (struct segment_command *)((char *)sgp +
		    (fSwap ? NXSwapLong(sgp->cmdsize) : sgp->cmdsize));
	    }
	}
	return((struct section *)0);
}


/*
 * 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.
 */
const struct section *
getsectbyname(
    char *segname,
    char *sectname)
{
	return(getsectbynamefromheader(
		(struct mach_header *)&_mh_execute_header, segname, sectname));
}

/*
 * This routine returns the a pointer to the data for the named section in the
 * named segment if it exist in the mach executable it is linked into.  Also
 * it returns the size of the section data indirectly through the pointer size.
 * Otherwise it returns zero for the pointer and the size.
 */
char *
getsectdata(
    char *segname,
    char *sectname,
    int *size)
{
	const struct section *sp;

	sp = getsectbyname(segname, sectname);
	if(sp == (struct section *)0){
	    *size = 0;
	    return((char *)0);
	}
	*size = sp->size;
	return((char *)(sp->addr));
}

/*
 * This routine returns the a pointer to the data for the named section in the
 * 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.
 */
char *
getsectdatafromheader(
    struct mach_header *mhp,
    char *segname,
    char *sectname,
    int *size)
{
	const struct section *sp;

	sp = getsectbynamefromheader(mhp, segname, sectname);
	if(sp == (struct section *)0){
	    *size = 0;
	    return((char *)0);
	}
	*size = sp->size;
	return((char *)(sp->addr));
}

/*
 * This routine returns the a pointer to the data for the named section in the
 * named segment if it exist in the named shared library the executable it is
 * linked into.  Also it returns the size of the section data indirectly
 * through the pointer size.  Otherwise it returns zero for the pointer and
 * the size.  The last component of the shared libraries name must be of the
 * form libx.X.shlib.  Where the library name passed to this routine would
 * be libx and x is any string.  In libx.X.shlib, X is any single character.
 */
char *
getsectdatafromlib(
    char *libname,
    char *segname,
    char *sectname,
    int *size)
{
	struct mach_header *mhp;
	struct fvmlib_command *flp;
	const struct section *sp;
	long i, libnamelen, namelen;
	char *name, *p;

	libnamelen = strlen(libname);
	mhp = (struct mach_header *)(&_mh_execute_header);
	flp = (struct fvmlib_command *)
	      ((char *)mhp + sizeof(struct mach_header));
	for(i = 0; i < mhp->ncmds; i++){
	    if(flp->cmd == LC_LOADFVMLIB){
		name = (char *)flp + flp->fvmlib.name.offset;
		p = strrchr(name, '/');
		if(p == NULL)
		    p = name;
		else
		    p++;
		namelen = strlen(p);
		if(namelen >= libnamelen + sizeof(".X.shlib") - 1 &&
		   strncmp(p, libname, libnamelen) == 0 &&
		   *(p + libnamelen) == '.' &&
		   strcmp(p + libnamelen + 2, ".shlib") == 0){
		    sp = getsectbynamefromheader(
				(struct mach_header *)flp->fvmlib.header_addr,
				segname, sectname);
		    if(sp == (struct section *)0){
			*size = 0;
			return((char *)0);
		    }
		    *size = sp->size;
		    return((char *)(sp->addr));
		}
	    }
	    flp = (struct fvmlib_command *)((char *)flp + flp->cmdsize);
	}

	*size = 0;
	return((char *)0);
}

unix.superglobalmegacorp.com

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