64-bit emulator

Patch to allow emulator searches for emulator64-${ARCH} first on
64-bit OS.  If none is found, the original behavior which searchs
for 32-bit emulator-${ARCH} is performed as usual.

64-bit emulator (which still emulates Android built in 32-bit) offers
up to 20% speedup compared to its 32-bit counterpart.

Details:

android/main-emulator.c
 1) search emulator64 based on the OS
 2) dlopen lib64OpenglRender in 64-bit

Makefile.*
 1) Rules to build 64-bit executable emulator64-{x86,arm} and libraries
    emulator64-{libui,libqemu,target-i386,target-arm,libelff,common}
 2) remove -Wa,-32
 3) Changes prebuit toolchain path

android-configure.h
android/build/common.h
 1) no longer force 32-bit build (because now prebuilts/tools/gcc-sdk/gcc
    can now handle 64-bit
 2) set ANDROID_PREBUILTS to correctly locate ccache

android/config/*/config-host.h
 1) Detect HOST_X86_64 and HOST_X86_64/HOST_I386

Misc 64-bit porting clean-up
 1) use %zx to print variable of type size_t in hex
 2) use %zu to print variable of type size_t in dec
 3) Initialize query_parm to NULL
 4) use PRIu64 to replace PDUd64
 5) use PRId64/PRIu64/PRIX64 to print 64-bit
 6) drop PRUx64 because PRIx64 does the same
 7) cast pointer arith to intptr_t before casting to int
 8) fixed 1ULL<<63

Change-Id: Ife62a20063a6ec38d4a9b23977e840af1fce149a
diff --git a/android/build/common.sh b/android/build/common.sh
index de4e3c1..c7235ae 100644
--- a/android/build/common.sh
+++ b/android/build/common.sh
@@ -493,21 +493,20 @@
 # Locate the Android prebuilt directory for your os
 # you should only call this if IN_ANDROID_BUILD is "yes"
 #
-# This will set ANDROID_PREBUILT_HOST_TAG and ANDROID_PREBUILT
+# This will set ANDROID_PREBUILT_HOST_TAG, ANDROID_PREBUILT and ANDROID_PREBUILTS
 #
 locate_android_prebuilt ()
 {
     # locate prebuilt directory
     ANDROID_PREBUILT_HOST_TAG=$OS
     ANDROID_PREBUILT=$ANDROID_TOP/prebuilt/$ANDROID_PREBUILT_HOST_TAG
+    ANDROID_PREBUILTS=$ANDROID_TOP/prebuilts/misc/$ANDROID_PREBUILT_HOST_TAG
     if [ ! -d $ANDROID_PREBUILT ] ; then
         # this can happen when building on x86_64
         case $OS in
             linux-x86_64)
                 ANDROID_PREBUILT_HOST_TAG=linux-x86
                 ANDROID_PREBUILT=$ANDROID_TOP/prebuilt/$ANDROID_PREBUILT_HOST_TAG
-                log "Forcing usage of 32-bit prebuilts"
-                force_32bit_binaries
                 ;;
             *)
         esac
@@ -516,7 +515,22 @@
             exit 1
         fi
     fi
+    if [ ! -d $ANDROID_PREBUILTS ] ; then
+        # this can happen when building on x86_64
+        case $OS in
+            linux-x86_64)
+                ANDROID_PREBUILT_HOST_TAG=linux-x86
+                ANDROID_PREBUILTS=$ANDROID_TOP/prebuilts/misc/$ANDROID_PREBUILT_HOST_TAG
+                ;;
+            *)
+        esac
+        if [ ! -d $ANDROID_PREBUILTS ] ; then
+            echo "Can't find the prebuilts directory $ANDROID_PREBUILTS in Android build"
+            exit 1
+        fi
+    fi
     log "Prebuilt   : ANDROID_PREBUILT=$ANDROID_PREBUILT"
+    log "Prebuilts  : ANDROID_PREBUILTS=$ANDROID_PREBUILTS"
 }
 
 ## Build configuration file support
@@ -561,6 +575,7 @@
     fi
     echo "HOST_PREBUILT_TAG := $HOST_TAG" >> $config_mk
     echo "PREBUILT          := $ANDROID_PREBUILT" >> $config_mk
+    echo "PREBUILTS         := $ANDROID_PREBUILTS" >> $config_mk
 }
 
 # Find pattern $1 in string $2
diff --git a/android/camera/camera-service.c b/android/camera/camera-service.c
index bfdde56..51af2de 100644
--- a/android/camera/camera-service.c
+++ b/android/camera/camera-service.c
@@ -407,7 +407,7 @@
 _qemu_client_reply_payload(QemudClient* qc, size_t payload_size)
 {
     char payload_size_str[9];
-    snprintf(payload_size_str, sizeof(payload_size_str), "%08x", payload_size);
+    snprintf(payload_size_str, sizeof(payload_size_str), "%08zx", payload_size);
     qemud_client_send(qc, (const uint8_t*)payload_size_str, 8);
 }
 
@@ -1203,7 +1203,7 @@
     static const char _query_frame[]      = "frame";
 
     char query_name[64];
-    const char* query_param;
+    const char* query_param = NULL;
     CameraClient* cc = (CameraClient*)opaque;
 
     /*
diff --git a/android/config/darwin-x86/config-host.h b/android/config/darwin-x86/config-host.h
index 0395918..97a83dc 100644
--- a/android/config/darwin-x86/config-host.h
+++ b/android/config/darwin-x86/config-host.h
@@ -1,6 +1,15 @@
 /* This file was autogenerated by 'android-configure.sh' */
 #define CONFIG_QEMU_SHAREDIR   "/usr/local/share/qemu"
+#if defined(__x86_64__)
+#define HOST_X86_64    1
+#define HOST_LONG_BITS  64
+#elif defined(__i386__)
+#define HOST_I386    1
 #define HOST_LONG_BITS  32
+#else
+#error Unknown architecture for codegen
+#endif
+
 #define CONFIG_FNMATCH  1
 #define CONFIG_GDBSTUB  1
 #define CONFIG_SLIRP    1
@@ -9,7 +18,6 @@
 #define CONFIG_NAND_LIMITS  1
 #define QEMU_VERSION    "0.10.50"
 #define QEMU_PKGVERSION "Android"
-#define HOST_I386    1
 #define CONFIG_IOVEC 1
 #define CONFIG_DARWIN   1
 #define CONFIG_BSD       1
diff --git a/android/config/freebsd-x86/config-host.h b/android/config/freebsd-x86/config-host.h
index 2e44a83..fd31de4 100644
--- a/android/config/freebsd-x86/config-host.h
+++ b/android/config/freebsd-x86/config-host.h
@@ -1,7 +1,15 @@
 /* Automatically generated by configure - do not modify */
 #define CONFIG_QEMU_SHAREDIR "/usr/local/share/qemu"
-#define HOST_I386 1
-#define HOST_LONG_BITS 32
+#if defined(__x86_64__)
+#define HOST_X86_64    1
+#define HOST_LONG_BITS  64
+#elif defined(__i386__)
+#define HOST_I386    1
+#define HOST_LONG_BITS  32
+#else
+#error Unknown architecture for codegen
+#endif
+
 #define CONFIG_MACHINE_BSWAP_H 1
 #define CONFIG_FNMATCH 1
 #define CONFIG_GDBSTUB 1
diff --git a/android/config/linux-x86/config-host.h b/android/config/linux-x86/config-host.h
index 70a0eed..70b9ce7 100644
--- a/android/config/linux-x86/config-host.h
+++ b/android/config/linux-x86/config-host.h
@@ -1,6 +1,15 @@
 /* This file was autogenerated by 'android-configure.sh' */
 #define CONFIG_QEMU_SHAREDIR   "/usr/local/share/qemu"
+#if defined(__x86_64__)
+#define HOST_X86_64    1
+#define HOST_LONG_BITS  64
+#elif defined(__i386__)
+#define HOST_I386    1
 #define HOST_LONG_BITS  32
+#else
+#error Unknown architecture for codegen
+#endif
+
 #define CONFIG_BYTESWAP_H 1
 #define CONFIG_FNMATCH  1
 #define CONFIG_GDBSTUB  1
@@ -11,7 +20,6 @@
 #define CONFIG_NAND_LIMITS  1
 #define QEMU_VERSION    "0.10.50"
 #define QEMU_PKGVERSION "Android"
-#define HOST_I386    1
 #define CONFIG_KVM_GS_RESTORE   1
 #define CONFIG_IOVEC 1
 #define CONFIG_LINUX   1
diff --git a/android/config/windows/config-host.h b/android/config/windows/config-host.h
index ef36e4c..1b50927 100644
--- a/android/config/windows/config-host.h
+++ b/android/config/windows/config-host.h
@@ -1,12 +1,20 @@
 /* This file was autogenerated by 'android-configure.sh' */
 #define CONFIG_QEMU_SHAREDIR   "/usr/local/share/qemu"
+#if defined(__x86_64__)
+#define HOST_X86_64    1
+#define HOST_LONG_BITS  64
+#elif defined(__i386__)
+#define HOST_I386    1
 #define HOST_LONG_BITS  32
+#else
+#error Unknown architecture for codegen
+#endif
+
 #define CONFIG_GDBSTUB  1
 #define CONFIG_SLIRP    1
 #define CONFIG_SKINS    1
 #define CONFIG_TRACE    1
 #define QEMU_VERSION    "0.10.50"
 #define QEMU_PKGVERSION "Android"
-#define HOST_I386    1
 #define CONFIG_WIN32   1
 #define CONFIG_ANDROID       1
diff --git a/android/console.c b/android/console.c
index ed02db5..07a59d2 100644
--- a/android/console.c
+++ b/android/console.c
@@ -1867,7 +1867,7 @@
         if (q == p)
             break;
 
-        snprintf(temp, sizeof temp, "%.*s", q-p, p);
+        snprintf(temp, sizeof temp, "%.*s", (int)(intptr_t)(q-p), p);
         ret = android_event_from_str( temp, &type, &code, &value );
         if (ret < 0) {
             if (ret == -1) {
diff --git a/android/hw-sensors.c b/android/hw-sensors.c
index 51170cb..17b2491 100644
--- a/android/hw-sensors.c
+++ b/android/hw-sensors.c
@@ -339,7 +339,7 @@
 
     now_ns = qemu_get_clock_ns(vm_clock);
 
-    snprintf(buffer, sizeof buffer, "sync:%lld", now_ns/1000);
+    snprintf(buffer, sizeof buffer, "sync:%" PRId64, now_ns/1000);
     _hwSensorClient_send(cl, (uint8_t*)buffer, strlen(buffer));
 
     /* rearm timer, use a minimum delay of 20 ms, just to
diff --git a/android/main-emulator.c b/android/main-emulator.c
index a6e95c7..f2e30e2 100644
--- a/android/main-emulator.c
+++ b/android/main-emulator.c
@@ -50,7 +50,17 @@
 #  define DLL_EXTENSION  ".so"
 #endif
 
+#if defined(__x86_64__)
+/* Normally emulator is compiled in 32-bit.  In standalone it can be compiled
+   in 64-bit (with ,/android-configure.sh --try-64).  In this case, emulator-$ARCH
+   are also compiled in 64-bit and will search for lib64*.so instead of lib*so */
+#define  GLES_EMULATION_LIB  "lib64OpenglRender" DLL_EXTENSION
+#elif defined(__i386__)
 #define  GLES_EMULATION_LIB  "libOpenglRender" DLL_EXTENSION
+#else
+#error Unknown architecture for codegen
+#endif
+
 
 /* Forward declarations */
 static char* getTargetEmulatorPath(const char* progName, const char* avdArch);
@@ -173,6 +183,29 @@
     return errno;
 }
 
+static int
+getHostOSBitness()
+{
+  /*
+     This function returns 64 if host is running 64-bit OS, or 32 otherwise.
+
+     It uses the same technique in ndk/build/core/ndk-common.sh.
+     Here are comments from there:
+
+  ## On Linux or Darwin, a 64-bit kernel (*) doesn't mean that the user-land
+  ## is always 32-bit, so use "file" to determine the bitness of the shell
+  ## that invoked us. The -L option is used to de-reference symlinks.
+  ##
+  ## Note that on Darwin, a single executable can contain both x86 and
+  ## x86_64 machine code, so just look for x86_64 (darwin) or x86-64 (Linux)
+  ## in the output.
+
+    (*) ie. The following code doesn't always work:
+        struct utsname u;
+        int host_runs_64bit_OS = (uname(&u) == 0 && strcmp(u.machine, "x86_64") == 0);
+  */
+    return system("file -L \"$SHELL\" | grep -q \"x86[_-]64\"") == 0 ? 64 : 32;
+}
 
 /* Find the target-specific emulator binary. This will be something
  * like  <programDir>/emulator-<targetArch>, where <programDir> is
@@ -182,24 +215,43 @@
 getTargetEmulatorPath(const char* progName, const char* avdArch)
 {
     char*  progDir;
-    char   temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
+    char   path[PATH_MAX], *pathEnd=path+sizeof(path), *p;
+    const char* emulatorPrefix = "emulator-";
+    const char* emulator64Prefix = "emulator64-";
 #ifdef _WIN32
     const char* exeExt = ".exe";
+    /* ToDo: currently amd64-mingw32msvc-gcc doesn't work (http://b/issue?id=5949152)
+             which prevents us from generating 64-bit emulator for Windows */
+    int host_runs_64bit_OS = 0;
 #else
     const char* exeExt = "";
+    int host_runs_64bit_OS = getHostOSBitness() == 64;
 #endif
 
     /* Get program's directory name in progDir */
     path_split(progName, &progDir, NULL);
 
-    p = bufprint(temp, end, "%s/emulator-%s%s", progDir, avdArch, exeExt);
+    if (host_runs_64bit_OS) {
+        /* Find 64-bit emulator first */
+        p = bufprint(path, pathEnd, "%s/%s%s%s", progDir, emulator64Prefix, avdArch, exeExt);
+        if (p >= pathEnd) {
+            APANIC("Path too long: %s\n", progName);
+        }
+        if (path_exists(path)) {
+            free(progDir);
+            return strdup(path);
+        }
+    }
+
+    /* Find 32-bit emulator */
+    p = bufprint(path, pathEnd, "%s/%s%s%s", progDir, emulatorPrefix, avdArch, exeExt);
     free(progDir);
-    if (p >= end) {
+    if (p >= pathEnd) {
         APANIC("Path too long: %s\n", progName);
     }
 
-    if (path_exists(temp)) {
-        return strdup(temp);
+    if (path_exists(path)) {
+        return strdup(path);
     }
 
     /* Mmm, the file doesn't exist, If there is no slash / backslash
@@ -210,16 +262,25 @@
 #else
     if (strchr(progName, '/') == NULL) {
 #endif
-        p = bufprint(temp, end, "emulator-%s%s", avdArch, exeExt);
-        if (p < end) {
-            char*  resolved = path_search_exec(temp);
+        if (host_runs_64bit_OS) {
+           p = bufprint(path, pathEnd, "%s%s%s", emulator64Prefix, avdArch, exeExt);
+           if (p < pathEnd) {
+               char*  resolved = path_search_exec(path);
+               if (resolved != NULL)
+                   return resolved;
+           }
+        }
+
+        p = bufprint(path, pathEnd, "%s%s%s", emulatorPrefix, avdArch, exeExt);
+        if (p < pathEnd) {
+            char*  resolved = path_search_exec(path);
             if (resolved != NULL)
                 return resolved;
         }
     }
 
     /* Otherwise, the program is missing */
-    APANIC("Missing arch-specific emulator program: %s\n", temp);
+    APANIC("Missing arch-specific emulator program: %s\n", path);
     return NULL;
 }
 
@@ -271,7 +332,7 @@
     }
 
     /* try in $progDir/../lib, this corresponds to the platform build
-     * where the emulator binary is under out/host/<system>/lib and
+     * where the emulator binary is under out/host/<system>/bin and
      * the libraries are under out/host/<system>/lib
      */
     {
diff --git a/android/main.c b/android/main.c
index d3e7e8f..6ce18e2 100644
--- a/android/main.c
+++ b/android/main.c
@@ -145,7 +145,7 @@
     if (imageMB > defaultMB) {
         snprintf(temp, sizeof temp, "(%d MB > %d MB)", imageMB, defaultMB);
     } else {
-        snprintf(temp, sizeof temp, "(%lld bytes > %lld bytes)", imageBytes, defaultBytes);
+        snprintf(temp, sizeof temp, "(%" PRIu64 "  bytes > %" PRIu64 " bytes)", imageBytes, defaultBytes);
     }
 
     if (inAndroidBuild) {
diff --git a/android/opengles.c b/android/opengles.c
index 4913d0c..5a29d3a 100644
--- a/android/opengles.c
+++ b/android/opengles.c
@@ -27,7 +27,13 @@
 int  android_gles_fast_pipes = 1;
 
 /* Name of the GLES rendering library we're going to use */
+#if HOST_LONG_BITS == 32
 #define RENDERER_LIB_NAME  "libOpenglRender"
+#elif HOST_LONG_BITS == 64
+#define RENDERER_LIB_NAME  "lib64OpenglRender"
+#else
+#error Unknown HOST_LONG_BITS
+#endif
 
 /* These definitions *must* match those under:
  * development/tools/emulator/opengl/host/include/libOpenglRender/render_api.h
diff --git a/android/utils/system.c b/android/utils/system.c
index e65c602..6a6a4e1 100644
--- a/android/utils/system.c
+++ b/android/utils/system.c
@@ -67,7 +67,7 @@
     if (block2 != NULL)
         return block2;
 
-    fprintf(stderr, "PANIC: not enough memory to reallocate %lld bytes\n", (uint64_t)size);
+    fprintf(stderr, "PANIC: not enough memory to reallocate %zu bytes\n", size);
     exit(1);
     return NULL;
 }
diff --git a/android/utils/system.h b/android/utils/system.h
index 464957d..531c7eb 100644
--- a/android/utils/system.h
+++ b/android/utils/system.h
@@ -14,6 +14,7 @@
 
 #include <string.h>
 #include <stdint.h>
+#define __STDC_FORMAT_MACROS 1
 #include <inttypes.h>  /* for PRId64 et al. */
 #include "android/utils/assert.h"
 
@@ -173,11 +174,8 @@
 #ifndef PRIx64
 #  define PRIx64  "llx"
 #endif
-#ifndef PRUd64
-#  define PRUd64  "llu"
-#endif
-#ifndef PRUx64
-#  define PRUx64  "llx"
+#ifndef PRIu64
+#  define PRIu64  "llu"
 #endif
 
 /* */