Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions cpython-unix/build-cpython.sh
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,19 @@ if [ -n "${CROSS_COMPILING}" ]; then
fi
fi

# Inject -Bsymbolic* on shared library to force direct symbol resolution
# and potentially unlock more compiler+linker optimizations.
#
# Patch is safe on all arches but runs into context conflict on macOS.
# It isn't needed for macOS. So workaround by not applying there.
if [[ "${PYBUILD_PLATFORM}" != macos* ]]; then
if [ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_11}" ]; then
patch -p1 -i "${ROOT}/patch-configure-linker-symbolic.patch"
else
patch -p1 -i "${ROOT}/patch-configure-linker-symbolic-3.10.patch"
fi
fi

# LIBTOOL_CRUFT is unused and breaks cross-compiling on macOS. Nuke it.
# Submitted upstream at https://github.com/python/cpython/pull/101048.
if [ -n "${PYTHON_MEETS_MAXIMUM_VERSION_3_11}" ]; then
Expand Down
23 changes: 23 additions & 0 deletions cpython-unix/patch-configure-linker-symbolic-3.10.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
diff --git a/configure.ac b/configure.ac
index ac3be3850a9..88a2027f517 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2713,8 +2713,16 @@ then
fi
;;
Linux*|GNU*|QNX*|VxWorks*)
- LDSHARED='$(CC) -shared'
- LDCXXSHARED='$(CXX) -shared';;
+ # See https://maskray.me/blog/2021-05-16-elf-interposition-and-bsymbolic.
+ # This is related to the -fno-semantic-interposition optimization that
+ # --enable-optimizations engages automatically. It changes the linkage
+ # behavior so the runtime loader searches the current DSO first before
+ # falling back to the default search mechanism of the executable plus
+ # all its loaded DSOs. It has much the same effect as
+ # -fno-semantic-interposition but can also enable optimizations across
+ # translation units.
+ LDSHARED='$(CC) -shared -Wl,-Bsymbolic-functions'
+ LDCXXSHARED='$(CXX) -shared -Wl,-Bsymbolic-functions';;
FreeBSD*)
if [[ "`$CC -dM -E - </dev/null | grep __ELF__`" != "" ]]
then
23 changes: 23 additions & 0 deletions cpython-unix/patch-configure-linker-symbolic.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
diff --git a/configure.ac b/configure.ac
index a1f4a567095..f7aa69556e5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3489,8 +3489,16 @@ then
LDSHARED='$(CC) -shared'
LDCXXSHARED='$(CXX) -shared';;
Linux*|GNU*|QNX*|VxWorks*|Haiku*)
- LDSHARED='$(CC) -shared'
- LDCXXSHARED='$(CXX) -shared';;
+ # See https://maskray.me/blog/2021-05-16-elf-interposition-and-bsymbolic.
+ # This is related to the -fno-semantic-interposition optimization that
+ # --enable-optimizations engages automatically. It changes the linkage
+ # behavior so the runtime loader searches the current DSO first before
+ # falling back to the default search mechanism of the executable plus
+ # all its loaded DSOs. It has much the same effect as
+ # -fno-semantic-interposition but can also enable optimizations across
+ # translation units.
+ LDSHARED='$(CC) -shared -Wl,-Bsymbolic-functions'
+ LDCXXSHARED='$(CXX) -shared -Wl,-Bsymbolic-functions';;
FreeBSD*)
if [[ "`$CC -dM -E - </dev/null | grep __ELF__`" != "" ]]
then
16 changes: 16 additions & 0 deletions docs/quirks.rst
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,22 @@ compile extensions, too.
If there is a build time normalization that you think should be performed to
make distributions more portable, please file a GitHub issue.

.. _quirk_ld_preload_doesnt_work:

``LD_PRELOAD`` Does Not Work
============================

This project applies various build optimizations that undermine the
ability for ``LD_PRELOAD`` to reliably intercept symbols provided by
``libpython``:

* Functions can be aggressively inlined - bypassing the PLT - and inlined
function calls cannot be intercepted by ``LD_PRELOAD``'d libraries.
* Use of the linker option ``-Bsymbolic-functions`` on ``libpython`` forces
symbols to resolve to the local library (``libpython``) instead of going
through the regular loader lookup sequence, which would otherwise process
``LD_PRELOAD``'d libraries before ``libpython``.

.. _quirk_former:
.. _quirk_missing_libcrypt:
.. _quirk_linux_libx11:
Expand Down
Loading