Merge branch 'upstream' into merge_2012_03_18

Change-Id: I45a9f74b42eae6a1fe5320a46a3a562eee0a8357
diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..b284082
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,348 @@
+#
+# Copyright (C) 2012 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.
+#
+#
+
+LOCAL_PATH := $(call my-dir)
+
+# The following list contains platform-independent functionalities.
+#
+# Skip apple_versioning.c since it is unused.
+# Skip atomic.c since it needs to be built separately according to the docs.
+# Skip clear_cache.c since it redefines a system function on Android.
+# Skip gcc_personality_v0.c since it depends on libunwind.
+libcompiler_rt_common_SRC_FILES := \
+  lib/absvdi2.c \
+  lib/absvsi2.c \
+  lib/absvti2.c \
+  lib/adddf3.c \
+  lib/addsf3.c \
+  lib/addvdi3.c \
+  lib/addvsi3.c \
+  lib/addvti3.c \
+  lib/ashldi3.c \
+  lib/ashlti3.c \
+  lib/ashrdi3.c \
+  lib/ashrti3.c \
+  lib/clzdi2.c \
+  lib/clzsi2.c \
+  lib/clzti2.c \
+  lib/cmpdi2.c \
+  lib/cmpti2.c \
+  lib/comparedf2.c \
+  lib/comparesf2.c \
+  lib/ctzdi2.c \
+  lib/ctzsi2.c \
+  lib/ctzti2.c \
+  lib/divdc3.c \
+  lib/divdf3.c \
+  lib/divdi3.c \
+  lib/divmoddi4.c \
+  lib/divmodsi4.c \
+  lib/divsc3.c \
+  lib/divsf3.c \
+  lib/divsi3.c \
+  lib/divti3.c \
+  lib/divxc3.c \
+  lib/enable_execute_stack.c \
+  lib/eprintf.c \
+  lib/extendsfdf2.c \
+  lib/ffsdi2.c \
+  lib/ffsti2.c \
+  lib/fixdfdi.c \
+  lib/fixdfsi.c \
+  lib/fixdfti.c \
+  lib/fixsfdi.c \
+  lib/fixsfsi.c \
+  lib/fixsfti.c \
+  lib/fixunsdfdi.c \
+  lib/fixunsdfsi.c \
+  lib/fixunsdfti.c \
+  lib/fixunssfdi.c \
+  lib/fixunssfsi.c \
+  lib/fixunssfti.c \
+  lib/fixunsxfdi.c \
+  lib/fixunsxfsi.c \
+  lib/fixunsxfti.c \
+  lib/fixxfdi.c \
+  lib/fixxfti.c \
+  lib/floatdidf.c \
+  lib/floatdisf.c \
+  lib/floatdixf.c \
+  lib/floatsidf.c \
+  lib/floatsisf.c \
+  lib/floattidf.c \
+  lib/floattisf.c \
+  lib/floattixf.c \
+  lib/floatundidf.c \
+  lib/floatundisf.c \
+  lib/floatundixf.c \
+  lib/floatunsidf.c \
+  lib/floatunsisf.c \
+  lib/floatuntidf.c \
+  lib/floatuntisf.c \
+  lib/floatuntixf.c \
+  lib/int_util.c \
+  lib/lshrdi3.c \
+  lib/lshrti3.c \
+  lib/moddi3.c \
+  lib/modsi3.c \
+  lib/modti3.c \
+  lib/muldc3.c \
+  lib/muldf3.c \
+  lib/muldi3.c \
+  lib/mulodi4.c \
+  lib/mulosi4.c \
+  lib/muloti4.c \
+  lib/mulsc3.c \
+  lib/mulsf3.c \
+  lib/multi3.c \
+  lib/mulvdi3.c \
+  lib/mulvsi3.c \
+  lib/mulvti3.c \
+  lib/mulxc3.c \
+  lib/negdf2.c \
+  lib/negdi2.c \
+  lib/negsf2.c \
+  lib/negti2.c \
+  lib/negvdi2.c \
+  lib/negvsi2.c \
+  lib/negvti2.c \
+  lib/paritydi2.c \
+  lib/paritysi2.c \
+  lib/parityti2.c \
+  lib/popcountdi2.c \
+  lib/popcountsi2.c \
+  lib/popcountti2.c \
+  lib/powidf2.c \
+  lib/powisf2.c \
+  lib/powitf2.c \
+  lib/powixf2.c \
+  lib/subdf3.c \
+  lib/subsf3.c \
+  lib/subvdi3.c \
+  lib/subvsi3.c \
+  lib/subvti3.c \
+  lib/trampoline_setup.c \
+  lib/truncdfsf2.c \
+  lib/ucmpdi2.c \
+  lib/ucmpti2.c \
+  lib/udivdi3.c \
+  lib/udivmoddi4.c \
+  lib/udivmodsi4.c \
+  lib/udivmodti4.c \
+  lib/udivsi3.c \
+  lib/udivti3.c \
+  lib/umoddi3.c \
+  lib/umodsi3.c \
+  lib/umodti3.c
+
+# ARM-specific runtimes
+libcompiler_rt_arm_SRC_FILES := \
+  lib/arm/aeabi_dcmp.S \
+  lib/arm/aeabi_fcmp.S \
+  lib/arm/aeabi_idivmod.S \
+  lib/arm/aeabi_ldivmod.S \
+  lib/arm/aeabi_memcmp.S \
+  lib/arm/aeabi_memcpy.S \
+  lib/arm/aeabi_memmove.S \
+  lib/arm/aeabi_memset.S \
+  lib/arm/aeabi_uidivmod.S \
+  lib/arm/aeabi_uldivmod.S \
+  lib/arm/comparesf2.S \
+  lib/arm/divmodsi4.S \
+  lib/arm/divsi3.S \
+  lib/arm/modsi3.S \
+  lib/arm/udivmodsi4.S \
+  lib/arm/udivsi3.S \
+  lib/arm/umodsi3.S
+
+# MIPS-specific runtimes
+libcompiler_rt_mips_SRC_FILES := # nothing to add
+
+# X86-specific runtimes
+#
+# We don't support x86-64 right now
+libcompiler_rt_x86_SRC_FILES := \
+  lib/i386/ashldi3.S \
+  lib/i386/ashrdi3.S \
+  lib/i386/divdi3.S \
+  lib/i386/floatdidf.S \
+  lib/i386/floatdisf.S \
+  lib/i386/floatdixf.S \
+  lib/i386/floatundidf.S \
+  lib/i386/floatundisf.S \
+  lib/i386/floatundixf.S \
+  lib/i386/lshrdi3.S \
+  lib/i386/moddi3.S \
+  lib/i386/muldi3.S \
+  lib/i386/udivdi3.S \
+  lib/i386/umoddi3.S
+
+# The following list contains functions that are not available in libgcc.a, so
+# we potentially need them when using a Clang-built component (e.g., -ftrapv
+# with 64-bit integer multiplies. See http://llvm.org/bugs/show_bug.cgi?id=14469.)
+libcompiler_rt_extras_SRC_FILES := \
+  lib/mulodi4.c
+
+# $(1): arch
+define get-libcompiler-rt-source-files
+  $(if $(findstring $(1),arm),$(call get-libcompiler-rt-arm-source-files),
+      $(if $(findstring $(1),mips),$(call get-libcompiler-rt-mips-source-files),
+          $(if $(findstring $(1),x86),$(call get-libcompiler-rt-x86-source-files),
+  $(error Unsupported ARCH $(1)))))
+endef
+
+# $(1): source list
+# $(2): arch
+#
+# If lib/<arch>/X.S is included in the source list, we should filter out lib/X.c
+# in the result source list (i.e., use the one optimized for the arch.) Otherwise
+# there'll be multiple definitions for one symbol.
+define filter-libcompiler-rt-common-source-files
+  $(filter-out $(patsubst lib/$(strip $(2))/%.S,lib/%.c,$(filter %.S,$(1))),$(1))
+endef
+
+define get-libcompiler-rt-arm-common-source-files
+  $(call filter-libcompiler-rt-common-source-files,
+      $(libcompiler_rt_common_SRC_FILES) \
+      $(libcompiler_rt_arm_SRC_FILES), arm)
+endef
+
+# $(1): common runtime list
+#
+# Add ARM runtimes implemented in VFP
+define add-libcompiler-rt-arm-vfp-source-files
+  $(filter-out $(addprefix lib/,adddf3.c addsf3.c comparedf2.c comparesf2.c         \
+                                arm/comparesf2.S divdf3.c divsf3.c extendsfdf2.c    \
+                                fixdfsi.c fixsfsi.c fixunsdfsi.c fixunssfsi.c       \
+                                floatsidf.c floatsisf.c floatunsidf.c floatunsisf.c \
+                                muldf3.c mulsf3.c negdf2.c negsf2.c subdf3.c        \
+                                subsf3.c truncdfsf2.c),$(1)) lib/arm/vfp_alias.S
+endef
+
+define get-libcompiler-rt-arm-source-files
+  $(if $(findstring $(ARCH_ARM_HAVE_VFP),true),
+      $(call add-libcompiler-rt-arm-vfp-source-files,
+          $(call get-libcompiler-rt-arm-common-source-files)),
+      $(call get-libcompiler-rt-arm-common-source-files))
+endef
+
+define get-libcompiler-rt-mips-source-files
+  $(call filter-libcompiler-rt-common-source-files,
+      $(libcompiler_rt_common_SRC_FILES) \
+      $(libcompiler_rt_mips_SRC_FILES),mips)
+endef
+
+define get-libcompiler-rt-x86-source-files
+  $(call filter-libcompiler-rt-common-source-files,
+      $(libcompiler_rt_common_SRC_FILES) \
+      $(libcompiler_rt_x86_SRC_FILES),i386)
+endef
+
+# $(1): target or host
+# $(2): static or shared
+define build-libcompiler-rt
+  ifneq ($(1),target)
+    ifneq ($(1),host)
+      $$(error expected target or host for argument 1, received $(1))
+    endif
+  endif
+  ifneq ($(2),static)
+    ifneq ($(2),shared)
+      $$(error expected static or shared for argument 2, received $(2))
+    endif
+  endif
+
+  target_or_host := $(1)
+  static_or_shared := $(2)
+
+  arch :=
+  ifeq ($$(target_or_host),target)
+    arch := $(TARGET_ARCH)
+  else
+    arch := $(HOST_ARCH)
+  endif
+
+  include $(CLEAR_VARS)
+
+  LOCAL_MODULE := libcompiler_rt
+  LOCAL_MODULE_TAGS := optional
+
+  ifeq ($$(static_or_shared),static)
+    LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+  else
+    LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+  endif
+
+  # TODO: Fix -integrated-as
+  # LOCAL_CFLAGS := -integrated-as
+
+  # Add -D__ARM_EABI__ for ARM
+  ifeq ($$(arch),arm)
+    LOCAL_CFLAGS += -D__ARM_EABI__
+  endif
+
+  # Use MC assembler to compile assembly
+  LOCAL_ASFLAGS += -integrated-as
+
+  # Use Clang to compile libcompiler_rt
+  LOCAL_CLANG := true
+  LOCAL_SRC_FILES := $$(call get-libcompiler-rt-source-files,$$(arch))
+  LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+
+  ifeq ($$(target_or_host),target)
+    ifeq ($$(static_or_shared),static)
+      include $(BUILD_STATIC_LIBRARY)
+    else
+      include $(BUILD_SHARED_LIBRARY)
+    endif
+  else
+    LOCAL_IS_HOST_MODULE := true
+    ifeq ($$(static_or_shared),static)
+      include $(BUILD_HOST_STATIC_LIBRARY)
+    else
+      include $(BUILD_HOST_SHARED_LIBRARY)
+    endif
+  endif
+endef
+
+#=====================================================================
+# Device Static Library: libcompiler_rt-extras
+#=====================================================================
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libcompiler_rt-extras
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_CLANG := true
+LOCAL_SRC_FILES := $(libcompiler_rt_extras_SRC_FILES)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+
+include $(BUILD_STATIC_LIBRARY)
+
+#=====================================================================
+# Device Static Library: libcompiler_rt
+#=====================================================================
+$(eval $(call build-libcompiler-rt,target,static))
+
+#=====================================================================
+# Device Shared Library: libcompiler_rt
+#=====================================================================
+$(eval $(call build-libcompiler-rt,target,shared))
+
+# Build ASan
+include $(LOCAL_PATH)/lib/asan/Android.mk
diff --git a/README.android b/README.android
new file mode 100644
index 0000000..3e2a226
--- /dev/null
+++ b/README.android
@@ -0,0 +1,32 @@
+/*
+ * README.android describes in high-level the compiler-rt changes that we
+ * cannot push upstream to the llvm.org repository:
+ *  - Changes due to Android's build system.
+ *  - Changes due to Android's toolchain.
+ *  - Changes due to the limitations in Android-based consumer electronics.
+ *
+ * Some of them are to-dos. If and when they are done, there will no longer be
+ * merge conflicts with upstream on those parts.
+ *
+ * The file contains useful hints when we try to resolve future 3-way merge
+ * conflicts.
+ */
+
+* For JellyBean: Synced to upstream r155350
+* For JellyBean MR1: Synced to upstream r162279
+* For Jellybean MR2: Synced to upstream r176091
+
+* Recent downstreaming on 2013/3/5: Synced to r176091 (Contact srhines for merge questions.)
+* Recent downstreaming on 2013/1/8: Synced to r171802 (Contact srhines for merge questions.)
+* Recent downstreaming on 2012/08/23: Synced to r162279 (Contact srhines for merge questions.)
+* Recent downstreaming on 2012/08/15: Synced to r159129 (Contact sliao for merge questions.)
+* Cherry-pick on 2012/07/27: https://llvm.org/svn/llvm-project/compiler-rt/trunk@160853 for ASan (Contact srhines for merge questions.)
+* Cherry-pick on 2012/05/23: https://llvm.org/svn/llvm-project/compiler-rt/trunk@157318 for ASan (Contact srhines for merge questions.)
+* Recent downstreaming on 2012/04/25: Synced to r155350 (Contact sliao for merge questions.)
+* Recent downstreaming on 2012/03/08: Synced to r152058 (Contact srhines for merge questions.)
+
+TODO: This is still not building by default (no Android.mk files are present
+yet). Look at frameworks/compile/libbcc/runtime for potential starting points.
+
+TODO: Switch libbcc to use this version of compiler-rt instead of its own
+tweaked version.
diff --git a/lib/arm/vfp_alias.S b/lib/arm/vfp_alias.S
new file mode 100644
index 0000000..6bdae15
--- /dev/null
+++ b/lib/arm/vfp_alias.S
@@ -0,0 +1,93 @@
+//===-- vfp_alias.S - Override generic runtimes with VFP version ----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+#include "adddf3vfp.S"
+#include "addsf3vfp.S"
+#include "divdf3vfp.S"
+#include "divsf3vfp.S"
+#include "eqdf2vfp.S"
+#include "eqsf2vfp.S"
+#include "extendsfdf2vfp.S"
+#include "fixdfsivfp.S"
+#include "fixsfsivfp.S"
+#include "fixunsdfsivfp.S"
+#include "fixunssfsivfp.S"
+#include "floatsidfvfp.S"
+#include "floatsisfvfp.S"
+#include "floatunssidfvfp.S"
+#include "floatunssisfvfp.S"
+#include "gedf2vfp.S"
+#include "gesf2vfp.S"
+#include "gtdf2vfp.S"
+#include "gtsf2vfp.S"
+#include "ledf2vfp.S"
+#include "lesf2vfp.S"
+#include "ltdf2vfp.S"
+#include "ltsf2vfp.S"
+#include "muldf3vfp.S"
+#include "mulsf3vfp.S"
+#include "nedf2vfp.S"
+#include "negdf2vfp.S"
+#include "negsf2vfp.S"
+#include "nesf2vfp.S"
+#include "subdf3vfp.S"
+#include "subsf3vfp.S"
+#include "truncdfsf2vfp.S"
+#include "unorddf2vfp.S"
+#include "unordsf2vfp.S"
+
+#define DEFINE_VFP_FUNCTION_ALIAS(name)              \
+  DEFINE_COMPILERRT_FUNCTION_ALIAS(name, name ## vfp)
+
+#define DEFINE_VFP_AND_AEABI_ALIAS(aeabi_name, name) \
+  DEFINE_VFP_FUNCTION_ALIAS(name)                    \
+  DEFINE_AEABI_FUNCTION_ALIAS(aeabi_name, name)
+
+DEFINE_VFP_AND_AEABI_ALIAS(__aeabi_dadd, __adddf3)
+DEFINE_VFP_AND_AEABI_ALIAS(__aeabi_fadd, __addsf3)
+DEFINE_VFP_AND_AEABI_ALIAS(__aeabi_ddiv, __divdf3)
+DEFINE_VFP_AND_AEABI_ALIAS(__aeabi_fdiv, __divsf3)
+DEFINE_VFP_FUNCTION_ALIAS(__eqdf2)
+DEFINE_VFP_FUNCTION_ALIAS(__eqsf2)
+DEFINE_VFP_AND_AEABI_ALIAS(__aeabi_f2d, __extendsfdf2)
+DEFINE_VFP_AND_AEABI_ALIAS(__aeabi_d2iz, __fixdfsi)
+DEFINE_VFP_AND_AEABI_ALIAS(__aeabi_f2iz, __fixsfsi)
+DEFINE_VFP_AND_AEABI_ALIAS(__aeabi_d2uiz, __fixunsdfsi)
+DEFINE_VFP_AND_AEABI_ALIAS(__aeabi_f2uiz, __fixunssfsi)
+DEFINE_VFP_AND_AEABI_ALIAS(__aeabi_i2d, __floatsidf)
+DEFINE_VFP_AND_AEABI_ALIAS(__aeabi_i2f, __floatsisf)
+DEFINE_VFP_FUNCTION_ALIAS(__gedf2)
+DEFINE_VFP_FUNCTION_ALIAS(__gesf2)
+DEFINE_VFP_FUNCTION_ALIAS(__gtdf2)
+DEFINE_VFP_FUNCTION_ALIAS(__gtsf2)
+DEFINE_VFP_FUNCTION_ALIAS(__ledf2)
+DEFINE_VFP_FUNCTION_ALIAS(__lesf2)
+DEFINE_VFP_FUNCTION_ALIAS(__ltdf2)
+DEFINE_VFP_FUNCTION_ALIAS(__ltsf2)
+DEFINE_VFP_AND_AEABI_ALIAS(__aeabi_dmul, __muldf3)
+DEFINE_VFP_AND_AEABI_ALIAS(__aeabi_fmul, __mulsf3)
+DEFINE_VFP_FUNCTION_ALIAS(__nedf2)
+DEFINE_VFP_AND_AEABI_ALIAS(__aeabi_dneg, __negdf2)
+DEFINE_VFP_AND_AEABI_ALIAS(__aeabi_fneg, __negsf2)
+DEFINE_VFP_FUNCTION_ALIAS(__nesf2)
+DEFINE_VFP_AND_AEABI_ALIAS(__aeabi_dsub, __subdf3)
+DEFINE_VFP_AND_AEABI_ALIAS(__aeabi_fsub, __subsf3)
+DEFINE_VFP_AND_AEABI_ALIAS(__aeabi_d2f, __truncdfsf2)
+DEFINE_VFP_AND_AEABI_ALIAS(__aeabi_dcmpun, __unorddf2)
+DEFINE_VFP_AND_AEABI_ALIAS(__aeabi_fcmpun, __unordsf2)
+
+// Alias __floatunsidf to __floatunssidfvfp
+DEFINE_COMPILERRT_FUNCTION_ALIAS(__floatunsidf, __floatunssidfvfp)
+DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_ui2d, __floatunsidf)
+
+// Alias __floatunsisf to __floatunsisfvfp
+DEFINE_COMPILERRT_FUNCTION_ALIAS(__floatunsisf, __floatunssisfvfp)
+DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_ui2f, __floatunsisf)
diff --git a/lib/asan/Android.mk b/lib/asan/Android.mk
new file mode 100644
index 0000000..c743a2c
--- /dev/null
+++ b/lib/asan/Android.mk
@@ -0,0 +1,192 @@
+#
+# Copyright (C) 2012 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.
+#
+#
+
+LOCAL_PATH:= $(call my-dir)
+
+ifeq ($(TARGET_ARCH),arm)
+
+ASAN_NEEDS_SEGV=0
+ASAN_HAS_EXCEPTIONS=1
+ASAN_FLEXIBLE_MAPPING_AND_OFFSET=0
+
+asan_rtl_files := \
+	asan_allocator.cc	\
+	asan_allocator2.cc	\
+	asan_fake_stack.cc \
+	asan_globals.cc	\
+	asan_interceptors.cc	\
+	asan_linux.cc \
+	asan_mac.cc \
+	asan_malloc_linux.cc \
+	asan_malloc_mac.cc \
+	asan_malloc_win.cc \
+	asan_new_delete.cc	\
+	asan_poisoning.cc	\
+	asan_posix.cc \
+	asan_report.cc	\
+	asan_rtl.cc \
+	asan_stack.cc	\
+	asan_stats.cc	\
+	asan_thread.cc	\
+	asan_thread_registry.cc \
+	asan_win.cc \
+	../interception/interception_linux.cc \
+	../sanitizer_common/sanitizer_allocator.cc \
+	../sanitizer_common/sanitizer_common.cc \
+	../sanitizer_common/sanitizer_flags.cc \
+	../sanitizer_common/sanitizer_libc.cc \
+	../sanitizer_common/sanitizer_linux.cc \
+	../sanitizer_common/sanitizer_mac.cc \
+	../sanitizer_common/sanitizer_posix.cc \
+	../sanitizer_common/sanitizer_platform_limits_posix.cc \
+	../sanitizer_common/sanitizer_printf.cc \
+	../sanitizer_common/sanitizer_stackdepot.cc \
+	../sanitizer_common/sanitizer_stacktrace.cc \
+	../sanitizer_common/sanitizer_symbolizer.cc \
+	../sanitizer_common/sanitizer_symbolizer_itanium.cc \
+	../sanitizer_common/sanitizer_symbolizer_linux.cc \
+	../sanitizer_common/sanitizer_symbolizer_mac.cc \
+	../sanitizer_common/sanitizer_symbolizer_win.cc \
+	../sanitizer_common/sanitizer_win.cc \
+
+asan_rtl_cflags := \
+	-fvisibility=hidden \
+	-fno-exceptions \
+	-DASAN_LOW_MEMORY=1 \
+	-DASAN_NEEDS_SEGV=$(ASAN_NEEDS_SEGV) \
+	-DASAN_HAS_EXCEPTIONS=$(ASAN_HAS_EXCEPTIONS) \
+	-DASAN_FLEXIBLE_MAPPING_AND_OFFSET=$(ASAN_FLEXIBLE_MAPPING_AND_OFFSET) \
+	-Wno-covered-switch-default \
+	-Wno-sign-compare \
+	-Wno-unused-parameter \
+	-D__WORDSIZE=32
+
+asan_test_files := \
+	tests/asan_globals_test.cc \
+	tests/asan_test.cc
+
+#tests/asan_noinst_test.cc \
+#tests/asan_test_main.cc \
+
+asan_test_cflags := \
+	-mllvm -asan-blacklist=external/compiler-rt/lib/asan/tests/asan_test.ignore \
+	-DASAN_LOW_MEMORY=1 \
+	-DASAN_UAR=0 \
+	-DASAN_NEEDS_SEGV=$(ASAN_NEEDS_SEGV) \
+	-DASAN_HAS_EXCEPTIONS=$(ASAN_HAS_EXCEPTIONS) \
+	-DASAN_HAS_BLACKLIST=1 \
+	-Wno-covered-switch-default \
+	-Wno-sign-compare \
+	-Wno-unused-parameter \
+	-D__WORDSIZE=32
+
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libasan
+LOCAL_MODULE_TAGS := optional
+LOCAL_C_INCLUDES := bionic external/compiler-rt/lib external/compiler-rt/include
+LOCAL_CFLAGS += $(asan_rtl_cflags)
+LOCAL_SRC_FILES := asan_preinit.cc
+#LOCAL_SRC_FILES := asan_android_stub.cc asan_preinit.cc
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_CLANG := true
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+include $(BUILD_STATIC_LIBRARY)
+
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libasan_preload
+LOCAL_MODULE_TAGS := eng
+LOCAL_C_INCLUDES := \
+  bionic \
+  external/compiler-rt/lib \
+  external/compiler-rt/include
+LOCAL_CFLAGS += $(asan_rtl_cflags)
+LOCAL_SRC_FILES := $(asan_rtl_files)
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_SHARED_LIBRARIES := libc libdl
+LOCAL_CLANG := true
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+include $(BUILD_SHARED_LIBRARY)
+
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := asanwrapper
+LOCAL_MODULE_TAGS := eng
+LOCAL_C_INCLUDES := \
+        bionic \
+        external/stlport/stlport
+LOCAL_SRC_FILES := asanwrapper.cc
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_SHARED_LIBRARIES := libstlport libc
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+
+include $(BUILD_EXECUTABLE)
+
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libasan_noinst_test
+LOCAL_MODULE_TAGS := tests
+LOCAL_C_INCLUDES := \
+        bionic \
+        external/stlport/stlport \
+        external/gtest/include \
+        external/compiler-rt/include \
+        external/compiler-rt/lib \
+	external/compiler-rt/lib/asan/tests \
+	external/compiler-rt/lib/sanitizer_common/tests
+LOCAL_CFLAGS += \
+        -Wno-unused-parameter \
+        -Wno-sign-compare \
+        -DASAN_UAR=0 \
+        -DASAN_HAS_BLACKLIST=1 \
+	-DASAN_HAS_EXCEPTIONS=$(ASAN_HAS_EXCEPTIONS) \
+	-DASAN_NEEDS_SEGV=$(ASAN_NEEDS_SEGV) \
+        -D__WORDSIZE=32
+LOCAL_SRC_FILES := tests/asan_noinst_test.cc tests/asan_test_main.cc
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_CLANG := true
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+include $(BUILD_STATIC_LIBRARY)
+
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := asan_test
+LOCAL_MODULE_TAGS := tests
+LOCAL_C_INCLUDES := \
+        bionic \
+        external/stlport/stlport \
+        external/gtest/include \
+        external/compiler-rt/lib \
+	external/compiler-rt/lib/asan/tests \
+	external/compiler-rt/lib/sanitizer_common/tests
+LOCAL_CFLAGS += $(asan_test_cflags)
+LOCAL_SRC_FILES := $(asan_test_files)
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_STATIC_LIBRARIES := libgtest libasan_noinst_test
+LOCAL_SHARED_LIBRARIES := libc libstlport
+LOCAL_ADDRESS_SANITIZER := true
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+
+include $(BUILD_EXECUTABLE)
+
+endif # ifeq($(TARGET_ARCH),arm)
diff --git a/lib/asan/asan_android_stub.cc b/lib/asan/asan_android_stub.cc
new file mode 100644
index 0000000..cf68f58
--- /dev/null
+++ b/lib/asan/asan_android_stub.cc
@@ -0,0 +1,4 @@
+#include "sanitizer/asan_interface.h"
+
+__attribute__((section(".preinit_array")))
+  typeof(__asan_init) *__asan_preinit =__asan_init;
diff --git a/lib/asan/asanwrapper.cc b/lib/asan/asanwrapper.cc
new file mode 100644
index 0000000..53a4852
--- /dev/null
+++ b/lib/asan/asanwrapper.cc
@@ -0,0 +1,51 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string>
+
+void usage(const char* me) {
+  static const char* usage_s = "Usage:\n"
+    "  %s /system/bin/app_process <args>\n"
+    "or, better:\n"
+    "  setprop wrap.<nicename> %s\n";
+  fprintf(stderr, usage_s, me, me);
+  exit(1);
+}
+
+void env_prepend(const char* name, const char* value, const char* delim) {
+  const char* value_old = getenv(name);
+  std::string value_new = value;
+  if (value_old) {
+    value_new += delim;
+    value_new += value_old;
+  }
+  setenv(name, value_new.c_str(), 1);
+}
+
+int main(int argc, char** argv) {
+  if (argc < 2) {
+    usage(argv[0]);
+  }
+  char** args = new char*[argc];
+  // If we are wrapping app_process, replace it with app_process_asan.
+  // TODO(eugenis): rewrite to <dirname>/asan/<basename>, if exists?
+  if (strcmp(argv[1], "/system/bin/app_process") == 0) {
+    args[0] = (char*)"/system/bin/asan/app_process";
+  } else {
+    args[0] = argv[1];
+  }
+
+  for (int i = 1; i < argc - 1; ++i)
+    args[i] = argv[i + 1];
+  args[argc - 1] = 0;
+
+  env_prepend("ASAN_OPTIONS", "debug=1,verbosity=1", ",");
+  env_prepend("LD_LIBRARY_PATH", "/system/lib/asan", ":");
+  env_prepend("LD_PRELOAD", "/system/lib/libasan_preload.so", ":");
+
+  printf("ASAN_OPTIONS: %s\n", getenv("ASAN_OPTIONS"));
+  printf("LD_LIBRARY_PATH: %s\n", getenv("LD_LIBRARY_PATH"));
+  printf("LD_PRELOAD: %s\n", getenv("LD_PRELOAD"));
+
+  execv(args[0], args);
+}
diff --git a/lib/asan/scripts/symbolize.py b/lib/asan/scripts/symbolize.py
new file mode 100755
index 0000000..672226f
--- /dev/null
+++ b/lib/asan/scripts/symbolize.py
@@ -0,0 +1,118 @@
+#!/usr/bin/env python
+#===- lib/asan/scripts/asan_symbolize.py -----------------------------------===#
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+import os
+import re
+import sys
+import string
+import subprocess
+
+pipes = {}
+load_addresses = {}
+next_inline_frameno = 0
+
+def patch_address(frameno, addr_s):
+  ''' Subtracts 1 or 2 from the top frame's address.
+  Top frame is normally the return address from asan_report*
+  call, which is not expected to return at all. Because of that, this
+  address often belongs to the next source code line, or even to a different
+  function. '''
+  if frameno == '0':
+    addr = int(addr_s, 16)
+    if os.uname()[4].startswith('arm'):
+      # Cancel the Thumb bit
+      addr = addr & (~1)
+    addr -= 1
+    return hex(addr)
+  return addr_s
+
+def android_get_load_address(path):
+  if load_addresses.has_key(path):
+    return load_addresses[path]
+  readelf = os.path.join(os.environ['ANDROID_EABI_TOOLCHAIN'], 'arm-linux-androideabi-readelf')
+  readelf_pipe = subprocess.Popen([readelf, "-l", path], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
+  for line in readelf_pipe.stdout:
+      if ('LOAD' in line) and (' E ' in line):
+          match = re.match(r'\s*LOAD\s+0x[01-9a-zA-Z]+\s+(0x[01-9a-zA-Z]+)', line, re.UNICODE)
+          if match:
+              load_addr = int(match.group(1), 16)
+              load_addresses[path] = load_addr
+              return load_addr
+          else: break
+  print 'Could not make sense of readelf output!'
+  sys.exit(1)
+
+def postprocess_file_name(file_name, paths_to_cut):
+  for path_to_cut in paths_to_cut:
+    file_name = re.sub(".*" + path_to_cut, "", file_name)
+  file_name = re.sub(".*asan_[a-z_]*.(cc|h):[0-9]*", "[asan_rtl]", file_name)
+  file_name = re.sub(".*crtstuff.c:0", "???:0", file_name)
+  return file_name
+
+# TODO(glider): need some refactoring here
+def symbolize_addr2line(line, binary_prefix, paths_to_cut):
+  global next_inline_frameno
+  # Strip the log prefix ("I/asanwrapper( 1196): ").
+  line = re.sub(r'^[A-Z]/[^\s]*\(\s*\d+\): ', '', line)
+  #0 0x7f6e35cf2e45  (/blah/foo.so+0x11fe45)
+  match = re.match(r'^(\s*#)([0-9]+) *(0x[0-9a-f]+) *\((.*)\+(0x[0-9a-f]+)\)', line, re.UNICODE)
+  if match:
+    frameno = match.group(2)
+    binary = match.group(4)
+    addr = match.group(5)
+    addr = patch_address(frameno, addr)
+
+    if binary.startswith('/'):
+      binary = binary[1:]
+    binary = os.path.join(binary_prefix, binary)
+
+    load_addr = android_get_load_address(binary)
+    addr = hex(int(addr, 16) + load_addr)
+
+    if not pipes.has_key(binary):
+      pipes[binary] = subprocess.Popen(["addr2line", "-i", "-f", "-e", binary],
+                         stdin=subprocess.PIPE, stdout=subprocess.PIPE)
+    p = pipes[binary]
+    frames = []
+    try:
+      print >>p.stdin, addr
+      # This will trigger a "??" response from addr2line so we know when to stop
+      print >>p.stdin
+      while True:
+        function_name = p.stdout.readline().rstrip()
+        file_name     = p.stdout.readline().rstrip()
+        if function_name in ['??', '']:
+          break
+        file_name = postprocess_file_name(file_name, paths_to_cut)
+        frames.append((function_name, file_name))
+    except:
+      pass
+    if not frames:
+      frames.append(('', ''))
+      # Consume another pair of "??" lines
+      try:
+        p.stdout.readline()
+        p.stdout.readline()
+      except:
+        pass
+    for frame in frames:
+      inline_frameno = next_inline_frameno
+      next_inline_frameno += 1
+      print "%s%d" % (match.group(1).encode('utf-8'), inline_frameno), \
+          match.group(3).encode('utf-8'), "in", frame[0], frame[1]
+  else:
+    print line.rstrip().encode('utf-8')
+
+
+binary_prefix = os.path.join(os.environ['ANDROID_PRODUCT_OUT'], 'symbols')
+paths_to_cut = [os.getcwd() + '/', os.environ['ANDROID_BUILD_TOP'] + '/'] + sys.argv[1:]
+
+for line in sys.stdin:
+  line = line.decode('utf-8')
+  symbolize_addr2line(line, binary_prefix, paths_to_cut)
diff --git a/lib/sanitizer_common/sanitizer_symbolizer_linux.cc b/lib/sanitizer_common/sanitizer_symbolizer_linux.cc
index c068839..fbc1284 100644
--- a/lib/sanitizer_common/sanitizer_symbolizer_linux.cc
+++ b/lib/sanitizer_common/sanitizer_symbolizer_linux.cc
@@ -124,6 +124,7 @@
 #if defined(__ANDROID__) || defined(ANDROID)
 uptr GetListOfModules(LoadedModule *modules, uptr max_modules) {
   UNIMPLEMENTED();
+  return max_modules;
 }
 #else  // ANDROID
 typedef ElfW(Phdr) Elf_Phdr;