]> git.saurik.com Git - apple/objc4.git/blob - runtime/objc-file.m
objc4-208.tar.gz
[apple/objc4.git] / runtime / objc-file.m
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.1 (the "License"). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24 // Copyright 1988-1996 NeXT Software, Inc.
25
26 #if defined(__APPLE__) && defined(__MACH__)
27 #import "objc-private.h"
28 #import <mach-o/ldsyms.h>
29 #import <mach-o/dyld.h>
30 #include <string.h>
31 #include <stdlib.h>
32
33 #import <crt_externs.h>
34
35 /* prototype coming soon to <mach-o/getsect.h> */
36 extern char *getsectdatafromheader(
37 struct mach_header *mhp,
38 char *segname,
39 char *sectname,
40 int *size);
41
42 /* Returns an array of all the objc headers in the executable
43 * Caller is responsible for freeing.
44 */
45 headerType **_getObjcHeaders()
46 {
47 const struct mach_header **headers;
48 headers = malloc(sizeof(struct mach_header *) * 2);
49 headers[0] = (const struct mach_header *)_NSGetMachExecuteHeader();
50 headers[1] = 0;
51 return (headerType**)headers;
52 }
53
54 Module _getObjcModules(headerType *head, int *nmodules)
55 {
56 unsigned size;
57 void *mods = getsectdatafromheader((headerType *)head,
58 SEG_OBJC,
59 SECT_OBJC_MODULES,
60 &size);
61 *nmodules = size / sizeof(struct objc_module);
62 return (Module)mods;
63 }
64
65 SEL *_getObjcMessageRefs(headerType *head, int *nmess)
66 {
67 unsigned size;
68 void *refs = getsectdatafromheader ((headerType *)head,
69 SEG_OBJC, "__message_refs", &size);
70 *nmess = size / sizeof(SEL);
71 return (SEL *)refs;
72 }
73
74 ProtocolTemplate *_getObjcProtocols(headerType *head, int *nprotos)
75 {
76 unsigned size;
77 void *protos = getsectdatafromheader ((headerType *)head,
78 SEG_OBJC, "__protocol", &size);
79 *nprotos = size / sizeof(ProtocolTemplate);
80 return (ProtocolTemplate *)protos;
81 }
82
83 NXConstantStringTemplate *_getObjcStringObjects(headerType *head, int *nstrs)
84 {
85 *nstrs = 0;
86 return NULL;
87 }
88
89 Class *_getObjcClassRefs(headerType *head, int *nclasses)
90 {
91 unsigned size;
92 void *classes = getsectdatafromheader ((headerType *)head,
93 SEG_OBJC, "__cls_refs", &size);
94 *nclasses = size / sizeof(Class);
95 return (Class *)classes;
96 }
97
98 /* returns start of all objective-c info and the size of the data */
99 void *_getObjcHeaderData(headerType *head, unsigned *size)
100 {
101 struct segment_command *sgp;
102 unsigned long i;
103
104 sgp = (struct segment_command *) ((char *)head + sizeof(headerType));
105 for(i = 0; i < ((headerType *)head)->ncmds; i++){
106 if(sgp->cmd == LC_SEGMENT)
107 if(strncmp(sgp->segname, "__OBJC", sizeof(sgp->segname)) == 0) {
108 *size = sgp->filesize;
109 return (void*)sgp;
110 }
111 sgp = (struct segment_command *)((char *)sgp + sgp->cmdsize);
112 }
113 *size = 0;
114 return nil;
115 }
116
117 static const headerType *_getExecHeader (void)
118 {
119 return (const struct mach_header *)_NSGetMachExecuteHeader();
120 }
121
122 const char *_getObjcHeaderName(headerType *header)
123 {
124 const headerType *execHeader;
125 const struct fvmlib_command *libCmd, *endOfCmds;
126 char **argv;
127 #if !defined(NeXT_PDO)
128 extern char ***_NSGetArgv();
129 argv = *_NSGetArgv();
130 #else
131 extern char **NXArgv;
132 argv = NXArgv;
133 #endif
134
135 if (header && ((headerType *)header)->filetype == MH_FVMLIB) {
136 execHeader = _getExecHeader();
137 for (libCmd = (const struct fvmlib_command *)(execHeader + 1),
138 endOfCmds = ((void *)libCmd) + execHeader->sizeofcmds;
139 libCmd < endOfCmds; ((void *)libCmd) += libCmd->cmdsize) {
140 if ((libCmd->cmd == LC_LOADFVMLIB) && (libCmd->fvmlib.header_addr
141 == (unsigned long)header)) {
142 return (char *)libCmd
143 + libCmd->fvmlib.name.offset;
144 }
145 }
146 return NULL;
147 } else {
148 unsigned long i, n = _dyld_image_count();
149 for( i = 0; i < n ; i++ ) {
150 if ( _dyld_get_image_header(i) == header )
151 return _dyld_get_image_name(i);
152 }
153 return argv[0];
154 }
155 }
156
157 #elif defined(hpux) || defined(__hpux__)
158
159 /*
160 * Objective-C runtime information module.
161 * This module is specific to hp-ux a.out format files.
162 */
163
164 #import <pdo.h> // place where padding_bug would be
165 #include <a.out.h>
166 #include "objc-private.h"
167
168 OBJC_EXPORT int __argc_value;
169 OBJC_EXPORT char **__argv_value;
170 int NXArgc = 0;
171 char **NXArgv = NULL;
172
173 OBJC_EXPORT unsigned SEG_OBJC_CLASS_START;
174 OBJC_EXPORT unsigned SEG_OBJC_METACLASS_START;
175 OBJC_EXPORT unsigned SEG_OBJC_CAT_CLS_METH_START;
176 OBJC_EXPORT unsigned SEG_OBJC_CAT_INST_METH_START;
177 OBJC_EXPORT unsigned SEG_OBJC_CLS_METH_START;
178 OBJC_EXPORT unsigned SEG_OBJC_INST_METHODS_START;
179 OBJC_EXPORT unsigned SEG_OBJC_MESSAGE_REFS_START;
180 OBJC_EXPORT unsigned SEG_OBJC_SYMBOLS_START;
181 OBJC_EXPORT unsigned SEG_OBJC_CATEGORY_START;
182 OBJC_EXPORT unsigned SEG_OBJC_PROTOCOL_START;
183 OBJC_EXPORT unsigned SEG_OBJC_CLASS_VARS_START;
184 OBJC_EXPORT unsigned SEG_OBJC_INSTANCE_VARS_START;
185 OBJC_EXPORT unsigned SEG_OBJC_MODULES_START;
186 OBJC_EXPORT unsigned SEG_OBJC_STRING_OBJECT_START;
187 OBJC_EXPORT unsigned SEG_OBJC_CLASS_NAMES_START;
188 OBJC_EXPORT unsigned SEG_OBJC_METH_VAR_NAMES_START;
189 OBJC_EXPORT unsigned SEG_OBJC_METH_VAR_TYPES_START;
190 OBJC_EXPORT unsigned SEG_OBJC_CLS_REFS_START;
191
192 OBJC_EXPORT unsigned SEG_OBJC_CLASS_END;
193 OBJC_EXPORT unsigned SEG_OBJC_METACLASS_END;
194 OBJC_EXPORT unsigned SEG_OBJC_CAT_CLS_METH_END;
195 OBJC_EXPORT unsigned SEG_OBJC_CAT_INST_METH_END;
196 OBJC_EXPORT unsigned SEG_OBJC_CLS_METH_END;
197 OBJC_EXPORT unsigned SEG_OBJC_INST_METHODS_END;
198 OBJC_EXPORT unsigned SEG_OBJC_MESSAGE_REFS_END;
199 OBJC_EXPORT unsigned SEG_OBJC_SYMBOLS_END;
200 OBJC_EXPORT unsigned SEG_OBJC_CATEGORY_END;
201 OBJC_EXPORT unsigned SEG_OBJC_PROTOCOL_END;
202 OBJC_EXPORT unsigned SEG_OBJC_CLASS_VARS_END;
203 OBJC_EXPORT unsigned SEG_OBJC_INSTANCE_VARS_END;
204 OBJC_EXPORT unsigned SEG_OBJC_MODULES_END;
205 OBJC_EXPORT unsigned SEG_OBJC_STRING_OBJECT_END;
206 OBJC_EXPORT unsigned SEG_OBJC_CLASS_NAMES_END;
207 OBJC_EXPORT unsigned SEG_OBJC_METH_VAR_NAMES_END;
208 OBJC_EXPORT unsigned SEG_OBJC_METH_VAR_TYPES_END;
209 OBJC_EXPORT unsigned SEG_OBJC_CLS_REFS_END;
210
211 typedef struct _simple_header_struct {
212 char * subspace_name ;
213 void * start_address ;
214 void * end_address ;
215 } simple_header_struct ;
216
217 static simple_header_struct our_objc_header[] = {
218 { "$$OBJC_CLASS$$", &SEG_OBJC_CLASS_START, &SEG_OBJC_CLASS_END },
219 { "$$OBJC_METACLASS$$", &SEG_OBJC_METACLASS_START, &SEG_OBJC_METACLASS_END },
220 { "$$OBJC_CAT_CLS_METH$$", &SEG_OBJC_CAT_CLS_METH_START, &SEG_OBJC_CAT_CLS_METH_END },
221 { "$$OBJC_CAT_INST_METH$$", &SEG_OBJC_CAT_INST_METH_START, &SEG_OBJC_CAT_INST_METH_END },
222 { "$$OBJC_CLS_METH$$", &SEG_OBJC_CLS_METH_START, &SEG_OBJC_CLS_METH_END },
223 { "$$OBJC_INST_METHODS$$", &SEG_OBJC_INST_METHODS_START, &SEG_OBJC_INST_METHODS_END },
224 { "$$OBJC_MESSAGE_REFS$$", &SEG_OBJC_MESSAGE_REFS_START, &SEG_OBJC_MESSAGE_REFS_END },
225 { "$$OBJC_SYMBOLS$$", &SEG_OBJC_SYMBOLS_START, &SEG_OBJC_SYMBOLS_END },
226 { "$$OBJC_CATEGORY$$", &SEG_OBJC_CATEGORY_START, &SEG_OBJC_CATEGORY_END },
227 { "$$OBJC_PROTOCOL$$", &SEG_OBJC_PROTOCOL_START, &SEG_OBJC_PROTOCOL_END },
228 { "$$OBJC_CLASS_VARS$$", &SEG_OBJC_CLASS_VARS_START, &SEG_OBJC_CLASS_VARS_END },
229 { "$$OBJC_INSTANCE_VARS$$", &SEG_OBJC_INSTANCE_VARS_START, &SEG_OBJC_INSTANCE_VARS_END },
230 { "$$OBJC_MODULES$$", &SEG_OBJC_MODULES_START, &SEG_OBJC_MODULES_END },
231 { "$$OBJC_STRING_OBJECT$$", &SEG_OBJC_STRING_OBJECT_START, &SEG_OBJC_STRING_OBJECT_END },
232 { "$$OBJC_CLASS_NAMES$$", &SEG_OBJC_CLASS_NAMES_START, &SEG_OBJC_CLASS_NAMES_END },
233 { "$$OBJC_METH_VAR_NAMES$$", &SEG_OBJC_METH_VAR_TYPES_START, &SEG_OBJC_METH_VAR_NAMES_END },
234 { "$$OBJC_METH_VAR_TYPES$$", &SEG_OBJC_METH_VAR_TYPES_START, &SEG_OBJC_METH_VAR_TYPES_END },
235 { "$$OBJC_CLS_REFS$$", &SEG_OBJC_CLS_REFS_START, &SEG_OBJC_CLS_REFS_END },
236 { NULL, NULL, NULL }
237 };
238
239 /* Returns an array of all the objc headers in the executable (and shlibs)
240 * Caller is responsible for freeing.
241 */
242 headerType **_getObjcHeaders()
243 {
244
245 /* Will need to fill in with any shlib info later as well. Need more
246 * info on this.
247 */
248
249 /*
250 * this is truly ugly, hpux does not map in the header so we have to
251 * try and find it and map it in. their crt0 has some global vars
252 * that hold argv[0] which we will use to find the executable file
253 */
254
255 headerType **hdrs = (headerType**)malloc(2 * sizeof(headerType*));
256 NXArgv = __argv_value;
257 NXArgc = __argc_value;
258 hdrs[0] = &our_objc_header;
259 hdrs[1] = 0;
260 return hdrs;
261 }
262
263 // I think we are getting the address of the table (ie the table itself)
264 // isn't that expensive ?
265 static void *getsubspace(headerType *objchead, char *sname, unsigned *size)
266 {
267 simple_header_struct *table = (simple_header_struct *)objchead;
268 int i = 0;
269
270 while ( table[i].subspace_name){
271 if (!strcmp(table[i].subspace_name, sname)){
272 *size = table[i].end_address - table[i].start_address;
273 return table[i].start_address;
274 }
275 i++;
276 }
277 *size = 0;
278 return nil;
279 }
280
281 Module _getObjcModules(headerType *head, int *nmodules)
282 {
283 unsigned size;
284 void *mods = getsubspace(head,"$$OBJC_MODULES$$",&size);
285 *nmodules = size / sizeof(struct objc_module);
286 return (Module)mods;
287 }
288
289 SEL *_getObjcMessageRefs(headerType *head, int *nmess)
290 {
291 unsigned size;
292 void *refs = getsubspace (head,"$$OBJC_MESSAGE_REFS$$", &size);
293 *nmess = size / sizeof(SEL);
294 return (SEL *)refs;
295 }
296
297 struct proto_template *_getObjcProtocols(headerType *head, int *nprotos)
298 {
299 unsigned size;
300 char *p;
301 char *end;
302 char *start;
303
304 start = getsubspace (head,"$$OBJC_PROTOCOL$$", &size);
305
306 #ifdef PADDING_BUG
307 /*
308 * XXX: Look for padding of 4 zero bytes and remove it.
309 * XXX: Depends upon first four bytes of a proto_template never being 0.
310 * XXX: Somebody should check to see if this is really the case.
311 */
312 end = start + size;
313 for (p = start; p < end; p += sizeof(struct proto_template)) {
314 if (!p[0] && !p[1] && !p[2] && !p[3]) {
315 memcpy(p, p + sizeof(long), (end - p) - sizeof(long));
316 end -= sizeof(long);
317 }
318 }
319 size = end - start;
320 #endif
321 *nprotos = size / sizeof(struct proto_template);
322 return ((struct proto_template *)start);
323 }
324
325 NXConstantStringTemplate *_getObjcStringObjects(headerType *head, int *nstrs)
326 {
327 unsigned size;
328 void *str = getsubspace (head,"$$OBJC_STRING_OBJECT$$", &size);
329 *nstrs = size / sizeof(NXConstantStringTemplate);
330 return (NXConstantStringTemplate *)str;
331 }
332
333 Class *_getObjcClassRefs(headerType *head, int *nclasses)
334 {
335 unsigned size;
336 void *classes = getsubspace (head,"$$OBJC_CLS_REFS$$", &size);
337 *nclasses = size / sizeof(Class);
338 return (Class *)classes;
339 }
340
341 /* returns start of all objective-c info and the size of the data */
342 void *_getObjcHeaderData(headerType *head, unsigned *size)
343 {
344 #warning _getObjcHeaderData not implemented yet
345 *size = 0;
346 return nil;
347 }
348
349
350 const char *_getObjcHeaderName(headerType *header)
351 {
352 return "oh poo";
353 }
354
355 #else
356
357 /*
358 * Objective-C runtime information module.
359 * This module is generic for all object format files.
360 */
361
362 #import <pdo.h>
363 #import <Protocol.h>
364 #import "objc-private.h"
365 #if defined(WIN32)
366 #import <stdlib.h>
367 #endif
368
369 int NXArgc = 0;
370 char ** NXArgv = NULL;
371
372
373 char ***_NSGetArgv(void)
374 {
375 return &NXArgv;
376 }
377
378 int *_NSGetArgc(void)
379 {
380 return &NXArgc;
381
382 }
383
384 #if defined(WIN32)
385 OBJC_EXPORT char ***_environ_dll;
386 #elif defined(NeXT_PDO)
387 OBJC_EXPORT char ***environ;
388 #endif
389
390 char ***_NSGetEnviron(void)
391 {
392 #if defined(WIN32)
393 return (char ***)_environ_dll;
394 #elif defined(NeXT_PDO)
395 return (char ***)&environ;
396 #else
397 #warning "_NSGetEnviron() is unimplemented for this architecture"
398 return (char ***)NULL;
399 #endif
400 }
401
402
403 #if !defined(__hpux__) && !defined(hpux) && !defined(__osf__)
404 const char OBJC_METH_VAR_NAME_FORWARD[10]="forward::";
405 #else
406 OBJC_EXPORT char OBJC_METH_VAR_NAME_FORWARD[];
407 #endif
408
409 static objcSectionStruct objcHeaders = {0,0,sizeof(objcModHeader)};
410 objcModHeader *CMH = 0; // Current Module Header
411
412 int _objcModuleCount() {
413 return objcHeaders.count;
414 }
415
416 const char *_objcModuleNameAtIndex(int i) {
417 if ( i < 0 || i >= objcHeaders.count)
418 return NULL;
419 return ((objcModHeader*)objcHeaders.data + i)->name;
420 }
421
422 static inline void allocElements (objcSectionStruct *ptr, int nelmts)
423 {
424 if (ptr->data == 0) {
425 ptr->data = (void*)malloc ((ptr->count+nelmts) * ptr->size);
426 } else {
427 volatile void *tempData = (void *)realloc(ptr->data, (ptr->count+nelmts) * ptr->size);
428 ptr->data = (void **)tempData;
429 }
430
431 bzero((char*)ptr->data + ptr->count * ptr->size, ptr->size * nelmts);
432 }
433
434 OBJC_EXPORT void _objcInit(void);
435 void objc_finish_header (void)
436 {
437 _objcInit ();
438 CMH = (objcModHeader *)0;
439 // leaking like a stuck pig.
440 }
441
442 void objc_register_header_name (const char * name) {
443 if (name) {
444 CMH->name = malloc(strlen(name)+1);
445 #if defined(WIN32) || defined(__svr4__)
446 bzero(CMH->name, (strlen(name)+1));
447 #endif
448 strcpy(CMH->name, name);
449 }
450 }
451
452 void objc_register_header (const char * name)
453 {
454 if (CMH) {
455 // we've already registered a header (probably via __objc_execClass),
456 // so just update the name.
457 if (CMH->name)
458 free(CMH->name);
459 } else {
460 allocElements (&objcHeaders, 1);
461 CMH = (objcModHeader *)objcHeaders.data + objcHeaders.count;
462 objcHeaders.count++;
463 bzero(CMH, sizeof(objcModHeader));
464
465 CMH->Modules.size = sizeof(struct objc_module);
466 CMH->Classes.size = sizeof(void *);
467 CMH->Protocols.size = sizeof(void *);
468 CMH->StringObjects.size = sizeof(void *);
469 }
470 objc_register_header_name(name);
471 }
472
473 #if defined(DEBUG)
474 void printModule(Module mod)
475 {
476 printf("name=\"%s\", symtab=%x\n", mod->name, mod->symtab);
477 }
478
479 void dumpModules(void)
480 {
481 int i,j;
482 Module mod;
483 objcModHeader *cmh;
484
485 printf("dumpModules(): found %d header(s)\n", objcHeaders.count);
486 for (j=0; j<objcHeaders.count; ++j) {
487 cmh = (objcModHeader *)objcHeaders.data + j;
488
489 printf("===%s, found %d modules\n", cmh->name, cmh->Modules.count);
490
491
492 mod = (Module)cmh->Modules.data;
493
494 for (i=0; i<cmh->Modules.count; i++) {
495 printf("\tname=\"%s\", symtab=%x, sel_ref_cnt=%d\n", mod->name, mod->symtab, (Symtab)(mod->symtab)->sel_ref_cnt);
496 mod++;
497 }
498 }
499 }
500 #endif // DEBUG
501
502 static inline void addObjcProtocols(struct objc_protocol_list * pl)
503 {
504 if ( !pl )
505 return;
506 else {
507 int count = 0;
508 struct objc_protocol_list *list = pl;
509 while ( list ) {
510 count += list->count;
511 list = list->next;
512 }
513 allocElements( &CMH->Protocols, count );
514
515 list = pl;
516 while ( list ) {
517 int i = 0;
518 while ( i < list->count )
519 CMH->Protocols.data[ CMH->Protocols.count++ ] = (void*) list->list[i++];
520 list = list->next;
521 }
522
523 list = pl;
524 while ( list ) {
525 int i = 0;
526 while ( i < list->count )
527 addObjcProtocols( ((ProtocolTemplate*)list->list[i++])->protocol_list );
528 list = list->next;
529 }
530 }
531 }
532
533 static void
534 _parseObjcModule(struct objc_symtab *symtab)
535 {
536 int i=0, j=0, k;
537 SEL *refs = symtab->refs, sel;
538
539
540 // Add the selector references
541
542 if (refs)
543 {
544 symtab->sel_ref_cnt = 0;
545
546 while (*refs)
547 {
548 symtab->sel_ref_cnt++;
549 // don't touvh the VM page if not necessary
550 if ( (sel = sel_registerNameNoCopy ((const char *)*refs)) != *refs ) {
551 *refs = sel;
552 }
553 refs++;
554 }
555 }
556
557 // Walk through all of the ObjC Classes
558
559 if ((k = symtab->cls_def_cnt))
560 {
561 allocElements (&CMH->Classes, k);
562
563 for ( i=0, j = symtab->cls_def_cnt; i < j; i++ )
564 {
565 struct objc_class *class;
566 unsigned loop;
567
568 class = (struct objc_class *)symtab->defs[i];
569 objc_addClass(class);
570 CMH->Classes.data[ CMH->Classes.count++ ] = (void*) class->name;
571 addObjcProtocols (class->protocols);
572
573 // ignore fixing up the selectors to be unique (for now; done lazily later)
574
575 }
576 }
577
578 // Walk through all of the ObjC Categories
579
580 if ((k = symtab->cat_def_cnt))
581 {
582 allocElements (&CMH->Classes, k);
583
584 for ( j += symtab->cat_def_cnt;
585 i < j;
586 i++ )
587 {
588 struct objc_category *category;
589
590 category = (struct objc_category *)symtab->defs[i];
591 CMH->Classes.data[ CMH->Classes.count++ ] =
592 (void*) category->class_name;
593
594 addObjcProtocols (category->protocols);
595
596 // ignore fixing the selectors to be unique
597 // this is now done lazily upon use
598 //_objc_inlined_fixup_selectors_in_method_list(category->instance_methods);
599 //_objc_inlined_fixup_selectors_in_method_list(category->class_methods);
600 }
601 }
602
603
604 // Walk through all of the ObjC Static Strings
605
606 if ((k = symtab->obj_defs))
607 {
608 allocElements (&CMH->StringObjects, k);
609
610 for ( j += symtab->obj_defs;
611 i < j;
612 i++ )
613 {
614 NXConstantStringTemplate *string = ( NXConstantStringTemplate *)symtab->defs[i];
615 CMH->StringObjects.data[ CMH->StringObjects.count++ ] =
616 (void*) string;
617 }
618 }
619
620 // Walk through all of the ObjC Static Protocols
621
622 if ((k = symtab->proto_defs))
623 {
624 allocElements (&CMH->Protocols, k);
625
626 for ( j += symtab->proto_defs;
627 i < j;
628 i++ )
629 {
630 ProtocolTemplate *proto = ( ProtocolTemplate *)symtab->defs[i];
631 allocElements (&CMH->Protocols, 1);
632 CMH->Protocols.data[ CMH->Protocols.count++ ] =
633 (void*) proto;
634
635 addObjcProtocols(proto->protocol_list);
636 }
637 }
638 }
639
640 // used only as a dll initializer on Windows and/or hppa (!)
641 void __objc_execClass(Module mod)
642 {
643 sel_registerName ((const char *)OBJC_METH_VAR_NAME_FORWARD);
644
645 if (CMH == 0) {
646 objc_register_header(NXArgv ? NXArgv[0] : "");
647 }
648
649 allocElements (&CMH->Modules, 1);
650
651 memcpy( (Module)CMH->Modules.data
652 + CMH->Modules.count,
653 mod,
654 sizeof(struct objc_module));
655 CMH->Modules.count++;
656
657 _parseObjcModule(mod->symtab);
658 }
659
660 const char * NSModulePathForClass(Class cls)
661 {
662 #if defined(WIN32)
663 int i, j, k;
664
665 for (i = 0; i < objcHeaders.count; i++) {
666 volatile objcModHeader *aHeader = (objcModHeader *)objcHeaders.data + i;
667 for (j = 0; j < aHeader->Modules.count; j++) {
668 Module mod = (void *)(aHeader->Modules.data) + j * aHeader->Modules.size;
669 struct objc_symtab *symtab = mod->symtab;
670 for (k = 0; k < symtab->cls_def_cnt; k++) {
671 if (cls == (Class)symtab->defs[k])
672 return aHeader->name;
673 }
674 }
675 }
676 #else
677 #warning "NSModulePathForClass is not fully implemented!"
678 #endif
679 return NULL;
680 }
681
682 unsigned int _objc_goff_headerCount (void)
683 {
684 return objcHeaders.count;
685 }
686
687 /* Build the header vector, of all headers seen so far. */
688
689 struct header_info *_objc_goff_headerVector ()
690 {
691 unsigned int hidx;
692 struct header_info *hdrVec;
693
694 hdrVec = malloc_zone_malloc (_objc_create_zone(),
695 objcHeaders.count * sizeof (struct header_info));
696 #if defined(WIN32) || defined(__svr4__)
697 bzero(hdrVec, (objcHeaders.count * sizeof (struct header_info)));
698 #endif
699
700 for (hidx = 0; hidx < objcHeaders.count; hidx++)
701 {
702 objcModHeader *aHeader = (objcModHeader *)objcHeaders.data + hidx;
703
704 hdrVec[hidx].mhdr = (headerType**) aHeader;
705 hdrVec[hidx].mod_ptr = (Module)(aHeader->Modules.data);
706 }
707 return hdrVec;
708 }
709
710
711 #if defined(sparc)
712 int __NXArgc = 0;
713 char ** __NXArgv = 0;
714 #endif
715
716 /* Returns an array of all the objc headers in the executable (and shlibs)
717 * Caller is responsible for freeing.
718 */
719 headerType **_getObjcHeaders()
720 {
721
722 #if defined(__hpux__) || defined(hpux)
723 OBJC_EXPORT int __argc_value;
724 OBJC_EXPORT char ** __argv_value;
725 #endif
726
727 /* Will need to fill in with any shlib info later as well. Need more
728 * info on this.
729 */
730
731 headerType **hdrs = (headerType**)malloc(2 * sizeof(headerType*));
732 #if defined(WIN32) || defined(__svr4__)
733 bzero(hdrs, (2 * sizeof(headerType*)));
734 #endif
735 #if defined(__hpux__) || defined(hpux)
736 NXArgv = __argv_value;
737 NXArgc = __argc_value;
738 #else /* __hpux__ || hpux */
739 #if defined(sparc)
740 NXArgv = __NXArgv;
741 NXArgc = __NXArgc;
742 #endif /* sparc */
743 #endif /* __hpux__ || hpux */
744
745 hdrs[0] = (headerType*)CMH;
746 hdrs[1] = 0;
747 return hdrs;
748 }
749
750 static objcModHeader *_getObjcModHeader(headerType *head)
751 {
752 return (objcModHeader *)head;
753 }
754
755 Module _getObjcModules(headerType *head, int *size)
756 {
757 objcModHeader *modHdr = _getObjcModHeader(head);
758 if (modHdr) {
759 *size = modHdr->Modules.count;
760 return (Module)(modHdr->Modules.data);
761 }
762 else {
763 *size = 0;
764 return (Module)0;
765 }
766 }
767
768 ProtocolTemplate **_getObjcProtocols(headerType *head, int *nprotos)
769 {
770 objcModHeader *modHdr = _getObjcModHeader(head);
771
772 if (modHdr) {
773 *nprotos = modHdr->Protocols.count;
774 return (ProtocolTemplate **)modHdr->Protocols.data;
775 }
776 else {
777 *nprotos = 0;
778 return (ProtocolTemplate **)0;
779 }
780 }
781
782
783 NXConstantStringTemplate **_getObjcStringObjects(headerType *head, int *nstrs)
784 {
785 objcModHeader *modHdr = _getObjcModHeader(head);
786
787 if (modHdr) {
788 *nstrs = modHdr->StringObjects.count;
789 return (NXConstantStringTemplate **)modHdr->StringObjects.data;
790 }
791 else {
792 *nstrs = 0;
793 return (NXConstantStringTemplate **)0;
794 }
795 }
796
797 Class *_getObjcClassRefs(headerType *head, int *nclasses)
798 {
799 objcModHeader *modHdr = _getObjcModHeader(head);
800
801 if (modHdr) {
802 *nclasses = modHdr->Classes.count;
803 return (Class *)modHdr->Classes.data;
804 }
805 else {
806 *nclasses = 0;
807 return (Class *)0;
808 }
809 }
810
811 /* returns start of all objective-c info and the size of the data */
812 void *_getObjcHeaderData(headerType *head, unsigned *size)
813 {
814 *size = 0;
815 return NULL;
816 }
817
818 SEL *_getObjcMessageRefs(headerType *head, int *nmess)
819 {
820 *nmess = 0;
821 return (SEL *)NULL;
822 }
823
824 const char *_getObjcHeaderName(headerType *header)
825 {
826 return "InvalidHeaderName";
827 }
828 #endif