Android hints: Detect stub functions and mark them as undefined.
authorBrian Fraser <fraserbn@gmail.com>
Sun, 28 Apr 2013 00:01:44 +0000 (21:01 -0300)
committerBrian Fraser <fraserbn@gmail.com>
Sun, 26 Jan 2014 17:44:19 +0000 (14:44 -0300)
Bionic implements several functions as stumps that simply warn
and return null, which leads to situations like this:

FIX ME! implement getprotobyname() bionic/libc/bionic/stubs.c:378

This commit introduces some probes for functions (getnetbyname,
getnetbyaddr, getmntent, getprotobyname, getprotobynumber, endpwent,
ttyname) that we use and are actually stubs in at least some
versions of Android.
If we find a stub, we pretend that the function is undefined, so
the above example becomes this:

Unsupported socket function "getprotobyname" called at -e line 1.

Note that this commit does not fix the modules that assume that
these functions are always available, so 'make test' still fails.

hints/linux-android.sh

index ae8be9d..1c5281f 100644 (file)
@@ -12,6 +12,98 @@ d_setlocale='undef'
 d_setlocale_r='undef'
 i_locale='undef'
 
+# Bionic defines several stubs that just warn and return NULL
+# https://gitorious.org/0xdroid/bionic/blobs/70b2ef0ec89a9c9d4c2d4bcab728a0e72bafb18e/libc/bionic/stubs.c
+# https://android.googlesource.com/platform/bionic/+/master/libc/bionic/stubs.cpp
+
+# If they warn with 'FIX' or 'Android', assume they are the stubs
+# we want to avoid.
+
+# These are all stubs as well, but the core doesn't use them:
+# getusershell setusershell endusershell
+
+# This script UU/archname.cbu will get 'called-back' by Configure.
+cat > UU/archname.cbu <<'EOCBU'
+# egrep pattern to detect a stub warning on Android.
+# Right now we're checking for:
+# Android 2.x: FIX ME! implement FUNC
+# Android 4.x: FUNC is not implemented on Android
+android_stub='FIX|Android'
+
+cat > try.c << 'EOM'
+#include <netdb.h>
+int main() { (void) getnetbyname("foo"); return(0); }
+EOM
+$cc $ccflags try.c -o try
+android_warn=`$run ./try 2>&1 | $egrep "$android_stub"`
+if test "X$android_warn" != X; then
+   d_getnbyname="$undef"
+fi
+
+cat > try.c << 'EOM'
+#include <netdb.h>
+int main() { (void) getnetbyaddr((uint32_t)1, AF_INET); return(0); }
+EOM
+$cc $ccflags try.c -o try
+android_warn=`$run ./try 2>&1 | $egrep "$android_stub"`
+if test "X$android_warn" != X; then
+   d_getnbyaddr="$undef"
+fi
+
+cat > try.c << 'EOM'
+#include <stdio.h>
+#include <mntent.h>
+#include <unistd.h>
+int main() { (void) getmntent(stdout); return(0); }
+EOM
+$cc $ccflags try.c -o try
+android_warn=`$run ./try 2>&1 | $egrep "$android_stub"`
+if test "X$android_warn" != X; then
+   d_getmntent="$undef"
+fi
+
+cat > try.c << 'EOM'
+#include <netdb.h>
+int main() { (void) getprotobyname("foo"); return(0); }
+EOM
+$cc $ccflags try.c -o try
+android_warn=`$run ./try 2>&1 | $egrep "$android_stub"`
+if test "X$android_warn" != X; then
+   d_getpbyname="$undef"
+fi
+
+cat > try.c << 'EOM'
+#include <netdb.h>
+int main() { (void) getprotobynumber(1); return(0); }
+EOM
+$cc $ccflags try.c -o try
+android_warn=`$run ./try 2>&1 | $egrep "$android_stub"`
+if test "X$android_warn" != X; then
+   d_getpbynumber="$undef"
+fi
+
+cat > try.c << 'EOM'
+#include <sys/types.h>
+#include <pwd.h>
+int main() { endpwent(); return(0); }
+EOM
+$cc $ccflags try.c -o try
+android_warn=`$run ./try 2>&1 | $egrep "$android_stub"`
+if test "X$android_warn" != X; then
+   d_endpwent="$undef"
+fi
+
+cat > try.c << 'EOM'
+#include <unistd.h>
+int main() { (void) ttyname(STDIN_FILENO); return(0); }
+EOM
+$cc $ccflags try.c -o try
+android_warn=`$run ./try 2>&1 | $egrep "$android_stub"`
+if test "X$android_warn" != X; then
+   d_ttyname="$undef"
+fi
+
+EOCBU
 
 case "$src" in
     /*) run=$src/Cross/run