2 * Copyright (c) 1999-2001, 2004-2007 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
26 * Copyright 1988-1996, NeXT Software, Inc.
33 #import "objc-private.h"
34 #import <objc/objc-runtime.h>
35 #import <objc/hashtable2.h>
36 #import <objc/Object.h>
37 #include <mach-o/dyld.h>
40 extern void (*callbackFunction)( Class, const char * );
43 /**********************************************************************************
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.
52 * Error handling is still somewhat crude. If we encounter errors while
53 * linking up classes or categories, we will not recover correctly.
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)
64 NSObjectFileImage objectFileImage;
65 NSObjectFileImageReturnCode code;
67 // So we don't have to check this everywhere
68 if (errorCode == NULL)
69 errorCode = &locErrorCode;
71 if (moduleName == NULL)
73 *errorCode = NSObjectFileImageInappropriateFile;
77 if (_dyld_present () == 0)
79 *errorCode = NSObjectFileImageFailure;
83 callbackFunction = class_callback;
84 code = NSCreateObjectFileImageFromFile (moduleName, &objectFileImage);
85 if (code != NSObjectFileImageSuccess)
91 if (NSLinkModule(objectFileImage, moduleName, NSLINKMODULE_OPTION_RETURN_ON_ERROR) == NULL) {
92 NSLinkEditErrors error;
94 const char *fileName, *errorString;
95 NSLinkEditError(&error, &errorNum, &fileName, &errorString);
96 // These errors may overlap with other errors that objc_loadModule returns in other failure cases.
100 callbackFunction = NULL;
106 /**********************************************************************************
108 **********************************************************************************/
109 /* Lock for dynamic loading and unloading. */
110 // static OBJC_DECLARE_LOCK (loadLock);
113 long objc_loadModules (char * modlist[],
115 void (*class_callback) (Class, const char *),
116 headerType ** hdr_addr,
126 for (modules = &modlist[0]; *modules != 0; modules++)
128 itWorked = objc_loadModule (*modules, class_callback, &code);
132 // NXPrintf ((NXStream *) errStream, "objc_loadModules(%s) code = %d\n", *modules, code);
143 /**********************************************************************************
144 * objc_unloadModules.
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 **********************************************************************************/
151 long objc_unloadModules (void * errStream,
152 void (*unload_callback) (Class, Category))
154 headerType * header_addr = 0;
157 // TODO: to make unloading work, should get the current header
161 ; // TODO: unload the current header