1/*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23#include <mach-o/ldsyms.h>
24#include <string.h>
25#ifndef __OPENSTEP__
26
27#ifndef RLD
28#include <crt_externs.h>
29#endif /* !defined(RLD) */
30
31#else /* defined(__OPENSTEP__) */
32#ifdef __DYNAMIC__
33#include "mach-o/dyld.h" /* defines _dyld_lookup_and_bind() */
34#endif
35
36#if !defined(__DYNAMIC__)
37#define DECLARE_VAR(var, type) \
38extern type var
39#define SETUP_VAR(var)
40#define USE_VAR(var) var
41#else
42#define STRINGIFY(a) # a
43#define DECLARE_VAR(var, type)	\
44static type * var ## _pointer = 0
45#define SETUP_VAR(var)						\
46if ( var ## _pointer == 0) {				\
47    _dyld_lookup_and_bind( STRINGIFY(_ ## var),		\
48                           (uint32_t *) & var ## _pointer, 0);	\
49}
50#define USE_VAR(var) (* var ## _pointer)
51#endif
52#endif /* __OPENSTEP__ */
53
54/*
55 * This routine returns the segment_command structure for the named segment if
56 * it exist in the mach executible it is linked into.  Otherwise it returns
57 * zero.  It uses the link editor defined symbol _mh_execute_header and just
58 * looks through the load commands.  Since these are mapped into the text
59 * segment they are read only and thus const.
60 */
61#ifndef __LP64__
62
63const struct segment_command *
64getsegbyname(
65char *segname)
66{
67    struct segment_command *sgp;
68    uint32_t i;
69#ifndef RLD
70#ifndef __OPENSTEP__
71    struct mach_header *mhp = _NSGetMachExecuteHeader();
72#else /* defined(__OPENSTEP__) */
73    static struct mach_header *mhp = NULL;
74        DECLARE_VAR(_mh_execute_header, struct mach_header);
75        SETUP_VAR(_mh_execute_header);
76	mhp = (struct mach_header *)(& USE_VAR(_mh_execute_header));
77#endif /* __OPENSTEP__ */
78#else /* defined(RLD) */
79	mhp = (struct mach_header *)(&_mh_execute_header);
80#endif /* defined(RLD) */
81
82	sgp = (struct segment_command *)
83	      ((char *)mhp + sizeof(struct mach_header));
84	for(i = 0; i < mhp->ncmds; i++){
85	    if(sgp->cmd == LC_SEGMENT)
86		if(strncmp(sgp->segname, segname, sizeof(sgp->segname)) == 0)
87		    return(sgp);
88	    sgp = (struct segment_command *)((char *)sgp + sgp->cmdsize);
89	}
90	return(NULL);
91}
92
93#else /* defined(__LP64__) */
94
95const struct segment_command_64 *
96getsegbyname(
97char *segname)
98{
99    struct mach_header_64 *mhp = NULL;
100    struct segment_command_64 *sgp;
101    uint32_t i;
102
103#ifndef RLD
104	mhp = _NSGetMachExecuteHeader();
105#else /* defined(RLD) */
106	mhp = (struct mach_header_64 *)(&_mh_execute_header);
107#endif /* defined(RLD) */
108
109	sgp = (struct segment_command_64 *)
110	      ((char *)mhp + sizeof(struct mach_header_64));
111	for(i = 0; i < mhp->ncmds; i++){
112	    if(sgp->cmd == LC_SEGMENT_64)
113		if(strncmp(sgp->segname, segname, sizeof(sgp->segname)) == 0)
114		    return(sgp);
115	    sgp = (struct segment_command_64 *)((char *)sgp + sgp->cmdsize);
116	}
117	return(NULL);
118}
119#endif /* defined(__LP64__) */
120