Merge changes I5d034506,I05390f79

* changes:
  [MIPS64] target-mips : implement unaligned loads using TCG
  [MIPS] Refactor page table walk
diff --git a/Makefile.qemu-launcher b/Makefile.qemu-launcher
index 9c26567..16c1dbf 100644
--- a/Makefile.qemu-launcher
+++ b/Makefile.qemu-launcher
@@ -26,6 +26,9 @@
 LOCAL_CFLAGS := $(qemu_launcher_CFLAGS)
 LOCAL_STATIC_LIBRARIES := \
     emulator-common \
+    emulator-libext4_utils \
+    emulator-libsparse \
+    emulator-libselinux \
     emulator-zlib
 LOCAL_LDLIBS := $(qemu_launcher_LDLIBS)
 $(call gen-hw-config-defs)
@@ -36,6 +39,9 @@
 LOCAL_CFLAGS := $(qemu_launcher_CFLAGS)
 LOCAL_STATIC_LIBRARIES := \
     emulator64-common \
+    emulator64-libext4_utils \
+    emulator64-libsparse \
+    emulator64-libselinux \
     emulator64-zlib
 LOCAL_LDLIBS := $(qemu_launcher_LDLIBS)
 $(call gen-hw-config-defs)
diff --git a/android-configure.sh b/android-configure.sh
index 3e13cc2..5d5e725 100755
--- a/android-configure.sh
+++ b/android-configure.sh
@@ -31,6 +31,8 @@
 
 PCBIOS_PROBE=yes
 
+QEMU_PREBUILTS_DIR=
+
 HOST_CC=${CC:-gcc}
 OPTION_CC=
 
@@ -68,6 +70,8 @@
   ;;
   --gles-dir=*) GLES_DIR=$optarg
   ;;
+  --qemu-prebuilts-dir=*) QEMU_PREBUILTS_DIR=$optarg
+  ;;
   --no-gles) GLES_PROBE=no
   ;;
   --no-pcbios) PCBIOS_PROBE=no
@@ -90,23 +94,24 @@
 Options: [defaults in brackets after descriptions]
 EOF
     echo "Standard options:"
-    echo "  --help                   print this message"
-    echo "  --install=FILEPATH       copy emulator executable to FILEPATH [$TARGETS]"
-    echo "  --cc=PATH                specify C compiler [$HOST_CC]"
-    echo "  --sdl-config=FILE        use specific sdl-config script [$SDL_CONFIG]"
-    echo "  --no-strip               do not strip emulator executable"
-    echo "  --debug                  enable debug (-O0 -g) build"
-    echo "  --ignore-audio           ignore audio messages (may build sound-less emulator)"
-    echo "  --no-prebuilts           do not use prebuilt libraries and compiler"
-    echo "  --out-dir=<path>         use specific output directory [objs/]"
-    echo "  --mingw                  build Windows executable on Linux"
-    echo "  --static                 build a completely static executable"
-    echo "  --verbose                verbose configuration"
-    echo "  --debug                  build debug version of the emulator"
-    echo "  --gles-dir=PATH          specify path to GLES host emulation sources [auto-detected]"
-    echo "  --no-gles                disable GLES emulation support"
-    echo "  --no-pcbios              disable copying of PC Bios files"
-    echo "  --no-tests               don't run unit test suite"
+    echo "  --help                      Print this message"
+    echo "  --install=FILEPATH          Copy emulator executable to FILEPATH [$TARGETS]"
+    echo "  --cc=PATH                   Specify C compiler [$HOST_CC]"
+    echo "  --sdl-config=FILE           Use specific sdl-config script [$SDL_CONFIG]"
+    echo "  --no-strip                  Do not strip emulator executable"
+    echo "  --debug                     Enable debug (-O0 -g) build"
+    echo "  --ignore-audio              Ignore audio messages (may build sound-less emulator)"
+    echo "  --no-prebuilts              Do not use prebuilt libraries and compiler"
+    echo "  --out-dir=<path>            Use specific output directory [objs/]"
+    echo "  --mingw                     Build Windows executable on Linux"
+    echo "  --static                    Build a completely static executable"
+    echo "  --verbose                   Verbose configuration"
+    echo "  --debug                     Build debug version of the emulator"
+    echo "  --gles-dir=PATH             Specify path to GLES host emulation sources [auto-detected]"
+    echo "  --qemu-prebuilts-dir=PATH   Specify path to QEMU prebuilt binaries"
+    echo "  --no-gles                   Disable GLES emulation support"
+    echo "  --no-pcbios                 Disable copying of PC Bios files"
+    echo "  --no-tests                  Don't run unit test suite"
     echo ""
     exit 1
 fi
@@ -753,6 +758,15 @@
 python scripts/qapi-commands.py --output-dir=$AUTOGENERATED_DIR -m < qapi-schema.json
 log "Generate   : $AUTOGENERATED_DIR"
 
+if [ "$QEMU_PREBUILTS_DIR" ]; then
+    if [ ! -d "$QEMU_PREBUILTS_DIR/binaries" ]; then
+        panic "Missing QEMU prebuilts directory: $QEMU_PREBUILTS_DIR/binaries"
+    fi
+    log "Copying QEMU prebuilt binaries to: $OUT_DIR/qemu"
+    mkdir -p "$OUT_DIR"/qemu || panic "Could not create $OUT_DIR/qemu"
+    cp -rp "$QEMU_PREBUILTS_DIR/binaries"/* "$OUT_DIR/qemu"
+fi
+
 clean_temp
 
 echo "Ready to go. Type 'make' to build emulator"
diff --git a/android/avd/util.c b/android/avd/util.c
index 51236ac..39e25d9 100644
--- a/android/avd/util.c
+++ b/android/avd/util.c
@@ -170,6 +170,7 @@
         } kData[] = {
             { "armeabi", "arm" },
             { "armeabi-v7a", "arm" },
+            { "arm64-v8a", "arm64" },
         };
         size_t n;
         for (n = 0; n < sizeof(kData)/sizeof(kData[0]); ++n) {
diff --git a/android/kernel/kernel_utils.cpp b/android/kernel/kernel_utils.cpp
index cbc4f4e..5f5ace8 100755
--- a/android/kernel/kernel_utils.cpp
+++ b/android/kernel/kernel_utils.cpp
@@ -34,14 +34,13 @@
 
 using android::base::PodVector;
 
-namespace android {
-namespace kernel {
+namespace {
 
-static const char kVersionStringPrefix[] = "Linux version ";
-static const size_t kVersionStringPrefixLen = sizeof(kVersionStringPrefix) - 1U;
+const char kLinuxVersionStringPrefix[] = "Linux version ";
+const size_t kLinuxVersionStringPrefixLen =
+        sizeof(kLinuxVersionStringPrefix) - 1U;
 
-}  // namespace kernel
-}  // namespace android
+}  // namespace
 
 #ifndef __APPLE__
 size_t strlcpy(char* dst, const char * src, size_t size)
@@ -84,13 +83,13 @@
 
 bool android_parseLinuxVersionString(const char* versionString,
                                      KernelVersion* kernelVersion) {
-    if (strncmp(versionString, android::kernel::kVersionStringPrefix,
-                android::kernel::kVersionStringPrefixLen)) {
+    if (strncmp(versionString, kLinuxVersionStringPrefix,
+            kLinuxVersionStringPrefixLen)) {
         KERNEL_ERROR << "unsupported kernel version string:" << versionString;
         return false;
     }
     // skip past the prefix to the version number
-    versionString += android::kernel::kVersionStringPrefixLen;
+    versionString += kLinuxVersionStringPrefixLen;
 
     uint32_t temp = 0;
     for (int i = 0; i < 3; i++) {
@@ -139,6 +138,8 @@
         return false;
     }
 
+    const char* versionStringStart = NULL;
+
     if (0 == memcmp(kElfHeader, kernelFileData, sizeof(kElfHeader))) {
         // this is an uncompressed ELF file (probably mips)
         uncompressedKernel = kernelFileData;
@@ -156,37 +157,49 @@
             return false;
         }
 
-        size_t compressedKernelLen = kernelFileSize -
-            (compressedKernel - kernelFileData);
+        // Special case: certain images, like the ARM64 one, contain a GZip
+        // header _after_ the actual Linux version string. So first try to
+        // see if there is something before the header.
+        versionStringStart = (const char*)memmem(
+                kernelFileData,
+                (compressedKernel - kernelFileData),
+                kLinuxVersionStringPrefix,
+                kLinuxVersionStringPrefixLen);
 
-        // inflate ratios for all prebuilt kernels on 2014-07-14 is 1.9:1 ~
-        // 3.43:1 not sure how big the uncompressed size is, so make an
-        // absurdly large buffer
-        uncompressedKernelLen = compressedKernelLen * 10;
-        uncompressed.resize(uncompressedKernelLen);
-        uncompressedKernel = uncompressed.begin();
+        if (!versionStringStart) {
+            size_t compressedKernelLen = kernelFileSize -
+                (compressedKernel - kernelFileData);
 
-        bool zOk = uncompress_gzipStream(uncompressed.begin(),
-                                         &uncompressedKernelLen,
-                                         compressedKernel,
-                                         compressedKernelLen);
-        if (!zOk) {
-            KERNEL_ERROR << "Kernel decompression error";
-            // it may have been partially decompressed, so we're going to 
-            // try to find the version string anyway
+            // inflate ratios for all prebuilt kernels on 2014-07-14 is 1.9:1 ~
+            // 3.43:1 not sure how big the uncompressed size is, so make an
+            // absurdly large buffer
+            uncompressedKernelLen = compressedKernelLen * 10;
+            uncompressed.resize(uncompressedKernelLen);
+            uncompressedKernel = uncompressed.begin();
+
+            bool zOk = uncompress_gzipStream(uncompressed.begin(),
+                                            &uncompressedKernelLen,
+                                            compressedKernel,
+                                            compressedKernelLen);
+            if (!zOk) {
+                KERNEL_ERROR << "Kernel decompression error";
+                // it may have been partially decompressed, so we're going to
+                // try to find the version string anyway
+            }
         }
     }
 
-    // okay, now we have a pointer to an uncompressed kernel, let's find the
-    // version string
-    const char* versionStringStart = (const char*)memmem(
-        uncompressedKernel,
-        uncompressedKernelLen,
-        android::kernel::kVersionStringPrefix,
-        android::kernel::kVersionStringPrefixLen);
     if (!versionStringStart) {
-        KERNEL_ERROR << "Could not find 'Linux version ' in kernel!";
-        return false;
+        versionStringStart = (const char*)memmem(
+                uncompressedKernel,
+                uncompressedKernelLen,
+                kLinuxVersionStringPrefix,
+                kLinuxVersionStringPrefixLen);
+
+        if (!versionStringStart) {
+            KERNEL_ERROR << "Could not find 'Linux version ' in kernel!";
+            return false;
+        }
     }
 
     strlcpy(dst, versionStringStart, dstLen);
diff --git a/android/kernel/kernel_utils_unittest.cpp b/android/kernel/kernel_utils_unittest.cpp
index 40ad06c..f24845a 100755
--- a/android/kernel/kernel_utils_unittest.cpp
+++ b/android/kernel/kernel_utils_unittest.cpp
@@ -85,6 +85,27 @@
         0x00, 0x00, 0x00
     };
 
+    // a mock semi-compressed kernel
+    // an unspecified number of bytes, followed by a version string,
+    // followed by a gzip header
+    static const unsigned char kMockKernelSemiCompressed[] = {
+    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x39, 0x61,
+    0x62, 0x63, 0x64, 0x65, 0x66, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x20, 0x76,
+    0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x33, 0x2e, 0x31, 0x30, 0x2e,
+    0x30, 0x2b, 0x20, 0x28, 0x76, 0x68, 0x61, 0x72, 0x72, 0x6f, 0x6e, 0x40,
+    0x74, 0x69, 0x66, 0x61, 0x2e, 0x6d, 0x74, 0x76, 0x2e, 0x63, 0x6f, 0x72,
+    0x70, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
+    0x29, 0x20, 0x28, 0x67, 0x63, 0x63, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69,
+    0x6f, 0x6e, 0x20, 0x34, 0x2e, 0x37, 0x20, 0x28, 0x47, 0x43, 0x43, 0x29,
+    0x20, 0x29, 0x20, 0x23, 0x31, 0x20, 0x50, 0x52, 0x45, 0x45, 0x4d, 0x50,
+    0x54, 0x20, 0x53, 0x61, 0x74, 0x20, 0x4a, 0x61, 0x6e, 0x20, 0x35, 0x20,
+    0x32, 0x3a, 0x34, 0x35, 0x3a, 0x32, 0x34, 0x20, 0x50, 0x44, 0x54, 0x20,
+    0x32, 0x30, 0x30, 0x38, 0x0a, 0x00, 0x31, 0x32, 0x33, 0x34, 0x35, 0x35,
+    0x37, 0x38, 0x39, 0x1f, 0x8b, 0x08, 0x00, 0x3e, 0xa9, 0xc7, 0x53, 0x00,
+    0x03, 0x0b, 0xf7, 0x70, 0x0c, 0x71, 0x0d, 0x73, 0x0d, 0x02, 0x00, 0xff,
+    0xdf, 0x22, 0x88, 0x08, 0x00, 0x00, 0x00
+    };
+
     char kernelVersionString[256];
 
     kernelVersionString[0] = 0;
@@ -103,8 +124,16 @@
         sizeof(kernelVersionString)));
     EXPECT_STREQ(kMockKernelVersion, kernelVersionString);
 
+    kernelVersionString[0] = 0;
+    EXPECT_EQ(true, android_imageProbeKernelVersionString(
+        kMockKernelSemiCompressed,
+        sizeof(kMockKernelSemiCompressed),
+        kernelVersionString,
+        sizeof(kernelVersionString)));
+    EXPECT_STREQ(kMockKernelVersion, kernelVersionString);
+
     kernelVersionString[0] = 127;
-    EXPECT_EQ(false, android_imageProbeKernelVersionString(
+    EXPECT_FALSE(android_imageProbeKernelVersionString(
         0,
         0,
         kernelVersionString,
@@ -112,7 +141,7 @@
     EXPECT_EQ(127, kernelVersionString[0]);
 
     kernelVersionString[0] = 127;
-    EXPECT_EQ(false, android_imageProbeKernelVersionString(
+    EXPECT_FALSE(android_imageProbeKernelVersionString(
         kMockKernelElfNoString,
         sizeof(kMockKernelElfNoString),
         kernelVersionString,
diff --git a/android/kernel/testing/print_mock_kernel_data.sh b/android/kernel/testing/print_mock_kernel_data.sh
index 1a1a5cb..c6ce113 100755
--- a/android/kernel/testing/print_mock_kernel_data.sh
+++ b/android/kernel/testing/print_mock_kernel_data.sh
@@ -26,6 +26,15 @@
 cat $TMP_FILE | xxd -i
 printf "};\n\n"
 
+printf "// a mock semi-compressed kernel\n"
+printf "// an unspecified number of bytes, followed by a version string,\n"
+printf "// followed by a gzip header\n"
+printf "static const unsigned char kMockKernelSemiCompressed[] = {\n"
+printf "01234567899abcdef${LINUX_VERSION}0123455789" > $TMP_FILE
+printf "WHATEVER" | gzip >> $TMP_FILE
+cat $TMP_FILE | xxd -i
+printf "};\n\n"
+
 rm $TMP_FILE
 
 
diff --git a/android/qemu-launcher/emulator-qemu.cpp b/android/qemu-launcher/emulator-qemu.cpp
index 280bd58..fdd38a7 100644
--- a/android/qemu-launcher/emulator-qemu.cpp
+++ b/android/qemu-launcher/emulator-qemu.cpp
@@ -23,6 +23,7 @@
 #include "android/cmdline-option.h"
 #include "android/globals.h"
 #include "android/help.h"
+#include "android/filesystems/ext4_utils.h"
 #include "android/kernel/kernel_utils.h"
 #include "android/main-common.h"
 #include "android/utils/bufprint.h"
@@ -85,6 +86,16 @@
 // The target CPU architecture.
 const char kTargetArch[] = "aarch64";
 
+String getNthParentDir(const char* path, size_t n) {
+    StringVector dir = PathUtils::decompose(path);
+    PathUtils::simplifyComponents(&dir);
+    if (dir.size() < n + 1U) {
+        return String("");
+    }
+    dir.resize(dir.size() - n);
+    return PathUtils::recompose(dir);
+}
+
 // Return the path of the QEMU executable
 String getQemuExecutablePath(const char* programPath) {
     StringVector path = PathUtils::decompose(programPath);
@@ -702,6 +713,38 @@
     String qemuExecutable = getQemuExecutablePath(argv[0]);
     D("QEMU EXECUTABLE=%s\n", qemuExecutable.c_str());
 
+    // Create userdata file from init version if needed.
+    if (!path_exists(hw->disk_dataPartition_path)) {
+        if (!path_exists(hw->disk_dataPartition_initPath)) {
+            derror("Missing initial data partition file: %s",
+                   hw->disk_dataPartition_initPath);
+            exit(1);
+        }
+        D("Creating: %s\n", hw->disk_dataPartition_path);
+
+        if (path_copy_file(hw->disk_dataPartition_path,
+                           hw->disk_dataPartition_initPath) < 0) {
+            derror("Could not create %s: %s", hw->disk_dataPartition_path,
+                   strerror(errno));
+            exit(1);
+        }
+    }
+
+    // Create cache partition image if it doesn't exist already.
+    if (!path_exists(hw->disk_cachePartition_path)) {
+        D("Creating empty ext4 cache partition: %s",
+          hw->disk_cachePartition_path);
+        int ret = android_createEmptyExt4Image(
+                hw->disk_cachePartition_path,
+                hw->disk_cachePartition_size,
+                "cache");
+        if (ret < 0) {
+            derror("Could not create %s: %s", hw->disk_cachePartition_path,
+                   strerror(-ret));
+            exit(1);
+        }
+    }
+
     // Now build the QEMU parameters.
     const char* args[128];
     int n = 0;
@@ -769,6 +812,12 @@
     args[n++] = "virtio-net-device,netdev=mynet";
     args[n++] = "-show-cursor";
 
+    // Data directory (for keymaps and PC Bios).
+    args[n++] = "-L";
+    String dataDir = getNthParentDir(qemuExecutable.c_str(), 2U);
+    dataDir += "/pc-bios";
+    args[n++] = dataDir.c_str();
+
     if(VERBOSE_CHECK(init)) {
         int i;
         printf("QEMU options list:\n");