ยปCore Development>Code coverage>Python/dynload_aix.c

Python code coverage for Python/dynload_aix.c

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