Skip to content

[BUG] with ndk r23 and newer, builtin symbols cannot be found when a program is linked with libtool #1614

Closed as not planned
@Grimler91

Description

@Grimler91

Hi,

Description

Moving from ndk r21 to r23 we started having issues [1], [2], [3], [4], [5], with some programs failing to be run on device with errors like:

CANNOT LINK EXECUTABLE "tesseract": cannot locate symbol "__extenddftf2" referenced by "/data/data/com.termux/files/usr/lib/libtesseract.so"...

In both cases the issue seem to only happen if the code is compiled using a configure && make system, with a CMakeLists.txt it works fine. After some digging we suspect this happens due to libtool and how it handles the linker flags (see discussion).

One (rather ugly) workaround to solve the issue is to add libclang_rt.builtins-aarch64-android.a as a lib in LDFLAGS. Is there a better solution?

Steps to reproduce

The example below is for aarch64.

# Clone a minimal configure&make project that uses `static_cast<long double>` (which compiles into __extenddftf2)
git clone https://github.com/grimler91/minimal-ndk-r23-issue-example 
cd minimal-ndk-r23-issue-example

aclocal
libtoolize --copy
autoconf
automake --add-missing --foreign

# Adjust for path to your ndk
TOOLCHAINROOT=/opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64
CCPREFIX=$TOOLCHAINROOT/bin/aarch64-linux-android28-

# Optimization level seem to make a difference
CXXFLAGS=-O0 CXX=${CCPREFIX}clang++ CC=${CCPREFIX}clang ./configure --host=aarch64-linux-android --prefix=$(pwd)

make
make install

# Push compiled program, library and libc++_shared to device
adb push bin/main lib/libtest.so $TOOLCHAINROOT/sysroot/usr/lib/aarch64-linux-android/libc++_shared.so /data/local/tmp/

# Try to run the program on device:
adb shell
$ cd /data/local/tmp
$ LD_PRELOAD=./libtest.so:./libc++_shared.so ./main

You should get something like:

WARNING: linker: Warning: "/data/local/tmp/libc++_shared.so" unused DT entry: unknown processor-specific (type 0x70000001 arg 0x0) (ignoring)
CANNOT LINK EXECUTABLE "./main": cannot locate symbol "__extenddftf2" referenced by "/data/local/tmp/libtest.so"...

The __extend* symbols are undefined in libtest.so when compiled like above:

$ readelf -Wa lib/libtest.so | grep __extend
0000000000002938  0000000400000402 R_AARCH64_JUMP_SLOT    0000000000000000 __extenddftf2 + 0
     4: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND __extenddftf2
    35: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND __extenddftf2

but for ndk r21, where we linked against libgcc, we get

$ readelf -Wa lib/libtest.so | grep __extend
0000000000001fd0  0000000e00000402 R_AARCH64_JUMP_SLOT    0000000000000704 __extenddftf2 + 0
    14: 0000000000000704   248 FUNC    GLOBAL DEFAULT   10 __extenddftf2
    73: 0000000000000704   248 FUNC    GLOBAL DEFAULT   10 __extenddftf2

Environment Details

  • NDK Version: 23.1.7779620
  • Build system: see above
  • Host OS: Linux (ubuntu/archlinux)
  • ABI: arm64-v8a
  • NDK API level: Tested with 24 and 28
  • Device API level: 30

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions