|
|
1.1 root 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.0 (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: #include <stdio.h>
25: #include <stdlib.h>
26: #include <sys/file.h>
27: #include <sys/types.h>
28: #include <sys/stat.h>
29: #include <mach-o/loader.h>
30: #include <objc/objc-runtime.h>
31: #include <objc/NXString.h>
32: #include <sys/types.h>
33: #include "Protocol.h"
34:
35: /* These are in libc in later updates */
36: void
37: swap_mach_header(
38: struct mach_header *mh,
39: enum NXByteOrder target_byte_order)
40: {
41: mh->magic = NXSwapLong(mh->magic);
42: mh->cputype = NXSwapLong(mh->cputype);
43: mh->cpusubtype = NXSwapLong(mh->cpusubtype);
44: mh->filetype = NXSwapLong(mh->filetype);
45: mh->ncmds = NXSwapLong(mh->ncmds);
46: mh->sizeofcmds = NXSwapLong(mh->sizeofcmds);
47: mh->flags = NXSwapLong(mh->flags);
48: }
49:
50: void
51: swap_load_command(
52: struct load_command *lc,
53: enum NXByteOrder target_byte_order)
54: {
55: lc->cmd = NXSwapLong(lc->cmd);
56: lc->cmdsize = NXSwapLong(lc->cmdsize);
57: }
58:
59: void
60: swap_segment_command(
61: struct segment_command *sg,
62: enum NXByteOrder target_byte_order)
63: {
64: /* segname[16] */
65: sg->cmd = NXSwapLong(sg->cmd);
66: sg->cmdsize = NXSwapLong(sg->cmdsize);
67: sg->vmaddr = NXSwapLong(sg->vmaddr);
68: sg->vmsize = NXSwapLong(sg->vmsize);
69: sg->fileoff = NXSwapLong(sg->fileoff);
70: sg->filesize = NXSwapLong(sg->filesize);
71: sg->maxprot = NXSwapLong(sg->maxprot);
72: sg->initprot = NXSwapLong(sg->initprot);
73: sg->nsects = NXSwapLong(sg->nsects);
74: sg->flags = NXSwapLong(sg->flags);
75: }
76:
77: void
78: swap_section(
79: struct section *s,
80: unsigned long nsects,
81: enum NXByteOrder target_byte_order)
82: {
83: unsigned long i;
84:
85: for(i = 0; i < nsects; i++){
86: /* sectname[16] */
87: /* segname[16] */
88: s[i].addr = NXSwapLong(s[i].addr);
89: s[i].size = NXSwapLong(s[i].size);
90: s[i].offset = NXSwapLong(s[i].offset);
91: s[i].align = NXSwapLong(s[i].align);
92: s[i].reloff = NXSwapLong(s[i].reloff);
93: s[i].nreloc = NXSwapLong(s[i].nreloc);
94: s[i].flags = NXSwapLong(s[i].flags);
95: s[i].reserved1 = NXSwapLong(s[i].reserved1);
96: s[i].reserved2 = NXSwapLong(s[i].reserved2);
97: }
98: }
99:
100: void
101: swap_symtab_command(
102: struct symtab_command *st,
103: enum NXByteOrder target_byte_order)
104: {
105: st->cmd = NXSwapLong(st->cmd);
106: st->cmdsize = NXSwapLong(st->cmdsize);
107: st->symoff = NXSwapLong(st->symoff);
108: st->nsyms = NXSwapLong(st->nsyms);
109: st->stroff = NXSwapLong(st->stroff);
110: st->strsize = NXSwapLong(st->strsize);
111: }
112:
113: void
114: swap_symseg_command(
115: struct symseg_command *ss,
116: enum NXByteOrder target_byte_order)
117: {
118: ss->cmd = NXSwapLong(ss->cmd);
119: ss->cmdsize = NXSwapLong(ss->cmdsize);
120: ss->offset = NXSwapLong(ss->offset);
121: ss->size = NXSwapLong(ss->size);
122: }
123:
124: /*
125: * For system call errors the error messages allways contains
126: * sys_errlist[errno] as part of the message.
127: */
128: extern char *sys_errlist[];
129: extern int errno;
130:
131: /* Name of this program for error messages (argv[0]) */
132: char *progname;
133:
134: extern void _sel_writeHashTable(
135: int start_addr,
136: char *myselectorstraddr,
137: char *shlibselectorstraddr,
138: void **stuff,
139: int *stuffsize
140: );
141:
142: /*
143: * Declarations for the static routines in this file.
144: */
145: static void usage();
146:
147: static Module get_objc(
148: long fd,
149: char *filename,
150: struct section *objcsects,
151: int nsects
152: );
153: static void print_method_list(
154: struct objc_method_list *mlist_before_reloc,
155: struct section *firstobjcsect,
156: int nsects
157: );
158: static void print_method_list2(
159: struct objc_method_description_list *mlist_before_reloc,
160: struct section *firstobjcsect,
161: int nsects
162: );
163: static void getObjcSections(
164: struct mach_header *mh,
165: struct load_command *lc,
166: struct section **objcsects,
167: int *nsects
168: );
169: static void readObjcData(
170: long fd,
171: char *filename,
172: struct section *objcsects,
173: int nsects
174: );
175: static void swapObjcData(
176: struct section *objcsects,
177: int nsects
178: );
179: static void swap_objc_modules(
180: struct objc_module *modules,
181: unsigned long size
182: );
183: static void swap_objc_symtabs(
184: struct objc_symtab *symtabs,
185: unsigned long size
186: );
187: static void swap_objc_classes(
188: struct objc_class *classes,
189: unsigned long size
190: );
191: static void swap_objc_categories(
192: struct objc_category *categories,
193: unsigned long size
194: );
195: static void swap_objc_method_lists(
196: struct objc_method_list *method_lists,
197: unsigned long size
198: );
199: static void swap_objc_protocols(
200: Protocol *protocols,
201: unsigned long size
202: );
203: static void swap_objc_ivar_lists(
204: struct objc_ivar_list *ivar_lists,
205: unsigned long size
206: );
207: static void swap_objc_protocol_lists(
208: struct objc_protocol_list *protocol_lists,
209: unsigned long size
210: );
211: static void swap_objc_refs(
212: unsigned long *refs,
213: unsigned long size
214: );
215: static void swap_string_objects(
216: NXConstantString *s,
217: unsigned long size
218: );
219: static void swap_objc_method_description_lists(
220: struct objc_method_description_list *mdls,
221: unsigned long size
222: );
223: struct _hashEntry {
224: struct _hashEntry *next;
225: char *sel;
226: };
227: static void swap_hashEntries(
228: struct _hashEntry *_hashEntries,
229: unsigned long size
230: );
231: static void *getObjcData(
232: struct section *objcsects,
233: int nsects,
234: const void *addr
235: );
236: static struct section *getObjcSection(
237: struct section *objcsects,
238: int nsects,
239: char *name
240: );
241:
242: int swapped = 0;
243:
244: void
245: main(argc, argv)
246: int argc;
247: char *argv[];
248: {
249: long fd;
250: char *filename;
251: struct mach_header mh;
252: struct load_command *lcp;
253:
254: progname = argv[0];
255:
256: if(argc == 1) {
257: fprintf(stderr, "%s: At least one file must be specified\n",
258: progname);
259: usage();
260: exit(1);
261: }
262: else if (argc == 2)
263: filename = argv[1];
264: else
265: {
266: usage();
267: exit(1);
268: }
269:
270: fd = open(filename, O_RDONLY);
271: if(fd < 0){
272: fprintf(stderr, "%s : Can't open %s (%s)\n", progname,
273: filename, sys_errlist[errno]);
274: }
275: lseek(fd, 0, 0);
276: if(read(fd, (char *)&mh, sizeof(mh)) != sizeof(mh)){
277: fprintf(stderr, "%s : Can't read mach header of %s (%s)\n",
278: progname, filename, sys_errlist[errno]);
279: return;
280: }
281: if(mh.magic == MH_MAGIC){
282: if((lcp = (struct load_command *)malloc(mh.sizeofcmds))
283: == (struct load_command *)0){
284: fprintf(stderr, "%s : Ran out of memory (%s)\n",
285: progname, sys_errlist[errno]);
286: exit(1);
287: }
288: if(read(fd, (char *)lcp, mh.sizeofcmds) != mh.sizeofcmds){
289: fprintf(stderr,"%s : Can't read load commands of %s (%s)\n",
290: progname, filename, sys_errlist[errno]);
291: lcp = (struct load_command *)0;
292: }
293: }
294: else if(mh.magic == NXSwapLong(MH_MAGIC)){
295: if((lcp = (struct load_command *)
296: malloc(NXSwapLong(mh.sizeofcmds)))
297: == (struct load_command *)0){
298: fprintf(stderr, "%s : Ran out of memory (%s)\n",
299: progname, sys_errlist[errno]);
300: exit(1);
301: }
302: if(read(fd, (char *)lcp, NXSwapLong(mh.sizeofcmds)) !=
303: NXSwapLong(mh.sizeofcmds)){
304: fprintf(stderr,"%s : Can't read load commands of %s (%s)\n",
305: progname, filename, sys_errlist[errno]);
306: lcp = (struct load_command *)0;
307: }
308: }
309:
310: {
311: struct section *firstobjcsect;
312: int nsects, size;
313: long vm_hashaddr;
314: void *table;
315: struct section *sel, *tmp;
316: char *selectors, tempfilename[] = "objcoptXXXXXX";
317:
318: getObjcSections(&mh, lcp, &firstobjcsect, &nsects);
319: get_objc(fd, filename, firstobjcsect, nsects);
320:
321: if (strcmp(firstobjcsect[nsects-1].sectname, "__runtime_setup") == 0)
322: // we are doing a `replace'
323: vm_hashaddr = firstobjcsect[nsects-1].addr;
324: else
325: vm_hashaddr = round(firstobjcsect[nsects-1].addr +
326: firstobjcsect[nsects-1].size, sizeof(long));
327:
328: sel = getObjcSection(firstobjcsect, nsects, "__meth_var_names");
329:
330: tmp = getObjcSection(firstobjcsect, nsects, "__selector_strs");
331:
332: if (sel && tmp)
333: {
334: fprintf (stderr,
335: "Cannot objcopt mixture of new and old strings\n");
336: exit (1);
337: }
338:
339: if (!sel)
340: sel = tmp; // Use old-style strings
341:
342: selectors = (char *)sel->reserved1;
343:
344: _sel_writeHashTable(vm_hashaddr, (char *)selectors, (char *)sel->addr,
345: &table, &size);
346: if(swapped)
347: swap_hashEntries((struct _hashEntry *)table, size);
348:
349: mktemp(tempfilename);
350: add_objc_runtime_setup(filename,tempfilename,table, size);
351:
352: close(fd);
353: unlink(filename);
354: if (rename(tempfilename, filename) == -1) {
355: fprintf(stderr, "%s : Cannot rename temporary file from: "
356: "%s to %s\n", progname, tempfilename, filename);
357: exit(1);
358: }
359: }
360:
361: exit(0);
362: }
363:
364: static void getObjcSections(
365: struct mach_header *mh,
366: struct load_command *lc,
367: struct section **objcsects,
368: int *nsects
369: )
370: {
371: int i,j;
372: struct segment_command *sg;
373: struct section *s;
374: struct load_command l, *initlc;
375:
376: swapped = mh->magic == NXSwapLong(MH_MAGIC);
377: if(swapped)
378: swap_mach_header(mh, NXHostByteOrder());
379: initlc = lc;
380:
381: for(i = 0 ; i < mh->ncmds; i++){
382: l = *lc;
383: if(swapped)
384: swap_load_command(&l, NXHostByteOrder());
385: if(l.cmdsize % sizeof(long) != 0)
386: printf("load command %d size not a multiple of sizeof(long)\n",
387: i);
388: if((char *)lc + l.cmdsize > (char *)initlc + mh->sizeofcmds)
389: printf("load command %d extends past end of load commands\n",i);
390: if(l.cmd == LC_SEGMENT){
391: sg = (struct segment_command *)lc;
392: if(swapped)
393: swap_segment_command(sg, NXHostByteOrder());
394: if(mh->filetype == MH_OBJECT ||
395: strcmp(sg->segname, SEG_OBJC) == 0){
396:
397: s = (struct section *)
398: ((char *)sg + sizeof(struct segment_command));
399:
400: *objcsects = s;
401: *nsects = sg->nsects;
402:
403: for(j = 0 ; j < sg->nsects ; j++){
404: if(swapped)
405: swap_section(s, 1, NXHostByteOrder());
406: if((char *)s + sizeof(struct section) >
407: (char *)initlc + mh->sizeofcmds){
408: printf("section structure command extends past end "
409: "of load commands\n");
410: }
411: if((char *)s + sizeof(struct section) >
412: (char *)initlc + mh->sizeofcmds)
413: break;
414: s++;
415: }
416: }
417: }
418: if(l.cmdsize <= 0){
419: printf("load command %d size negative or zero (can't "
420: "advance to other load commands)\n", i);
421: break;
422: }
423: lc = (struct load_command *)((char *)lc + l.cmdsize);
424: if((char *)lc > (char *)initlc + mh->sizeofcmds)
425: break;
426: }
427: if((char *)initlc + mh->sizeofcmds != (char *)lc)
428: printf("Inconsistant mh_sizeofcmds\n");
429: }
430:
431: static void readObjcData(
432: long fd,
433: char *filename,
434: struct section *objcsects,
435: int nsects
436: )
437: {
438: int i;
439:
440: for (i = 0; i < nsects; i++) {
441:
442: struct section *s;
443:
444: s = objcsects + i;
445:
446: if (s->size > 0) {
447: if((s->reserved1 = (long)malloc(s->size)) == 0) {
448: fprintf(stderr, "%s : Ran out of memory (%s)\n",
449: progname, sys_errlist[errno]);
450: exit(1);
451: }
452: lseek(fd, s->offset, 0);
453: if((read(fd, s->reserved1, s->size)) != s->size){
454: fprintf(stderr, "%s : Can't read modules of %s (%s)\n",
455: progname, filename, sys_errlist[errno]);
456: free((void *)s->reserved1);
457: return;
458: }
459: }
460: }
461: }
462:
463: struct objc_protocol
464: {
465: @defs(Protocol)
466: };
467:
468: struct objc_string_object
469: {
470: @defs(NXConstantString)
471: };
472:
473: static void swapObjcData(
474: struct section *objcsects,
475: int nsects
476: )
477: {
478: int i, categories_size = 0, protocols_size = 0;
479: struct objc_category *categories = NULL;
480: struct objc_protocol *protocols = NULL;
481: struct section *s, *cat_inst = NULL, *cat_cls = NULL;
482: struct objc_method_list *method_list;
483: struct objc_protocol_list *protocol_list;
484: struct objc_method_description_list *mdl;
485:
486: for (i = 0; i < nsects; i++) {
487:
488: s = objcsects + i;
489: if(strncmp(s->sectname, "__class", 16) == 0 ||
490: strncmp(s->sectname, "__meta_class", 16) == 0){
491: swap_objc_classes((struct objc_class *)s->reserved1,
492: s->size);
493: }
494: else if(strncmp(s->sectname, "__string_object", 16) == 0){
495: swap_string_objects((NXConstantString *)s->reserved1,
496: s->size);
497: }
498: else if(strncmp(s->sectname, "__protocol", 16) == 0){
499: protocols = (struct objc_protocol *)s->reserved1;
500: protocols_size = s->size;
501: swap_objc_protocols((Protocol *)s->reserved1,
502: s->size);
503: }
504: else if(strncmp(s->sectname, "__cat_cls_meth", 16) == 0){
505: /* handled special below */
506: cat_cls = s;
507: }
508: else if(strncmp(s->sectname, "__cat_inst_meth", 16) == 0){
509: /* handled special below */
510: cat_inst = s;
511: }
512: else if(strncmp(s->sectname, "__cls_meth", 16) == 0 ||
513: strncmp(s->sectname, "__inst_meth", 16) == 0){
514: swap_objc_method_lists((struct objc_method_list *)
515: s->reserved1, s->size);
516: }
517: else if(strncmp(s->sectname, "__message_refs", 16) == 0 ||
518: strncmp(s->sectname, "__selector_refs", 16) == 0 ||
519: strncmp(s->sectname, "__cls_refs", 16) == 0){
520: swap_objc_refs((unsigned long *)s->reserved1, s->size);
521: }
522: else if(strncmp(s->sectname, "__class_names", 16) == 0 ||
523: strncmp(s->sectname, "__meth_var_names", 16) == 0 ||
524: strncmp(s->sectname, "__meth_var_types", 16) == 0 ||
525: strncmp(s->sectname, "__selector_strs", 16) == 0){
526: ; /* character strings, no swapping */
527: }
528: else if(strncmp(s->sectname, "__module_info", 16) == 0){
529: swap_objc_modules((struct objc_module *)s->reserved1,
530: s->size);
531: }
532: else if(strncmp(s->sectname, "__symbols", 16) == 0){
533: swap_objc_symtabs((struct objc_symtab *)s->reserved1,
534: s->size);
535: }
536: else if(strncmp(s->sectname, "__category", 16) == 0){
537: categories = (struct objc_category *)s->reserved1;
538: categories_size = s->size;
539: swap_objc_categories((struct objc_category *)s->reserved1,
540: s->size);
541: }
542: else if(strncmp(s->sectname, "__class_vars", 16) == 0 ||
543: strncmp(s->sectname, "__instance_vars", 16) == 0){
544: swap_objc_ivar_lists((struct objc_ivar_list *)s->reserved1,
545: s->size);
546: }
547: else if(strncmp(s->sectname, "__runtime_setup", 16) == 0){
548: ; /* do nothing it will be tossed */
549: }
550: else if(strncmp(s->sectname, "__cstring_object", 16)) {
551: ; /* do nothing */
552: }
553: else if(strncmp(s->sectname, "__sel_fixup", 16)) {
554: ; /* do nothing */
555: }
556: else{
557: fprintf(stderr, "%s : unknown __OBJC section: %s\n",
558: progname, s->sectname);
559: exit(1);
560: }
561: }
562:
563: for (i = 0; i < categories_size; i += sizeof(struct objc_category)){
564: if(categories->instance_methods != 0){
565: method_list = (struct objc_method_list *)
566: (cat_inst->reserved1 +
567: ((unsigned long)categories->instance_methods -
568: (unsigned long)cat_inst->addr));
569: swap_objc_method_lists(method_list,
570: sizeof(struct objc_method_list) -
571: sizeof(struct objc_method));
572: }
573:
574: if(categories->class_methods != 0){
575: method_list = (struct objc_method_list *)
576: (cat_cls->reserved1 +
577: ((unsigned long)categories->class_methods -
578: (unsigned long)cat_cls->addr));
579: swap_objc_method_lists(method_list,
580: sizeof(struct objc_method_list) -
581: sizeof(struct objc_method));
582: }
583:
584: if(categories->protocols != 0){
585: protocol_list = (struct objc_protocol_list *)
586: (cat_cls->reserved1 +
587: ((unsigned long)categories->protocols -
588: (unsigned long)cat_cls->addr));
589: swap_objc_protocol_lists(protocol_list,
590: sizeof(struct objc_protocol_list) -
591: sizeof(struct objc_protocol *));
592: }
593: categories++;
594: }
595: for (i = 0; i < protocols_size; i += sizeof(struct objc_protocol)){
596: if(protocols->instance_methods != 0){
597: mdl = (struct objc_method_description_list *)
598: (cat_inst->reserved1 +
599: ((unsigned long)protocols->instance_methods -
600: (unsigned long)cat_inst->addr));
601: swap_objc_method_description_lists(mdl,
602: sizeof(struct objc_method_description_list) -
603: sizeof(struct objc_method_description));
604: }
605:
606: if(protocols->class_methods != 0){
607: mdl = (struct objc_method_description_list *)
608: (cat_cls->reserved1 +
609: ((unsigned long)protocols->class_methods -
610: (unsigned long)cat_cls->addr));
611: swap_objc_method_description_lists(mdl,
612: sizeof(struct objc_method_description_list) -
613: sizeof(struct objc_method_description));
614: }
615: protocols++;
616: }
617: }
618:
619: static
620: void
621: swap_objc_module(
622: struct objc_module *module,
623: enum NXByteOrder target_byte_order)
624: {
625: module->version = NXSwapLong(module->version);
626: module->size = NXSwapLong(module->size);
627: module->name = (char *) NXSwapLong((long)module->name);
628: module->symtab = (Symtab) NXSwapLong((long)module->symtab);
629: }
630:
631: static
632: void
633: swap_objc_symtab(
634: struct objc_symtab *symtab,
635: enum NXByteOrder target_byte_order)
636: {
637: symtab->sel_ref_cnt = NXSwapLong(symtab->sel_ref_cnt);
638: symtab->refs = (SEL *) NXSwapLong((long)symtab->refs);
639: symtab->cls_def_cnt = NXSwapShort(symtab->cls_def_cnt);
640: symtab->cat_def_cnt = NXSwapShort(symtab->cat_def_cnt);
641: }
642:
643: static
644: void
645: swap_objc_class(
646: struct objc_class *objc_class,
647: enum NXByteOrder target_byte_order)
648: {
649: objc_class->isa = (struct objc_class *)
650: NXSwapLong((long)objc_class->isa);
651: objc_class->super_class = (struct objc_class *)
652: NXSwapLong((long)objc_class->super_class);
653: objc_class->name = (const char *)
654: NXSwapLong((long)objc_class->name);
655: objc_class->version =
656: NXSwapLong(objc_class->version);
657: objc_class->info =
658: NXSwapLong(objc_class->info);
659: objc_class->instance_size =
660: NXSwapLong(objc_class->instance_size);
661: objc_class->ivars = (struct objc_ivar_list *)
662: NXSwapLong((long)objc_class->ivars);
663: objc_class->methods = (struct objc_method_list *)
664: NXSwapLong((long)objc_class->methods);
665: objc_class->cache = (struct objc_cache *)
666: NXSwapLong((long)objc_class->cache);
667: objc_class->protocols = (struct objc_protocol_list *)
668: NXSwapLong((long)objc_class->protocols);
669: }
670:
671: static
672: void
673: swap_objc_category(
674: struct objc_category *objc_category,
675: enum NXByteOrder target_byte_order)
676: {
677: objc_category->category_name = (char *)
678: NXSwapLong((long)objc_category->category_name);
679: objc_category->class_name = (char *)
680: NXSwapLong((long)objc_category->class_name);
681: objc_category->instance_methods = (struct objc_method_list *)
682: NXSwapLong((long)objc_category->instance_methods);
683: objc_category->class_methods = (struct objc_method_list *)
684: NXSwapLong((long)objc_category->class_methods);
685: objc_category->protocols = (struct objc_protocol_list *)
686: NXSwapLong((long)objc_category->protocols);
687: }
688:
689: static
690: void
691: swap_objc_ivar_list(
692: struct objc_ivar_list *objc_ivar_list,
693: enum NXByteOrder target_byte_order)
694: {
695: objc_ivar_list->ivar_count = NXSwapLong(objc_ivar_list->ivar_count);
696: }
697:
698: static
699: void
700: swap_objc_ivar(
701: struct objc_ivar *objc_ivar,
702: enum NXByteOrder target_byte_order)
703: {
704: objc_ivar->ivar_name = (char *)
705: NXSwapLong((long)objc_ivar->ivar_name);
706: objc_ivar->ivar_type = (char *)
707: NXSwapLong((long)objc_ivar->ivar_type);
708: objc_ivar->ivar_offset =
709: NXSwapLong(objc_ivar->ivar_offset);
710: }
711:
712: static
713: void
714: swap_objc_method_list(
715: struct objc_method_list *method_list,
716: enum NXByteOrder target_byte_order)
717: {
718: method_list->method_next = (struct objc_method_list *)
719: NXSwapLong((long)method_list->method_next);
720: method_list->method_count =
721: NXSwapLong(method_list->method_count);
722: }
723:
724: static
725: void
726: swap_objc_method(
727: struct objc_method *method,
728: enum NXByteOrder target_byte_order)
729: {
730: method->method_name = (SEL)
731: NXSwapLong((long)method->method_name);
732: method->method_types = (char *)
733: NXSwapLong((long)method->method_types);
734: method->method_imp = (IMP)
735: NXSwapLong((long)method->method_imp);
736: }
737:
738: static
739: void
740: swap_objc_protocol_list(
741: struct objc_protocol_list *protocol_list,
742: enum NXByteOrder target_byte_order)
743: {
744: protocol_list->next = (struct objc_protocol_list *)
745: NXSwapLong((long)protocol_list->next);
746: protocol_list->count =
747: NXSwapLong(protocol_list->count);
748: }
749:
750: static
751: void
752: swap_objc_protocol(
753: Protocol *p,
754: enum NXByteOrder target_byte_order)
755: {
756: struct objc_protocol *protocol;
757:
758: protocol = (struct objc_protocol *)p;
759:
760: protocol->isa = (struct objc_class *)
761: NXSwapLong((long)protocol->isa);
762: protocol->protocol_name = (char *)
763: NXSwapLong((long)protocol->protocol_name);
764: protocol->protocol_list = (struct objc_protocol_list *)
765: NXSwapLong((long)protocol->protocol_list);
766: protocol->instance_methods = (struct objc_method_description_list *)
767: NXSwapLong((long)protocol->instance_methods);
768: protocol->class_methods = (struct objc_method_description_list *)
769: NXSwapLong((long)protocol->class_methods);
770:
771: }
772:
773: static
774: void
775: swap_objc_method_description_list(
776: struct objc_method_description_list *mdl,
777: enum NXByteOrder target_byte_order)
778: {
779: mdl->count = NXSwapLong(mdl->count);
780: }
781:
782: static
783: void
784: swap_objc_method_description(
785: struct objc_method_description *md,
786: enum NXByteOrder target_byte_order)
787: {
788: md->name = (SEL)NXSwapLong((long)md->name);
789: md->types = (char *)NXSwapLong((long)md->types);
790: }
791:
792: void
793: swap_string_object(
794: NXConstantString *p,
795: enum NXByteOrder target_byte_order)
796: {
797: struct objc_string_object *string_object;
798:
799: string_object = (struct objc_string_object *)p;
800:
801: string_object->isa = (struct objc_class *)
802: NXSwapLong((long)string_object->isa);
803: string_object->characters = (char *)
804: NXSwapLong((long)string_object->characters);
805: string_object->_length =
806: NXSwapLong(string_object->_length);
807: }
808:
809: static
810: void
811: swap_hashEntry(
812: struct _hashEntry *_hashEntry,
813: enum NXByteOrder target_byte_order)
814: {
815: _hashEntry->next = (struct _hashEntry *)
816: NXSwapLong((long)_hashEntry->next);
817: _hashEntry->sel = (char *)
818: NXSwapLong((long)_hashEntry->sel);
819: }
820:
821: static void swap_objc_modules(
822: struct objc_module *modules,
823: unsigned long size
824: )
825: {
826: int i, j;
827:
828: for (i = 0, j = 0; i < size; i += sizeof(struct objc_module), j++)
829: swap_objc_module(modules + j, NXHostByteOrder());
830: }
831:
832: static void swap_objc_symtabs(
833: struct objc_symtab *symtabs,
834: unsigned long size
835: )
836: {
837: int i, j;
838: struct objc_symtab *symtab;
839:
840: symtab = symtabs;
841: while ((unsigned long)symtab - (unsigned long)symtabs < size){
842: swap_objc_symtab(symtab, NXHostByteOrder());
843: for(j = 0; j < symtab->cls_def_cnt; j++){
844: symtab->defs[j] = (struct objc_class *)
845: NXSwapLong((long)symtab->defs[j]);
846: }
847: for(j = 0; j < symtab->cat_def_cnt; j++){
848: symtab->defs[j + symtab->cls_def_cnt] =
849: (struct objc_class *)
850: NXSwapLong((long)symtab->defs[j + symtab->cls_def_cnt]);
851: }
852: symtab = (struct objc_symtab *)
853: (&(symtab->defs[symtab->cls_def_cnt +
854: symtab->cat_def_cnt]));
855: }
856: }
857:
858: static void swap_objc_classes(
859: struct objc_class *classes,
860: unsigned long size
861: )
862: {
863: int i, j;
864:
865: for (i = 0, j = 0; i < size; i += sizeof(struct objc_class), j++)
866: swap_objc_class(classes + j, NXHostByteOrder());
867: }
868:
869: static void swap_objc_categories(
870: struct objc_category *categories,
871: unsigned long size
872: )
873: {
874: int i, j;
875:
876: for (i = 0, j = 0; i < size; i += sizeof(struct objc_category), j++)
877: swap_objc_category(categories + j, NXHostByteOrder());
878: }
879:
880: static void swap_objc_method_lists(
881: struct objc_method_list *method_lists,
882: unsigned long size
883: )
884: {
885: int i, j;
886: struct objc_method_list *method_list;
887:
888: method_list = method_lists;
889: while ((unsigned long)method_list - (unsigned long)method_lists < size){
890: swap_objc_method_list(method_list, NXHostByteOrder());
891: for (j = 0; j < method_list->method_count; j++){
892: swap_objc_method(&(method_list->method_list[j]),
893: NXHostByteOrder());
894: }
895: method_list = (struct objc_method_list *)
896: (&(method_list->method_list[method_list->method_count]));
897: }
898: }
899:
900: static void swap_objc_protocols(
901: Protocol *protocols,
902: unsigned long size
903: )
904: {
905: int i, j;
906:
907: for (i = 0, j = 0; i < size; i += sizeof(struct objc_protocol), j++)
908: swap_objc_protocol(protocols + j, NXHostByteOrder());
909: }
910:
911: static void swap_objc_ivar_lists(
912: struct objc_ivar_list *ivar_lists,
913: unsigned long size
914: )
915: {
916: int i, j;
917: struct objc_ivar_list *ivar_list;
918:
919: ivar_list = ivar_lists;
920: while ((unsigned long)ivar_list - (unsigned long)ivar_lists < size){
921: swap_objc_ivar_list(ivar_list, NXHostByteOrder());
922: for (j = 0; j < ivar_list->ivar_count; j++){
923: swap_objc_ivar(&(ivar_list->ivar_list[j]),
924: NXHostByteOrder());
925: }
926: ivar_list = (struct objc_ivar_list *)
927: (&(ivar_list->ivar_list[ivar_list->ivar_count]));
928: }
929: }
930:
931: static void swap_objc_protocol_lists(
932: struct objc_protocol_list *protocol_lists,
933: unsigned long size
934: )
935: {
936: int i, j;
937: struct objc_protocol_list *protocol_list;
938:
939: protocol_list = protocol_lists;
940: while ((unsigned long)protocol_list -
941: (unsigned long)protocol_lists < size){
942: swap_objc_protocol_list(protocol_list, NXHostByteOrder());
943: for (j = 0; j < protocol_list->count; j++){
944: protocol_list->list[j] = (Protocol *)
945: NXSwapLong((long)(protocol_list->list[j]));
946: }
947: protocol_list = (struct objc_protocol_list *)
948: (&(protocol_list->list[protocol_list->count]));
949: }
950: }
951:
952: static void swap_objc_method_description_lists(
953: struct objc_method_description_list *mdls,
954: unsigned long size
955: )
956: {
957: int i, j;
958: struct objc_method_description_list *mdl;
959:
960: mdl = mdls;
961: while ((unsigned long)mdl - (unsigned long)mdls < size){
962: swap_objc_method_description_list(mdl, NXHostByteOrder());
963: for (j = 0; j < mdl->count; j++){
964: swap_objc_method_description( &(mdl->list[j]),
965: NXHostByteOrder());
966: }
967: mdl = (struct objc_method_description_list *)
968: (&(mdl->list[mdl->count]));
969: }
970: }
971:
972: static void *getObjcData(
973: struct section *objcsects,
974: int nsects,
975: const void *addr
976: )
977: {
978: int i;
979:
980: if (addr == 0)
981: return 0;
982:
983: for (i = 0; i < nsects; i++) {
984: struct section *s;
985:
986: s = objcsects + i;
987: if (((long)addr >= s->addr) &&
988: ((long)addr < (s->addr + s->size)))
989: return (void *)(s->reserved1 + ((long)addr - s->addr));
990: }
991: fprintf(stderr, "%s : Could not `getObjcData'\n", progname);
992: exit(1);
993: }
994:
995: static void swap_objc_refs(
996: unsigned long *refs,
997: unsigned long size
998: )
999: {
1000: int i,j;
1001:
1002: for (i = 0, j = 0; i < size; i += sizeof(unsigned long), j++)
1003: refs[j] = NXSwapLong(refs[j]);
1004: }
1005:
1006: static struct section *getObjcSection(
1007: struct section *objcsects,
1008: int nsects,
1009: char *name
1010: )
1011: {
1012: int i;
1013:
1014: for (i = 0; i < nsects; i++) {
1015: struct section *s;
1016:
1017: s = objcsects + i;
1018: if (strncmp(s->sectname,name,16) == 0)
1019: return s;
1020: }
1021: return 0;
1022: }
1023:
1024: static void swap_string_objects(
1025: NXConstantString *s,
1026: unsigned long size
1027: )
1028: {
1029: int i, j;
1030:
1031: for (i = 0, j = 0; i < size; i += sizeof(struct objc_string_object), j++)
1032: swap_string_object(s + j, NXHostByteOrder());
1033: }
1034:
1035: static void swap_hashEntries(
1036: struct _hashEntry *_hashEntries,
1037: unsigned long size
1038: )
1039: {
1040: int i, j;
1041: enum NXByteOrder target_byte_order;
1042:
1043: target_byte_order = NXHostByteOrder() == NX_BigEndian ?
1044: NX_LittleEndian : NX_BigEndian;
1045:
1046: for (i = 0, j = 0; i < size; i += sizeof(struct _hashEntry), j++)
1047: swap_hashEntry(_hashEntries + j, target_byte_order);
1048: }
1049:
1050: /*
1051: * Print the objc segment.
1052: */
1053: static
1054: struct objc_module *
1055: get_objc(fd, filename, firstobjcsect, nsects)
1056: long fd;
1057: char *filename;
1058: struct section *firstobjcsect;
1059: int nsects;
1060: {
1061: long i, j;
1062: struct section *modsect, *msgsect, *selsect, *protosect;
1063: struct objc_module *modules, *m;
1064: struct objc_symtab *t;
1065:
1066: readObjcData(fd, filename, firstobjcsect, nsects);
1067: if(swapped)
1068: swapObjcData(firstobjcsect, nsects);
1069:
1070: modsect = getObjcSection(firstobjcsect, nsects, "__module_info");
1071: msgsect = getObjcSection(firstobjcsect, nsects, "__message_refs");
1072: if (msgsect) {
1073: int i, cnt = msgsect->size/sizeof(SEL);
1074: SEL *sels = (SEL *)msgsect->reserved1;
1075:
1076: /* overwrite the string with a unique identifier */
1077: for (i = 0; i < cnt; i++)
1078: sels[i] = (SEL)sel_registerName(
1079: getObjcData(firstobjcsect, nsects,
1080: sels[i]));
1081: }
1082: selsect = getObjcSection(firstobjcsect, nsects, "__selector_refs");
1083: if (selsect) {
1084: int i, cnt = selsect->size/sizeof(SEL);
1085: SEL *sels = (SEL *)selsect->reserved1;
1086:
1087: /* overwrite the string with a unique identifier */
1088: for (i = 0; i < cnt; i++)
1089: sels[i] = (SEL)sel_registerName(
1090: getObjcData(firstobjcsect, nsects,
1091: sels[i]));
1092: }
1093: modules = (Module)modsect->reserved1;
1094:
1095: for(m = modules ;
1096: (char *)m < (char *)modules + modsect->size;
1097: m = (struct objc_module *)((char *)m + m->size) ){
1098:
1099: /* relocate fields in module structure */
1100:
1101: m->name = (char *)getObjcData(firstobjcsect, nsects,
1102: m->name);
1103: m->symtab = t = (Symtab)getObjcData(firstobjcsect, nsects,
1104: m->symtab);
1105:
1106: if (t) {
1107:
1108: /* Simulate map! */
1109: if (m->version == 1) {
1110: int i, cnt = m->symtab->sel_ref_cnt;
1111: SEL *sels = (SEL *)getObjcData(firstobjcsect, nsects,
1112: m->symtab->refs);
1113:
1114: /* overwrite the string with a unique identifier */
1115: for (i = 0; i < cnt; i++)
1116: sels[i] = (SEL)sel_registerName(
1117: getObjcData(firstobjcsect, nsects,
1118: sels[i]));
1119: }
1120:
1121: for(i = 0; i < t->cls_def_cnt; i++){
1122:
1123: struct objc_class *objc_class;
1124:
1125: t->defs[i] = objc_class =
1126: (Class)getObjcData(firstobjcsect, nsects,
1127: t->defs[i]);
1128: print_objc_class:
1129: /* relocate class structure */
1130:
1131: if(CLS_GETINFO(objc_class, CLS_META)){
1132: objc_class->isa = (Class)getObjcData(
1133: firstobjcsect, nsects, objc_class->isa);
1134: }
1135:
1136: objc_class->super_class = (Class)getObjcData(
1137: firstobjcsect, nsects,
1138: objc_class->super_class);
1139:
1140: objc_class->name = (char *)getObjcData(
1141: firstobjcsect, nsects,
1142: objc_class->name);
1143:
1144: if (objc_class->ivars) {
1145: struct objc_ivar_list *ilist;
1146: struct objc_ivar *ivar;
1147:
1148: objc_class->ivars = ilist =
1149: (struct objc_ivar_list *)getObjcData(
1150: firstobjcsect, nsects,
1151: objc_class->ivars);
1152:
1153: ivar = ilist->ivar_list;
1154: for(j = 0; j < ilist->ivar_count; j++, ivar++){
1155: ivar->ivar_name= (char *)getObjcData(
1156: firstobjcsect, nsects,
1157: ivar->ivar_name);
1158:
1159: ivar->ivar_type= (char *)getObjcData(
1160: firstobjcsect, nsects,
1161: ivar->ivar_type);
1162: }
1163: }
1164:
1165: if (objc_class->methods) {
1166: print_method_list(objc_class->methods,
1167: firstobjcsect, nsects);
1168: }
1169:
1170: if(CLS_GETINFO(objc_class, CLS_CLASS)){
1171: objc_class->isa = objc_class =
1172: (Class)getObjcData(
1173: firstobjcsect, nsects,
1174: objc_class->isa);
1175: goto print_objc_class;
1176: }
1177: }
1178:
1179: for(i = 0; i < t->cat_def_cnt; i++){
1180:
1181: struct objc_category *objc_category;
1182:
1183: t->defs[i + t->cls_def_cnt] = objc_category =
1184: (Category)getObjcData(firstobjcsect, nsects,
1185: t->defs[i+t->cls_def_cnt]);
1186:
1187: objc_category->category_name = (char *)getObjcData(
1188: firstobjcsect, nsects,
1189: objc_category->category_name);
1190:
1191: objc_category->class_name = (char *)getObjcData(
1192: firstobjcsect, nsects,
1193: objc_category->class_name);
1194:
1195: if (objc_category->instance_methods) {
1196: print_method_list(objc_category->instance_methods,
1197: firstobjcsect, nsects);
1198: }
1199:
1200: if (objc_category->class_methods) {
1201: print_method_list(objc_category->class_methods,
1202: firstobjcsect, nsects);
1203: }
1204: }
1205: }
1206: }
1207: protosect = getObjcSection(firstobjcsect, nsects, "__protocol");
1208: if (protosect) {
1209: int i, cnt = protosect->size/sizeof(Protocol);
1210: struct proto_template { @defs(Protocol) } *protos;
1211:
1212: protos = (struct proto_template *) protosect->reserved1;
1213:
1214: for (i = 0; i < cnt; i++)
1215: {
1216: if (protos[i].instance_methods) {
1217: print_method_list2(protos[i].instance_methods,
1218: firstobjcsect, nsects);
1219: }
1220:
1221: if (protos[i].class_methods) {
1222: print_method_list2(protos[i].class_methods,
1223: firstobjcsect, nsects);
1224: }
1225: }
1226: }
1227: return modules;
1228: }
1229:
1230: static
1231: void
1232: print_method_list(struct objc_method_list *mlist_before_reloc,
1233: struct section *firstobjcsect,
1234: int nsects)
1235: {
1236: long i;
1237: struct objc_method *method;
1238: struct objc_method_list *mlist;
1239:
1240: mlist = (struct objc_method_list *)getObjcData(firstobjcsect, nsects,
1241: mlist_before_reloc);
1242: method = mlist->method_list;
1243: for(i = 0; i < mlist->method_count; i++, method++){
1244:
1245: method->method_name = (SEL)getObjcData(firstobjcsect, nsects,
1246: method->method_name);
1247:
1248: method->method_types = (char *)getObjcData(firstobjcsect, nsects,
1249: method->method_types);
1250:
1251: method->method_name =
1252: (SEL)sel_registerName((STR)method->method_name);
1253:
1254: }
1255: }
1256:
1257: static
1258: void
1259: print_method_list2(struct objc_method_description_list *mlist_before_reloc,
1260: struct section *firstobjcsect,
1261: int nsects)
1262: {
1263: long i;
1264: struct objc_method_description *method;
1265: struct objc_method_description_list *mlist;
1266:
1267: mlist = (struct objc_method_description_list *)getObjcData(firstobjcsect, nsects,
1268: mlist_before_reloc);
1269: method = mlist->list;
1270: for(i = 0; i < mlist->count; i++, method++){
1271:
1272: method->name = (SEL)getObjcData(firstobjcsect, nsects,
1273: method->name);
1274: method->name =
1275: (SEL)sel_registerName((STR)method->name);
1276:
1277: }
1278: }
1279:
1280: /*
1281: * Print the current usage message.
1282: */
1283: static
1284: void
1285: usage()
1286: {
1287: fprintf(stderr,
1288: "Usage: %s <shlib file>\n",
1289: progname);
1290: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.