darling-objc4/runtime/objc-load.mm
Lubos Dolezel adfc003729 objc4-706
2017-01-18 22:41:26 +01:00

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