Merge "Drop clang version check for __builtin_isinf and __builtin_isnan"
diff --git a/build/tools/windows_sdk.mk b/build/tools/windows_sdk.mk
index 3581c6d..594fcfd 100644
--- a/build/tools/windows_sdk.mk
+++ b/build/tools/windows_sdk.mk
@@ -49,8 +49,8 @@
 # build prerequisites.
 WIN_BUILD_PREREQ := \
 	acp \
-	bcc_compat \
-	llvm-rs-cc \
+	llvm-tblgen \
+	clang-tblgen \
 	$(WIN_SDK_BUILD_PREREQ)
 
 
diff --git a/ndk/sources/android/libportable/arch-mips/signal.c b/ndk/sources/android/libportable/arch-mips/signal.c
new file mode 100644
index 0000000..7da2801
--- /dev/null
+++ b/ndk/sources/android/libportable/arch-mips/signal.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2014, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <signal_portable.h>
diff --git a/ndk/sources/android/libportable/common/include/errno_portable.h b/ndk/sources/android/libportable/common/include/errno_portable.h
index 8742bb4..8966c77 100644
--- a/ndk/sources/android/libportable/common/include/errno_portable.h
+++ b/ndk/sources/android/libportable/common/include/errno_portable.h
@@ -22,6 +22,8 @@
 #include <pthread.h>
 #include <string.h>
 
+#define ALOGV(...)
+
 #define EDEADLK_PORTABLE 35
 #define ENAMETOOLONG_PORTABLE 36
 #define ENOLCK_PORTABLE 37
@@ -461,7 +463,7 @@
 extern char* REAL(strerror)(int);
 char *WRAP(strerror)(int errnum)
 {
-    return REAL(strerror)(errno_p2on(errnum));
+    return REAL(strerror)(errno_pton(errnum));
 }
 
 /* BSD style strerror_r */
diff --git a/ndk/sources/android/libportable/common/include/signal_portable.h b/ndk/sources/android/libportable/common/include/signal_portable.h
new file mode 100644
index 0000000..e80db4b
--- /dev/null
+++ b/ndk/sources/android/libportable/common/include/signal_portable.h
@@ -0,0 +1,442 @@
+/*
+ * Copyright 2014, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _SIGNAL_PORTABLE_H_
+#define _SIGNAL_PORTABLE_H_
+
+#if (__mips__)
+
+#include <portability.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+struct stack_t_portable {
+  void *ss_sp;
+  int ss_flags;
+  size_t ss_size;
+};
+
+static inline void stack_t_pton(const struct stack_t_portable *ptr_p, stack_t *ptr_n) {
+  memset(ptr_n, '\0', sizeof(stack_t));
+  ptr_n->ss_sp    = ptr_p->ss_sp;
+  ptr_n->ss_flags = ptr_p->ss_flags;
+  ptr_n->ss_size  = ptr_p->ss_size;
+}
+
+static inline void stack_t_ntop(const stack_t *ptr_n, struct stack_t_portable *ptr_p) {
+  memset(ptr_p, '\0', sizeof(struct stack_t_portable));
+  ptr_p->ss_sp    = ptr_n->ss_sp;
+  ptr_p->ss_flags = ptr_n->ss_flags;
+  ptr_p->ss_size  = ptr_n->ss_size;
+}
+
+int WRAP(sigaltstack)(const struct stack_t_portable *ss, struct stack_t_portable *oss) {
+  stack_t ss_n, oss_n;
+  if (ss != NULL) {
+    stack_t_pton(ss, &ss_n);
+    if (oss != NULL){
+      int ret = REAL(sigaltstack)(&ss_n, &oss_n);
+      stack_t_ntop(&oss_n, oss);
+      return ret;
+    }
+    else
+      return REAL(sigaltstack)(&ss_n, NULL);
+  }
+  else if (oss != NULL) {
+    int ret = REAL(sigaltstack)(NULL, &oss_n);
+    stack_t_ntop(&oss_n, oss);
+    return ret;
+  }
+  else
+    return REAL(sigaltstack)(NULL, NULL);
+}
+
+#define SIGHUP_PORTABLE 1
+#define SIGINT_PORTABLE 2
+#define SIGQUIT_PORTABLE 3
+#define SIGILL_PORTABLE 4
+#define SIGTRAP_PORTABLE 5
+#define SIGABRT_PORTABLE 6
+#define SIGIOT_PORTABLE 6
+#define SIGBUS_PORTABLE 7
+#define SIGFPE_PORTABLE 8
+#define SIGKILL_PORTABLE 9
+#define SIGUSR1_PORTABLE 10
+#define SIGSEGV_PORTABLE 11
+#define SIGUSR2_PORTABLE 12
+#define SIGPIPE_PORTABLE 13
+#define SIGALRM_PORTABLE 14
+#define SIGTERM_PORTABLE 15
+// unsupported in MIPS
+#define SIGSTKFLT_PORTABLE 16
+//
+#define SIGCHLD_PORTABLE 17
+#define SIGCONT_PORTABLE 18
+#define SIGSTOP_PORTABLE 19
+#define SIGTSTP_PORTABLE 20
+#define SIGTTIN_PORTABLE 21
+#define SIGTTOU_PORTABLE 22
+#define SIGURG_PORTABLE 23
+#define SIGXCPU_PORTABLE 24
+#define SIGXFSZ_PORTABLE 25
+#define SIGVTALRM_PORTABLE 26
+#define SIGPROF_PORTABLE 27
+#define SIGWINCH_PORTABLE 28
+#define SIGIO_PORTABLE 29
+#define SIGPOLL_PORTABLE SIGIO_PORTABLE
+#define SIGPWR_PORTABLE 30
+#define SIGSYS_PORTABLE 31
+#define SIGUNUSED_PORTABLE 31
+// unsupported in MIPS
+#define SIGSWI_PORTABLE 32
+//
+
+static inline int signo_pton(int signum_p) {
+  switch(signum_p) {
+    case SIGHUP_PORTABLE: return SIGHUP;
+    case SIGINT_PORTABLE: return SIGINT;
+    case SIGQUIT_PORTABLE: return SIGQUIT;
+    case SIGILL_PORTABLE: return SIGILL;
+    case SIGTRAP_PORTABLE: return SIGTRAP;
+    case SIGABRT_PORTABLE: return SIGABRT;
+    case SIGBUS_PORTABLE: return SIGBUS;
+    case SIGFPE_PORTABLE: return SIGFPE;
+    case SIGKILL_PORTABLE: return SIGKILL;
+    case SIGUSR1_PORTABLE: return SIGUSR1;
+    case SIGSEGV_PORTABLE: return SIGSEGV;
+    case SIGUSR2_PORTABLE: return SIGUSR2;
+    case SIGPIPE_PORTABLE: return SIGPIPE;
+    case SIGALRM_PORTABLE: return SIGALRM;
+    case SIGTERM_PORTABLE: return SIGTERM;
+    case SIGCHLD_PORTABLE: return SIGCHLD;
+    case SIGCONT_PORTABLE: return SIGCONT;
+    case SIGSTOP_PORTABLE: return SIGSTOP;
+    case SIGTSTP_PORTABLE: return SIGTSTP;
+    case SIGTTIN_PORTABLE: return SIGTTIN;
+    case SIGTTOU_PORTABLE: return SIGTTOU;
+    case SIGURG_PORTABLE: return SIGURG;
+    case SIGXCPU_PORTABLE: return SIGXCPU;
+    case SIGXFSZ_PORTABLE: return SIGXFSZ;
+    case SIGVTALRM_PORTABLE: return SIGVTALRM;
+    case SIGPROF_PORTABLE: return SIGPROF;
+    case SIGWINCH_PORTABLE: return SIGWINCH;
+    case SIGIO_PORTABLE: return SIGIO;
+    case SIGPWR_PORTABLE: return SIGPWR;
+    case SIGSYS_PORTABLE: return SIGSYS;
+    default:
+      fprintf(stderr, "Unknown SIGNAL:%d\n", signum_p);
+      abort();
+  }
+}
+
+static inline int signo_ntop(int signum_n) {
+  switch(signum_n) {
+    case SIGHUP: return SIGHUP_PORTABLE;
+    case SIGINT: return SIGINT_PORTABLE;
+    case SIGQUIT: return SIGQUIT_PORTABLE;
+    case SIGILL: return SIGILL_PORTABLE;
+    case SIGTRAP: return SIGTRAP_PORTABLE;
+    case SIGABRT: return SIGABRT_PORTABLE;
+    case SIGBUS: return SIGBUS_PORTABLE;
+    case SIGFPE: return SIGFPE_PORTABLE;
+    case SIGKILL: return SIGKILL_PORTABLE;
+    case SIGUSR1: return SIGUSR1_PORTABLE;
+    case SIGSEGV: return SIGSEGV_PORTABLE;
+    case SIGUSR2: return SIGUSR2_PORTABLE;
+    case SIGPIPE: return SIGPIPE_PORTABLE;
+    case SIGALRM: return SIGALRM_PORTABLE;
+    case SIGTERM: return SIGTERM_PORTABLE;
+    case SIGCHLD: return SIGCHLD_PORTABLE;
+    case SIGCONT: return SIGCONT_PORTABLE;
+    case SIGSTOP: return SIGSTOP_PORTABLE;
+    case SIGTSTP: return SIGTSTP_PORTABLE;
+    case SIGTTIN: return SIGTTIN_PORTABLE;
+    case SIGTTOU: return SIGTTOU_PORTABLE;
+    case SIGURG: return SIGURG_PORTABLE;
+    case SIGXCPU: return SIGXCPU_PORTABLE;
+    case SIGXFSZ: return SIGXFSZ_PORTABLE;
+    case SIGVTALRM: return SIGVTALRM_PORTABLE;
+    case SIGPROF: return SIGPROF_PORTABLE;
+    case SIGWINCH: return SIGWINCH_PORTABLE;
+    case SIGIO: return SIGIO_PORTABLE;
+    case SIGPWR: return SIGPWR_PORTABLE;
+    case SIGSYS: return SIGSYS_PORTABLE;
+    default:
+      fprintf(stderr, "Unknown SIGNAL:%d\n", signum_n);
+      abort();
+  }
+}
+
+#define SA_NOCLDSTOP_PORTABLE 0x00000001
+#define SA_NOCLDWAIT_PORTABLE 0x00000002
+#define SA_SIGINFO_PORTABLE 0x00000004
+// unsupported in MIPS
+#define SA_THIRTYTWO_PORTABLE 0x02000000
+#define SA_RESTORER_PORTABLE 0x04000000
+//
+#define SA_ONSTACK_PORTABLE 0x08000000
+#define SA_RESTART_PORTABLE 0x10000000
+#define SA_NODEFER_PORTABLE 0x40000000
+#define SA_RESETHAND_PORTABLE 0x80000000
+#define SA_NOMASK_PORTABLE SA_NODEFER_PORTABLE
+#define SA_ONESHOT_PORTABLE SA_RESETHAND_PORTABLE
+
+static inline int sa_flags_pton(int sa_flags_p) {
+  int sa_flags_n = 0;
+  sa_flags_n |= (sa_flags_p & SA_NOCLDSTOP_PORTABLE) ? SA_NOCLDSTOP : 0;
+  sa_flags_n |= (sa_flags_p & SA_NOCLDWAIT_PORTABLE) ? SA_NOCLDWAIT : 0;
+  sa_flags_n |= (sa_flags_p & SA_SIGINFO_PORTABLE) ? SA_SIGINFO : 0;
+  sa_flags_n |= (sa_flags_p & SA_ONSTACK_PORTABLE) ? SA_ONSTACK : 0;
+  sa_flags_n |= (sa_flags_p & SA_RESTART_PORTABLE) ? SA_RESTART : 0;
+  sa_flags_n |= (sa_flags_p & SA_NODEFER_PORTABLE) ? SA_NODEFER : 0;
+  sa_flags_n |= (sa_flags_p & SA_RESETHAND_PORTABLE) ? SA_RESETHAND : 0;
+  return sa_flags_n;
+}
+
+static inline int sa_flags_ntop(int sa_flags_n) {
+  int sa_flags_p = 0;
+  sa_flags_p |= (sa_flags_n & SA_NOCLDSTOP) ? SA_NOCLDSTOP_PORTABLE : 0;
+  sa_flags_p |= (sa_flags_n & SA_NOCLDWAIT) ? SA_NOCLDWAIT_PORTABLE : 0;
+  sa_flags_p |= (sa_flags_n & SA_SIGINFO) ? SA_SIGINFO_PORTABLE : 0;
+  sa_flags_p |= (sa_flags_n & SA_ONSTACK) ? SA_ONSTACK_PORTABLE : 0;
+  sa_flags_p |= (sa_flags_n & SA_RESTART) ? SA_RESTART_PORTABLE : 0;
+  sa_flags_p |= (sa_flags_n & SA_NODEFER) ? SA_NODEFER_PORTABLE : 0;
+  sa_flags_p |= (sa_flags_n & SA_RESETHAND) ? SA_RESETHAND_PORTABLE : 0;
+  return sa_flags_p;
+}
+
+typedef unsigned long  sigset_t_portable;
+struct sigaction_portable {
+  union {
+    __sighandler_t _sa_handler;
+    void (*_sa_sigaction)(int, struct siginfo *, void *);
+  } _u;
+  sigset_t_portable sa_mask;
+  unsigned long sa_flags;
+  void (*sa_restorer)(void); // obsolete
+};
+
+static inline void sigset_t_pton(const sigset_t_portable *ptr_p, sigset_t *ptr_n) {
+  memset(ptr_n, '\0', sizeof(sigset_t));
+  ptr_n->sig[0] = *ptr_p;
+}
+
+static inline void sigset_t_ntop(const sigset_t *ptr_n, sigset_t_portable *ptr_p) {
+  memset(ptr_p, '\0', sizeof(sigset_t_portable));
+  *ptr_p = ptr_n->sig[0];
+}
+
+static inline void sigaction_pton(const struct sigaction_portable *ptr_p, struct sigaction *ptr_n) {
+  memset(ptr_n, '\0', sizeof(struct sigaction));
+  ptr_n->sa_sigaction = ptr_p->_u._sa_sigaction;
+  sigset_t_pton(&ptr_p->sa_mask, &ptr_n->sa_mask);
+  ptr_n->sa_flags       = sa_flags_pton(ptr_p->sa_flags);
+}
+
+static inline void sigaction_ntop(const struct sigaction *ptr_n, struct sigaction_portable *ptr_p) {
+  memset(ptr_p, '\0', sizeof(struct sigaction_portable));
+  ptr_p->_u._sa_sigaction = ptr_n->sa_sigaction;
+  sigset_t_ntop(&ptr_n->sa_mask, &ptr_p->sa_mask);
+  ptr_p->sa_flags      = sa_flags_ntop(ptr_n->sa_flags);
+}
+
+int WRAP(sigaction)(int signum, const struct sigaction_portable *act, struct sigaction_portable *oldact) {
+  struct sigaction act_n, oldact_n;
+  int signum_n = signo_pton(signum);
+
+  if (act != NULL) {
+    sigaction_pton(act, &act_n);
+    if (oldact != NULL) {
+      int ret = REAL(sigaction)(signum_n, &act_n, &oldact_n);
+      sigaction_ntop(&oldact_n, oldact);
+      return ret;
+    }
+    else
+      return REAL(sigaction)(signum_n, &act_n, NULL);
+  }
+  else if (oldact != NULL) {
+    int ret = REAL(sigaction)(signum_n, NULL, &oldact_n);
+    sigaction_ntop(&oldact_n, oldact);
+    return ret;
+  }
+  else
+    return REAL(sigaction)(signum_n, NULL, NULL);
+}
+
+int WRAP(sigaddset)(sigset_t_portable *set, int signum) {
+  int signum_n = signo_pton(signum);
+  sigset_t set_n;
+  sigset_t_pton(set, &set_n);
+  int ret = REAL(sigaddset)(&set_n, signum_n);
+  sigset_t_ntop(&set_n, set);
+  return ret;
+}
+
+int WRAP(sigdelset)(sigset_t_portable *set, int signum) {
+  int signum_n = signo_pton(signum);
+  sigset_t set_n;
+  sigset_t_pton(set, &set_n);
+  int ret = REAL(sigdelset)(&set_n, signum_n);
+  sigset_t_ntop(&set_n, set);
+  return ret;
+}
+
+int WRAP(sigemptyset)(sigset_t_portable *set){
+  sigset_t set_n;
+  sigset_t_pton(set, &set_n);
+  int ret = REAL(sigemptyset)(&set_n);
+  sigset_t_ntop(&set_n, set);
+  return ret;
+}
+
+int WRAP(sigfillset)(sigset_t_portable *set){
+  sigset_t set_n;
+  sigset_t_pton(set, &set_n);
+  int ret = REAL(sigfillset)(&set_n);
+  sigset_t_ntop(&set_n, set);
+  return ret;
+}
+
+int WRAP(sigismember)(const sigset_t_portable *set, int signum) {
+  int signum_n = signo_pton(signum);
+  sigset_t set_n;
+  sigset_t_pton(set, &set_n);
+  return REAL(sigismember)(&set_n, signum_n);
+}
+
+int WRAP(sigpending)(sigset_t_portable *set) {
+  sigset_t set_n;
+  sigset_t_pton(set, &set_n);
+  int ret = REAL(sigpending)(&set_n);
+  sigset_t_ntop(&set_n, set);
+  return ret;
+}
+
+#define SIG_BLOCK_PORTABLE 0
+#define SIG_UNBLOCK_PORTABLE 1
+#define SIG_SETMASK_PORTABLE 2
+
+int WRAP(sigprocmask)(int how, const sigset_t_portable *set, sigset_t_portable *oldset) {
+  int how_n;
+  switch(how) {
+    case SIG_BLOCK_PORTABLE: how_n =  SIG_BLOCK; break;
+    case SIG_UNBLOCK_PORTABLE: how_n = SIG_UNBLOCK; break;
+    case SIG_SETMASK_PORTABLE: how_n = SIG_SETMASK; break;
+    default:
+      fprintf(stderr, "Unknown sigprocmask action:%d\n", how);
+      abort();
+  }
+  sigset_t set_n, oldset_n;
+  if (set != NULL) {
+    sigset_t_pton(set, &set_n);
+    if (oldset != NULL) {
+      int ret = REAL(sigprocmask)(how_n, &set_n, &oldset_n);
+      sigset_t_ntop(&oldset_n, oldset);
+      return ret;
+    }
+    else
+      return REAL(sigprocmask)(how_n, &set_n, NULL);
+  }
+  else if (oldset != NULL) {
+    int ret = REAL(sigprocmask)(how_n, NULL, &oldset_n);
+    sigset_t_ntop(&oldset_n, oldset);
+    return ret;
+  }
+  else
+    return REAL(sigprocmask)(how_n, NULL, NULL);
+}
+
+int WRAP(sigsuspend)(const sigset_t_portable *mask) {
+  sigset_t mask_n;
+  sigset_t_pton(mask, &mask_n);
+  return REAL(sigsuspend)(&mask_n);
+}
+
+int WRAP(sigwait)(const sigset_t_portable *set, int *sig) {
+  sigset_t set_n;
+  sigset_t_pton(set, &set_n);
+  int ret = REAL(sigwait)(&set_n, sig);
+  *sig = signo_ntop(*sig);
+  return ret;
+}
+
+int WRAP(kill)(pid_t pid, int sig) {
+  int sig_n = signo_pton(sig);
+  return REAL(kill)(pid, sig_n);
+}
+
+// sigset_t related function
+#include <sys/select.h>
+int WRAP(pselect)(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec *timeout, const sigset_t_portable *sigmask) {
+  sigset_t sigmask_n;
+  sigset_t_pton(sigmask, &sigmask_n);
+  return  REAL(pselect)(nfds, readfds, writefds, exceptfds, timeout, sigmask_n);
+}
+
+#include <sys/signalfd.h>
+int WRAP(signalfd)(int fd, const sigset_t_portable* mask, int flags) {
+  sigset_t mask_n;
+  sigset_t_pton(mask, &mask_n);
+  return REAL(signalfd)(fd, mask_n, flags);
+}
+
+#include <poll.h>
+int WRAP(ppoll)(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts, const sigset_t_portable *sigmask) {
+  sigset_t sigmask_n;
+  sigset_t_pton(sigmask, &sigmask_n);
+  return REAL(ppoll)(fds, nfds, timeout_ts, sigmask_n);
+}
+
+#include <pthread.h>
+int WRAP(pthread_sigmask)(int how, const sigset_t_portable *set, sigset_t_portable *oldset) {
+  int how_n;
+  switch(how) {
+    case SIG_BLOCK_PORTABLE: how_n =  SIG_BLOCK; break;
+    case SIG_UNBLOCK_PORTABLE: how_n = SIG_UNBLOCK; break;
+    case SIG_SETMASK_PORTABLE: how_n = SIG_SETMASK; break;
+    default:
+      fprintf(stderr, "Unknown pthread_sigmask action:%d\n", how);
+      abort();
+  }
+  sigset_t set_n, oldset_n;
+  if (set != NULL) {
+    sigset_t_pton(set, &set_n);
+    if (oldset != NULL) {
+      int ret = REAL(pthread_sigmask)(how_n, &set_n, &oldset_n);
+      sigset_t_ntop(&oldset_n, oldset);
+      return ret;
+    }
+    else
+      return REAL(pthread_sigmask)(how_n, &set_n, NULL);
+  }
+  else if (oldset != NULL) {
+    int ret = REAL(pthread_sigmask)(how_n, NULL, &oldset_n);
+    sigset_t_ntop(&oldset_n, oldset);
+    return ret;
+  }
+  else
+    return REAL(pthread_sigmask)(how_n, NULL, NULL);
+}
+
+#include <sys/epoll.h>
+int WRAP(epoll_pwait)(int fd, struct epoll_event* events, int max_events, int timeout, const sigset_t_portable* ss) {
+  sigset_t ss_n;
+  sigset_t_pton(ss, &ss_n);
+  return REAL(epoll_pwait)(fd, events, max_events, timeout, ss_n);
+}
+#endif /* __mips__ */
+#endif /* _SIGNAL_PORTABLE_H */
diff --git a/perftests/panorama/feature_mos/src/mosaic_renderer/SurfaceTextureRenderer.cpp b/perftests/panorama/feature_mos/src/mosaic_renderer/SurfaceTextureRenderer.cpp
index 88aac36..fa56402 100755
--- a/perftests/panorama/feature_mos/src/mosaic_renderer/SurfaceTextureRenderer.cpp
+++ b/perftests/panorama/feature_mos/src/mosaic_renderer/SurfaceTextureRenderer.cpp
@@ -16,6 +16,8 @@
 
 #include "SurfaceTextureRenderer.h"
 
+#include <string.h>
+
 #include <GLES2/gl2ext.h>
 const GLfloat g_vVertices[] = {
     -1.f, -1.f, 0.0f, 1.0f,  // Position 0
diff --git a/scripts/acov b/scripts/acov
index ef7c86a..9b2fbbf 100755
--- a/scripts/acov
+++ b/scripts/acov
@@ -30,17 +30,40 @@
 # it in your browser).
 #
 
+if [ "$1" = "--clean" ]; then
+  find $ANDROID_HOST_OUT \( -name '*.gcda' -o -name '*.gcno' \) -delete
+  find $ANDROID_PRODUCT_OUT \( -name '*.gcda' -o -name '*.gcno' \) -delete
+  exit 0
+fi
+
+if [ "$1" = "--prep" ]; then
+  find $ANDROID_HOST_OUT -name '*.gcda' -delete
+  find $ANDROID_PRODUCT_OUT -name '*.gcda' -delete
+  exit 0
+fi
+
 which lcov >/dev/null 2>/dev/null
 if [ $? -ne 0 ]; then
   echo 'lcov not found: running `sudo apt-get install lcov`'
   sudo apt-get install lcov
 fi
 
+HOST=false
+ANDROID_OUT=$ANDROID_PRODUCT_OUT
+if [ "$1" = "--host" ]; then
+  HOST=true
+  ANDROID_OUT=$ANDROID_HOST_OUT
+fi
+
 cd $ANDROID_BUILD_TOP
 FILE=cov.info
 DIR=$(mktemp -d covreport-XXXXXX)
-adb pull /data/local/tmp/gcov
-lcov -c -d $ANDROID_PRODUCT_OUT -o $DIR/$FILE
+
+if [ "$HOST" = "false" ]; then
+  adb pull /data/local/tmp/gcov
+fi
+
+lcov -c -d $ANDROID_OUT -o $DIR/$FILE
 echo "Generating coverage report at $DIR"
 genhtml -q -o $DIR $DIR/$FILE
 xdg-open $DIR/index.html >/dev/null