]> git.saurik.com Git - apple/objc4.git/blob - runtime/objc-load.m
objc4-237.tar.gz
[apple/objc4.git] / runtime / objc-load.m
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
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.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25
26 /*
27 * objc-load.m
28 * Copyright 1988-1996, NeXT Software, Inc.
29 * Author: s. naroff
30 *
31 */
32
33 #import "objc-private.h"
34 #import <objc/objc-runtime.h>
35 #import <objc/hashtable2.h>
36 #import <objc/Object.h>
37 #import <objc/Protocol.h>
38
39 //#import <streams/streams.h>
40
41 #include <mach-o/dyld.h>
42
43
44
45
46 extern char * getsectdatafromheader (const headerType * mhp, const char * segname, const char * sectname, int * size);
47
48 /* Private extern */
49 OBJC_EXPORT void (*callbackFunction)( Class, const char * );
50
51
52 struct objc_method_list **get_base_method_list(Class cls) {
53 struct objc_method_list **ptr = ((struct objc_class * )cls)->methodLists;
54 if (!*ptr) return NULL;
55 while ( *ptr != 0 && *ptr != END_OF_METHODS_LIST ) { ptr++; }
56 --ptr;
57 return ptr;
58 }
59
60
61 /**********************************************************************************
62 * objc_loadModule.
63 *
64 * NOTE: Loading isn't really thread safe. If a load message recursively calls
65 * objc_loadModules() both sets will be loaded correctly, but if the original
66 * caller calls objc_unloadModules() it will probably unload the wrong modules.
67 * If a load message calls objc_unloadModules(), then it will unload
68 * the modules currently being loaded, which will probably cause a crash.
69 *
70 * Error handling is still somewhat crude. If we encounter errors while
71 * linking up classes or categories, we will not recover correctly.
72 *
73 * I removed attempts to lock the class hashtable, since this introduced
74 * deadlock which was hard to remove. The only way you can get into trouble
75 * is if one thread loads a module while another thread tries to access the
76 * loaded classes (using objc_lookUpClass) before the load is complete.
77 **********************************************************************************/
78 int objc_loadModule(const char *moduleName, void (*class_callback) (Class, const char *categoryName), int *errorCode)
79 {
80 int successFlag = 1;
81 int locErrorCode;
82 NSObjectFileImage objectFileImage;
83 NSObjectFileImageReturnCode code;
84
85 // So we don't have to check this everywhere
86 if (errorCode == NULL)
87 errorCode = &locErrorCode;
88
89 if (moduleName == NULL)
90 {
91 *errorCode = NSObjectFileImageInappropriateFile;
92 return 0;
93 }
94
95 if (_dyld_present () == 0)
96 {
97 *errorCode = NSObjectFileImageFailure;
98 return 0;
99 }
100
101 callbackFunction = class_callback;
102 code = NSCreateObjectFileImageFromFile (moduleName, &objectFileImage);
103 if (code != NSObjectFileImageSuccess)
104 {
105 *errorCode = code;
106 return 0;
107 }
108
109 if (NSLinkModule(objectFileImage, moduleName, NSLINKMODULE_OPTION_RETURN_ON_ERROR) == NULL) {
110 NSLinkEditErrors error;
111 int errorNum;
112 char *fileName, *errorString;
113 NSLinkEditError(&error, &errorNum, &fileName, &errorString);
114 // These errors may overlap with other errors that objc_loadModule returns in other failure cases.
115 *errorCode = error;
116 return 0;
117 }
118 callbackFunction = NULL;
119
120
121 return successFlag;
122 }
123
124 /**********************************************************************************
125 * objc_loadModules.
126 **********************************************************************************/
127 /* Lock for dynamic loading and unloading. */
128 // static OBJC_DECLARE_LOCK (loadLock);
129
130
131 long objc_loadModules (char * modlist[],
132 void * errStream,
133 void (*class_callback) (Class, const char *),
134 headerType ** hdr_addr,
135 char * debug_file)
136 {
137 char ** modules;
138 int code;
139 int itWorked;
140
141 if (modlist == 0)
142 return 0;
143
144 for (modules = &modlist[0]; *modules != 0; modules++)
145 {
146 itWorked = objc_loadModule (*modules, class_callback, &code);
147 if (itWorked == 0)
148 {
149 //if (errStream)
150 // NXPrintf ((NXStream *) errStream, "objc_loadModules(%s) code = %d\n", *modules, code);
151 return 1;
152 }
153
154 if (hdr_addr)
155 *(hdr_addr++) = 0;
156 }
157
158 return 0;
159 }
160
161 /**********************************************************************************
162 * objc_unloadModules.
163 *
164 * NOTE: Unloading isn't really thread safe. If an unload message calls
165 * objc_loadModules() or objc_unloadModules(), then the current call
166 * to objc_unloadModules() will probably unload the wrong stuff.
167 **********************************************************************************/
168
169 long objc_unloadModules (void * errStream,
170 void (*unload_callback) (Class, Category))
171 {
172 headerType * header_addr = 0;
173 int errflag = 0;
174
175 // TODO: to make unloading work, should get the current header
176
177 if (header_addr)
178 {
179 ; // TODO: unload the current header
180 }
181 else
182 {
183 errflag = 1;
184 }
185
186 return errflag;
187 }
188