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