Commit c5ae169e authored by Michael Felt's avatar Michael Felt Committed by Victor Stinner

bpo-26439 Fix ctypes.util.find_library failure on AIX (#4507)

Implement find_library() support in ctypes/util for AIX.

Add some AIX specific tests.
parent 319c0345
# added for local development
.buildaix/
Modules/python.exp
buildaix/
installp/
.gitignore
# Two-trick pony for OSX and other case insensitive file systems:
# Ignore ./python binary on Unix but still look into ./Python/ directory.
/python
......
......@@ -338,6 +338,14 @@ class CDLL(object):
flags |= _FUNCFLAG_USE_ERRNO
if use_last_error:
flags |= _FUNCFLAG_USE_LASTERROR
if _sys.platform.startswith("aix"):
"""When the name contains ".a(" and ends with ")",
e.g., "libFOO.a(libFOO.so)" - this is taken to be an
archive(member) syntax for dlopen(), and the mode is adjusted.
Otherwise, name is presented to dlopen() as a file argument.
"""
if name and name.endswith(")") and ".a(" in name:
mode |= ( _os.RTLD_MEMBER | _os.RTLD_NOW )
class _FuncPtr(_CFuncPtr):
_flags_ = flags
......
This diff is collapsed.
......@@ -80,6 +80,15 @@ if os.name == "posix" and sys.platform == "darwin":
continue
return None
if sys.platform.startswith("aix"):
# AIX has two styles of storing shared libraries
# GNU auto_tools refer to these as svr4 and aix
# svr4 (System V Release 4) is a regular file, often with .so as suffix
# AIX style uses an archive (suffix .a) with members (e.g., shr.o, libssl.so)
# see issue#26439 and _aix.py for more details
from ctypes._aix import find_library
elif os.name == "posix":
# Andreas Degert's find functions, using gcc, /sbin/ldconfig, objdump
import re, tempfile
......@@ -324,6 +333,22 @@ def test():
print(cdll.LoadLibrary("libcrypto.dylib"))
print(cdll.LoadLibrary("libSystem.dylib"))
print(cdll.LoadLibrary("System.framework/System"))
# issue-26439 - fix broken test call for AIX
elif sys.platform.startswith("aix"):
from ctypes import CDLL
if sys.maxsize < 2**32:
print("Using CDLL(name, os.RTLD_MEMBER): %s" % CDLL("libc.a(shr.o)", os.RTLD_MEMBER))
print("Using cdll.LoadLibrary(): %s" % cdll.LoadLibrary("libc.a(shr.o)"))
# librpm.so is only available as 32-bit shared library
print(find_library("rpm"))
print(cdll.LoadLibrary("librpm.so"))
else:
print("Using CDLL(name, os.RTLD_MEMBER): %s" % CDLL("libc.a(shr_64.o)", os.RTLD_MEMBER))
print("Using cdll.LoadLibrary(): %s" % cdll.LoadLibrary("libc.a(shr_64.o)"))
print("crypt\t:: %s" % find_library("crypt"))
print("crypt\t:: %s" % cdll.LoadLibrary(find_library("crypt")))
print("crypto\t:: %s" % find_library("crypto"))
print("crypto\t:: %s" % cdll.LoadLibrary(find_library("crypto")))
else:
print(cdll.LoadLibrary("libm.so"))
print(cdll.LoadLibrary("libcrypt.so"))
......
Fix ctypes.util.find_library() for AIX
by implementing ctypes._aix.find_library()
Patch by: Michael Felt aka aixtools
ctypes.util.find_library has always returned None on a standard AIX.
With this patch there is support for both AIX and svr4 shared libraries.
None is returned only when there is nothinbg found. Normal behavior is now:
on AIX find_library("FOO") returns either libFOO.a(libFOO.so) or libFOO.so
while legacy names e.g., find_library("c") returns libc.a(shr.o)
or libc.a(shr_64.o) - depending on 32 or 64-bit operations.
Include RTLD_MEMBER to mode to support AIX legacy library(member) names
(Modules/_ctype/posixmodule.c), ctypes/__init__.py and configure.ac)
......@@ -13007,6 +13007,9 @@ all_ins(PyObject *m)
#if HAVE_DECL_RTLD_DEEPBIND
if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
#endif
#if HAVE_DECL_RTLD_MEMBER
if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
#endif
#ifdef HAVE_GETRANDOM_SYSCALL
if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
......
......@@ -9872,7 +9872,6 @@ fi
if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
......@@ -14360,6 +14359,17 @@ fi
cat >>confdefs.h <<_ACEOF
#define HAVE_DECL_RTLD_DEEPBIND $ac_have_decl
_ACEOF
ac_fn_c_check_decl "$LINENO" "RTLD_MEMBER" "ac_cv_have_decl_RTLD_MEMBER" "#include <dlfcn.h>
"
if test "x$ac_cv_have_decl_RTLD_MEMBER" = xyes; then :
ac_have_decl=1
else
ac_have_decl=0
fi
cat >>confdefs.h <<_ACEOF
#define HAVE_DECL_RTLD_MEMBER $ac_have_decl
_ACEOF
# determine what size digit to use for Python's longs
......
......@@ -4480,7 +4480,7 @@ then
[define to 1 if your sem_getvalue is broken.])
fi
AC_CHECK_DECLS([RTLD_LAZY, RTLD_NOW, RTLD_GLOBAL, RTLD_LOCAL, RTLD_NODELETE, RTLD_NOLOAD, RTLD_DEEPBIND], [], [], [[#include <dlfcn.h>]])
AC_CHECK_DECLS([RTLD_LAZY, RTLD_NOW, RTLD_GLOBAL, RTLD_LOCAL, RTLD_NODELETE, RTLD_NOLOAD, RTLD_DEEPBIND, RTLD_MEMBER], [], [], [[#include <dlfcn.h>]])
# determine what size digit to use for Python's longs
AC_MSG_CHECKING([digit size for Python's longs])
......
......@@ -210,6 +210,10 @@
don't. */
#undef HAVE_DECL_RTLD_LOCAL
/* Define to 1 if you have the declaration of `RTLD_MEMBER', and to 0 if you
don't. */
#undef HAVE_DECL_RTLD_MEMBER
/* Define to 1 if you have the declaration of `RTLD_NODELETE', and to 0 if you
don't. */
#undef HAVE_DECL_RTLD_NODELETE
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment