Last active
August 22, 2018 23:29
-
-
Save landonf/e745c308dbbf19755c55 to your computer and use it in GitHub Desktop.
Examples: How DYLD_* Environmental Variables Break Mach-O Library Resolution
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# DYLD_LIBRARY_PATH library variables break linking of standard system libraries by forcing dyld to ignore | |
# everything but the library's basename when performing what would otherwise be successful library | |
# resolution. | |
mkdir rust-lib | |
echo 'void my_libjpeg_api (void) { }' | clang -dynamiclib -x objective-c -o rust-lib/libjpeg.dylib - | |
echo 'extern void my_libjpeg_api(void); int main (int argc, char *argv[]) { my_libjpeg_api(); return 0; }' | clang -x objective-c -o example - -framework ImageIO -Lrust-lib -ljpeg | |
env DYLD_LIBRARY_PATH=`pwd`/rust-lib ./example | |
#dyld: Library not loaded: /System/Library/Frameworks/ImageIO.framework/Versions/A/Resources/libJPEG.dylib | |
# Referenced from: /System/Library/Frameworks/ImageIO.framework/Versions/A/ImageIO | |
# Reason: Incompatible library version: ImageIO requires version 1.0.0 or later, but libjpeg.dylib provides version 0.0.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# DYLD_FALLBACK_LIBRARY_PATH breaks library path resolution when you have two applications that | |
# have a library name collision and use DYLD_* varibles to force dyld to find their libraries -- a | |
# use-case that would work without error when using proper install name/@rpath Mach-O linking. | |
mkdir rust-lib | |
mkdir mathematica-lib | |
echo 'void my_libjpeg_api (void) { }' | clang -dynamiclib -x objective-c -o rust-lib/libjpeg.dylib -install_name libjpeg.dylib - | |
clang -dynamiclib -x objective-c -o mathematica-lib/libjpeg.dylib -install_name libjpeg.dylib - < /dev/null | |
echo 'extern void my_libjpeg_api(void); int main (int argc, char *argv[]) { my_libjpeg_api(); return 0; }' | clang -x objective-c -o example - -framework ImageIO -Lrust-lib -ljpeg | |
env DYLD_FALLBACK_LIBRARY_PATH=`pwd`/mathematica-lib:`pwd`/rust-lib ./example | |
#dyld: lazy symbol binding failed: Symbol not found: _my_libjpeg_api | |
# Referenced from: /private/tmp/./example | |
# Expected in: /tmp/mathematica-lib/libjpeg.dylib | |
# | |
#dyld: Symbol not found: _my_libjpeg_api | |
# Referenced from: /private/tmp/./example | |
# Expected in: /tmp/mathematica-lib/libjpeg.dylib |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# DYLD_FALLBACK_LIBRARY_PATH library variables can also break weak linking of libraries if 1) the weakly linked | |
# library is not found, and 2) a fallback path contains an incompatible library. | |
# | |
# Assume a library weakly linked by a third-party library. If the library is not found, but a similarly named library | |
# is found in DYLD_FALLBACK_LIBRARY_PATH, dyld will attempt to use that (incorrect) library. | |
mkdir rust-lib | |
mkdir third-party-lib | |
# Create a 'libthird_party.dylib' library that weakly links to a 'libcommon_libname.dylib' | |
echo 'void my_weak_api (void) { }' | clang -dynamiclib -x objective-c -o third-party-lib/libcommon_libname.dylib - | |
echo 'extern void my_weak_api (void); void my_weak_api_caller (void) { if (my_weak_api) my_weak_api(); }' | clang -dynamiclib -x objective-c -o third-party-lib/libthird_party.dylib -weak_library third-party-lib/libcommon_libname.dylib - | |
# Remove the weakly linked library; we're pretending that it's not available on this install, a possibility | |
# that led us to weakly link it in the first place. | |
rm third-party-lib/libcommon_libname.dylib | |
# Create a conflictingly-named 'libcommon_libname.dylib' library | |
clang -dynamiclib -x objective-c -o rust-lib/libcommon_libname.dylib - < /dev/null | |
# Link our binary against libthird_party.dylib | |
echo 'extern void my_weak_api_caller(void); int main (int argc, char *argv[]) { my_weak_api_caller(); return 0; }' | clang -x objective-c -o example - -Lthird-party-lib -lthird_party | |
env DYLD_FALLBACK_LIBRARY_PATH=`pwd`/rust-lib ./example | |
#dyld: lazy symbol binding failed: Symbol not found: _my_weak_api | |
# Referenced from: third-party-lib/libthird_party.dylib | |
# Expected in: /tmp/rust-lib/libcommon_libname.dylib | |
#dyld: Symbol not found: _my_weak_api | |
# Referenced from: third-party-lib/libthird_party.dylib | |
# Expected in: /tmp/rust-lib/libcommon_libname.dylib |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment