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