From e3a41a51dab04d346db6d64bd202aa72cdff80c5 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Wed, 18 Sep 2013 23:10:25 +0900 Subject: [PATCH] Fix link error with Android NDK r9 Since Android ndk r9, __set_errno is deprecated. It is now defined as inline function in errno.h. The syscall assembly calls __set_errno, but since libc.so does not export it, the link fails. To workaround this, replace all occurrences of __set_errno with a2_set_errno and define it as normal C function. --- configure.ac | 2 ++ src/Makefile.am | 4 +++ src/android/android.c | 48 ++++++++++++++++++++++++++++++++++ src/android/arm-ftruncate64.S | 2 +- src/android/mips-ftruncate64.S | 2 +- src/android/x86-ftruncate64.S | 2 +- 6 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 src/android/android.c diff --git a/configure.ac b/configure.ac index ba678ccd..2f827930 100644 --- a/configure.ac +++ b/configure.ac @@ -869,6 +869,7 @@ AC_SUBST([bashcompletiondir]) case "$host" in *android*) + android=yes LIBS="$LIBS -lstdc++ -lsupc++" case "$host" in arm-*) @@ -886,6 +887,7 @@ case "$host" in ;; esac +AM_CONDITIONAL([ANDROID], [test "x$android" = "xyes"]) AM_CONDITIONAL([ANDROID_ARM], [test "x$android_arm" = "xyes"]) AM_CONDITIONAL([ANDROID_MIPS], [test "x$android_mips" = "xyes"]) AM_CONDITIONAL([ANDROID_X86], [test "x$android_x86" = "xyes"]) diff --git a/src/Makefile.am b/src/Makefile.am index b9f8edc4..01532752 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -253,6 +253,10 @@ SRCS = option_processing.cc\ FtpTunnelRequestConnectChain.h\ Lock.h +if ANDROID +SRCS += android/android.c +endif # ANDROID + # Android NDK R8e does not provide ftruncate64. Use assembly code from # android source code and link it. if ANDROID_ARM diff --git a/src/android/android.c b/src/android/android.c new file mode 100644 index 00000000..73ac29b2 --- /dev/null +++ b/src/android/android.c @@ -0,0 +1,48 @@ +/* */ +#include + +/* + * Since Android ndk r9, __set_errno is deprecated. It is now defined + * as inline function in errno.h. The syscall assembly calls + * __set_errno, but since libc.so does not export it, the link + * fails. To workaround this, replace all occurrences of __set_errno + * with a2_set_errno and define it here. + */ +int a2_set_errno(int n) +{ + errno = n; + return -1; +} diff --git a/src/android/arm-ftruncate64.S b/src/android/arm-ftruncate64.S index 123897dc..7addbc40 100644 --- a/src/android/arm-ftruncate64.S +++ b/src/android/arm-ftruncate64.S @@ -11,5 +11,5 @@ ENTRY(ftruncate64) cmn r0, #(MAX_ERRNO + 1) bxls lr neg r0, r0 - b __set_errno + b a2_set_errno END(ftruncate64) diff --git a/src/android/mips-ftruncate64.S b/src/android/mips-ftruncate64.S index 398069c4..ff507ba5 100644 --- a/src/android/mips-ftruncate64.S +++ b/src/android/mips-ftruncate64.S @@ -15,7 +15,7 @@ ftruncate64: j $ra nop 1: - la $t9,__set_errno + la $t9,a2_set_errno j $t9 nop .set reorder diff --git a/src/android/x86-ftruncate64.S b/src/android/x86-ftruncate64.S index 021cc8fe..46dc5d84 100644 --- a/src/android/x86-ftruncate64.S +++ b/src/android/x86-ftruncate64.S @@ -17,7 +17,7 @@ ENTRY(ftruncate64) jb 1f negl %eax pushl %eax - call __set_errno + call a2_set_errno addl $4, %esp orl $-1, %eax 1: