symbian-qemu-0.9.1-12/python-2.6.1/Python/dynload_aix.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 
       
     2 /* Support for dynamic loading of extension modules */
       
     3 
       
     4 #include "Python.h"
       
     5 #include "importdl.h"
       
     6 
       
     7 #include <ctype.h>	/*  for isdigit()	  */
       
     8 #include <errno.h>	/*  for global errno      */
       
     9 #include <string.h>	/*  for strerror()        */
       
    10 #include <stdlib.h>	/*  for malloc(), free()  */
       
    11 #include <sys/ldr.h>
       
    12 
       
    13 
       
    14 #ifdef AIX_GENUINE_CPLUSPLUS
       
    15 #include "/usr/lpp/xlC/include/load.h"
       
    16 #define aix_load loadAndInit
       
    17 #else
       
    18 #define aix_load load
       
    19 #endif
       
    20 
       
    21 
       
    22 extern char *Py_GetProgramName(void);
       
    23 
       
    24 typedef struct Module {
       
    25 	struct Module *next;
       
    26 	void          *entry;
       
    27 } Module, *ModulePtr;
       
    28 
       
    29 const struct filedescr _PyImport_DynLoadFiletab[] = {
       
    30 	{".so", "rb", C_EXTENSION},
       
    31 	{"module.so", "rb", C_EXTENSION},
       
    32 	{0, 0}
       
    33 };
       
    34 
       
    35 static int
       
    36 aix_getoldmodules(void **modlistptr)
       
    37 {
       
    38 	register ModulePtr       modptr, prevmodptr;
       
    39 	register struct ld_info  *ldiptr;
       
    40 	register char            *ldibuf;
       
    41 	register int             errflag, bufsize = 1024;
       
    42 	register unsigned int    offset;
       
    43 	char *progname = Py_GetProgramName();
       
    44 	
       
    45 	/*
       
    46 	-- Get the list of loaded modules into ld_info structures.
       
    47 	*/
       
    48 	if ((ldibuf = malloc(bufsize)) == NULL) {
       
    49 		PyErr_SetString(PyExc_ImportError, strerror(errno));
       
    50 		return -1;
       
    51 	}
       
    52 	while ((errflag = loadquery(L_GETINFO, ldibuf, bufsize)) == -1
       
    53 	       && errno == ENOMEM) {
       
    54 		free(ldibuf);
       
    55 		bufsize += 1024;
       
    56 		if ((ldibuf = malloc(bufsize)) == NULL) {
       
    57 			PyErr_SetString(PyExc_ImportError, strerror(errno));
       
    58 			return -1;
       
    59 		}
       
    60 	}
       
    61 	if (errflag == -1) {
       
    62 		PyErr_SetString(PyExc_ImportError, strerror(errno));
       
    63 		return -1;
       
    64 	}
       
    65 	/*
       
    66 	-- Make the modules list from the ld_info structures.
       
    67 	*/
       
    68 	ldiptr = (struct ld_info *)ldibuf;
       
    69 	prevmodptr = NULL;
       
    70 	do {
       
    71 		if (strstr(progname, ldiptr->ldinfo_filename) == NULL &&
       
    72 		    strstr(ldiptr->ldinfo_filename, "python") == NULL) {
       
    73 			/*
       
    74 			-- Extract only the modules belonging to the main
       
    75 			-- executable + those containing "python" as a
       
    76 			-- substring (like the "python[version]" binary or
       
    77 			-- "libpython[version].a" in case it's a shared lib).
       
    78 			*/
       
    79 			offset = (unsigned int)ldiptr->ldinfo_next;
       
    80 			ldiptr = (struct ld_info *)((char*)ldiptr + offset);
       
    81 			continue;
       
    82 		}
       
    83 		if ((modptr = (ModulePtr)malloc(sizeof(Module))) == NULL) {
       
    84 			PyErr_SetString(PyExc_ImportError, strerror(errno));
       
    85 			while (*modlistptr) {
       
    86 				modptr = (ModulePtr)*modlistptr;
       
    87 				*modlistptr = (void *)modptr->next;
       
    88 				free(modptr);
       
    89 			}
       
    90 			return -1;
       
    91 		}
       
    92 		modptr->entry = ldiptr->ldinfo_dataorg;
       
    93 		modptr->next  = NULL;
       
    94 		if (prevmodptr == NULL)
       
    95 			*modlistptr = (void *)modptr;
       
    96 		else
       
    97 			prevmodptr->next = modptr;
       
    98 		prevmodptr = modptr;
       
    99 		offset = (unsigned int)ldiptr->ldinfo_next;
       
   100 		ldiptr = (struct ld_info *)((char*)ldiptr + offset);
       
   101 	} while (offset);
       
   102 	free(ldibuf);
       
   103 	return 0;
       
   104 }
       
   105 
       
   106 
       
   107 static void
       
   108 aix_loaderror(const char *pathname)
       
   109 {
       
   110 
       
   111 	char *message[1024], errbuf[1024];
       
   112 	register int i,j;
       
   113 
       
   114 	struct errtab { 
       
   115 		int errNo;
       
   116 		char *errstr;
       
   117 	} load_errtab[] = {
       
   118 		{L_ERROR_TOOMANY,	"too many errors, rest skipped."},
       
   119 		{L_ERROR_NOLIB,		"can't load library:"},
       
   120 		{L_ERROR_UNDEF,		"can't find symbol in library:"},
       
   121 		{L_ERROR_RLDBAD,
       
   122 		 "RLD index out of range or bad relocation type:"},
       
   123 		{L_ERROR_FORMAT,	"not a valid, executable xcoff file:"},
       
   124 		{L_ERROR_MEMBER,
       
   125 		 "file not an archive or does not contain requested member:"},
       
   126 		{L_ERROR_TYPE,		"symbol table mismatch:"},
       
   127 		{L_ERROR_ALIGN,		"text alignment in file is wrong."},
       
   128 		{L_ERROR_SYSTEM,	"System error:"},
       
   129 		{L_ERROR_ERRNO,		NULL}
       
   130 	};
       
   131 
       
   132 #define LOAD_ERRTAB_LEN	(sizeof(load_errtab)/sizeof(load_errtab[0]))
       
   133 #define ERRBUF_APPEND(s) strncat(errbuf, s, sizeof(errbuf)-strlen(errbuf)-1)
       
   134 
       
   135 	PyOS_snprintf(errbuf, sizeof(errbuf), "from module %.200s ", pathname);
       
   136 
       
   137 	if (!loadquery(L_GETMESSAGES, &message[0], sizeof(message))) {
       
   138 		ERRBUF_APPEND(strerror(errno));
       
   139 		ERRBUF_APPEND("\n");
       
   140 	}
       
   141 	for(i = 0; message[i] && *message[i]; i++) {
       
   142 		int nerr = atoi(message[i]);
       
   143 		for (j=0; j<LOAD_ERRTAB_LEN ; j++) {
       
   144 		    if (nerr == load_errtab[j].errNo && load_errtab[j].errstr)
       
   145 			ERRBUF_APPEND(load_errtab[j].errstr);
       
   146 		}
       
   147 		while (isdigit(Py_CHARMASK(*message[i]))) message[i]++ ; 
       
   148 		ERRBUF_APPEND(message[i]);
       
   149 		ERRBUF_APPEND("\n");
       
   150 	}
       
   151 	errbuf[strlen(errbuf)-1] = '\0';	/* trim off last newline */
       
   152 	PyErr_SetString(PyExc_ImportError, errbuf); 
       
   153 	return; 
       
   154 }
       
   155 
       
   156 
       
   157 dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
       
   158 				    const char *pathname, FILE *fp)
       
   159 {
       
   160 	dl_funcptr p;
       
   161 
       
   162 	/*
       
   163 	-- Invoke load() with L_NOAUTODEFER leaving the imported symbols
       
   164 	-- of the shared module unresolved. Thus we have to resolve them
       
   165 	-- explicitly with loadbind. The new module is loaded, then we
       
   166 	-- resolve its symbols using the list of already loaded modules
       
   167 	-- (only those that belong to the python executable). Get these
       
   168 	-- with loadquery(L_GETINFO).
       
   169 	*/
       
   170 
       
   171 	static void *staticmodlistptr = NULL;
       
   172 
       
   173 	if (!staticmodlistptr)
       
   174 		if (aix_getoldmodules(&staticmodlistptr) == -1)
       
   175 			return NULL;
       
   176 	p = (dl_funcptr) aix_load((char *)pathname, L_NOAUTODEFER, 0);
       
   177 	if (p == NULL) {
       
   178 		aix_loaderror(pathname);
       
   179 		return NULL;
       
   180 	}
       
   181 
       
   182 	return p;
       
   183 }