2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
24 #include <mach-o/ldsyms.h>
25 #include <mach-o/swap.h>
28 #include <mach-o/dyld.h> /* defines _dyld_lookup_and_bind() */
29 #endif /* defined(__DYNAMIC__) */
33 extern struct mach_header_64
*_NSGetMachExecuteHeader(void);
34 #else /* !defined(__LP64__) */
35 #include <crt_externs.h>
36 #endif /* !defined(__LP64__) */
38 #else /* defined(__OPENSTEP__) */
40 #if !defined(__DYNAMIC__)
41 #define DECLARE_VAR(var, type) \
43 #define SETUP_VAR(var)
44 #define USE_VAR(var) var
46 #define STRINGIFY(a) # a
47 #define DECLARE_VAR(var, type) \
48 static type * var ## _pointer = NULL
49 #define SETUP_VAR(var) \
50 if ( var ## _pointer == NULL) { \
51 _dyld_lookup_and_bind( STRINGIFY(_ ## var), \
52 (unsigned long *) & var ## _pointer, NULL); \
54 #define USE_VAR(var) (* var ## _pointer)
56 #endif /* __OPENSTEP__ */
59 * This routine returns the section structure for the named section in the
60 * named segment for the mach_header pointer passed to it if it exist.
61 * Otherwise it returns zero.
63 const struct section
*
64 getsectbynamefromheader(
65 struct mach_header
*mhp
,
69 struct segment_command
*sgp
;
73 sgp
= (struct segment_command
*)
74 ((char *)mhp
+ sizeof(struct mach_header
));
75 for(i
= 0; i
< mhp
->ncmds
; i
++){
76 if(sgp
->cmd
== LC_SEGMENT
)
77 if(strncmp(sgp
->segname
, segname
, sizeof(sgp
->segname
)) == 0 ||
78 mhp
->filetype
== MH_OBJECT
){
79 sp
= (struct section
*)((char *)sgp
+
80 sizeof(struct segment_command
));
81 for(j
= 0; j
< sgp
->nsects
; j
++){
82 if(strncmp(sp
->sectname
, sectname
,
83 sizeof(sp
->sectname
)) == 0 &&
84 strncmp(sp
->segname
, segname
,
85 sizeof(sp
->segname
)) == 0)
87 sp
= (struct section
*)((char *)sp
+
88 sizeof(struct section
));
91 sgp
= (struct segment_command
*)((char *)sgp
+ sgp
->cmdsize
);
93 return((struct section
*)0);
97 * This routine returns the section structure for the named section in the
98 * named segment for the mach_header_64 pointer passed to it if it exist.
99 * Otherwise it returns zero.
101 const struct section_64
*
102 getsectbynamefromheader_64(
103 struct mach_header_64
*mhp
,
105 const char *sectname
)
107 struct segment_command_64
*sgp
;
108 struct section_64
*sp
;
111 sgp
= (struct segment_command_64
*)
112 ((char *)mhp
+ sizeof(struct mach_header_64
));
113 for(i
= 0; i
< mhp
->ncmds
; i
++){
114 if(sgp
->cmd
== LC_SEGMENT_64
)
115 if(strncmp(sgp
->segname
, segname
, sizeof(sgp
->segname
)) == 0 ||
116 mhp
->filetype
== MH_OBJECT
){
117 sp
= (struct section_64
*)((char *)sgp
+
118 sizeof(struct segment_command_64
));
119 for(j
= 0; j
< sgp
->nsects
; j
++){
120 if(strncmp(sp
->sectname
, sectname
,
121 sizeof(sp
->sectname
)) == 0 &&
122 strncmp(sp
->segname
, segname
,
123 sizeof(sp
->segname
)) == 0)
125 sp
= (struct section_64
*)((char *)sp
+
126 sizeof(struct section_64
));
129 sgp
= (struct segment_command_64
*)((char *)sgp
+ sgp
->cmdsize
);
131 return((struct section_64
*)0);
135 * This routine returns the section structure for the named section in the
136 * named segment for the mach_header pointer passed to it if it exist.
137 * Otherwise it returns zero. If fSwap == YES (the mach header has been
138 * swapped to the endiannes of the current machine, but the segments and
139 * sections are different) then the segment and sections are swapped.
141 const struct section
*
142 getsectbynamefromheaderwithswap(
143 struct mach_header
*mhp
,
145 const char *sectname
,
148 struct segment_command
*sgp
;
152 sgp
= (struct segment_command
*)
153 ((char *)mhp
+ sizeof(struct mach_header
));
154 for(i
= 0; i
< mhp
->ncmds
; i
++){
155 if(sgp
->cmd
== (fSwap
? NXSwapLong(LC_SEGMENT
) : LC_SEGMENT
)) {
158 #ifdef __LITTLE_ENDIAN__
159 swap_segment_command(sgp
, NX_BigEndian
);
161 swap_segment_command(sgp
, NX_LittleEndian
);
162 #endif /* __LITTLE_ENDIAN__ */
165 if(strncmp(sgp
->segname
, segname
, sizeof(sgp
->segname
)) == 0 ||
166 mhp
->filetype
== MH_OBJECT
){
167 sp
= (struct section
*)((char *)sgp
+
168 sizeof(struct segment_command
));
171 #ifdef __LITTLE_ENDIAN__
172 swap_section(sp
, sgp
->nsects
, NX_BigEndian
);
174 swap_section(sp
, sgp
->nsects
, NX_LittleEndian
);
175 #endif /* __LITTLE_ENDIAN__ */
178 for(j
= 0; j
< sgp
->nsects
; j
++){
179 if(strncmp(sp
->sectname
, sectname
,
180 sizeof(sp
->sectname
)) == 0 &&
181 strncmp(sp
->segname
, segname
,
182 sizeof(sp
->segname
)) == 0)
184 sp
= (struct section
*)((char *)sp
+
185 sizeof(struct section
));
188 sgp
= (struct segment_command
*)((char *)sgp
+ sgp
->cmdsize
);
190 sgp
= (struct segment_command
*)((char *)sgp
+
191 (fSwap
? NXSwapLong(sgp
->cmdsize
) : sgp
->cmdsize
));
194 return((struct section
*)0);
198 * This routine returns the a pointer the section structure of the named
199 * section in the named segment if it exist in the mach executable it is
200 * linked into. Otherwise it returns zero.
204 const struct section
*
207 const char *sectname
)
209 static struct mach_header
*mhp
= NULL
;
212 mhp
= _NSGetMachExecuteHeader();
213 #else /* defined(__OPENSTEP__) */
214 DECLARE_VAR(_mh_execute_header
, struct mach_header
);
215 SETUP_VAR(_mh_execute_header
);
216 mhp
= (struct mach_header
*)(& USE_VAR(_mh_execute_header
));
217 #endif /* __OPENSTEP__ */
218 return(getsectbynamefromheader(mhp
, segname
, sectname
));
221 #else /* defined(__LP64__) */
223 const struct section_64
*
226 const char *sectname
)
228 static struct mach_header_64
*mhp
= NULL
;
231 mhp
= _NSGetMachExecuteHeader();
232 return(getsectbynamefromheader_64(mhp
, segname
, sectname
));
235 #endif /* defined(__LP64__) */
238 * This routine returns the a pointer to the data for the named section in the
239 * named segment if it exist in the mach executable it is linked into. Also
240 * it returns the size of the section data indirectly through the pointer size.
241 * Otherwise it returns zero for the pointer and the size.
246 const char *sectname
,
250 const struct section
*sp
;
251 #else /* defined(__LP64__) */
252 const struct section_64
*sp
;
253 #endif /* defined(__LP64__) */
255 sp
= getsectbyname(segname
, sectname
);
261 return((char *)(sp
->addr
));
265 * This routine returns the a pointer to the data for the named section in the
266 * named segment if it exist in the mach header passed to it. Also it returns
267 * the size of the section data indirectly through the pointer size. Otherwise
268 * it returns zero for the pointer and the size.
271 getsectdatafromheader(
272 struct mach_header
*mhp
,
274 const char *sectname
,
277 const struct section
*sp
;
279 sp
= getsectbynamefromheader(mhp
, segname
, sectname
);
285 return((char *)((unsigned long)(sp
->addr
)));
289 * This routine returns the a pointer to the data for the named section in the
290 * named segment if it exist in the 64-bit mach header passed to it. Also it
291 * returns the size of the section data indirectly through the pointer size.
292 * Otherwise it returns zero for the pointer and the size.
295 getsectdatafromheader_64(
296 struct mach_header_64
*mhp
,
298 const char *sectname
,
301 const struct section_64
*sp
;
303 sp
= getsectbynamefromheader_64(mhp
, segname
, sectname
);
309 return((char *)((unsigned long)(sp
->addr
)));
314 * This routine returns the a pointer to the data for the named section in the
315 * named segment if it exist in the named Framework. Also it returns the size
316 * of the section data indirectly through the pointer size. Otherwise it
317 * returns zero for the pointer and the size. The last component of the path
318 * of the Framework is passed as FrameworkName.
321 getsectdatafromFramework(
322 const char *FrameworkName
,
324 const char *sectname
,
327 unsigned long i
, n
, vmaddr_slide
;
329 struct mach_header
*mh
;
330 const struct section
*s
;
331 #else /* defined(__LP64__) */
332 struct mach_header_64
*mh
;
333 const struct section_64
*s
;
334 #endif /* defined(__LP64__) */
337 n
= _dyld_image_count();
338 for(i
= 0; i
< n
; i
++){
339 name
= _dyld_get_image_name(i
);
340 p
= strrchr(name
, '/');
341 if(p
!= NULL
&& p
[1] != '\0')
343 if(strcmp(name
, FrameworkName
) != 0)
345 mh
= _dyld_get_image_header(i
);
346 vmaddr_slide
= _dyld_get_image_vmaddr_slide(i
);
348 s
= getsectbynamefromheader(mh
, segname
, sectname
);
349 #else /* defined(__LP64__) */
350 s
= getsectbynamefromheader_64(mh
, segname
, sectname
);
351 #endif /* defined(__LP64__) */
357 return((void *)(s
->addr
+ vmaddr_slide
));
362 #endif /* __DYNAMIC__ */
363 #endif /* !defined(RLD) */