]> git.saurik.com Git - apple/objc4.git/blob - runtime/objc-load.m
objc4-437.1.tar.gz
[apple/objc4.git] / runtime / objc-load.m
1 /*
2 * Copyright (c) 1999-2001, 2004-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
24 /*
25 * objc-load.m
26 * Copyright 1988-1996, NeXT Software, Inc.
27 * Author: s. naroff
28 *
29 */
30
31 #include "objc-private.h"
32
33 #if !__OBJC2__ && !TARGET_OS_WIN32
34
35 extern void (*callbackFunction)( Class, const char * );
36
37
38 /**********************************************************************************
39 * objc_loadModule.
40 *
41 * NOTE: Loading isn't really thread safe. If a load message recursively calls
42 * objc_loadModules() both sets will be loaded correctly, but if the original
43 * caller calls objc_unloadModules() it will probably unload the wrong modules.
44 * If a load message calls objc_unloadModules(), then it will unload
45 * the modules currently being loaded, which will probably cause a crash.
46 *
47 * Error handling is still somewhat crude. If we encounter errors while
48 * linking up classes or categories, we will not recover correctly.
49 *
50 * I removed attempts to lock the class hashtable, since this introduced
51 * deadlock which was hard to remove. The only way you can get into trouble
52 * is if one thread loads a module while another thread tries to access the
53 * loaded classes (using objc_lookUpClass) before the load is complete.
54 **********************************************************************************/
55 int objc_loadModule(const char *moduleName, void (*class_callback) (Class, const char *categoryName), int *errorCode)
56 {
57 int successFlag = 1;
58 int locErrorCode;
59 NSObjectFileImage objectFileImage;
60 NSObjectFileImageReturnCode code;
61
62 // So we don't have to check this everywhere
63 if (errorCode == NULL)
64 errorCode = &locErrorCode;
65
66 if (moduleName == NULL)
67 {
68 *errorCode = NSObjectFileImageInappropriateFile;
69 return 0;
70 }
71
72 if (_dyld_present () == 0)
73 {
74 *errorCode = NSObjectFileImageFailure;
75 return 0;
76 }
77
78 callbackFunction = class_callback;
79 code = NSCreateObjectFileImageFromFile (moduleName, &objectFileImage);
80 if (code != NSObjectFileImageSuccess)
81 {
82 *errorCode = code;
83 return 0;
84 }
85
86 if (NSLinkModule(objectFileImage, moduleName, NSLINKMODULE_OPTION_RETURN_ON_ERROR) == NULL) {
87 NSLinkEditErrors error;
88 int errorNum;
89 const char *fileName, *errorString;
90 NSLinkEditError(&error, &errorNum, &fileName, &errorString);
91 // These errors may overlap with other errors that objc_loadModule returns in other failure cases.
92 *errorCode = error;
93 return 0;
94 }
95 callbackFunction = NULL;
96
97
98 return successFlag;
99 }
100
101 /**********************************************************************************
102 * objc_loadModules.
103 **********************************************************************************/
104 /* Lock for dynamic loading and unloading. */
105 // static OBJC_DECLARE_LOCK (loadLock);
106
107
108 long objc_loadModules (char * modlist[],
109 void * errStream,
110 void (*class_callback) (Class, const char *),
111 headerType ** hdr_addr,
112 char * debug_file)
113 {
114 char ** modules;
115 int code;
116 int itWorked;
117
118 if (modlist == 0)
119 return 0;
120
121 for (modules = &modlist[0]; *modules != 0; modules++)
122 {
123 itWorked = objc_loadModule (*modules, class_callback, &code);
124 if (itWorked == 0)
125 {
126 //if (errStream)
127 // NXPrintf ((NXStream *) errStream, "objc_loadModules(%s) code = %d\n", *modules, code);
128 return 1;
129 }
130
131 if (hdr_addr)
132 *(hdr_addr++) = 0;
133 }
134
135 return 0;
136 }
137
138 /**********************************************************************************
139 * objc_unloadModules.
140 *
141 * NOTE: Unloading isn't really thread safe. If an unload message calls
142 * objc_loadModules() or objc_unloadModules(), then the current call
143 * to objc_unloadModules() will probably unload the wrong stuff.
144 **********************************************************************************/
145
146 long objc_unloadModules (void * errStream,
147 void (*unload_callback) (Class, Category))
148 {
149 headerType * header_addr = 0;
150 int errflag = 0;
151
152 // TODO: to make unloading work, should get the current header
153
154 if (header_addr)
155 {
156 ; // TODO: unload the current header
157 }
158 else
159 {
160 errflag = 1;
161 }
162
163 return errflag;
164 }
165
166 #endif