]> git.saurik.com Git - apple/objc4.git/blame - runtime/objc-file.m
objc4-267.1.tar.gz
[apple/objc4.git] / runtime / objc-file.m
CommitLineData
13d88034
A
1/*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
390d5862
A
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
13d88034
A
14 *
15 * The Original Code and all software distributed under the License are
390d5862 16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
13d88034
A
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
390d5862
A
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
13d88034
A
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25// Copyright 1988-1996 NeXT Software, Inc.
26
13d88034
A
27#import "objc-private.h"
28#import <mach-o/ldsyms.h>
29#import <mach-o/dyld.h>
2bfd4448 30#import <mach-o/getsect.h>
13d88034
A
31#include <string.h>
32#include <stdlib.h>
33
34#import <crt_externs.h>
35
13d88034
A
36
37/* Returns an array of all the objc headers in the executable
38 * Caller is responsible for freeing.
39 */
40headerType **_getObjcHeaders()
41{
42 const struct mach_header **headers;
43 headers = malloc(sizeof(struct mach_header *) * 2);
44 headers[0] = (const struct mach_header *)_NSGetMachExecuteHeader();
45 headers[1] = 0;
46 return (headerType**)headers;
47}
48
2bfd4448 49Module _getObjcModules(const headerType *head, int *nmodules)
13d88034 50{
2bfd4448 51 uint32_t size;
13d88034
A
52 void *mods = getsectdatafromheader((headerType *)head,
53 SEG_OBJC,
54 SECT_OBJC_MODULES,
55 &size);
56 *nmodules = size / sizeof(struct objc_module);
57 return (Module)mods;
58}
59
60SEL *_getObjcMessageRefs(headerType *head, int *nmess)
61{
2bfd4448 62 uint32_t size;
13d88034
A
63 void *refs = getsectdatafromheader ((headerType *)head,
64 SEG_OBJC, "__message_refs", &size);
65 *nmess = size / sizeof(SEL);
66 return (SEL *)refs;
67}
68
69ProtocolTemplate *_getObjcProtocols(headerType *head, int *nprotos)
70{
2bfd4448 71 uint32_t size;
13d88034
A
72 void *protos = getsectdatafromheader ((headerType *)head,
73 SEG_OBJC, "__protocol", &size);
74 *nprotos = size / sizeof(ProtocolTemplate);
75 return (ProtocolTemplate *)protos;
76}
77
78NXConstantStringTemplate *_getObjcStringObjects(headerType *head, int *nstrs)
79{
80 *nstrs = 0;
81 return NULL;
82}
83
84Class *_getObjcClassRefs(headerType *head, int *nclasses)
85{
2bfd4448 86 uint32_t size;
13d88034
A
87 void *classes = getsectdatafromheader ((headerType *)head,
88 SEG_OBJC, "__cls_refs", &size);
89 *nclasses = size / sizeof(Class);
90 return (Class *)classes;
91}
92
2bfd4448 93objc_image_info *_getObjcImageInfo(const headerType *head, uint32_t *sizep)
390d5862 94{
2bfd4448
A
95 objc_image_info *info = (objc_image_info *)
96 getsectdatafromheader(head, SEG_OBJC, "__image_info", sizep);
97 return info;
390d5862
A
98}
99
2bfd4448
A
100const struct segment_command *getsegbynamefromheader(const headerType *head,
101 const char *segname)
13d88034 102{
2bfd4448
A
103 const struct segment_command *sgp;
104 unsigned long i;
105
106 sgp = (const struct segment_command *) ((char *)head + sizeof(headerType));
107 for (i = 0; i < head->ncmds; i++){
108 if (sgp->cmd == LC_SEGMENT) {
109 if (strncmp(sgp->segname, segname, sizeof(sgp->segname)) == 0) {
110 return sgp;
111 }
112 }
113 sgp = (const struct segment_command *)((char *)sgp + sgp->cmdsize);
114 }
115 return NULL;
13d88034
A
116}
117
118static const headerType *_getExecHeader (void)
119{
120 return (const struct mach_header *)_NSGetMachExecuteHeader();
121}
122
2bfd4448 123const char *_getObjcHeaderName(const headerType *header)
13d88034
A
124{
125 const headerType *execHeader;
126 const struct fvmlib_command *libCmd, *endOfCmds;
13d88034
A
127
128 if (header && ((headerType *)header)->filetype == MH_FVMLIB) {
129 execHeader = _getExecHeader();
130 for (libCmd = (const struct fvmlib_command *)(execHeader + 1),
131 endOfCmds = ((void *)libCmd) + execHeader->sizeofcmds;
132 libCmd < endOfCmds; ((void *)libCmd) += libCmd->cmdsize) {
133 if ((libCmd->cmd == LC_LOADFVMLIB) && (libCmd->fvmlib.header_addr
134 == (unsigned long)header)) {
135 return (char *)libCmd
136 + libCmd->fvmlib.name.offset;
137 }
138 }
139 return NULL;
140 } else {
141 unsigned long i, n = _dyld_image_count();
142 for( i = 0; i < n ; i++ ) {
143 if ( _dyld_get_image_header(i) == header )
144 return _dyld_get_image_name(i);
145 }
2bfd4448
A
146
147 return (*_NSGetArgv())[0];
13d88034
A
148 }
149}
150
2bfd4448
A
151
152// 1. Find segment with file offset == 0 and file size != 0. This segment's
153// contents span the Mach-O header. (File size of 0 is .bss, for example)
154// 2. Slide is header's address - segment's preferred address
155ptrdiff_t _getImageSlide(const headerType *header)
156{
157 int i;
158 const struct segment_command *sgp =
159 (const struct segment_command *)(header + 1);
160
161 for (i = 0; i < header->ncmds; i++){
162 if (sgp->cmd == LC_SEGMENT) {
163 if (sgp->fileoff == 0 && sgp->filesize != 0) {
164 return (uintptr_t)header - (uintptr_t)sgp->vmaddr;
165 }
166 }
167 sgp = (const struct segment_command *)((char *)sgp + sgp->cmdsize);
168 }
169
170 // uh-oh
171 _objc_fatal("could not calculate VM slide for image '%s'",
172 _getObjcHeaderName(header));
173 return 0; // not reached
174}