Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d5962ad

Browse files
committed
Changes for AIX sharedlibs.
1 parent 02530b0 commit d5962ad

1 file changed

Lines changed: 120 additions & 14 deletions

File tree

Python/importdl.c

Lines changed: 120 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -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>
130132
typedef 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

Comments
 (0)