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