/Python/dynload_next.c

http://unladen-swallow.googlecode.com/ · C · 114 lines · 89 code · 8 blank · 17 comment · 11 complexity · 6df9b0ef3982aee5a6c721296010162e MD5 · raw file

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