mirror of
https://github.com/darlinghq/darling-objc4.git
synced 2024-11-23 04:09:46 +00:00
168 lines
5.2 KiB
Plaintext
168 lines
5.2 KiB
Plaintext
/*
|
|
* Copyright (c) 1999-2001, 2004-2007 Apple Inc. All Rights Reserved.
|
|
*
|
|
* @APPLE_LICENSE_HEADER_START@
|
|
*
|
|
* This file contains Original Code and/or Modifications of Original Code
|
|
* as defined in and that are subject to the Apple Public Source License
|
|
* Version 2.0 (the 'License'). You may not use this file except in
|
|
* compliance with the License. Please obtain a copy of the License at
|
|
* http://www.opensource.apple.com/apsl/ and read it before using this
|
|
* file.
|
|
*
|
|
* The Original Code and all software distributed under the License are
|
|
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
|
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
|
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
|
* Please see the License for the specific language governing rights and
|
|
* limitations under the License.
|
|
*
|
|
* @APPLE_LICENSE_HEADER_END@
|
|
*/
|
|
|
|
/*
|
|
* objc-load.m
|
|
* Copyright 1988-1996, NeXT Software, Inc.
|
|
* Author: s. naroff
|
|
*
|
|
*/
|
|
|
|
#include "objc-private.h"
|
|
#include "objc-load.h"
|
|
|
|
#if !__OBJC2__ && !TARGET_OS_WIN32
|
|
|
|
extern void (*callbackFunction)( Class, Category );
|
|
|
|
|
|
/**********************************************************************************
|
|
* objc_loadModule.
|
|
*
|
|
* NOTE: Loading isn't really thread safe. If a load message recursively calls
|
|
* objc_loadModules() both sets will be loaded correctly, but if the original
|
|
* caller calls objc_unloadModules() it will probably unload the wrong modules.
|
|
* If a load message calls objc_unloadModules(), then it will unload
|
|
* the modules currently being loaded, which will probably cause a crash.
|
|
*
|
|
* Error handling is still somewhat crude. If we encounter errors while
|
|
* linking up classes or categories, we will not recover correctly.
|
|
*
|
|
* I removed attempts to lock the class hashtable, since this introduced
|
|
* deadlock which was hard to remove. The only way you can get into trouble
|
|
* is if one thread loads a module while another thread tries to access the
|
|
* loaded classes (using objc_lookUpClass) before the load is complete.
|
|
**********************************************************************************/
|
|
int objc_loadModule(char *moduleName, void (*class_callback) (Class, Category), int *errorCode)
|
|
{
|
|
int successFlag = 1;
|
|
int locErrorCode;
|
|
NSObjectFileImage objectFileImage;
|
|
NSObjectFileImageReturnCode code;
|
|
|
|
// So we don't have to check this everywhere
|
|
if (errorCode == NULL)
|
|
errorCode = &locErrorCode;
|
|
|
|
if (moduleName == NULL)
|
|
{
|
|
*errorCode = NSObjectFileImageInappropriateFile;
|
|
return 0;
|
|
}
|
|
|
|
if (_dyld_present () == 0)
|
|
{
|
|
*errorCode = NSObjectFileImageFailure;
|
|
return 0;
|
|
}
|
|
|
|
callbackFunction = class_callback;
|
|
code = NSCreateObjectFileImageFromFile (moduleName, &objectFileImage);
|
|
if (code != NSObjectFileImageSuccess)
|
|
{
|
|
*errorCode = code;
|
|
return 0;
|
|
}
|
|
|
|
if (NSLinkModule(objectFileImage, moduleName, NSLINKMODULE_OPTION_RETURN_ON_ERROR) == NULL) {
|
|
NSLinkEditErrors error;
|
|
int errorNum;
|
|
const char *fileName, *errorString;
|
|
NSLinkEditError(&error, &errorNum, &fileName, &errorString);
|
|
// These errors may overlap with other errors that objc_loadModule returns in other failure cases.
|
|
*errorCode = error;
|
|
return 0;
|
|
}
|
|
callbackFunction = NULL;
|
|
|
|
|
|
return successFlag;
|
|
}
|
|
|
|
/**********************************************************************************
|
|
* objc_loadModules.
|
|
**********************************************************************************/
|
|
/* Lock for dynamic loading and unloading. */
|
|
// static OBJC_DECLARE_LOCK (loadLock);
|
|
|
|
|
|
long objc_loadModules (char * modlist[],
|
|
void * errStream,
|
|
void (*class_callback) (Class, Category),
|
|
headerType ** hdr_addr,
|
|
char * debug_file)
|
|
{
|
|
char ** modules;
|
|
int code;
|
|
int itWorked;
|
|
|
|
if (modlist == 0)
|
|
return 0;
|
|
|
|
for (modules = &modlist[0]; *modules != 0; modules++)
|
|
{
|
|
itWorked = objc_loadModule (*modules, class_callback, &code);
|
|
if (itWorked == 0)
|
|
{
|
|
//if (errStream)
|
|
// NXPrintf ((NXStream *) errStream, "objc_loadModules(%s) code = %d\n", *modules, code);
|
|
return 1;
|
|
}
|
|
|
|
if (hdr_addr)
|
|
*(hdr_addr++) = 0;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**********************************************************************************
|
|
* objc_unloadModules.
|
|
*
|
|
* NOTE: Unloading isn't really thread safe. If an unload message calls
|
|
* objc_loadModules() or objc_unloadModules(), then the current call
|
|
* to objc_unloadModules() will probably unload the wrong stuff.
|
|
**********************************************************************************/
|
|
|
|
long objc_unloadModules (void * errStream,
|
|
void (*unload_callback) (Class, Category))
|
|
{
|
|
headerType * header_addr = 0;
|
|
int errflag = 0;
|
|
|
|
// TODO: to make unloading work, should get the current header
|
|
|
|
if (header_addr)
|
|
{
|
|
; // TODO: unload the current header
|
|
}
|
|
else
|
|
{
|
|
errflag = 1;
|
|
}
|
|
|
|
return errflag;
|
|
}
|
|
|
|
#endif
|