Bug in Android ARM 32-bit build with assembly allowed

Marian Kechlibar marian.kechlibar at circletech.net
Tue Apr 21 12:36:49 UTC 2020


GMP version:         6.2.0, the bug has already been observed in January
2020 here: https://github.com/tanersener/mobile-ffmpeg/wiki/ASM-Support

What is wrong:      A 32-bit native Android application using GMP
crashes upon start (System.loadLibrary Unsatisfied Link Error in
library) with a complaint that the symbol __gmp_binvert_limb_table missing.

18 04-17 13:28:55.270 I/System.out(19997): System.loadLibrary
Unsatisfied Link Error in library: (library_name) 19 04-17 13:28:55.270
W/System.err(19997): java.lang.UnsatisfiedLinkError: dlopen failed:
cannot locate symbol "__gmp_binvert_limb_table" referenced by
"/data/app/(application_name)/lib/arm/libgmp.so".
                         
Compiler:            The library libgmp is cross-compiled on Linux using
Android NDK 21. A short compilation script is attached. The compiler is
clang 9.0.8.                   
                               
Configure options:     Everything is found in the compilation script
attached.

Special note:        This problem only arises if assembly is enabled. If
the --disable-assembly option is used, the problem disappears.
                    64-bit ARM build (arm64-v8a) does not have this
problem, only 32-bit ARM does (armeabi-v7a, with or without NEON support).

I prepared a special test harness (a MSVC Android Solution) that
demonstrates the bad behavior when the library is compiled with assembly
and good behavior when it is compiled without assembly. I am attaching
screenshots of both situations. I am not attaching the solution, though,
because it is a 6 MB ZIP and I do not want to send an e-mail with a huge
attachment to a list prior to the administrator's consent.

Best regards

Marian Kechlibar

           

-------------- next part --------------
#!/bin/bash

if [ ! -x configure ]
then
  echo "Run this script from the GMP base directory"
  exit 1
fi

export NDK="/opt/android-ndk-r21"
if [ ! -d ${NDK} ]
then
  echo "Please download and install the NDK, then update the path in this script."
  echo "  http://developer.android.com/sdk/ndk/index.html"
  exit 1
fi

export PATH_TO_VERSION_SCRIPT="/home/marian/CryptoCult/DLL_BigInt_0/android/libgmp.map.txt"

export GC_SECTION_ARGUMENT="-Wl,--gc-sections"

export LIBGMP_LDFLAGS='-avoid-version'
export LIBGMPXX_LDFLAGS='-avoid-version'

export TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64
export API=21
export TARGET=aarch64-linux-android
export AR=$TOOLCHAIN/bin/$TARGET-ar
export AS=$TOOLCHAIN/bin/$TARGET-as
export CC=$TOOLCHAIN/bin/$TARGET$API-clang
export CXX=$TOOLCHAIN/bin/$TARGET$API-clang++
export LD=$TOOLCHAIN/bin/ld.lld
export RANLIB=$TOOLCHAIN/bin/$TARGET-ranlib
export STRIP=$TOOLCHAIN/bin/$TARGET-strip

################################################################################################################

export BASE_CFLAGS='-O2 -g -pedantic -fomit-frame-pointer -Wa,--noexecstack -ffunction-sections -funwind-tables -no-canonical-prefixes -fno-strict-aliasing'

# LDFLAGS for 64-bit ARM
export LDFLAGS="-Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now $GC_SECTION_ARGUMENT -Wl,--version-script,$PATH_TO_VERSION_SCRIPT"

# arm64-v8a
echo "======= COMPILING FOR arm64-v8a ======="
export CFLAGS="${BASE_CFLAGS} -fstack-protector-strong"
./configure --prefix=/usr --disable-static --disable-cxx --disable-fft --build=x86_64-pc-linux-gnu --host=$TARGET MPN_PATH="arm64 generic"
sed -i.bak '/HAVE_LOCALECONV 1/d' ./config.h
make -j8 V=1 2>&1 | tee arm64-v8a.log
make install DESTDIR=$PWD/arm64-v8a
cd arm64-v8a && mv usr/lib/libgmp.so usr/include/gmp.h . && rm -rf usr && cd ..
make distclean

export TARGET=arm-linux-androideabi
export TARGET2=armv7a-linux-androideabi
export AR=$TOOLCHAIN/bin/$TARGET-ar
export AS=$TOOLCHAIN/bin/$TARGET-as
export CC=$TOOLCHAIN/bin/$TARGET2$API-clang
export CXX=$TOOLCHAIN/bin/$TARGET2$API-clang++
export LD=$TOOLCHAIN/bin/ld.lld

export RANLIB=$TOOLCHAIN/bin/$TARGET-ranlib
export STRIP=$TOOLCHAIN/bin/$TARGET-strip

# LDFLAGS for 32-bit ARM
export LDFLAGS="-Wl,--fix-cortex-a8 -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now $GC_SECTION_ARGUMENT -Wl,--version-script,$PATH_TO_VERSION_SCRIPT -Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libgcc_real.a -Wl,--exclude-libs,libunwind.a"

# armeabi-v7a with neon (unsupported target: will cause crashes on many phones, but works well on the Nexus One)
export CFLAGS="${BASE_CFLAGS} -fstack-protector -march=armv7-a -mfloat-abi=softfp -mfpu=neon -ftree-vectorize"
./configure --prefix=/usr --disable-static --disable-cxx --disable-fft --build=x86_64-pc-linux-gnu --host=$TARGET MPN_PATH="arm/v6t2 arm/v6 arm/v5 arm generic"
sed -i.bak '/HAVE_LOCALECONV 1/d' ./config.h
make -j8 V=1 2>&1 | tee armeabi-v7a-neon.log
make install DESTDIR=$PWD/armeabi-v7a-neon
cd armeabi-v7a-neon && mv usr/lib/libgmp.so usr/include/gmp.h . && rm -rf usr && cd ..
make distclean

# armeabi-v7a
export CFLAGS="${BASE_CFLAGS} -fstack-protector -march=armv7-a -mfloat-abi=softfp -mfpu=vfp"
./configure --prefix=/usr --disable-static --disable-cxx --disable-fft --build=x86_64-pc-linux-gnu --host=$TARGET MPN_PATH="arm/v6t2 arm/v6 arm/v5 arm generic"
sed -i.bak '/HAVE_LOCALECONV 1/d' ./config.h
make -j8 V=1 2>&1 | tee armeabi-v7a.log
make install DESTDIR=$PWD/armeabi-v7a
cd armeabi-v7a && mv usr/lib/libgmp.so usr/include/gmp.h . && rm -rf usr && cd ..
make distclean

exit 0
-------------- next part --------------
A non-text attachment was scrubbed...
Name: bad-library_Test Harness.jpg
Type: image/jpeg
Size: 157923 bytes
Desc: not available
URL: <https://gmplib.org/list-archives/gmp-bugs/attachments/20200421/2fada3d9/attachment-0002.jpg>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: good-library_Test Harness.jpg
Type: image/jpeg
Size: 77828 bytes
Desc: not available
URL: <https://gmplib.org/list-archives/gmp-bugs/attachments/20200421/2fada3d9/attachment-0003.jpg>


More information about the gmp-bugs mailing list