1
2 /* Support for dynamic loading of extension modules */
3
4 #include "Python.h"
5 #include "pycore_call.h"
6 #include "pycore_import.h"
7 #include "pycore_pyerrors.h" // _PyErr_FormatFromCause()
8 #include "pycore_pystate.h"
9 #include "pycore_runtime.h"
10
11 #include "pycore_importdl.h"
12
13 /* ./configure sets HAVE_DYNAMIC_LOADING if dynamic loading of modules is
14 supported on this platform. configure will then compile and link in one
15 of the dynload_*.c files, as appropriate. We will call a function in
16 those modules to get a function pointer to the module's init function.
17 */
18 #ifdef HAVE_DYNAMIC_LOADING
19
20 #ifdef MS_WINDOWS
21 extern dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix,
22 const char *shortname,
23 PyObject *pathname,
24 FILE *fp);
25 #else
26 extern dl_funcptr _PyImport_FindSharedFuncptr(const char *prefix,
27 const char *shortname,
28 const char *pathname, FILE *fp);
29 #endif
30
31 #endif /* HAVE_DYNAMIC_LOADING */
32
33
34 /***********************************/
35 /* module info to use when loading */
36 /***********************************/
37
38 static const char * const ascii_only_prefix = "PyInit";
39 static const char * const nonascii_prefix = "PyInitU";
40
41 /* Get the variable part of a module's export symbol name.
42 * Returns a bytes instance. For non-ASCII-named modules, the name is
43 * encoded as per PEP 489.
44 * The hook_prefix pointer is set to either ascii_only_prefix or
45 * nonascii_prefix, as appropriate.
46 */
47 static PyObject *
get_encoded_name(PyObject * name,const char ** hook_prefix)48 get_encoded_name(PyObject *name, const char **hook_prefix) {
49 PyObject *tmp;
50 PyObject *encoded = NULL;
51 PyObject *modname = NULL;
52 Py_ssize_t name_len, lastdot;
53
54 /* Get the short name (substring after last dot) */
55 name_len = PyUnicode_GetLength(name);
56 if (name_len < 0) {
57 return NULL;
58 }
59 lastdot = PyUnicode_FindChar(name, '.', 0, name_len, -1);
60 if (lastdot < -1) {
61 return NULL;
62 } else if (lastdot >= 0) {
63 tmp = PyUnicode_Substring(name, lastdot + 1, name_len);
64 if (tmp == NULL)
65 return NULL;
66 name = tmp;
67 /* "name" now holds a new reference to the substring */
68 } else {
69 Py_INCREF(name);
70 }
71
72 /* Encode to ASCII or Punycode, as needed */
73 encoded = PyUnicode_AsEncodedString(name, "ascii", NULL);
74 if (encoded != NULL) {
75 *hook_prefix = ascii_only_prefix;
76 } else {
77 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
78 PyErr_Clear();
79 encoded = PyUnicode_AsEncodedString(name, "punycode", NULL);
80 if (encoded == NULL) {
81 goto error;
82 }
83 *hook_prefix = nonascii_prefix;
84 } else {
85 goto error;
86 }
87 }
88
89 /* Replace '-' by '_' */
90 modname = _PyObject_CallMethod(encoded, &_Py_ID(replace), "cc", '-', '_');
91 if (modname == NULL)
92 goto error;
93
94 Py_DECREF(name);
95 Py_DECREF(encoded);
96 return modname;
97 error:
98 Py_DECREF(name);
99 Py_XDECREF(encoded);
100 return NULL;
101 }
102
103 void
_Py_ext_module_loader_info_clear(struct _Py_ext_module_loader_info * info)104 _Py_ext_module_loader_info_clear(struct _Py_ext_module_loader_info *info)
105 {
106 Py_CLEAR(info->filename);
107 #ifndef MS_WINDOWS
108 Py_CLEAR(info->filename_encoded);
109 #endif
110 Py_CLEAR(info->name);
111 Py_CLEAR(info->name_encoded);
112 }
113
114 int
_Py_ext_module_loader_info_init(struct _Py_ext_module_loader_info * p_info,PyObject * name,PyObject * filename,_Py_ext_module_origin origin)115 _Py_ext_module_loader_info_init(struct _Py_ext_module_loader_info *p_info,
116 PyObject *name, PyObject *filename,
117 _Py_ext_module_origin origin)
118 {
119 struct _Py_ext_module_loader_info info = {
120 .origin=origin,
121 };
122
123 assert(name != NULL);
124 if (!PyUnicode_Check(name)) {
125 PyErr_SetString(PyExc_TypeError,
126 "module name must be a string");
127 _Py_ext_module_loader_info_clear(&info);
128 return -1;
129 }
130 assert(PyUnicode_GetLength(name) > 0);
131 info.name = Py_NewRef(name);
132
133 info.name_encoded = get_encoded_name(info.name, &info.hook_prefix);
134 if (info.name_encoded == NULL) {
135 _Py_ext_module_loader_info_clear(&info);
136 return -1;
137 }
138
139 info.newcontext = PyUnicode_AsUTF8(info.name);
140 if (info.newcontext == NULL) {
141 _Py_ext_module_loader_info_clear(&info);
142 return -1;
143 }
144
145 if (filename != NULL) {
146 if (!PyUnicode_Check(filename)) {
147 PyErr_SetString(PyExc_TypeError,
148 "module filename must be a string");
149 _Py_ext_module_loader_info_clear(&info);
150 return -1;
151 }
152 info.filename = Py_NewRef(filename);
153
154 #ifndef MS_WINDOWS
155 info.filename_encoded = PyUnicode_EncodeFSDefault(info.filename);
156 if (info.filename_encoded == NULL) {
157 _Py_ext_module_loader_info_clear(&info);
158 return -1;
159 }
160 #endif
161
162 info.path = info.filename;
163 }
164 else {
165 info.path = info.name;
166 }
167
168 *p_info = info;
169 return 0;
170 }
171
172 int
_Py_ext_module_loader_info_init_for_builtin(struct _Py_ext_module_loader_info * info,PyObject * name)173 _Py_ext_module_loader_info_init_for_builtin(
174 struct _Py_ext_module_loader_info *info,
175 PyObject *name)
176 {
177 assert(PyUnicode_Check(name));
178 assert(PyUnicode_FindChar(name, '.', 0, PyUnicode_GetLength(name), -1) == -1);
179 assert(PyUnicode_GetLength(name) > 0);
180
181 PyObject *name_encoded = PyUnicode_AsEncodedString(name, "ascii", NULL);
182 if (name_encoded == NULL) {
183 return -1;
184 }
185
186 *info = (struct _Py_ext_module_loader_info){
187 .name=Py_NewRef(name),
188 .name_encoded=name_encoded,
189 /* We won't need filename. */
190 .path=name,
191 .origin=_Py_ext_module_origin_BUILTIN,
192 .hook_prefix=ascii_only_prefix,
193 .newcontext=NULL,
194 };
195 return 0;
196 }
197
198 int
_Py_ext_module_loader_info_init_for_core(struct _Py_ext_module_loader_info * info,PyObject * name)199 _Py_ext_module_loader_info_init_for_core(
200 struct _Py_ext_module_loader_info *info,
201 PyObject *name)
202 {
203 if (_Py_ext_module_loader_info_init_for_builtin(info, name) < 0) {
204 return -1;
205 }
206 info->origin = _Py_ext_module_origin_CORE;
207 return 0;
208 }
209
210 #ifdef HAVE_DYNAMIC_LOADING
211 int
_Py_ext_module_loader_info_init_from_spec(struct _Py_ext_module_loader_info * p_info,PyObject * spec)212 _Py_ext_module_loader_info_init_from_spec(
213 struct _Py_ext_module_loader_info *p_info,
214 PyObject *spec)
215 {
216 PyObject *name = PyObject_GetAttrString(spec, "name");
217 if (name == NULL) {
218 return -1;
219 }
220 PyObject *filename = PyObject_GetAttrString(spec, "origin");
221 if (filename == NULL) {
222 Py_DECREF(name);
223 return -1;
224 }
225 /* We could also accommodate builtin modules here without much trouble. */
226 _Py_ext_module_origin origin = _Py_ext_module_origin_DYNAMIC;
227 int err = _Py_ext_module_loader_info_init(p_info, name, filename, origin);
228 Py_DECREF(name);
229 Py_DECREF(filename);
230 return err;
231 }
232 #endif /* HAVE_DYNAMIC_LOADING */
233
234
235 /********************************/
236 /* module init function results */
237 /********************************/
238
239 void
_Py_ext_module_loader_result_clear(struct _Py_ext_module_loader_result * res)240 _Py_ext_module_loader_result_clear(struct _Py_ext_module_loader_result *res)
241 {
242 /* Instead, the caller should have called
243 * _Py_ext_module_loader_result_apply_error(). */
244 assert(res->err == NULL);
245 *res = (struct _Py_ext_module_loader_result){0};
246 }
247
248 static void
_Py_ext_module_loader_result_set_error(struct _Py_ext_module_loader_result * res,enum _Py_ext_module_loader_result_error_kind kind)249 _Py_ext_module_loader_result_set_error(
250 struct _Py_ext_module_loader_result *res,
251 enum _Py_ext_module_loader_result_error_kind kind)
252 {
253 #ifndef NDEBUG
254 switch (kind) {
255 case _Py_ext_module_loader_result_EXCEPTION: /* fall through */
256 case _Py_ext_module_loader_result_ERR_UNREPORTED_EXC:
257 assert(PyErr_Occurred());
258 break;
259 case _Py_ext_module_loader_result_ERR_MISSING: /* fall through */
260 case _Py_ext_module_loader_result_ERR_UNINITIALIZED: /* fall through */
261 case _Py_ext_module_loader_result_ERR_NONASCII_NOT_MULTIPHASE: /* fall through */
262 case _Py_ext_module_loader_result_ERR_NOT_MODULE: /* fall through */
263 case _Py_ext_module_loader_result_ERR_MISSING_DEF:
264 assert(!PyErr_Occurred());
265 break;
266 default:
267 /* We added a new error kind but forgot to add it to this switch. */
268 assert(0);
269 }
270 #endif
271
272 assert(res->err == NULL && res->_err.exc == NULL);
273 res->err = &res->_err;
274 *res->err = (struct _Py_ext_module_loader_result_error){
275 .kind=kind,
276 .exc=PyErr_GetRaisedException(),
277 };
278
279 /* For some kinds, we also set/check res->kind. */
280 switch (kind) {
281 case _Py_ext_module_loader_result_ERR_UNINITIALIZED:
282 assert(res->kind == _Py_ext_module_kind_UNKNOWN);
283 res->kind = _Py_ext_module_kind_INVALID;
284 break;
285 /* None of the rest affect the result kind. */
286 case _Py_ext_module_loader_result_EXCEPTION: /* fall through */
287 case _Py_ext_module_loader_result_ERR_MISSING: /* fall through */
288 case _Py_ext_module_loader_result_ERR_UNREPORTED_EXC: /* fall through */
289 case _Py_ext_module_loader_result_ERR_NONASCII_NOT_MULTIPHASE: /* fall through */
290 case _Py_ext_module_loader_result_ERR_NOT_MODULE: /* fall through */
291 case _Py_ext_module_loader_result_ERR_MISSING_DEF:
292 break;
293 default:
294 /* We added a new error kind but forgot to add it to this switch. */
295 assert(0);
296 }
297 }
298
299 void
_Py_ext_module_loader_result_apply_error(struct _Py_ext_module_loader_result * res,const char * name)300 _Py_ext_module_loader_result_apply_error(
301 struct _Py_ext_module_loader_result *res,
302 const char *name)
303 {
304 assert(!PyErr_Occurred());
305 assert(res->err != NULL && res->err == &res->_err);
306 struct _Py_ext_module_loader_result_error err = *res->err;
307 res->err = NULL;
308
309 /* We're otherwise done with the result at this point. */
310 _Py_ext_module_loader_result_clear(res);
311
312 #ifndef NDEBUG
313 switch (err.kind) {
314 case _Py_ext_module_loader_result_EXCEPTION: /* fall through */
315 case _Py_ext_module_loader_result_ERR_UNREPORTED_EXC:
316 assert(err.exc != NULL);
317 break;
318 case _Py_ext_module_loader_result_ERR_MISSING: /* fall through */
319 case _Py_ext_module_loader_result_ERR_UNINITIALIZED: /* fall through */
320 case _Py_ext_module_loader_result_ERR_NONASCII_NOT_MULTIPHASE: /* fall through */
321 case _Py_ext_module_loader_result_ERR_NOT_MODULE: /* fall through */
322 case _Py_ext_module_loader_result_ERR_MISSING_DEF:
323 assert(err.exc == NULL);
324 break;
325 default:
326 /* We added a new error kind but forgot to add it to this switch. */
327 assert(0);
328 }
329 #endif
330
331 const char *msg = NULL;
332 switch (err.kind) {
333 case _Py_ext_module_loader_result_EXCEPTION:
334 break;
335 case _Py_ext_module_loader_result_ERR_MISSING:
336 msg = "initialization of %s failed without raising an exception";
337 break;
338 case _Py_ext_module_loader_result_ERR_UNREPORTED_EXC:
339 msg = "initialization of %s raised unreported exception";
340 break;
341 case _Py_ext_module_loader_result_ERR_UNINITIALIZED:
342 msg = "init function of %s returned uninitialized object";
343 break;
344 case _Py_ext_module_loader_result_ERR_NONASCII_NOT_MULTIPHASE:
345 msg = "initialization of %s did not return PyModuleDef";
346 break;
347 case _Py_ext_module_loader_result_ERR_NOT_MODULE:
348 msg = "initialization of %s did not return an extension module";
349 break;
350 case _Py_ext_module_loader_result_ERR_MISSING_DEF:
351 msg = "initialization of %s did not return a valid extension module";
352 break;
353 default:
354 /* We added a new error kind but forgot to add it to this switch. */
355 assert(0);
356 PyErr_Format(PyExc_SystemError,
357 "loading %s failed due to init function", name);
358 return;
359 }
360
361 if (err.exc != NULL) {
362 PyErr_SetRaisedException(err.exc);
363 err.exc = NULL; /* PyErr_SetRaisedException() stole our reference. */
364 if (msg != NULL) {
365 _PyErr_FormatFromCause(PyExc_SystemError, msg, name);
366 }
367 }
368 else {
369 assert(msg != NULL);
370 PyErr_Format(PyExc_SystemError, msg, name);
371 }
372 }
373
374
375 /********************************************/
376 /* getting/running the module init function */
377 /********************************************/
378
379 #ifdef HAVE_DYNAMIC_LOADING
380 PyModInitFunction
_PyImport_GetModInitFunc(struct _Py_ext_module_loader_info * info,FILE * fp)381 _PyImport_GetModInitFunc(struct _Py_ext_module_loader_info *info,
382 FILE *fp)
383 {
384 const char *name_buf = PyBytes_AS_STRING(info->name_encoded);
385 dl_funcptr exportfunc;
386 #ifdef MS_WINDOWS
387 exportfunc = _PyImport_FindSharedFuncptrWindows(
388 info->hook_prefix, name_buf, info->filename, fp);
389 #else
390 {
391 const char *path_buf = PyBytes_AS_STRING(info->filename_encoded);
392 exportfunc = _PyImport_FindSharedFuncptr(
393 info->hook_prefix, name_buf, path_buf, fp);
394 }
395 #endif
396
397 if (exportfunc == NULL) {
398 if (!PyErr_Occurred()) {
399 PyObject *msg;
400 msg = PyUnicode_FromFormat(
401 "dynamic module does not define "
402 "module export function (%s_%s)",
403 info->hook_prefix, name_buf);
404 if (msg != NULL) {
405 PyErr_SetImportError(msg, info->name, info->filename);
406 Py_DECREF(msg);
407 }
408 }
409 return NULL;
410 }
411
412 return (PyModInitFunction)exportfunc;
413 }
414 #endif /* HAVE_DYNAMIC_LOADING */
415
416 int
_PyImport_RunModInitFunc(PyModInitFunction p0,struct _Py_ext_module_loader_info * info,struct _Py_ext_module_loader_result * p_res)417 _PyImport_RunModInitFunc(PyModInitFunction p0,
418 struct _Py_ext_module_loader_info *info,
419 struct _Py_ext_module_loader_result *p_res)
420 {
421 struct _Py_ext_module_loader_result res = {
422 .kind=_Py_ext_module_kind_UNKNOWN,
423 };
424
425 /* Call the module init function. */
426
427 /* Package context is needed for single-phase init */
428 const char *oldcontext = _PyImport_SwapPackageContext(info->newcontext);
429 PyObject *m = p0();
430 _PyImport_SwapPackageContext(oldcontext);
431
432 /* Validate the result (and populate "res". */
433
434 if (m == NULL) {
435 /* The init func for multi-phase init modules is expected
436 * to return a PyModuleDef after calling PyModuleDef_Init().
437 * That function never raises an exception nor returns NULL,
438 * so at this point it must be a single-phase init modules. */
439 res.kind = _Py_ext_module_kind_SINGLEPHASE;
440 if (PyErr_Occurred()) {
441 _Py_ext_module_loader_result_set_error(
442 &res, _Py_ext_module_loader_result_EXCEPTION);
443 }
444 else {
445 _Py_ext_module_loader_result_set_error(
446 &res, _Py_ext_module_loader_result_ERR_MISSING);
447 }
448 goto error;
449 } else if (PyErr_Occurred()) {
450 /* Likewise, we infer that this is a single-phase init module. */
451 res.kind = _Py_ext_module_kind_SINGLEPHASE;
452 _Py_ext_module_loader_result_set_error(
453 &res, _Py_ext_module_loader_result_ERR_UNREPORTED_EXC);
454 /* We would probably be correct to decref m here,
455 * but we weren't doing so before,
456 * so we stick with doing nothing. */
457 m = NULL;
458 goto error;
459 }
460
461 if (Py_IS_TYPE(m, NULL)) {
462 /* This can happen when a PyModuleDef is returned without calling
463 * PyModuleDef_Init on it
464 */
465 _Py_ext_module_loader_result_set_error(
466 &res, _Py_ext_module_loader_result_ERR_UNINITIALIZED);
467 /* Likewise, decref'ing here makes sense. However, the original
468 * code has a note about "prevent segfault in DECREF",
469 * so we play it safe and leave it alone. */
470 m = NULL; /* prevent segfault in DECREF */
471 goto error;
472 }
473
474 if (PyObject_TypeCheck(m, &PyModuleDef_Type)) {
475 /* multi-phase init */
476 res.kind = _Py_ext_module_kind_MULTIPHASE;
477 res.def = (PyModuleDef *)m;
478 /* Run PyModule_FromDefAndSpec() to finish loading the module. */
479 }
480 else if (info->hook_prefix == nonascii_prefix) {
481 /* Non-ASCII is only supported for multi-phase init. */
482 res.kind = _Py_ext_module_kind_MULTIPHASE;
483 /* Don't allow legacy init for non-ASCII module names. */
484 _Py_ext_module_loader_result_set_error(
485 &res, _Py_ext_module_loader_result_ERR_NONASCII_NOT_MULTIPHASE);
486 goto error;
487 }
488 else {
489 /* single-phase init (legacy) */
490 res.kind = _Py_ext_module_kind_SINGLEPHASE;
491 res.module = m;
492
493 if (!PyModule_Check(m)) {
494 _Py_ext_module_loader_result_set_error(
495 &res, _Py_ext_module_loader_result_ERR_NOT_MODULE);
496 goto error;
497 }
498
499 res.def = _PyModule_GetDef(m);
500 if (res.def == NULL) {
501 PyErr_Clear();
502 _Py_ext_module_loader_result_set_error(
503 &res, _Py_ext_module_loader_result_ERR_MISSING_DEF);
504 goto error;
505 }
506 }
507
508 assert(!PyErr_Occurred());
509 assert(res.err == NULL);
510 *p_res = res;
511 return 0;
512
513 error:
514 assert(!PyErr_Occurred());
515 assert(res.err != NULL);
516 Py_CLEAR(res.module);
517 res.def = NULL;
518 *p_res = res;
519 p_res->err = &p_res->_err;
520 return -1;
521 }
522