]> git.saurik.com Git - apple/objc4.git/blob - runtime/objc-file.m
objc4-437.1.tar.gz
[apple/objc4.git] / runtime / objc-file.m
1 /*
2 * Copyright (c) 1999-2007 Apple 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 // Copyright 1988-1996 NeXT Software, Inc.
24
25 #define OLD 1
26 #include "objc-private.h"
27
28 #if TARGET_OS_WIN32
29
30 __private_extern__ const char *_getObjcHeaderName(const headerType *head)
31 {
32 return "??";
33 }
34
35 /*
36 __private_extern__ Module
37 _getObjcModules(const header_info *hi, size_t *nmodules)
38 {
39 if (nmodules) *nmodules = hi->os.moduleCount;
40 return hi->os.modules;
41 }
42 */
43 __private_extern__ SEL *
44 _getObjcSelectorRefs(const header_info *hi, size_t *nmess)
45 {
46 if (nmess) *nmess = hi->os.selrefCount;
47 return hi->os.selrefs;
48 }
49
50 __private_extern__ struct old_protocol **
51 _getObjcProtocols(const header_info *hi, size_t *nprotos)
52 {
53 if (nprotos) *nprotos = hi->os.protocolCount;
54 return hi->os.protocols;
55 }
56
57 __private_extern__ struct old_class **
58 _getObjcClassRefs(const header_info *hi, size_t *nclasses)
59 {
60 if (nclasses) *nclasses = hi->os.clsrefCount;
61 return (struct old_class **)hi->os.clsrefs;
62 }
63
64 // __OBJC,__class_names section only emitted by CodeWarrior rdar://4951638
65 __private_extern__ const char *
66 _getObjcClassNames(const header_info *hi, size_t *size)
67 {
68 if (size) *size = 0;
69 return NULL;
70 }
71
72 #else
73
74 #ifndef __LP64__
75 #define SEGMENT_CMD LC_SEGMENT
76 #define GETSECTDATAFROMHEADER(mh, seg, sect, sizep) \
77 getsectdatafromheader(mh, seg, sect, (uint32_t *)sizep)
78 #else
79 #define SEGMENT_CMD LC_SEGMENT_64
80 #define GETSECTDATAFROMHEADER(mh, seg, sect, sizep) \
81 getsectdatafromheader_64(mh, seg, sect, (uint64_t *)sizep)
82 #endif
83
84 __private_extern__ objc_image_info *
85 _getObjcImageInfo(const headerType *head, ptrdiff_t slide, size_t *sizep)
86 {
87 objc_image_info *info = (objc_image_info *)
88 #if __OBJC2__
89 GETSECTDATAFROMHEADER(head, SEG_DATA, "__objc_imageinfo", sizep);
90 if (!info) info = (objc_image_info *)
91 #endif
92 GETSECTDATAFROMHEADER(head, SEG_OBJC, "__image_info", sizep);
93 // size is BYTES, not count!
94 if (info) info = (objc_image_info *)((uintptr_t)info + slide);
95 return info;
96 }
97
98 // fixme !objc2 only (used for new-abi paranoia)
99 __private_extern__ Module
100 _getObjcModules(const header_info *hi, size_t *nmodules)
101 {
102 size_t size;
103 void *mods =
104 GETSECTDATAFROMHEADER(hi->mhdr, SEG_OBJC, SECT_OBJC_MODULES, &size);
105 #if !__OBJC2__
106 *nmodules = size / sizeof(struct objc_module);
107 #endif
108 if (mods) mods = (void *)((uintptr_t)mods + hi->os.image_slide);
109 return (Module)mods;
110 }
111
112 // fixme !objc2 only (used for new-abi paranoia)
113 __private_extern__ SEL *
114 _getObjcSelectorRefs(const header_info *hi, size_t *nmess)
115 {
116 size_t size;
117 void *refs =
118 GETSECTDATAFROMHEADER (hi->mhdr, SEG_OBJC, "__message_refs", &size);
119 if (refs) refs = (void *)((uintptr_t)refs + hi->os.image_slide);
120 *nmess = size / sizeof(SEL);
121 return (SEL *)refs;
122 }
123
124 #if !__OBJC2__
125
126 __private_extern__ BOOL
127 _hasObjcContents(const header_info *hi)
128 {
129 // Look for an __OBJC,* section other than __OBJC,__image_info
130 const segmentType *seg = hi->os.objcSegmentHeader;
131 const sectionType *sect;
132 uint32_t i;
133 for (i = 0; i < seg->nsects; i++) {
134 sect = ((const sectionType *)(seg+1))+i;
135 if (0 != strncmp(sect->sectname, "__image_info", 12)) {
136 return YES;
137 }
138 }
139
140 return NO;
141 }
142
143 __private_extern__ struct old_protocol **
144 _getObjcProtocols(const header_info *hi, size_t *nprotos)
145 {
146 size_t size;
147 struct old_protocol *protos = (struct old_protocol *)
148 GETSECTDATAFROMHEADER (hi->mhdr, SEG_OBJC, "__protocol", &size);
149 *nprotos = size / sizeof(struct old_protocol);
150 if (protos) protos = (struct old_protocol *)((uintptr_t)protos+hi->os.image_slide);
151
152 if (!hi->os.proto_refs && *nprotos) {
153 size_t i;
154 header_info *whi = (header_info *)hi;
155 whi->os.proto_refs = malloc(*nprotos * sizeof(*hi->os.proto_refs));
156 for (i = 0; i < *nprotos; i++) {
157 hi->os.proto_refs[i] = protos+i;
158 }
159 }
160
161 return hi->os.proto_refs;
162 }
163
164 __private_extern__ struct old_class **
165 _getObjcClassRefs(const header_info *hi, size_t *nclasses)
166 {
167 size_t size;
168 void *classes =
169 GETSECTDATAFROMHEADER(hi->mhdr, SEG_OBJC, "__cls_refs", &size);
170 *nclasses = size / sizeof(struct old_class *);
171 if (classes) classes = (void *)((uintptr_t)classes + hi->os.image_slide);
172 return (struct old_class **)classes;
173 }
174
175 // __OBJC,__class_names section only emitted by CodeWarrior rdar://4951638
176 __private_extern__ const char *
177 _getObjcClassNames(const header_info *hi, size_t *size)
178 {
179 void *names =
180 GETSECTDATAFROMHEADER(hi->mhdr, SEG_OBJC, "__class_names", size);
181 if (names) names = (void *)((uintptr_t)names + hi->os.image_slide);
182 return (const char *)names;
183 }
184
185 #endif
186
187 #if __OBJC2__
188
189 __private_extern__ BOOL
190 _hasObjcContents(const header_info *hi)
191 {
192 // Look for a __DATA,__objc* section other than __DATA,__objc_imageinfo
193 const segmentType *seg = hi->os.dataSegmentHeader;
194 const sectionType *sect;
195 uint32_t i;
196 for (i = 0; i < seg->nsects; i++) {
197 sect = ((const sectionType *)(seg+1))+i;
198 if (0 == strncmp(sect->sectname, "__objc_", 7) &&
199 0 != strncmp(sect->sectname, "__objc_imageinfo", 16))
200 {
201 return YES;
202 }
203 }
204
205 return NO;
206 }
207
208 __private_extern__ SEL *
209 _getObjc2SelectorRefs(const header_info *hi, size_t *nmess)
210 {
211 size_t size;
212 void *refs =
213 GETSECTDATAFROMHEADER (hi->mhdr, SEG_DATA, "__objc_selrefs", &size);
214 if (refs) refs = (void *)((uintptr_t)refs + hi->os.image_slide);
215 *nmess = size / sizeof(SEL);
216 return (SEL *)refs;
217 }
218
219 __private_extern__ message_ref *
220 _getObjc2MessageRefs(const header_info *hi, size_t *nmess)
221 {
222 size_t size;
223 void *refs =
224 GETSECTDATAFROMHEADER (hi->mhdr, SEG_DATA, "__objc_msgrefs", &size);
225 if (refs) refs = (void *)((uintptr_t)refs + hi->os.image_slide);
226 *nmess = size / sizeof(message_ref);
227 return (message_ref *)refs;
228 }
229
230 __private_extern__ struct class_t **
231 _getObjc2ClassRefs(const header_info *hi, size_t *nclasses)
232 {
233 size_t size;
234 void *classes =
235 GETSECTDATAFROMHEADER(hi->mhdr, SEG_DATA, "__objc_classrefs", &size);
236 *nclasses = size / sizeof(struct class_t *);
237 if (classes) classes = (void *)((uintptr_t)classes + hi->os.image_slide);
238 return (struct class_t **)classes;
239 }
240
241 __private_extern__ struct class_t **
242 _getObjc2SuperRefs(const header_info *hi, size_t *nclasses)
243 {
244 size_t size;
245 void *classes =
246 GETSECTDATAFROMHEADER(hi->mhdr, SEG_DATA, "__objc_superrefs", &size);
247 *nclasses = size / sizeof(struct class_t *);
248 if (classes) classes = (void *)((uintptr_t)classes + hi->os.image_slide);
249 return (struct class_t **)classes;
250 }
251
252 __private_extern__ struct class_t **
253 _getObjc2ClassList(const header_info *hi, size_t *nclasses)
254 {
255 size_t size;
256 void *classes =
257 GETSECTDATAFROMHEADER(hi->mhdr, SEG_DATA, "__objc_classlist", &size);
258 *nclasses = size / sizeof(struct class_t *);
259 if (classes) classes = (void *)((uintptr_t)classes + hi->os.image_slide);
260 return (struct class_t **)classes;
261 }
262
263 __private_extern__ struct class_t **
264 _getObjc2NonlazyClassList(const header_info *hi, size_t *nclasses)
265 {
266 size_t size;
267 void *classes =
268 GETSECTDATAFROMHEADER(hi->mhdr, SEG_DATA, "__objc_nlclslist", &size);
269 *nclasses = size / sizeof(struct class_t *);
270 if (classes) classes = (void *)((uintptr_t)classes + hi->os.image_slide);
271 return (struct class_t **)classes;
272 }
273
274 __private_extern__ struct category_t **
275 _getObjc2CategoryList(const header_info *hi, size_t *ncats)
276 {
277 size_t size;
278 void *cats =
279 GETSECTDATAFROMHEADER(hi->mhdr, SEG_DATA, "__objc_catlist", &size);
280 *ncats = size / sizeof(struct category_t *);
281 if (cats) cats = (void *)((uintptr_t)cats + hi->os.image_slide);
282 return (struct category_t **)cats;
283 }
284
285 __private_extern__ struct category_t **
286 _getObjc2NonlazyCategoryList(const header_info *hi, size_t *ncats)
287 {
288 size_t size;
289 void *cats =
290 GETSECTDATAFROMHEADER(hi->mhdr, SEG_DATA, "__objc_nlcatlist", &size);
291 *ncats = size / sizeof(struct category_t *);
292 if (cats) cats = (void *)((uintptr_t)cats + hi->os.image_slide);
293 return (struct category_t **)cats;
294 }
295
296 __private_extern__ struct protocol_t **
297 _getObjc2ProtocolList(const header_info *hi, size_t *nprotos)
298 {
299 size_t size;
300 void *protos =
301 GETSECTDATAFROMHEADER (hi->mhdr, SEG_DATA, "__objc_protolist", &size);
302 *nprotos = size / sizeof(struct protocol_t *);
303 if (protos) protos = (struct protocol_t **)((uintptr_t)protos+hi->os.image_slide);
304 return (struct protocol_t **)protos;
305 }
306
307 __private_extern__ struct protocol_t **
308 _getObjc2ProtocolRefs(const header_info *hi, size_t *nprotos)
309 {
310 size_t size;
311 void *protos =
312 GETSECTDATAFROMHEADER (hi->mhdr, SEG_DATA, "__objc_protorefs", &size);
313 *nprotos = size / sizeof(struct protocol_t *);
314 if (protos) protos = (struct protocol_t **)((uintptr_t)protos+hi->os.image_slide);
315 return (struct protocol_t **)protos;
316 }
317
318 #endif
319
320 __private_extern__ const char *
321 _getObjcHeaderName(const headerType *header)
322 {
323 Dl_info info;
324
325 if (dladdr(header, &info)) {
326 return info.dli_fname;
327 }
328 else {
329 return (*_NSGetArgv())[0];
330 }
331 }
332
333
334 // 1. Find segment with file offset == 0 and file size != 0. This segment's
335 // contents span the Mach-O header. (File size of 0 is .bss, for example)
336 // 2. Slide is header's address - segment's preferred address
337 __private_extern__ ptrdiff_t
338 _getImageSlide(const headerType *header)
339 {
340 unsigned long i;
341 const segmentType *sgp = (const segmentType *)(header + 1);
342
343 for (i = 0; i < header->ncmds; i++){
344 if (sgp->cmd == SEGMENT_CMD) {
345 if (sgp->fileoff == 0 && sgp->filesize != 0) {
346 return (uintptr_t)header - (uintptr_t)sgp->vmaddr;
347 }
348 }
349 sgp = (const segmentType *)((char *)sgp + sgp->cmdsize);
350 }
351
352 // uh-oh
353 _objc_fatal("could not calculate VM slide for image '%s'",
354 _getObjcHeaderName(header));
355 return 0; // not reached
356 }
357
358
359 #endif