objc-load.mm 5.2 KB

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