@@ -126,10 +126,14 @@ typedef void (*dl_funcptr)();
126126
127127#ifdef _AIX
128128#define DYNAMIC_LINK
129+ #define SHORT_EXT ".so"
130+ #define LONG_EXT "module.so"
129131#include <sys/ldr.h>
130132typedef void (* dl_funcptr )();
131133#define _DL_FUNCPTR_DEFINED
132- static void aix_loaderror (char * name );
134+ static int aix_getoldmodules (void * * );
135+ static int aix_bindnewmodule (void * , void * );
136+ static void aix_loaderror (char * );
133137#endif
134138
135139#ifdef DYNAMIC_LINK
@@ -335,10 +339,29 @@ load_dynamic_module(name, pathname, fp)
335339 }
336340#endif /* USE_SHLIB */
337341#ifdef _AIX
338- p = (dl_funcptr ) load (pathname , 1 , 0 );
339- if (p == NULL ) {
340- aix_loaderror (pathname );
341- return NULL ;
342+ /*
343+ -- Invoke load() with L_NOAUTODEFER leaving the imported symbols
344+ -- of the shared module unresolved. Thus we have to resolve them
345+ -- explicitely with loadbind. The new module is loaded, then we
346+ -- resolve its symbols using the list of already loaded modules
347+ -- (only those that belong to the python executable). Get these
348+ -- with loadquery(L_GETINFO).
349+ */
350+ {
351+ static void * staticmodlistptr = NULL ;
352+
353+ if (!staticmodlistptr )
354+ if (aix_getoldmodules (& staticmodlistptr ) == -1 )
355+ return NULL ;
356+ p = (dl_funcptr ) load (pathname , L_NOAUTODEFER , 0 );
357+ if (p == NULL ) {
358+ aix_loaderror (pathname );
359+ return NULL ;
360+ }
361+ if (aix_bindnewmodule ((void * )p , staticmodlistptr ) == -1 ) {
362+ aix_loaderror (pathname );
363+ return NULL ;
364+ }
342365 }
343366#endif /* _AIX */
344367#ifdef NT
@@ -490,18 +513,101 @@ load_dynamic_module(name, pathname, fp)
490513
491514#ifdef _AIX
492515
493- #include <ctype.h> /* for isdigit() */
494- #include <errno.h> /* for global errno */
495- #include <string.h> /* for strerror() */
516+ #include <ctype.h> /* for isdigit() */
517+ #include <errno.h> /* for global errno */
518+ #include <string.h> /* for strerror() */
519+ #include <stdlib.h> /* for malloc(), free() */
520+
521+ typedef struct Module {
522+ struct Module * next ;
523+ void * entry ;
524+ } Module , * ModulePtr ;
525+
526+ static int
527+ aix_getoldmodules (modlistptr )
528+ void * * modlistptr ;
529+ {
530+ register ModulePtr modptr , prevmodptr ;
531+ register struct ld_info * ldiptr ;
532+ register char * ldibuf ;
533+ register int errflag , bufsize = 1024 ;
534+ register unsigned int offset ;
535+
536+ /*
537+ -- Get the list of loaded modules into ld_info structures.
538+ */
539+ if ((ldibuf = malloc (bufsize )) == NULL ) {
540+ err_setstr (ImportError , strerror (errno ));
541+ return -1 ;
542+ }
543+ while ((errflag = loadquery (L_GETINFO , ldibuf , bufsize )) == -1
544+ && errno == ENOMEM ) {
545+ free (ldibuf );
546+ bufsize += 1024 ;
547+ if ((ldibuf = malloc (bufsize )) == NULL ) {
548+ err_setstr (ImportError , strerror (errno ));
549+ return -1 ;
550+ }
551+ }
552+ if (errflag == -1 ) {
553+ err_setstr (ImportError , strerror (errno ));
554+ return -1 ;
555+ }
556+ /*
557+ -- Make the modules list from the ld_info structures.
558+ */
559+ ldiptr = (struct ld_info * )ldibuf ;
560+ prevmodptr = NULL ;
561+ do {
562+ if ((modptr = (ModulePtr )malloc (sizeof (Module ))) == NULL ) {
563+ err_setstr (ImportError , strerror (errno ));
564+ while (* modlistptr ) {
565+ modptr = (ModulePtr )* modlistptr ;
566+ * modlistptr = (void * )modptr -> next ;
567+ free (modptr );
568+ }
569+ return -1 ;
570+ }
571+ modptr -> entry = ldiptr -> ldinfo_dataorg ;
572+ modptr -> next = NULL ;
573+ if (prevmodptr == NULL )
574+ * modlistptr = (void * )modptr ;
575+ else
576+ prevmodptr -> next = modptr ;
577+ prevmodptr = modptr ;
578+ offset = (unsigned int )ldiptr -> ldinfo_next ;
579+ ldiptr = (struct ld_info * )((unsigned int )ldiptr + offset );
580+ } while (offset );
581+ free (ldibuf );
582+ return 0 ;
583+ }
584+
585+ static int
586+ aix_bindnewmodule (newmoduleptr , modlistptr )
587+ void * newmoduleptr ;
588+ void * modlistptr ;
589+ {
590+ register ModulePtr modptr ;
591+
592+ /*
593+ -- Bind the new module with the list of loaded modules.
594+ */
595+ for (modptr = (ModulePtr )modlistptr ; modptr ; modptr = modptr -> next )
596+ if (loadbind (0 , modptr -> entry , newmoduleptr ) != 0 )
597+ return -1 ;
598+ return 0 ;
599+ }
496600
497- void aix_loaderror (char * pathname )
601+ static void
602+ aix_loaderror (pathname )
603+ char * pathname ;
498604{
499605
500606 char * message [1024 ], errbuf [1024 ];
501- int i ,j ;
607+ register int i ,j ;
502608
503609 struct errtab {
504- int errno ;
610+ int errNo ;
505611 char * errstr ;
506612 } load_errtab [] = {
507613 {L_ERROR_TOOMANY , "too many errors, rest skipped." },
@@ -521,16 +627,16 @@ void aix_loaderror(char *pathname)
521627#define LOAD_ERRTAB_LEN (sizeof(load_errtab)/sizeof(load_errtab[0]))
522628#define ERRBUF_APPEND (s ) strncat(errbuf, s, sizeof(errbuf)-strlen(errbuf)-1)
523629
524- sprintf (errbuf , " from module %.200s " , pathname );
630+ sprintf (errbuf , "from module %.200s " , pathname );
525631
526- if (!loadquery (1 , & message [0 ], sizeof (message ))) {
632+ if (!loadquery (L_GETMESSAGES , & message [0 ], sizeof (message ))) {
527633 ERRBUF_APPEND (strerror (errno ));
528634 ERRBUF_APPEND ("\n" );
529635 }
530636 for (i = 0 ; message [i ] && * message [i ]; i ++ ) {
531637 int nerr = atoi (message [i ]);
532638 for (j = 0 ; j < LOAD_ERRTAB_LEN ; j ++ ) {
533- if (nerr == load_errtab [j ].errno && load_errtab [j ].errstr )
639+ if (nerr == load_errtab [j ].errNo && load_errtab [j ].errstr )
534640 ERRBUF_APPEND (load_errtab [j ].errstr );
535641 }
536642 while (isdigit (* message [i ])) message [i ]++ ;
0 commit comments