ranlib: fix it
[odcctools-svp.git] / libmacho / getsecbyname.c
blob46c913b77beda9c353cbb6ba9d5376f8583a8c00
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
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.
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@
23 #ifndef RLD
24 #include <mach-o/ldsyms.h>
25 #include <mach-o/swap.h>
26 #include <string.h>
27 #ifdef __DYNAMIC__
28 #include <mach-o/dyld.h> /* defines _dyld_lookup_and_bind() */
29 #endif /* defined(__DYNAMIC__) */
30 #ifndef __OPENSTEP__
32 #ifdef __LP64__
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) \
42 extern type var
43 #define SETUP_VAR(var)
44 #define USE_VAR(var) var
45 #else
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)
55 #endif
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,
66 const char *segname,
67 const char *sectname)
69 struct segment_command *sgp;
70 struct section *sp;
71 unsigned long i, j;
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)
86 return(sp);
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,
104 const char *segname,
105 const char *sectname)
107 struct segment_command_64 *sgp;
108 struct section_64 *sp;
109 unsigned long i, j;
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)
124 return(sp);
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,
144 const char *segname,
145 const char *sectname,
146 int fSwap)
148 struct segment_command *sgp;
149 struct section *sp;
150 unsigned long i, j;
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)) {
157 if (fSwap) {
158 #ifdef __LITTLE_ENDIAN__
159 swap_segment_command(sgp, NX_BigEndian);
160 #else
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));
170 if (fSwap) {
171 #ifdef __LITTLE_ENDIAN__
172 swap_section(sp, sgp->nsects, NX_BigEndian);
173 #else
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)
183 return(sp);
184 sp = (struct section *)((char *)sp +
185 sizeof(struct section));
188 sgp = (struct segment_command *)((char *)sgp + sgp->cmdsize);
189 } else {
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.
202 #ifndef __LP64__
204 const struct section *
205 getsectbyname(
206 const char *segname,
207 const char *sectname)
209 static struct mach_header *mhp = NULL;
210 #ifndef __OPENSTEP__
211 if(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 *
224 getsectbyname(
225 const char *segname,
226 const char *sectname)
228 static struct mach_header_64 *mhp = NULL;
230 if(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.
243 char *
244 getsectdata(
245 const char *segname,
246 const char *sectname,
247 unsigned long *size)
249 #ifndef __LP64__
250 const struct section *sp;
251 #else /* defined(__LP64__) */
252 const struct section_64 *sp;
253 #endif /* defined(__LP64__) */
255 sp = getsectbyname(segname, sectname);
256 if(sp == NULL){
257 *size = 0;
258 return(NULL);
260 *size = sp->size;
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.
270 char *
271 getsectdatafromheader(
272 struct mach_header *mhp,
273 const char *segname,
274 const char *sectname,
275 unsigned long *size)
277 const struct section *sp;
279 sp = getsectbynamefromheader(mhp, segname, sectname);
280 if(sp == NULL){
281 *size = 0;
282 return(NULL);
284 *size = sp->size;
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.
294 char *
295 getsectdatafromheader_64(
296 struct mach_header_64 *mhp,
297 const char *segname,
298 const char *sectname,
299 unsigned long *size)
301 const struct section_64 *sp;
303 sp = getsectbynamefromheader_64(mhp, segname, sectname);
304 if(sp == NULL){
305 *size = 0;
306 return(NULL);
308 *size = sp->size;
309 return((char *)((unsigned long)(sp->addr)));
312 #ifdef __DYNAMIC__
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.
320 void *
321 getsectdatafromFramework(
322 const char *FrameworkName,
323 const char *segname,
324 const char *sectname,
325 unsigned long *size)
327 unsigned long i, n, vmaddr_slide;
328 #ifndef __LP64__
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__) */
335 char *name, *p;
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')
342 name = p + 1;
343 if(strcmp(name, FrameworkName) != 0)
344 continue;
345 mh = _dyld_get_image_header(i);
346 vmaddr_slide = _dyld_get_image_vmaddr_slide(i);
347 #ifndef __LP64__
348 s = getsectbynamefromheader(mh, segname, sectname);
349 #else /* defined(__LP64__) */
350 s = getsectbynamefromheader_64(mh, segname, sectname);
351 #endif /* defined(__LP64__) */
352 if(s == NULL){
353 *size = 0;
354 return(NULL);
356 *size = s->size;
357 return((void *)(s->addr + vmaddr_slide));
359 *size = 0;
360 return(NULL);
362 #endif /* __DYNAMIC__ */
363 #endif /* !defined(RLD) */