You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

111 lines
3.9 KiB

  1. /* Support for dynamic loading of extension modules on Mac OS X
  2. ** All references to "NeXT" are for historical reasons.
  3. */
  4. #include "Python.h"
  5. #include "importdl.h"
  6. #include <mach-o/dyld.h>
  7. const char *_PyImport_DynLoadFiletab[] = {".so", NULL};
  8. /*
  9. ** Python modules are Mach-O MH_BUNDLE files. The best way to load these
  10. ** is each in a private namespace, so you can load, say, a module bar and a
  11. ** module foo.bar. If we load everything in the global namespace the two
  12. ** initbar() symbols will conflict.
  13. ** However, it seems some extension packages depend upon being able to access
  14. ** each others' global symbols. There seems to be no way to eat our cake and
  15. ** have it, so the USE_DYLD_GLOBAL_NAMESPACE define determines which behaviour
  16. ** you get.
  17. */
  18. #ifdef USE_DYLD_GLOBAL_NAMESPACE
  19. #define LINKOPTIONS NSLINKMODULE_OPTION_BINDNOW|NSLINKMODULE_OPTION_RETURN_ON_ERROR
  20. #else
  21. #define LINKOPTIONS NSLINKMODULE_OPTION_BINDNOW| \
  22. NSLINKMODULE_OPTION_RETURN_ON_ERROR|NSLINKMODULE_OPTION_PRIVATE
  23. #endif
  24. dl_funcptr _PyImport_FindSharedFuncptr(const char *prefix,
  25. const char *shortname,
  26. const char *pathname, FILE *fp)
  27. {
  28. dl_funcptr p = NULL;
  29. char funcname[258];
  30. NSObjectFileImageReturnCode rc;
  31. NSObjectFileImage image;
  32. NSModule newModule;
  33. NSSymbol theSym;
  34. const char *errString;
  35. char errBuf[512];
  36. PyOS_snprintf(funcname, sizeof(funcname), "_%.20s_%.200s", prefix, shortname);
  37. #ifdef USE_DYLD_GLOBAL_NAMESPACE
  38. if (NSIsSymbolNameDefined(funcname)) {
  39. theSym = NSLookupAndBindSymbol(funcname);
  40. p = (dl_funcptr)NSAddressOfSymbol(theSym);
  41. return p;
  42. }
  43. #endif
  44. rc = NSCreateObjectFileImageFromFile(pathname, &image);
  45. switch(rc) {
  46. default:
  47. case NSObjectFileImageFailure:
  48. case NSObjectFileImageFormat:
  49. /* for these a message is printed on stderr by dyld */
  50. errString = "Can't create object file image";
  51. break;
  52. case NSObjectFileImageSuccess:
  53. errString = NULL;
  54. break;
  55. case NSObjectFileImageInappropriateFile:
  56. errString = "Inappropriate file type for dynamic loading";
  57. break;
  58. case NSObjectFileImageArch:
  59. errString = "Wrong CPU type in object file";
  60. break;
  61. case NSObjectFileImageAccess:
  62. errString = "Can't read object file (no access)";
  63. break;
  64. }
  65. if (errString == NULL) {
  66. newModule = NSLinkModule(image, pathname, LINKOPTIONS);
  67. if (newModule == NULL) {
  68. int errNo;
  69. const char *fileName, *moreErrorStr;
  70. NSLinkEditErrors c;
  71. NSLinkEditError( &c, &errNo, &fileName, &moreErrorStr );
  72. PyOS_snprintf(errBuf, 512, "Failure linking new module: %s: %s",
  73. fileName, moreErrorStr);
  74. errString = errBuf;
  75. }
  76. }
  77. if (errString != NULL) {
  78. PyErr_SetString(PyExc_ImportError, errString);
  79. return NULL;
  80. }
  81. #ifdef USE_DYLD_GLOBAL_NAMESPACE
  82. if (!NSIsSymbolNameDefined(funcname)) {
  83. /* UnlinkModule() isn't implemented in current versions, but calling it does no harm */
  84. /* NSUnLinkModule(newModule, FALSE); removed: causes problems for ObjC code */
  85. PyErr_Format(PyExc_ImportError,
  86. "Loaded module does not contain symbol %.200s",
  87. funcname);
  88. return NULL;
  89. }
  90. theSym = NSLookupAndBindSymbol(funcname);
  91. #else
  92. theSym = NSLookupSymbolInModule(newModule, funcname);
  93. if ( theSym == NULL ) {
  94. /* NSUnLinkModule(newModule, FALSE); removed: causes problems for ObjC code */
  95. PyErr_Format(PyExc_ImportError,
  96. "Loaded module does not contain symbol %.200s",
  97. funcname);
  98. return NULL;
  99. }
  100. #endif
  101. p = (dl_funcptr)NSAddressOfSymbol(theSym);
  102. return p;
  103. }