Fix ndk-gdb for debugging applications on x86_64

This patch fixes several issues:

1) Use ro.product.cpu.abilist64 and ro.product.cpu.abilist32
instead of ro.product.cpu.abi and ro.product.cpu.abi2. The latter
ones for x86_64 do not contain x86 abi.

2) Pull app_process32 instead pf app_process when debugging 32-bit
app on 64-bit device.

3) Pull linker64 for 64-bit.

4) Pull lib64/libc.so for 64-bit.

5) We have to push the gdbserver that matches the ABI of the app AND
the ABI of the device, not just the one that matches the ABI of the device.

Change-Id: Ibb0f264fdd007cb2a84aad87bcb396d24e2092e7
Signed-off-by: Alexander Ivchenko <alexander.ivchenko@intel.com>
diff --git a/ndk-gdb b/ndk-gdb
index a204ba2..6746a05 100755
--- a/ndk-gdb
+++ b/ndk-gdb
@@ -549,13 +549,23 @@
 # And check that they are supported by the application
 #
 COMPAT_ABI=none
-adb_var_shell CPU_ABI1 getprop ro.product.cpu.abi
-adb_var_shell CPU_ABI2 getprop ro.product.cpu.abi2
 
-# Both CPU_ABI1 and CPU_ABI2 may contain multiple comma-delimited abis.
-# Concatanate CPU_ABI1 and CPU_ABI2 and replace all ',' with space.
-# Add trailing space to ease whole-word matching of APP_ABI.
-CPU_ABIS="$CPU_ABI1,$CPU_ABI2"
+# All modern Android images must support ro.product.cpu.abilist32
+# and ro.product.cpu.abilist64. Otherwise fall back to obsolete
+# ro.product.cpu.abi and ro.product.cpu.abi2
+adb_var_shell CPU_ABILIST64 getprop ro.product.cpu.abilist64
+adb_var_shell CPU_ABILIST32 getprop ro.product.cpu.abilist32
+CPU_ABIS="$CPU_ABILIST64,$CPU_ABILIST32"
+if [ -z "$CPU_ABILIST64" ] && [ -z "$CPU_ABILIST32" ] ; then
+    adb_var_shell CPU_ABI1 getprop ro.product.cpu.abi
+    adb_var_shell CPU_ABI2 getprop ro.product.cpu.abi2
+    CPU_ABIS="$CPU_ABI1,$CPU_ABI2"
+fi
+
+# Replace all ',' with space and add trailing space to
+# ease whole-word matching of APP_ABI
+CPU_ABILIST64=$(echo $CPU_ABILIST64 | tr ',' ' ')
+CPU_ABILIST32=$(echo $CPU_ABILIST32 | tr ',' ' ')
 CPU_ABIS=$(echo $CPU_ABIS | tr ',' ' ')
 log "Device CPU ABIs: $CPU_ABIS"
 
@@ -565,13 +575,38 @@
 if [ $? = 0 ]; then
     COMPAT_ABI="$UNKNOWN_ABI"
 else
-    for CPU_ABI in $CPU_ABIS; do
-        if [ "$APP_ABIS" != "${APP_ABIS%$CPU_ABI *}" ] ; then
-            COMPAT_ABI=$CPU_ABI
-            break
-        fi
-    done
+    # Assume that compatible ABI is 32-bit
+    COMPAT_ABI_BITS=32
+    # First look compatible ABI in the list of 64-bit ABIs
+    if [ -n "$CPU_ABILIST64" ] ; then
+        for CPU_ABI64 in $CPU_ABILIST64; do
+            if [ "$APP_ABIS" != "${APP_ABIS%$CPU_ABI64 *}" ] ; then
+                COMPAT_ABI=$CPU_ABI64
+                COMPAT_ABI_BITS=64
+                break
+            fi
+        done
+    fi
+    # If we found nothing - look among 32-bit ABIs
+    if [ "$COMPAT_ABI" = none ] && [ -n "$CPU_ABILIST32" ] ; then
+        for CPU_ABI32 in $CPU_ABILIST32; do
+            if [ "$APP_ABIS" != "${APP_ABIS%$CPU_ABI32 *}" ] ; then
+                COMPAT_ABI=$CPU_ABI32
+                break
+            fi
+        done
+    fi
+    # Lastly, lets check ro.product.cpu.abi and ro.product.cpu.abi2
+    if [ "$COMPAT_ABI" = none ] && [ -z "$CPU_ABILIST64" ] && [ -z "$CPU_ABILIST32" ]; then
+        for CPU_ABI in $CPU_ABIS; do
+            if [ "$APP_ABIS" != "${APP_ABIS%$CPU_ABI *}" ] ; then
+                COMPAT_ABI=$CPU_ABI
+                break
+            fi
+        done
+    fi
 fi
+
 if [ "$COMPAT_ABI" = none ] ; then
     echo "ERROR: The device does not support the application's targetted CPU ABIs!"
     echo "       Device supports:  $CPU_ABIS"
@@ -649,8 +684,8 @@
     TARGET_ARCH=none
 
     for ANDROID_ARCH in $ANDROID_NDK_ROOT/prebuilt/android-*; do
-        ANDROID_ARCH=${ANDROID_ARCH#*android-}
-        if [ x"$CPU_ABIS" != x"${CPU_ABIS#$ANDROID_ARCH*}" ]; then
+        ANDROID_ARCH=${ANDROID_ARCH#$ANDROID_NDK_ROOT/prebuilt/android-}
+        if [ "$COMPAT_ABI" = "$ANDROID_ARCH" ]; then
             TARGET_ARCH=$ANDROID_ARCH
             break;
         fi
@@ -754,16 +789,33 @@
     exit 1
 fi
 
+# If we are debugging 32-bit application on 64-bit device
+# then we need to pull app_process32, not app_process
+APP_PROCESS_NAME=app_process
+if [ "$COMPAT_ABI_BITS" = 32 ] && [ -n "$CPU_ABILIST64" ] ; then
+    APP_PROCESS_NAME=app_process32
+    log "We are debugging 32-bit app on 64-bit device"
+fi
+
+# If we are debugging 64-bit app, then we need to pull linker64
+# and libc.so from lib64 directory
+LINKER_NAME=linker
+LIBDIR_NAME=lib
+if [ "$COMPAT_ABI_BITS" = 64 ] ; then
+    LINKER_NAME=linker64
+    LIBDIR_NAME=lib64
+fi
+
 # Get the app_server binary from the device
-APP_PROCESS=$APP_OUT/app_process
-run adb_cmd pull /system/bin/app_process `native_path $APP_PROCESS`
-log "Pulled app_process from device/emulator."
+APP_PROCESS=$APP_OUT/$APP_PROCESS_NAME
+run adb_cmd pull /system/bin/$APP_PROCESS_NAME `native_path $APP_PROCESS`
+log "Pulled $APP_PROCESS_NAME from device/emulator."
 
-run adb_cmd pull /system/bin/linker `native_path $APP_OUT/linker`
-log "Pulled linker from device/emulator."
+run adb_cmd pull /system/bin/$LINKER_NAME `native_path $APP_OUT/linker`
+log "Pulled $LINKER_NAME from device/emulator."
 
-run adb_cmd pull /system/lib/libc.so `native_path $APP_OUT/libc.so`
-log "Pulled libc.so from device/emulator."
+run adb_cmd pull /system/$LIBDIR_NAME/libc.so `native_path $APP_OUT/libc.so`
+log "Pulled /system/$LIBDIR_NAME/libc.so from device/emulator."
 
 # Setup JDB connection, for --start or --launch
 if [ "$OPTION_START" = "yes" ] || [ -n "$OPTION_LAUNCH" ] ; then