Merge "Initial upload of llvm libc++abi (r192248)."
diff --git a/build/core/add-application.mk b/build/core/add-application.mk
index 28d4da1..3b2cf23 100644
--- a/build/core/add-application.mk
+++ b/build/core/add-application.mk
@@ -60,6 +60,15 @@
APP_PROJECT_PATH := $(NDK_PROJECT_PATH)
endif
+ifeq (null,$(APP_PROJECT_PATH))
+
+ifndef APP_PLATFORM
+ APP_PLATFORM := android-3
+ $(call ndk_log, Defaulted to APP_PLATFORM=$(APP_PLATFORM))
+endif
+
+else
+
# check whether APP_PLATFORM is defined. If not, look for project.properties in
# the $(APP_PROJECT_PATH) and extract the value with awk's help. If nothing is here,
# revert to the default value (i.e. "android-3").
@@ -80,17 +89,19 @@
endif
endif
+endif # APP_PROJECT_PATH == null
+
# SPECIAL CASES:
# 1) android-6 and android-7 are the same thing as android-5
-# 2) android-10, 11, and 12 are the same thing as android-9
-# 3) android-18 and up are the same thing as android-18
+# 2) android-10 and 11 are the same thing as android-9
+# 3) android-19 and up are the same thing as android-19
#
APP_PLATFORM_LEVEL := $(strip $(subst android-,,$(APP_PLATFORM)))
ifneq (,$(filter 6 7,$(APP_PLATFORM_LEVEL)))
APP_PLATFORM := android-5
$(call ndk_log, Adjusting APP_PLATFORM android-$(APP_PLATFORM_LEVEL) to $(APP_PLATFORM))
endif
-ifneq (,$(filter 10 11 12,$(APP_PLATFORM_LEVEL)))
+ifneq (,$(filter 10 11,$(APP_PLATFORM_LEVEL)))
APP_PLATFORM := android-9
$(call ndk_log, Adjusting APP_PLATFORM android-$(APP_PLATFORM_LEVEL) to $(APP_PLATFORM))
endif
@@ -122,6 +133,8 @@
$(call ndk_log,Switching to $(APP_PLATFORM))
endif
+ifneq (null,$(APP_PROJECT_PATH))
+
# Check platform level (after adjustment) against android:minSdkVersion in AndroidManifest.xml
#
APP_MANIFEST := $(strip $(wildcard $(APP_PROJECT_PATH)/AndroidManifest.xml))
@@ -135,6 +148,9 @@
endif
endif
+endif # APP_PROJECT_PATH == null
+
+
# Check that the value of APP_ABI corresponds to known ABIs
# 'all' is a special case that means 'all supported ABIs'
#
@@ -145,7 +161,7 @@
# Because GNU Make makes the APP_ABI variable read-only (any assignments
# to it will be ignored)
#
-APP_ABI := $(strip $(APP_ABI))
+APP_ABI := $(subst $(comma),$(space),$(strip $(APP_ABI)))
ifndef APP_ABI
# Default ABI is 'armeabi'
APP_ABI := armeabi
@@ -173,6 +189,11 @@
APP_BUILD_SCRIPT := $(_build_script)
$(call ndk_log, Using build script $(APP_BUILD_SCRIPT))
else
+ ifeq (null,$(APP_PROJECT_PATH))
+ $(call __ndk_info,NDK_PROJECT_PATH==null. Please explicitly set APP_BUILD_SCRIPT.)
+ $(call __ndk_error,Aborting.)
+ endif
+
_build_script := $(strip $(wildcard $(APP_PROJECT_PATH)/jni/Android.mk))
ifndef _build_script
$(call __ndk_info,There is no Android.mk under $(APP_PROJECT_PATH)/jni)
@@ -242,7 +263,8 @@
APP_CPPFLAGS := $(strip $(APP_CPPFLAGS))
APP_CXXFLAGS := $(strip $(APP_CXXFLAGS))
APP_RENDERSCRIPT_FLAGS := $(strip $(APP_RENDERSCRIPT_FLAGS))
-APP_LDFLAGS := $(strip $(APP_LDFLAGS))
+APP_ASMFLAGS := $(strip $(APP_ASMFLAGS))
+APP_LDFLAGS := $(strip $(APP_LDFLAGS))
# Check that APP_STL is defined. If not, use the default value (system)
# otherwise, check that the name is correct.
diff --git a/build/core/build-binary.mk b/build/core/build-binary.mk
index 380ff4c..313c3cf 100644
--- a/build/core/build-binary.mk
+++ b/build/core/build-binary.mk
@@ -269,8 +269,8 @@
neon_sources := $(strip $(neon_sources))
ifdef neon_sources
- ifneq ($(TARGET_ARCH_ABI),armeabi-v7a)
- $(call __ndk_info,NEON support is only possible for armeabi-v7a ABI)
+ ifeq ($(filter $(TARGET_ARCH_ABI), armeabi-v7a armeabi-v7a-hard),)
+ $(call __ndk_info,NEON support is only possible for armeabi-v7a ABI and its variant armeabi-v7a-hard)
$(call __ndk_info,Please add checks against TARGET_ARCH_ABI in $(LOCAL_MAKEFILE))
$(call __ndk_error,Aborting)
endif
@@ -313,7 +313,11 @@
# all_source_patterns contains the list of filename patterns that correspond
# to source files recognized by our build system
+ifeq ($(TARGET_ARCH_ABI),x86)
+all_source_extensions := .c .s .S .asm $(LOCAL_CPP_EXTENSION) $(LOCAL_RS_EXTENSION)
+else
all_source_extensions := .c .s .S $(LOCAL_CPP_EXTENSION) $(LOCAL_RS_EXTENSION)
+endif
all_source_patterns := $(foreach _ext,$(all_source_extensions),%$(_ext))
all_cpp_patterns := $(foreach _ext,$(LOCAL_CPP_EXTENSION),%$(_ext))
all_rs_patterns := $(foreach _ext,$(LOCAL_RS_EXTENSION),%$(_ext))
@@ -333,6 +337,7 @@
)
LOCAL_OBJECTS := $(filter %$(TARGET_OBJ_EXTENSION),$(LOCAL_OBJECTS))
LOCAL_OBJECTS := $(subst ../,__/,$(LOCAL_OBJECTS))
+LOCAL_OBJECTS := $(subst :,_,$(LOCAL_OBJECTS))
LOCAL_OBJECTS := $(foreach _obj,$(LOCAL_OBJECTS),$(LOCAL_OBJS_DIR)/$(_obj))
LOCAL_RS_OBJECTS := $(filter $(all_rs_patterns),$(LOCAL_SRC_FILES))
@@ -341,6 +346,7 @@
)
LOCAL_RS_OBJECTS := $(filter %$(TARGET_OBJ_EXTENSION),$(LOCAL_RS_OBJECTS))
LOCAL_RS_OBJECTS := $(subst ../,__/,$(LOCAL_RS_OBJECTS))
+LOCAL_RS_OBJECTS := $(subst :,_,$(LOCAL_RS_OBJECTS))
LOCAL_RS_OBJECTS := $(foreach _obj,$(LOCAL_RS_OBJECTS),$(LOCAL_OBJS_DIR)/$(_obj))
# If the module has any kind of C++ features, enable them in LOCAL_CPPFLAGS
@@ -391,6 +397,10 @@
$(call compile-rs-source,$(src),$(call get-rs-scriptc-name,$(src)),$(call get-rs-bc-name,$(src)),$(call get-rs-so-name,$(src)),$(call get-object-name,$(src)),$(RS_COMPAT))\
)
+ifeq ($(TARGET_ARCH_ABI),x86)
+$(foreach src,$(filter %.asm,$(LOCAL_SRC_FILES)), $(call compile-asm-source,$(src),$(call get-object-name,$(src))))
+endif
+
#
# The compile-xxx-source calls updated LOCAL_OBJECTS and LOCAL_DEPENDENCY_DIRS
#
diff --git a/build/core/build-local.mk b/build/core/build-local.mk
index 33cabb7..860a784 100644
--- a/build/core/build-local.mk
+++ b/build/core/build-local.mk
@@ -52,6 +52,18 @@
# It turns out that some people use ndk-build to generate static
# libraries without a full Android project tree.
#
+# If NDK_PROJECT_PATH=null, ndk-build make no attempt to look for it, but does
+# need the following variables depending on NDK_PROJECT_PATH to be explicitly
+# specified (from the default, if any):
+#
+# NDK_OUT
+# NDK_LIBS_OUT
+# APP_BUILD_SCRIPT
+# NDK_DEBUG (optional, default to 0)
+# Other APP_* used to be in Application.mk
+#
+# This behavior may be useful in an integrated build system.
+#
# ====================================================================
ifeq ($(HOST_OS),windows)
@@ -100,6 +112,12 @@
NDK_PROJECT_PATH := $(strip $(NDK_PROJECT_PATH))
+ifeq (null,$(NDK_PROJECT_PATH))
+
+$(call ndk_log,Make no attempt to look for NDK_PROJECT_PATH.)
+
+else
+
# To keep paths as short as possible during the build, we first look if the
# current directory is the top of our project path. If this is the case, we
# will define NDK_PROJECT_PATH to simply '.'
@@ -137,25 +155,38 @@
$(call __ndk_error,Aborting.)
endif
+$(call ndk_log,Found project path: $(NDK_PROJECT_PATH))
+
NDK_APPLICATION_MK := $(strip $(wildcard $(NDK_PROJECT_PATH)/jni/Application.mk))
+
+endif # NDK_PROJECT_PATH == null
+
ifndef NDK_APPLICATION_MK
NDK_APPLICATION_MK := $(NDK_ROOT)/build/core/default-application.mk
endif
-$(call ndk_log,Found project path: $(NDK_PROJECT_PATH))
# Place all generated intermediate files here
NDK_APP_OUT := $(strip $(NDK_OUT))
ifndef NDK_APP_OUT
+ ifeq (null,$(NDK_PROJECT_PATH))
+ $(call __ndk_info,NDK_PROJECT_PATH==null. Please explicitly set NDK_OUT to directory for all generated intermediate files.)
+ $(call __ndk_error,Aborting.)
+ endif
NDK_APP_OUT := $(NDK_PROJECT_PATH)/obj
endif
-$(call ndk_log,Ouput path: $(NDK_APP_OUT))
+$(call ndk_log,Ouput path for intermediate files: $(NDK_APP_OUT))
# Place all generated library files here. This is rarely changed since aapt expects the default libs/
NDK_APP_LIBS_OUT := $(strip $(NDK_LIBS_OUT))
ifndef NDK_APP_LIBS_OUT
+ ifeq (null,$(NDK_PROJECT_PATH))
+ $(call __ndk_info,NDK_PROJECT_PATH==null. Please explicitly set NDK_LIBS_OUT to directory for generated library files.)
+ $(call __ndk_error,Aborting.)
+ endif
NDK_APP_LIBS_OUT := $(NDK_PROJECT_PATH)/libs
endif
+$(call ndk_log,Ouput path for generated library files: $(NDK_APP_LIBS_OUT))
# Fake an application named 'local'
_app := local
diff --git a/build/core/default-application.mk b/build/core/default-application.mk
index 8135c55..81147b0 100644
--- a/build/core/default-application.mk
+++ b/build/core/default-application.mk
@@ -19,5 +19,10 @@
APP_PROJECT_PATH := $(NDK_PROJECT_PATH)
# We expect the build script to be located here
-APP_BUILD_SCRIPT := $(APP_PROJECT_PATH)/jni/Android.mk
-
+ifndef APP_BUILD_SCRIPT
+ ifeq (null,$(NDK_PROJECT_PATH))
+ $(call __ndk_info,NDK_PROJECT_PATH==null. Please explicitly set APP_BUILD_SCRIPT.)
+ $(call __ndk_error,Aborting.)
+ endif
+ APP_BUILD_SCRIPT := $(APP_PROJECT_PATH)/jni/Android.mk
+endif
\ No newline at end of file
diff --git a/build/core/default-build-commands.mk b/build/core/default-build-commands.mk
index 41967f6..6143503 100644
--- a/build/core/default-build-commands.mk
+++ b/build/core/default-build-commands.mk
@@ -128,11 +128,14 @@
TARGET_RS_BCC = $(RENDERSCRIPT_TOOLCHAIN_PREFIX)bcc_compat
TARGET_RS_FLAGS = -Wall -Werror
+TARGET_ASM = $(HOST_PREBUILT)/yasm
+TARGET_ASMFLAGS =
+
TARGET_LD = $(TOOLCHAIN_PREFIX)ld
TARGET_LDFLAGS :=
TARGET_AR = $(TOOLCHAIN_PREFIX)ar
-TARGET_ARFLAGS := crs
+TARGET_ARFLAGS := crsD
TARGET_STRIP = $(TOOLCHAIN_PREFIX)strip
diff --git a/build/core/definitions-utils.mk b/build/core/definitions-utils.mk
index 3862880..e69dd35 100644
--- a/build/core/definitions-utils.mk
+++ b/build/core/definitions-utils.mk
@@ -36,6 +36,13 @@
space4 := $(space)$(space)$(space)$(space)
# -----------------------------------------------------------------------------
+# Macro : comma
+# Returns : a single comma
+# Usage : $(comma)
+# -----------------------------------------------------------------------------
+comma := ,
+
+# -----------------------------------------------------------------------------
# Function : remove-duplicates
# Arguments: a list
# Returns : the list with duplicate items removed, order is preserved.
diff --git a/build/core/definitions.mk b/build/core/definitions.mk
index c446064..1b9c9d4 100644
--- a/build/core/definitions.mk
+++ b/build/core/definitions.mk
@@ -384,6 +384,7 @@
CONLYFLAGS \
CXXFLAGS \
CPPFLAGS \
+ ASMFLAGS \
STATIC_LIBRARIES \
WHOLE_STATIC_LIBRARIES \
SHARED_LIBRARIES \
@@ -397,6 +398,8 @@
EXPORT_CFLAGS \
EXPORT_CONLYFLAGS \
EXPORT_CPPFLAGS \
+ EXPORT_ASMFLAGS \
+ EXPORT_LDFLAGS \
EXPORT_LDLIBS \
EXPORT_C_INCLUDES \
FILTER_ASM \
@@ -832,7 +835,8 @@
$(eval __ndk_modules.$1.CFLAGS := $(filter-out $2,$(__ndk_modules.$1.CFLAGS)))\
$(eval __ndk_modules.$1.CONLYFLAGS := $(filter-out $2,$(__ndk_modules.$1.CONLYFLAGS)))\
$(eval __ndk_modules.$1.CPPFLAGS := $(filter-out $2,$(__ndk_modules.$1.CPPFLAGS)))\
- $(eval __ndk_modules.$1.CXXFLAGS := $(filter-out $2,$(__ndk_modules.$1.CXXFLAGS)))
+ $(eval __ndk_modules.$1.CXXFLAGS := $(filter-out $2,$(__ndk_modules.$1.CXXFLAGS)))\
+ $(eval __ndk_modules.$1.ASMFLAGS := $(filter-out $2,$(__ndk_modules.$1.ASMFLAGS)))
# Return true if a module's compiler flags enable rtti
# We just look at -frtti and -fno-rtti on the command-line
@@ -1284,12 +1288,13 @@
get-object-name = $(strip \
$(subst ../,__/,\
+ $(subst :,_,\
$(eval __obj := $1)\
- $(foreach __ext,.c .s .S $(LOCAL_CPP_EXTENSION) $(LOCAL_RS_EXTENSION),\
+ $(foreach __ext,.c .s .S .asm $(LOCAL_CPP_EXTENSION) $(LOCAL_RS_EXTENSION),\
$(eval __obj := $(__obj:%$(__ext)=%$(TARGET_OBJ_EXTENSION)))\
)\
$(__obj)\
- ))
+ )))
-test-get-object-name = \
$(eval TARGET_OBJ_EXTENSION=.o)\
@@ -1299,34 +1304,38 @@
$(call test-expect,bar.o,$(call get-object-name,bar.s))\
$(call test-expect,zoo.o,$(call get-object-name,zoo.S))\
$(call test-expect,tot.o,$(call get-object-name,tot.cpp))\
- $(call test-expect,RS.o,$(call get-object-name,RS.rs))
+ $(call test-expect,RS.o,$(call get-object-name,RS.rs))\
+ $(call test-expect,goo.o,$(call get-object-name,goo.asm))
get-rs-scriptc-name = $(strip \
$(subst ../,__/,\
+ $(subst :,_,\
$(eval __obj := $1)\
$(foreach __ext,$(LOCAL_RS_EXTENSION),\
$(eval __obj := $(__obj:%$(__ext)=%.cpp))\
)\
$(dir $(__obj))ScriptC_$(notdir $(__obj))\
- ))
+ )))
get-rs-bc-name = $(strip \
$(subst ../,__/,\
+ $(subst :,_,\
$(eval __obj := $1)\
$(foreach __ext,$(LOCAL_RS_EXTENSION),\
$(eval __obj := $(__obj:%$(__ext)=%.bc))\
)\
$(__obj)\
- ))
+ )))
get-rs-so-name = $(strip \
$(subst ../,__/,\
+ $(subst :,_,\
$(eval __obj := $1)\
$(foreach __ext,$(LOCAL_RS_EXTENSION),\
$(eval __obj := $(__obj:%$(__ext)=%$(TARGET_SONAME_EXTENSION)))\
)\
$(notdir $(__obj))\
- ))
+ )))
# -----------------------------------------------------------------------------
# Macro : hide
@@ -1479,7 +1488,7 @@
$$(hide) \
cd $$(call host-path,$$(dir $$(PRIVATE_RS_SRC))) && $$(PRIVATE_RS_CC) -o $$(call host-path,$$(abspath $$(dir $$(PRIVATE_OBJ))))/ -d $$(abspath $$(call host-path,$$(dir $$(PRIVATE_OBJ)))) -MD -reflect-c++ $$(PRIVATE_RS_FLAGS) $$(notdir $$(PRIVATE_RS_SRC))
$$(hide) \
- $$(PRIVATE_RS_BCC) -O3 -o $$(call host-path,$$(PRIVATE_BC_OBJ)) -fPIC -shared -rt-path $$(call host-path,$(RENDERSCRIPT_TOOLCHAIN_LIB)/libclcore.bc) -mtriple $$(PRIVATE_RS_TRIPLE) $$(call host-path,$$(PRIVATE_BC_SRC)) && \
+ $$(PRIVATE_RS_BCC) -O3 -o $$(call host-path,$$(PRIVATE_BC_OBJ)) -fPIC -shared -rt-path $$(call host-path,$(SYSROOT_LINK)/usr/lib/rs/libclcore.bc) -mtriple $$(PRIVATE_RS_TRIPLE) $$(call host-path,$$(PRIVATE_BC_SRC)) && \
$$(PRIVATE_CXX) -shared -Wl,-soname,librs.$$(PRIVATE_BC_SO) -nostdlib $$(call host-path,$$(PRIVATE_BC_OBJ)) $$(call host-path,$(SYSROOT_LINK)/usr/lib/rs/libcompiler_rt.a) -o $$(call host-path,$$(PRIVATE_OUT)/librs.$$(PRIVATE_BC_SO)) -L $$(call host-path,$(SYSROOT_LINK)/usr/lib) -L $$(call host-path,$(SYSROOT_LINK)/usr/lib/rs) -lRSSupport -lm -lc && \
$$(PRIVATE_CXX) -MMD -MP -MF $$(call convert-deps,$$(PRIVATE_DEPS)) $$(PRIVATE_CPPFLAGS) $$(call host-path,$$(PRIVATE_CPP_SRC)) -o $$(call host-path,$$(PRIVATE_OBJ)) \
$$(call cmd-convert-deps,$$(PRIVATE_DEPS))
@@ -1598,6 +1607,48 @@
endef
# -----------------------------------------------------------------------------
+# Template : ev-compile-asm-source
+# Arguments : 1: single ASM source file name (relative to LOCAL_PATH)
+# 2: target object file (without path)
+# Returns : None
+# Usage : $(eval $(call ev-compile-asm-source,<srcfile>,<objfile>)
+# Rationale : Internal template evaluated by compile-asm-source
+# -----------------------------------------------------------------------------
+define ev-compile-asm-source
+_SRC:=$$(call local-source-file-path,$(1))
+_OBJ:=$$(LOCAL_OBJS_DIR:%/=%)/$(2)
+
+_FLAGS := $$(call host-c-includes,$$(LOCAL_C_INCLUDES) $$(LOCAL_PATH)) \
+ $$(LOCAL_ASMFLAGS) \
+ $$(NDK_APP_ASMFLAGS) \
+ $$(call host-c-includes,$$($(my)C_INCLUDES)) \
+ -f elf32 -m x86
+
+_TEXT := Assemble $$(call get-src-file-text,$1)
+_CC := $$(NDK_CCACHE) $$(TARGET_ASM)
+
+$$(_OBJ): PRIVATE_ABI := $$(TARGET_ARCH_ABI)
+$$(_OBJ): PRIVATE_SRC := $$(_SRC)
+$$(_OBJ): PRIVATE_OBJ := $$(_OBJ)
+$$(_OBJ): PRIVATE_MODULE := $$(LOCAL_MODULE)
+$$(_OBJ): PRIVATE_TEXT := $$(_TEXT)
+$$(_OBJ): PRIVATE_CC := $$(_CC)
+$$(_OBJ): PRIVATE_CFLAGS := $$(_FLAGS)
+
+ifeq ($$(LOCAL_SHORT_COMMANDS),true)
+_OPTIONS_LISTFILE := $$(_OBJ).cflags
+$$(_OBJ): $$(call generate-list-file,$$(_FLAGS),$$(_OPTIONS_LISTFILE))
+$$(_OBJ): PRIVATE_CFLAGS := @$$(call host-path,$$(_OPTIONS_LISTFILE))
+$$(_OBJ): $$(_OPTIONS_LISTFILE)
+endif
+
+$$(call generate-file-dir,$$(_OBJ))
+$$(_OBJ): $$(_SRC) $$(LOCAL_MAKEFILE) $$(NDK_APP_APPLICATION_MK) $$(NDK_DEPENDENCIES_CONVERTER) $(LOCAL_RS_OBJECTS)
+ $$(call host-echo-build-step,$$(PRIVATE_ABI),$$(PRIVATE_TEXT)) "$$(PRIVATE_MODULE) <= $$(notdir $$(PRIVATE_SRC))"
+ $$(hide) $$(PRIVATE_CC) $$(PRIVATE_CFLAGS) $$(call host-path,$$(PRIVATE_SRC)) -o $$(call host-path,$$(PRIVATE_OBJ))
+endef
+
+# -----------------------------------------------------------------------------
# Function : compile-c-source
# Arguments : 1: single C source file name (relative to LOCAL_PATH)
# 2: object file
@@ -1617,6 +1668,15 @@
# -----------------------------------------------------------------------------
compile-s-source = $(eval $(call ev-compile-c-source,$1,$2))
+# -----------------------------------------------------------------------------
+# Function : compile-asm-source
+# Arguments : 1: single Assembly source file name (relative to LOCAL_PATH)
+# 2: object file
+# Returns : None
+# Usage : $(call compile-asm-source,<srcfile>,<objfile>)
+# Rationale : Setup everything required to build a single Assembly source file
+# -----------------------------------------------------------------------------
+compile-asm-source = $(eval $(call ev-compile-asm-source,$1,$2))
# -----------------------------------------------------------------------------
# Template : ev-compile-cpp-source
diff --git a/build/core/import-locals.mk b/build/core/import-locals.mk
index 2c4dfba..5b9973d 100644
--- a/build/core/import-locals.mk
+++ b/build/core/import-locals.mk
@@ -17,12 +17,12 @@
$(call assert-defined,LOCAL_MODULE)
-# For LOCAL_CFLAGS, LOCAL_CONLYFLAGS, LOCAL_CPPFLAGS and LOCAL_C_INCLUDES,
+# For LOCAL_CFLAGS, LOCAL_CONLYFLAGS, LOCAL_CPPFLAGS and LOCAL_C_INCLUDES, etc,
# we need to use the exported definitions of the closure of all modules
# we depend on.
#
# I.e. If module 'foo' depends on 'bar' which depends on 'zoo',
-# then 'foo' will get the CFLAGS/CONLYFLAGS/CPPFLAGS/C_INCLUDES of both 'bar'
+# then 'foo' will get the CFLAGS/CONLYFLAGS/CPPFLAGS/C_INCLUDES/... of both 'bar'
# and 'zoo'
#
@@ -33,7 +33,9 @@
imported_CONLYFLAGS := $(call module-get-listed-export,$(all_depends),CONLYFLAGS)
imported_CPPFLAGS := $(call module-get-listed-export,$(all_depends),CPPFLAGS)
imported_RENDERSCRIPT_FLAGS := $(call module-get-listed-export,$(all_depends),RENDERSCRIPT_FLAGS)
+imported_ASMFLAGS := $(call module-get-listed-export,$(all_depends),ASMFLAGS)
imported_C_INCLUDES := $(call module-get-listed-export,$(all_depends),C_INCLUDES)
+imported_LDFLAGS := $(call module-get-listed-export,$(all_depends),LDFLAGS)
ifdef NDK_DEBUG_IMPORTS
$(info Imports for module $(LOCAL_MODULE):)
@@ -41,7 +43,9 @@
$(info CONLYFLAGS='$(imported_CONLYFLAGS)')
$(info CPPFLAGS='$(imported_CPPFLAGS)')
$(info RENDERSCRIPT_FLAGS='$(imported_RENDERSCRIPT_FLAGS)')
+ $(info ASMFLAGS='$(imported_ASMFLAGS)')
$(info C_INCLUDES='$(imported_C_INCLUDES)')
+ $(info LDFLAGS='$(imported_LDFLAGS)')
$(info All depends='$(all_depends)')
endif
@@ -53,6 +57,8 @@
LOCAL_CONLYFLAGS := $(strip $(imported_CONLYFLAGS) $(LOCAL_CONLYFLAGS))
LOCAL_CPPFLAGS := $(strip $(imported_CPPFLAGS) $(LOCAL_CPPFLAGS))
LOCAL_RENDERSCRIPT_FLAGS := $(strip $(imported_RENDERSCRIPT_FLAGS) $(LOCAL_RENDERSCRIPT_FLAGS))
+LOCAL_ASMFLAGS := $(strip $(imported_ASMFLAGS) $(LOCAL_ASMFLAGS))
+LOCAL_LDFLAGS := $(strip $(imported_LDFLAGS) $(LOCAL_LDFLAGS))
#
# The imported include directories are appended to their LOCAL_XXX value
diff --git a/build/core/init.mk b/build/core/init.mk
index 5c3fb7f..007f98d 100644
--- a/build/core/init.mk
+++ b/build/core/init.mk
@@ -466,7 +466,7 @@
$(if $(strip $(wildcard $(NDK_ROOT)/RELEASE.TXT)),\
$(call __ndk_info,Please define NDK_PLATFORMS_ROOT to point to a valid directory.)\
,\
- $(call __ndk_info,Please run build/tools/build-platforms.sh to build the corresponding directory.)\
+ $(call __ndk_info,Please run build/tools/gen-platforms.sh to build the corresponding directory.)\
)
$(call __ndk_error,Aborting)
endif
@@ -517,12 +517,20 @@
# the build script to include in each toolchain config.mk
ADD_TOOLCHAIN := $(BUILD_SYSTEM)/add-toolchain.mk
-# the list of known values
-NDK_KNOWN_ABIS := armeabi-v7a armeabi x86 mips
+# the list of known abis and archs
+NDK_KNOWN_DEVICE_ABIS := armeabi-v7a armeabi x86 mips
+NDK_KNOWN_ABIS := $(NDK_KNOWN_DEVICE_ABIS) armeabi-v7a-hard
NDK_KNOWN_ARCHS := arm x86 mips
_archs := $(sort $(strip $(notdir $(wildcard $(NDK_PLATFORMS_ROOT)/android-*/arch-*))))
NDK_FOUND_ARCHS := $(_archs:arch-%=%)
+# the list of abis 'APP_ABI=all' is expanded to
+ifeq ($(_NDK_TESTING_ALL_),yes)
+NDK_APP_ABI_ALL_EXPANDED := $(NDK_KNOWN_ABIS)
+else
+NDK_APP_ABI_ALL_EXPANDED := $(NDK_KNOWN_DEVICE_ABIS)
+endif
+
# the list of all toolchains in this NDK
NDK_ALL_TOOLCHAINS :=
NDK_ALL_ABIS :=
diff --git a/build/core/setup-abi.mk b/build/core/setup-abi.mk
index c3be36a..e6109a0 100644
--- a/build/core/setup-abi.mk
+++ b/build/core/setup-abi.mk
@@ -55,7 +55,7 @@
TARGET_GDB_SETUP := $(TARGET_OUT)/setup.gdb
# RS triple
-ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
+ifneq ($(filter $(TARGET_ARCH_ABI), armeabi-v7a armeabi-v7a-hard),)
RS_TRIPLE := armv7-none-linux-gnueabi
endif
ifeq ($(TARGET_ARCH_ABI),armeabi)
diff --git a/build/core/setup-app.mk b/build/core/setup-app.mk
index 6a9b850..b009f09 100644
--- a/build/core/setup-app.mk
+++ b/build/core/setup-app.mk
@@ -43,7 +43,7 @@
TARGET_PLATFORM := $(call get,$(_map),APP_PLATFORM)
# The ABI(s) to use
-NDK_APP_ABI := $(strip $(NDK_APP_ABI))
+NDK_APP_ABI := $(subst $(comma),$(space),$(strip $(NDK_APP_ABI)))
ifndef NDK_APP_ABI
# the default ABI for now is armeabi
NDK_APP_ABI := armeabi
@@ -58,7 +58,7 @@
# Otherwise, check that we don't have an invalid value here.
#
ifeq ($(NDK_APP_ABI),all)
- NDK_APP_ABI := $(NDK_KNOWN_ABIS)
+ NDK_APP_ABI := $(NDK_APP_ABI_ALL_EXPANDED)
else
# Plug in the unknown
_unknown_abis := $(strip $(filter-out $(NDK_ALL_ABIS),$(NDK_APP_ABI)))
@@ -110,7 +110,6 @@
RENDERSCRIPT_TOOLCHAIN_ROOT := $(NDK_ROOT)/toolchains/renderscript
RENDERSCRIPT_TOOLCHAIN_PREBUILT_ROOT := $(call host-prebuilt-tag,$(RENDERSCRIPT_TOOLCHAIN_ROOT))
RENDERSCRIPT_TOOLCHAIN_PREFIX := $(RENDERSCRIPT_TOOLCHAIN_PREBUILT_ROOT)/bin/
-RENDERSCRIPT_TOOLCHAIN_LIB := $(RENDERSCRIPT_TOOLCHAIN_PREBUILT_ROOT)/lib
RENDERSCRIPT_TOOLCHAIN_HEADER := $(RENDERSCRIPT_TOOLCHAIN_PREBUILT_ROOT)/lib/clang/3.3/include
# Each ABI
diff --git a/build/core/setup-toolchain.mk b/build/core/setup-toolchain.mk
index 61e641a..0526b6c 100644
--- a/build/core/setup-toolchain.mk
+++ b/build/core/setup-toolchain.mk
@@ -20,7 +20,7 @@
$(call assert-defined,TARGET_PLATFORM TARGET_ARCH TARGET_ARCH_ABI)
$(call assert-defined,NDK_APPS NDK_APP_STL)
-LLVM_VERSION_LIST := 2.6 2.7 2.8 2.9 3.0 3.1 3.2 3.3
+LLVM_VERSION_LIST := 2.6 2.7 2.8 2.9 3.0 3.1 3.2 3.3 3.4
# Check that we have a toolchain that supports the current ABI.
# NOTE: If NDK_TOOLCHAIN is defined, we're going to use it.
@@ -125,6 +125,12 @@
# compute NDK_APP_DST_DIR as the destination directory for the generated files
NDK_APP_DST_DIR := $(NDK_APP_LIBS_OUT)/$(TARGET_ARCH_ABI)
+# install armeabi-v7a-hard to lib/armeabi-v7a, unless under testing where env. var. _NDK_TESTING_ALL_=yes
+ifneq ($(_NDK_TESTING_ALL_),yes)
+ifeq ($(TARGET_ARCH_ABI),armeabi-v7a-hard)
+NDK_APP_DST_DIR := $(NDK_APP_LIBS_OUT)/armeabi-v7a
+endif
+endif
# Default build commands, can be overriden by the toolchain's setup script
include $(BUILD_SYSTEM)/default-build-commands.mk
@@ -155,7 +161,10 @@
$(NDK_APP_GDBSERVER): clean-installed-binaries
$(call host-echo-build-step,$(PRIVATE_ABI),Gdbserver) "[$(PRIVATE_NAME)] $(call pretty-dir,$(PRIVATE_DST))"
$(hide) $(call host-install,$(PRIVATE_SRC),$(PRIVATE_DST))
+endif
+# Install gdb.setup for both .so and .bc projects
+ifneq (,$(filter $(TARGET_SONAME_EXTENSION),.so .bc))
installed_modules: $(NDK_APP_GDBSETUP)
$(NDK_APP_GDBSETUP): PRIVATE_ABI := $(TARGET_ARCH_ABI)
diff --git a/build/tools/build-compiler-rt.sh b/build/tools/build-compiler-rt.sh
index 24c90fd..d72e13a 100755
--- a/build/tools/build-compiler-rt.sh
+++ b/build/tools/build-compiler-rt.sh
@@ -162,7 +162,7 @@
local ABI=$1
local ARCH_SOURCES GENERIC_SOURCES FOUND
- if [ $ABI == "armeabi" -o $ABI == "armeabi-v7a" ]; then
+ if [ $ABI == "armeabi" -o $ABI == "armeabi-v7a" -o $ABI == "armeabi-v7a-hard" ]; then
ARCH_SOURCES="$COMPILER_RT_ARM_SOURCES"
elif [ $ABI == "x86" ]; then
ARCH_SOURCES="$COMPILER_RT_X86_SOURCES"
@@ -211,11 +211,18 @@
builder_cflags "$COMPILER_RT_CFLAGS"
- if [ $ABI == "armeabi" -o $ABI == "armeabi-v7a" ]; then
+ if [ $ABI == "armeabi" -o $ABI == "armeabi-v7a" -o $ABI == "armeabi-v7a-hard" ]; then
builder_cflags "-D__ARM_EABI__"
+ if [ $ABI == "armeabi-v7a-hard" ]; then
+ builder_cflags "-mhard-float -D_NDK_MATH_NO_SOFTFP=1"
+ fi
fi
builder_ldflags "$COMPILER_RT_LDFLAGS"
+ if [ $ABI == "armeabi-v7a-hard" ]; then
+ builder_cflags "-Wl,--no-warn-mismatch -lm_hard"
+ fi
+
builder_sources $(prepare_compiler_rt_source_for_abi $ABI)
if [ "$TYPE" = "static" ]; then
@@ -223,7 +230,10 @@
builder_static_library libcompiler_rt_static
else
log "Building $DSTDIR/libcompiler_rt_shared.so"
- builder_ldflags "-lc -lm"
+ builder_ldflags "-lc"
+ if [ $ABI != "armeabi-v7a-hard" ]; then
+ builder_ldflags "-lm"
+ fi
builder_nostdlib_shared_library libcompiler_rt_shared
fi
builder_end
diff --git a/build/tools/build-cxx-stl.sh b/build/tools/build-cxx-stl.sh
index 6a41279..c803085 100755
--- a/build/tools/build-cxx-stl.sh
+++ b/build/tools/build-cxx-stl.sh
@@ -77,6 +77,9 @@
VISIBLE_STATIC=
register_var_option "--visible-static" VISIBLE_STATIC "Do not use hidden visibility for the static library"
+WITH_DEBUG_INFO=
+register_var_option "--with-debug-info" WITH_DEBUG_INFO "Build with -g. STL is still built with optimization but with debug info"
+
EXPLICIT_COMPILER_VERSION=
GCC_VERSION=$DEFAULT_GCC_VERSION
@@ -141,16 +144,24 @@
mkdir -p "$BUILD_DIR"
fail_panic "Could not create build directory: $BUILD_DIR"
-# Location of the various C++ runtime source trees.
-GABIXX_SRCDIR=$ANDROID_NDK_ROOT/$GABIXX_SUBDIR
-STLPORT_SRCDIR=$ANDROID_NDK_ROOT/$STLPORT_SUBDIR
-LIBCXX_SRCDIR=$ANDROID_NDK_ROOT/$LIBCXX_SUBDIR
+# Location of the various C++ runtime source trees. Use symlink from
+# $BUILD_DIR instead of $NDK which may contain full path of builder's working dir
+
+ln -sf $ANDROID_NDK_ROOT $BUILD_DIR/ndk
+
+GABIXX_SRCDIR=$BUILD_DIR/ndk/$GABIXX_SUBDIR
+STLPORT_SRCDIR=$BUILD_DIR/ndk/$STLPORT_SUBDIR
+LIBCXX_SRCDIR=$BUILD_DIR/ndk/$LIBCXX_SUBDIR
LIBCXX_INCLUDES="-I$LIBCXX_SRCDIR/libcxx/include -I$ANDROID_NDK_ROOT/sources/android/support/include -I$GABIXX_SRCDIR/include"
COMMON_CFLAGS="-fPIC -O2 -ffunction-sections -fdata-sections"
COMMON_CXXFLAGS="-fexceptions -frtti -fuse-cxa-atexit"
+if [ "$WITH_DEBUG_INFO" ]; then
+ COMMON_CFLAGS="$COMMON_CFLAGS -g"
+fi
+
# Determine GAbi++ build parameters. Note that GAbi++ is also built as part
# of STLport and Libc++, in slightly different ways.
if [ "$CXX_STL" = "libc++" ]; then
@@ -167,7 +178,7 @@
GABIXX_SOURCES=$(cd $ANDROID_NDK_ROOT/$GABIXX_SUBDIR && ls src/*.cc)
GABIXX_LDFLAGS="-ldl"
if [ "$CXX_STL" = "libc++" ]; then
- GABIXX_CXXFLAGS="$GABIXX_CXXFLAGS -DGABIXX_LIBCXX=1"
+ GABIXX_CXXFLAGS="$GABIXX_CXXFLAGS -DLIBCXXABI=1"
fi
# Determine STLport build parameters
@@ -209,7 +220,7 @@
# Determine Libc++ build parameters
LIBCXX_CFLAGS="$COMMON_CFLAGS $LIBCXX_INCLUDES -Drestrict=__restrict__"
-LIBCXX_CXXFLAGS="$COMMON_CXXFLAGS -DLIBCXXRT=1 -DGABIXX_LIBCXX=1 -std=c++11"
+LIBCXX_CXXFLAGS="$COMMON_CXXFLAGS -DLIBCXXABI=1 -std=c++11"
LIBCXX_SOURCES=\
"libcxx/src/algorithm.cpp \
libcxx/src/bind.cpp \
@@ -245,6 +256,8 @@
../../android/support/src/locale/localeconv.c \
../../android/support/src/locale/newlocale.c \
../../android/support/src/locale/uselocale.c \
+../../android/support/src/stdio/stdio_impl.c \
+../../android/support/src/stdio/vfprintf.c \
../../android/support/src/stdio/vfwprintf.c \
../../android/support/src/musl-multibyte/btowc.c \
../../android/support/src/musl-multibyte/internal.c \
@@ -332,9 +345,17 @@
../../android/support/src/musl-locale/wcsxfrm_l.c \
../../android/support/src/musl-locale/wctrans_l.c \
../../android/support/src/musl-locale/wctype_l.c \
+../../android/support/src/musl-math/frexpf.c \
+../../android/support/src/musl-math/frexpl.c \
+../../android/support/src/musl-math/frexp.c \
../../android/support/src/musl-stdio/swprintf.c \
../../android/support/src/musl-stdio/vwprintf.c \
../../android/support/src/musl-stdio/wprintf.c \
+../../android/support/src/musl-stdio/printf.c \
+../../android/support/src/musl-stdio/snprintf.c \
+../../android/support/src/musl-stdio/sprintf.c \
+../../android/support/src/musl-stdio/vprintf.c \
+../../android/support/src/musl-stdio/vsprintf.c \
"
# If the --no-makefile flag is not used, we're going to put all build
@@ -411,14 +432,23 @@
local BUILDDIR="$2"
local TYPE="$3"
local DSTDIR="$4"
+ local FLOAT_ABI=""
local DEFAULT_CFLAGS DEFAULT_CXXFLAGS
- local SRC OBJ OBJECTS EXTRA_CXXFLAGS LIB_SUFFIX
+ local SRC OBJ OBJECTS EXTRA_CFLAGS EXTRA_CXXFLAGS EXTRA_LDFLAGS LIB_SUFFIX
mkdir -p "$BUILDDIR"
DSTDIR=$DSTDIR/$CXX_STL_SUBDIR/libs/$ABI
LIB_SUFFIX="$(get_lib_suffix_for_abi $ABI)"
+ EXTRA_CFLAGS=""
+ EXTRA_LDFLAGS=""
+ if [ "$ABI" = "armeabi-v7a-hard" ]; then
+ EXTRA_CFLAGS="-mhard-float -D_NDK_MATH_NO_SOFTFP=1"
+ EXTRA_LDFLAGS="-Wl,--no-warn-mismatch -lm_hard"
+ FLOAT_ABI="hard"
+ fi
+
if [ "$TYPE" = "static" -a -z "$VISIBLE_STATIC" ]; then
EXTRA_CXXFLAGS="$STATIC_CXXFLAGS"
else
@@ -434,11 +464,11 @@
# Always rebuild GAbi++, except for unknown archs.
builder_set_srcdir "$GABIXX_SRCDIR"
builder_reset_cflags DEFAULT_CFLAGS
- builder_cflags "$DEFAULT_CFLAGS $GABIXX_CFLAGS"
+ builder_cflags "$DEFAULT_CFLAGS $GABIXX_CFLAGS $EXTRA_CFLAGS"
builder_reset_cxxflags DEFAULT_CXXFLAGS
builder_cxxflags "$DEFAULT_CXXFLAGS $GABIXX_CXXFLAGS $EXTRA_CXXFLAGS"
- builder_ldflags "$GABIXX_LDFLAGS"
+ builder_ldflags "$GABIXX_LDFLAGS $EXTRA_LDFLAGS"
if [ "$(find_ndk_unknown_archs)" != "$ABI" ]; then
builder_sources $GABIXX_SOURCES
elif [ "$CXX_STL" = "gabi++" ]; then
@@ -452,10 +482,10 @@
if [ "$CXX_STL" != "gabi++" ]; then
builder_set_srcdir "$CXX_STL_SRCDIR"
builder_reset_cflags
- builder_cflags "$DEFAULT_CFLAGS $CXX_STL_CFLAGS"
+ builder_cflags "$DEFAULT_CFLAGS $CXX_STL_CFLAGS $EXTRA_CFLAGS"
builder_reset_cxxflags DEFAULT_CXXFLAGS
builder_cxxflags "$DEFAULT_CXXFLAGS $CXX_STL_CXXFLAGS $EXTRA_CXXFLAGS"
- builder_ldflags "$CXX_STL_LDFLAGS"
+ builder_ldflags "$CXX_STL_LDFLAGS $EXTRA_LDFLAGS"
builder_sources $CXX_STL_SOURCES
fi
@@ -465,7 +495,7 @@
else
log "Building $DSTDIR/${CXX_STL_LIB}_shared${LIB_SUFFIX}"
if [ "$(find_ndk_unknown_archs)" != "$ABI" ]; then
- builder_shared_library ${CXX_STL_LIB}_shared $LIB_SUFFIX
+ builder_shared_library ${CXX_STL_LIB}_shared $LIB_SUFFIX "$FLOAT_ABI"
else
builder_ldflags "-lc -lm"
builder_nostdlib_shared_library ${CXX_STL_LIB}_shared $LIB_SUFFIX # Don't use libgcc
@@ -488,7 +518,11 @@
for LIB in ${CXX_STL_LIB}_static.a ${CXX_STL_LIB}_shared${LIB_SUFFIX}; do
FILES="$FILES $CXX_STL_SUBDIR/libs/$ABI/$LIB"
done
- PACKAGE="$PACKAGE_DIR/${CXX_STL_PACKAGE}-libs-$ABI.tar.bz2"
+ PACKAGE="$PACKAGE_DIR/${CXX_STL_PACKAGE}-libs-$ABI"
+ if [ "$WITH_DEBUG_INFO" ]; then
+ PACKAGE="${PACKAGE}-g"
+ fi
+ PACKAGE="${PACKAGE}.tar.bz2"
log "Packaging: $PACKAGE"
pack_archive "$PACKAGE" "$OUT_DIR" "$FILES"
fail_panic "Could not package $ABI $CXX_STL binaries!"
diff --git a/build/tools/build-device-llvm.sh b/build/tools/build-device-llvm.sh
index 60540f1..6fa9b50 100755
--- a/build/tools/build-device-llvm.sh
+++ b/build/tools/build-device-llvm.sh
@@ -42,7 +42,7 @@
register_var_option "--out-dir=<path>" OPTION_OUT_DIR "On-device toolchain will be put at <path>"
OPTION_ABIS=
-register_var_option "--abis=<armeabi,armeabi-v7a,x86,mips>" OPTION_ABIS "Default: $ABIS"
+register_var_option "--abis=<armeabi,armeabi-v7a,x86,mips,armeabi-v7a-hard>" OPTION_ABIS "Default: $ABIS"
OPTION_GCC_VERSION=
register_var_option "--gcc-version=<version>" OPTION_GCC_VERSION "Specify GCC toolchain version [Default: $DEFAULT_GCC_VERSION]"
@@ -167,8 +167,11 @@
# code such as "stmdb sp!,{r0,r1,r2,r3,lr}" which doesn't support thumb1
CFLAGS=$CFLAGS" -march=armv5te -msoft-float"
;;
- armeabi-v7a)
+ armeabi-v7a|armeabi-v7a-hard)
CFLAGS=$CFLAGS" -mthumb -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16"
+ if [ "$arbi" = "armeabi-v7a-hard" ]; then
+ CFLAGS=$CFLAGS" -mhard-float -D_NDK_MATH_NO_SOFTFP=1 -Wl,--no-warn-mismatch -lm_hard"
+ fi
;;
mips)
CFLAGS=$CFLAGS" -fmessage-length=0 -fno-inline-functions-called-once -fgcse-after-reload -frerun-cse-after-loop -frename-registers"
@@ -180,7 +183,7 @@
--stl=$STL \
--arch=$arch \
--system=$HOST_TAG \
- --platform=android-9 \
+ --platform=android-19 \
--install-dir=$BUILD_OUT/ndk-standalone-$arch
fail_panic "Couldn't make standalone for $arch"
@@ -210,6 +213,7 @@
--disable-polly \
--with-clang-srcdir=/dev/null \
--disable-assertions \
+ --disable-terminfo \
--with-extra-options="$CFLAGS" \
$EXTRA_LLVM_CONFIG
fail_panic "Couldn't configure llvm toolchain for ABI $abi"
diff --git a/build/tools/build-gcc.sh b/build/tools/build-gcc.sh
index 5d32964..696b689 100755
--- a/build/tools/build-gcc.sh
+++ b/build/tools/build-gcc.sh
@@ -426,17 +426,36 @@
pr-support.o \
unwind-c.o"
;;
+ armeabi-v7a-hard)
+ BASE_DIR="$BUILD_OUT/gcc-$GCC_VERSION/$ABI_CONFIGURE_TARGET/armv7-a/hard/libgcc/"
+ OBJS="unwind-arm.o \
+ libunwind.o \
+ pr-support.o \
+ unwind-c.o"
+ ;;
x86)
BASE_DIR="$BUILD_OUT/gcc-$GCC_VERSION/$ABI_CONFIGURE_TARGET/libgcc/"
- OBJS="unwind-c.o \
+ if [ "$GCC_VERSION" = "4.6" -o "$GCC_VERSION" = "4.4.3" ]; then
+ OBJS="unwind-c.o \
unwind-dw2-fde-glibc.o \
unwind-dw2.o"
+ else
+ OBJS="unwind-c.o \
+ unwind-dw2-fde-dip.o \
+ unwind-dw2.o"
+ fi
;;
mips)
BASE_DIR="$BUILD_OUT/gcc-$GCC_VERSION/$ABI_CONFIGURE_TARGET/libgcc/"
- OBJS="unwind-c.o \
+ if [ "$GCC_VERSION" = "4.6" -o "$GCC_VERSION" = "4.4.3" ]; then
+ OBJS="unwind-c.o \
unwind-dw2-fde-glibc.o \
unwind-dw2.o"
+ else
+ OBJS="unwind-c.o \
+ unwind-dw2-fde-dip.o \
+ unwind-dw2.o"
+ fi
;;
esac
@@ -459,7 +478,7 @@
UNWIND_OBJS=$(unwind_library_for_abi $ABI)
UNWIND_LIB_DIR="$NDK_DIR/$GCCUNWIND_SUBDIR/libs/$ABI/"
run mkdir -p $UNWIND_LIB_DIR
- run ar crs $UNWIND_LIB_DIR/libgccunwind.a $UNWIND_OBJS
+ run ar crsD $UNWIND_LIB_DIR/libgccunwind.a $UNWIND_OBJS
done
}
diff --git a/build/tools/build-gdbserver.sh b/build/tools/build-gdbserver.sh
index 18db73e..baad209 100755
--- a/build/tools/build-gdbserver.sh
+++ b/build/tools/build-gdbserver.sh
@@ -160,7 +160,7 @@
# with an .a suffix. The linker will handle that seamlessly.
run cp $LIBTHREAD_DB_DIR/thread_db.h $BUILD_SYSROOT/usr/include/
run $TOOLCHAIN_PREFIX-gcc --sysroot=$BUILD_SYSROOT -o $BUILD_SYSROOT/usr/lib/libthread_db.o -c $LIBTHREAD_DB_DIR/libthread_db.c
- run $TOOLCHAIN_PREFIX-ar -r $BUILD_SYSROOT/usr/lib/libthread_db.a $BUILD_SYSROOT/usr/lib/libthread_db.o
+ run $TOOLCHAIN_PREFIX-ar -rD $BUILD_SYSROOT/usr/lib/libthread_db.a $BUILD_SYSROOT/usr/lib/libthread_db.o
if [ $? != 0 ] ; then
dump "ERROR: Could not compile libthread_db.c!"
exit 1
diff --git a/build/tools/build-gnu-libstdc++.sh b/build/tools/build-gnu-libstdc++.sh
index a6b0c62..4ad05a0 100755
--- a/build/tools/build-gnu-libstdc++.sh
+++ b/build/tools/build-gnu-libstdc++.sh
@@ -67,6 +67,9 @@
VISIBLE_LIBGNUSTL_STATIC=
register_var_option "--visible-libgnustl-static" VISIBLE_LIBGNUSTL_STATIC "Do not use hidden visibility for libgnustl_static.a"
+WITH_DEBUG_INFO=
+register_var_option "--with-debug-info" WITH_DEBUG_INFO "Build with -g. STL is still built with optimization but with debug info"
+
register_jobs_option
extract_parameters "$@"
@@ -92,6 +95,7 @@
else
BUILD_DIR=$OPTION_BUILD_DIR
fi
+rm -rf "$BUILD_DIR"
mkdir -p "$BUILD_DIR"
fail_panic "Could not create build directory: $BUILD_DIR"
@@ -159,13 +163,18 @@
;;
esac
- EXTRA_FLAGS=
+ EXTRA_FLAGS="-ffunction-sections -fdata-sections"
if [ -n "$THUMB" ] ; then
EXTRA_FLAGS="-mthumb"
fi
- export CFLAGS="-fPIC $CFLAGS --sysroot=$SYSROOT -fexceptions -funwind-tables -D__BIONIC__ -O2 $EXTRA_FLAGS"
- export CXXFLAGS="-fPIC $CXXFLAGS --sysroot=$SYSROOT -fexceptions -frtti -funwind-tables -D__BIONIC__ -O2 $EXTRA_FLAGS"
- export CPPFLAGS="$CPPFLAGS --sysroot=$SYSROOT"
+ CFLAGS="-fPIC $CFLAGS --sysroot=$SYSROOT -fexceptions -funwind-tables -D__BIONIC__ -O2 $EXTRA_FLAGS"
+ CXXFLAGS="-fPIC $CXXFLAGS --sysroot=$SYSROOT -fexceptions -frtti -funwind-tables -D__BIONIC__ -O2 $EXTRA_FLAGS"
+ CPPFLAGS="$CPPFLAGS --sysroot=$SYSROOT"
+ if [ "$WITH_DEBUG_INFO" ]; then
+ CFLAGS="$CFLAGS -g"
+ CXXFLAGS="$CXXFLAGS -g"
+ fi
+ export CFLAGS CXXFLAGS CPPFLAGS
export CC=${BINPREFIX}gcc
export CXX=${BINPREFIX}g++
@@ -179,9 +188,15 @@
export LDFLAGS="-L$SYSROOT/usr/lib -lc $EXTRA_FLAGS"
- if [ "$ABI" = "armeabi-v7a" ]; then
- CXXFLAGS=$CXXFLAGS" -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16"
+ if [ "$ABI" = "armeabi-v7a" -o "$ABI" = "armeabi-v7a-hard" ]; then
+ CXXFLAGS=$CXXFLAGS" -march=armv7-a -mfpu=vfpv3-d16"
LDFLAGS=$LDFLAGS" -Wl,--fix-cortex-a8"
+ if [ "$ABI" != "armeabi-v7a-hard" ]; then
+ CXXFLAGS=$CXXFLAGS" -mfloat-abi=softfp"
+ else
+ CXXFLAGS=$CXXFLAGS" -mhard-float -D_NDK_MATH_NO_SOFTFP=1"
+ LDFLAGS=$LDFLAGS" -Wl,--no-warn-mismatch -lm_hard"
+ fi
fi
LIBTYPE_FLAGS=
@@ -304,7 +319,11 @@
FILES="$FILES $THUMB_FILE"
fi
done
- PACKAGE="$PACKAGE_DIR/gnu-libstdc++-libs-$VERSION-$ABI.tar.bz2"
+ PACKAGE="$PACKAGE_DIR/gnu-libstdc++-libs-$VERSION-$ABI"
+ if [ "$WITH_DEBUG_INFO" ]; then
+ PACKAGE="${PACKAGE}-g"
+ fi
+ PACKAGE="${PACKAGE}.tar.bz2"
dump "Packaging: $PACKAGE"
pack_archive "$PACKAGE" "$NDK_DIR" "$FILES"
fail_panic "Could not package $ABI STLport binaries!"
diff --git a/build/tools/build-host-prebuilts.sh b/build/tools/build-host-prebuilts.sh
index c6d0b57..678715d 100755
--- a/build/tools/build-host-prebuilts.sh
+++ b/build/tools/build-host-prebuilts.sh
@@ -260,7 +260,7 @@
# First, ndk-stack
echo "Building $SYSNAME ndk-stack"
- run $BUILDTOOLS/build-ndk-stack.sh $TOOLCHAIN_FLAGS
+ run $BUILDTOOLS/build-ndk-stack.sh $TOOLCHAIN_FLAGS --with-libbfd --src-dir=$SRC_DIR
fail_panic "ndk-stack build failure!"
echo "Building $SYSNAME ndk-depends"
@@ -305,6 +305,10 @@
run $BUILDTOOLS/build-host-python.sh $TOOLCHAIN_FLAGS "--toolchain-src-dir=$SRC_DIR" "--systems=$SYSTEM" "--force"
fail_panic "python build failure!"
+ echo "Building $SYSNAME ndk-yasm"
+ run $BUILDTOOLS/build-host-yasm.sh "$SRC_DIR" "$NDK_DIR" $TOOLCHAIN_FLAGS
+ fail_panic "yasm build failure!"
+
if [ "$SYSTEM" = "windows" ]; then
echo "Building $SYSNAME toolbox"
run $BUILDTOOLS/build-host-toolbox.sh $FLAGS
diff --git a/build/tools/build-host-yasm.sh b/build/tools/build-host-yasm.sh
new file mode 100755
index 0000000..c9c2b3e
--- /dev/null
+++ b/build/tools/build-host-yasm.sh
@@ -0,0 +1,148 @@
+#!/bin/sh
+#
+# Copyright (C) 2013 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.
+#
+# Build the host version of the yasm executable and place it
+# at the right location
+
+PROGDIR=$(dirname $0)
+. $PROGDIR/prebuilt-common.sh
+
+PROGRAM_PARAMETERS="<src-dir> <ndk-dir>"
+PROGRAM_DESCRIPTION=\
+"Rebuild yasm tool used by the NDK."
+
+register_try64_option
+register_canadian_option
+register_jobs_option
+
+BUILD_OUT=/tmp/ndk-$USER/build/yasm
+OPTION_BUILD_OUT=
+register_var_option "--build-out=<path>" OPTION_BUILD_OUT "Set temporary build directory"
+
+PACKAGE_DIR=
+register_var_option "--package-dir=<path>" PACKAGE_DIR "Archive binaries into package directory"
+
+extract_parameters "$@"
+
+set_parameters ()
+{
+ SRC_DIR="$1"
+ NDK_DIR="$2"
+
+ # Check source directory
+ #
+ if [ -z "$SRC_DIR" ] ; then
+ echo "ERROR: Missing source directory parameter. See --help for details."
+ exit 1
+ fi
+
+ if [ ! -d "$SRC_DIR/yasm" ] ; then
+ echo "ERROR: Source directory does not contain llvm sources: $SRC_DIR/yasm"
+ exit 1
+ fi
+
+ SRC_DIR=`cd $SRC_DIR; pwd`
+ log "Using source directory: $SRC_DIR"
+
+ # Check NDK installation directory
+ #
+ if [ -z "$NDK_DIR" ] ; then
+ echo "ERROR: Missing NDK directory parameter. See --help for details."
+ exit 1
+ fi
+
+ if [ ! -d "$NDK_DIR" ] ; then
+ mkdir -p $NDK_DIR
+ if [ $? != 0 ] ; then
+ echo "ERROR: Could not create target NDK installation path: $NDK_DIR"
+ exit 1
+ fi
+ fi
+ NDK_DIR=`cd $NDK_DIR; pwd`
+ log "Using NDK directory: $NDK_DIR"
+}
+
+set_parameters $PARAMETERS
+
+prepare_abi_configure_build
+prepare_host_build
+
+fix_option BUILD_OUT "$OPTION_BUILD_OUT" "build directory"
+setup_default_log_file $BUILD_OUT/config.log
+
+rm -rf $BUILD_OUT
+mkdir -p $BUILD_OUT
+
+log "Copying yasm sources to $BUILD_OUT/src"
+mkdir -p "$BUILD_OUT/src" && copy_directory "$SRC_DIR/yasm" "$BUILD_OUT/src"
+fail_panic "Could not copy yasm sources to: $BUILD_OUT/src"
+
+CONFIGURE_FLAGS="--disable-nls --disable-rpath --prefix=$BUILD_OUT/prefix"
+if [ "$MINGW" = "yes" ]; then
+ # Required for a proper mingw cross compile
+ CONFIGURE_FLAGS=$CONFIGURE_FLAGS" --host=i586-pc-mingw32"
+fi
+
+if [ "$DARWIN" = "yes" ]; then
+ # Required for a proper darwin cross compile
+ CONFIGURE_FLAGS=$CONFIGURE_FLAGS" --host=$ABI_CONFIGURE_HOST"
+fi
+
+prepare_canadian_toolchain $BUILD_OUT
+
+CFLAGS=$HOST_CFLAGS" -O2 -s"
+export CC CFLAGS
+
+cd $BUILD_OUT/src && run ./autogen.sh
+fail_panic "Couldn't run autogen.sh in $BUILD_OUT/yasm!"
+
+log "Configuring the build"
+run ./configure $CONFIGURE_FLAGS --build=$ABI_CONFIGURE_BUILD
+fail_panic "Failed to configure the $BUILD_OUT/yasm!"
+
+log "Building yasm"
+run make -j $NUM_JOBS
+fail_panic "Failed to build the $BUILD_OUT/yasm!"
+
+log "Installing yasm"
+run make install
+fail_panic "Failed to install $BUILD_OUT/yasm!"
+
+run rm -rf $BUILD_OUT/prefix/share
+
+log "Stripping yasm"
+test -z "$STRIP" && STRIP=strip
+find $BUILD_OUT/prefix/bin -maxdepth 1 -type f -exec $STRIP {} \;
+
+log "Copying yasm"
+#run copy_directory "$BUILD_OUT/prefix" "$(get_prebuilt_install_prefix)"
+SUBDIR=$(get_prebuilt_host_exec yasm)
+OUT=$NDK_DIR/$SUBDIR
+run mkdir -p $(dirname "$OUT") && cp $BUILD_OUT/prefix/bin/$(get_host_exec_name yasm) $OUT
+fail_panic "Could not copy yasm"
+
+if [ "$PACKAGE_DIR" ]; then
+ ARCHIVE=ndk-yasm-$HOST_TAG.tar.bz2
+ dump "Packaging: $ARCHIVE"
+ mkdir -p "$PACKAGE_DIR" &&
+ pack_archive "$PACKAGE_DIR/$ARCHIVE" "$NDK_DIR" "$SUBDIR"
+ fail_panic "Could not package archive: $PACKAGE_DIR/$ARCHIVE"
+fi
+
+log "Cleaning up"
+if [ -z "$OPTION_BUILD_OUT" ] ; then
+ rm -rf $BUILD_OUT
+fi
diff --git a/build/tools/build-llvm.sh b/build/tools/build-llvm.sh
index 423a645..2e75f89 100755
--- a/build/tools/build-llvm.sh
+++ b/build/tools/build-llvm.sh
@@ -28,7 +28,7 @@
Where <src-dir> is the location of toolchain sources, <ndk-dir> is
the top-level NDK installation path and <toolchain> is the name of
-the toolchain to use (e.g. llvm-3.3)."
+the toolchain to use (e.g. llvm-3.4)."
RELEASE=`date +%Y%m%d`
BUILD_OUT=/tmp/ndk-$USER/build/toolchain
@@ -251,13 +251,20 @@
fi
if [ "$USE_PYTHON" != "yes" ]; then
+ # Refresh intermediate source
+ rm -f $SRC_DIR/$TOOLCHAIN/llvm/tools/ndk-bc2native/*.cpp
+ rm -f $SRC_DIR/$TOOLCHAIN/llvm/tools/ndk-bc2native/*.c
+ rm -f $SRC_DIR/$TOOLCHAIN/llvm/tools/ndk-bc2native/*.h
run cp -a $NDK_DIR/tests/abcc/jni/*.cpp $SRC_DIR/$TOOLCHAIN/llvm/tools/ndk-bc2native
run cp -a $NDK_DIR/tests/abcc/jni/*.h $SRC_DIR/$TOOLCHAIN/llvm/tools/ndk-bc2native
run cp -a $NDK_DIR/tests/abcc/jni/host/*.cpp $SRC_DIR/$TOOLCHAIN/llvm/tools/ndk-bc2native
run cp -a $NDK_DIR/tests/abcc/jni/host/*.h $SRC_DIR/$TOOLCHAIN/llvm/tools/ndk-bc2native
+ run cp -a $NDK_DIR/tests/abcc/jni/mman-win32/mman.[ch] $SRC_DIR/$TOOLCHAIN/llvm/tools/ndk-bc2native
export LLVM_TOOLS_FILTER="PARALLEL_DIRS:=\$\$(PARALLEL_DIRS:%=% ndk-bc2native)"
fi
+BINUTILS_VERSION=$(get_default_binutils_version_for_llvm $TOOLCHAIN)
+
run $SRC_DIR/$TOOLCHAIN/llvm/configure \
--prefix=$TOOLCHAIN_BUILD_PREFIX \
--host=$ABI_CONFIGURE_HOST \
@@ -265,7 +272,7 @@
--with-bug-report-url=$DEFAULT_ISSUE_TRACKER_URL \
--enable-targets=arm,mips,x86 \
--enable-optimized \
- --with-binutils-include=$SRC_DIR/binutils/binutils-$DEFAULT_BINUTILS_VERSION/include \
+ --with-binutils-include=$SRC_DIR/binutils/binutils-$BINUTILS_VERSION/include \
$EXTRA_CONFIG_FLAGS
fail_panic "Couldn't configure llvm toolchain"
@@ -381,7 +388,7 @@
bugpoint c-index-test clang-check clang-format clang-tblgen lli llvm-bcanalyzer
llvm-config llvm-config-host llvm-cov llvm-diff llvm-dwarfdump llvm-extract llvm-ld
llvm-mc llvm-nm llvm-mcmarkup llvm-objdump llvm-prof llvm-ranlib llvm-readobj llvm-rtdyld
-llvm-size llvm-stress llvm-stub llvm-symbolizer llvm-tblgen macho-dump cloog"
+llvm-size llvm-stress llvm-stub llvm-symbolizer llvm-tblgen macho-dump cloog lli-child-target"
for i in $UNUSED_LLVM_EXECUTABLES; do
rm -f $TOOLCHAIN_BUILD_PREFIX/bin/$i
@@ -398,6 +405,7 @@
if [ "$USE_PYTHON" != "yes" ]; then
# Remove those intermediate cpp
rm -f $SRC_DIR/$TOOLCHAIN/llvm/tools/ndk-bc2native/*.cpp
+ rm -f $SRC_DIR/$TOOLCHAIN/llvm/tools/ndk-bc2native/*.c
rm -f $SRC_DIR/$TOOLCHAIN/llvm/tools/ndk-bc2native/*.h
else
cp -p "$SRC_DIR/$TOOLCHAIN/llvm/tools/ndk-bc2native/ndk-bc2native.py" "$TOOLCHAIN_BUILD_PREFIX/bin/"
@@ -415,7 +423,7 @@
armeabi)
LLVM_TARGET=armv5te-none-linux-androideabi
;;
- armeabi-v7a)
+ armeabi-v7a|armeabi-v7a-hard)
LLVM_TARGET=armv7-none-linux-androideabi
;;
x86)
@@ -472,9 +480,15 @@
if ERRORLEVEL 1 exit /b 1
:done
EOF
+ chmod 0755 "${ANALYZER}.cmd" "${ANALYZER}++.cmd"
fi
done
+# copy SOURCES file if present
+if [ -f "$SRC_DIR/SOURCES" ]; then
+ cp "$SRC_DIR/SOURCES" "$TOOLCHAIN_PATH/SOURCES"
+fi
+
if [ "$PACKAGE_DIR" ]; then
ARCHIVE="$TOOLCHAIN-$HOST_TAG.tar.bz2"
SUBDIR=$(get_toolchain_install_subdir $TOOLCHAIN $HOST_TAG)
diff --git a/build/tools/build-mingw64-toolchain.sh b/build/tools/build-mingw64-toolchain.sh
index b065200..d40e4ba 100755
--- a/build/tools/build-mingw64-toolchain.sh
+++ b/build/tools/build-mingw64-toolchain.sh
@@ -429,8 +429,9 @@
fi
if [ ! -d $MINGW_W64_SRC ]; then
- echo "Checking out https://mingw-w64.svn.sourceforge.net/svnroot/mingw-w64/trunk$MINGW_W64_REVISION $MINGW_W64_SRC"
- run svn co https://mingw-w64.svn.sourceforge.net/svnroot/mingw-w64/trunk$MINGW_W64_REVISION $MINGW_W64_SRC
+ MINGW64_SVN_URL=https://svn.code.sf.net/p/mingw-w64/code/trunk$MINGW_W64_REVISION
+ echo "Checking out $MINGW64_SVN_URL $MINGW_W64_SRC"
+ run svn co $MINGW64_SVN_URL $MINGW_W64_SRC
PATCHES_DIR="$PROGDIR/toolchain-patches-host/mingw-w64"
if [ -d "$PATCHES_DIR" ] ; then
PATCHES=$(find "$PATCHES_DIR" -name "*.patch" | sort)
diff --git a/build/tools/build-ndk-stack.sh b/build/tools/build-ndk-stack.sh
index f258f2f..3edba2b 100755
--- a/build/tools/build-ndk-stack.sh
+++ b/build/tools/build-ndk-stack.sh
@@ -29,6 +29,7 @@
register_jobs_option
+OPTION_BUILD_DIR=
BUILD_DIR=
register_var_option "--build-dir=<path>" BUILD_DIR "Specify build directory"
@@ -41,6 +42,12 @@
DEBUG=
register_var_option "--debug" DEBUG "Build debug version"
+WITH_LIBBFD=
+register_var_option "--with-libbfd" WITH_LIBBFD "Link with libbfd.a instead of elff/. Need to set --src-dir= too."
+
+SRC_DIR=
+register_var_option "--src-dir=<path>" SRC_DIR "Specify binutils source dir. Must be set for --with-libbfd"
+
PROGNAME=ndk-stack
register_var_option "--program-name=<name>" PROGNAME "Alternate NDK tool program name"
@@ -52,15 +59,63 @@
extract_parameters "$@"
+if [ "$WITH_LIBBFD" ]; then
+ if [ -z "$SRC_DIR" ]; then
+ echo "ERROR: Missing source directory parameter. See --help for details."
+ exit 1
+ fi
+fi
+
+prepare_abi_configure_build
prepare_host_build
# Choose a build directory if not specified by --build-dir
if [ -z "$BUILD_DIR" ]; then
BUILD_DIR=$NDK_TMPDIR/build-$PROGNAME
log "Auto-config: --build-dir=$BUILD_DIR"
+else
+ OPTION_BUILD_DIR="yes"
fi
+
+rm -rf $BUILD_DIR
+mkdir -p $BUILD_DIR
+
prepare_canadian_toolchain $BUILD_DIR
+CFLAGS=$HOST_CFLAGS" -O2 -s -ffunction-sections -fdata-sections"
+LDFLAGS=$HOST_LDFLAGS
+EXTRA_CONFIG=
+
+if [ "$HOST_OS" != "darwin" -a "$DARWIN" != "yes" ]; then
+ LDFLAGS=$LDFLAGS" -Wl,-gc-sections"
+else
+ # In darwin libbfd has to be built with some *linux* target or it won't understand ELF
+ EXTRA_CONFIG="-target=arm-linux-androideabi"
+fi
+
+BINUTILS_BUILD_DIR=$BUILD_DIR/binutils
+BINUTILS_SRC_DIR=$SRC_DIR/binutils/binutils-$RECENT_BINUTILS_VERSION
+if [ "$WITH_LIBBFD" ]; then
+ # build binutils first
+ if [ -z "$ABI_CONFIGURE_HOST" ]; then
+ ABI_CONFIGURE_HOST=$ABI_CONFIGURE_BUILD
+ fi
+ run mkdir -p $BINUTILS_BUILD_DIR
+ run export CC CFLAGS LDFLAGS
+ run pushd $BINUTILS_BUILD_DIR && \
+ run $BINUTILS_SRC_DIR/configure \
+ --host=$ABI_CONFIGURE_HOST \
+ --build=$ABI_CONFIGURE_BUILD \
+ --disable-nls \
+ --with-bug-report-url=$DEFAULT_ISSUE_TRACKER_URL \
+ $EXTRA_CONFIG
+ fail_panic "Can't configure $BINUTILS_SRC_DIR"
+ run make -j$NUM_JOBS
+ fail_panic "Can't build $BINUTILS_SRC_DIR"
+
+ popd > /dev/null
+fi
+
OUT=$NDK_DIR/$(get_host_exec_name $PROGNAME)
# GNU Make
@@ -84,13 +139,35 @@
SRCDIR=$ANDROID_NDK_ROOT/sources/host-tools/$PROGNAME
# Let's roll
-export CFLAGS=$HOST_CFLAGS" -O2 -s"
-export LDFLAGS=$HOST_LDFLAGS
+if [ "$WITH_LIBBFD" ]; then
+ CFLAGS="$CFLAGS \
+ -DWITH_LIBBFD=1 \
+ -DHAVE_CONFIG_H \
+ -I$BINUTILS_BUILD_DIR/binutils \
+ -I$BINUTILS_SRC_DIR/binutils \
+ -I$BINUTILS_BUILD_DIR/bfd \
+ -I$BINUTILS_SRC_DIR/bfd \
+ -I$BINUTILS_SRC_DIR/include \
+ "
+ LDFLAGS="$LDFLAGS \
+ $BINUTILS_BUILD_DIR/binutils/bucomm.o \
+ $BINUTILS_BUILD_DIR/binutils/version.o \
+ $BINUTILS_BUILD_DIR/binutils/filemode.o \
+ $BINUTILS_BUILD_DIR/bfd/libbfd.a \
+ $BINUTILS_BUILD_DIR/libiberty/libiberty.a \
+ "
+ if [ "$MINGW" != "yes" ]; then
+ LDFLAGS="$LDFLAGS -ldl -lz"
+ fi
+fi
+
+export CFLAGS LDFLAGS
run $GNUMAKE -C $SRCDIR -f $SRCDIR/GNUmakefile \
-B -j$NUM_JOBS \
PROGNAME="$OUT" \
+ WITH_LIBBFD=$WITH_LIBBFD \
BUILD_DIR="$BUILD_DIR" \
- CC="$CXX" CXX="$CXX" \
+ CC="$CC" CXX="$CXX" \
STRIP="$STRIP" \
DEBUG=$DEBUG
@@ -107,8 +184,12 @@
fail_panic "Could not create package: $PACKAGE_DIR/$ARCHIVE from $OUT"
fi
-log "Cleaning up"
-rm -rf $BUILD_DIR
+if [ "$OPTION_BUILD_DIR" != "yes" ]; then
+ log "Cleaning up..."
+ rm -rf $BUILD_DIR
+else
+ log "Don't forget to cleanup: $BUILD_DIR"
+fi
log "Done!"
exit 0
diff --git a/build/tools/build-target-prebuilts.sh b/build/tools/build-target-prebuilts.sh
index a316ebd..5eb4563 100755
--- a/build/tools/build-target-prebuilts.sh
+++ b/build/tools/build-target-prebuilts.sh
@@ -27,6 +27,9 @@
ARCHS="$DEFAULT_ARCHS $ARCHS"
register_var_option "--arch=<list>" ARCHS "List of target archs to build for"
+NO_GEN_PLATFORMS=
+register_var_option "--no-gen-platforms" NO_GEN_PLATFORMS "Don't generate platforms/ directory, use existing one"
+
PACKAGE_DIR=
register_var_option "--package-dir=<path>" PACKAGE_DIR "Package toolchain into this directory"
@@ -57,8 +60,16 @@
PACKAGE_FLAGS="--package-dir=$PACKAGE_DIR"
fi
-run $BUILDTOOLS/gen-platforms.sh --samples --fast-copy --dst-dir=$NDK_DIR --ndk-dir=$NDK_DIR --arch=$(spaces_to_commas $ARCHS) $PACKAGE_FLAGS
-fail_panic "Could not generate platforms and samples directores!"
+if [ -z "$NO_GEN_PLATFORMS" ]; then
+ echo "Preparing the build..."
+ run $BUILDTOOLS/gen-platforms.sh --samples --fast-copy --dst-dir=$NDK_DIR --ndk-dir=$NDK_DIR --arch=$(spaces_to_commas $ARCHS) $PACKAGE_FLAGS
+ fail_panic "Could not generate platforms and samples directores!"
+else
+ if [ ! -d "$NDK_DIR/platforms" ]; then
+ echo "ERROR: --no-gen-platforms used but directory missing: $NDK_DIR/platforms"
+ exit 1
+ fi
+fi
ARCHS=$(commas_to_spaces $ARCHS)
@@ -86,8 +97,9 @@
for ARCH in $ARCHS; do
GDB_TOOLCHAINS=$(get_default_toolchain_name_for_arch $ARCH)
for GDB_TOOLCHAIN in $GDB_TOOLCHAINS; do
+ GDB_VERSION="--gdb-version="$(get_default_gdb_version_for_gcc $GDB_TOOLCHAIN)
dump "Building $GDB_TOOLCHAIN gdbserver binaries..."
- run $BUILDTOOLS/build-gdbserver.sh "$SRC_DIR" "$NDK_DIR" "$GDB_TOOLCHAIN" $FLAGS
+ run $BUILDTOOLS/build-gdbserver.sh "$SRC_DIR" "$NDK_DIR" "$GDB_TOOLCHAIN" "$GDB_VERSION" $FLAGS
fail_panic "Could not build $GDB_TOOLCHAIN gdb-server!"
done
done
@@ -99,14 +111,20 @@
dump "Building $ABIS gabi++ binaries..."
run $BUILDTOOLS/build-cxx-stl.sh --stl=gabi++ --abis="$ABIS" $FLAGS
fail_panic "Could not build gabi++!"
+run $BUILDTOOLS/build-cxx-stl.sh --stl=gabi++ --abis="$ABIS" $FLAGS --with-debug-info
+fail_panic "Could not build gabi++ with debug info!"
dump "Building $ABIS $UNKNOWN_ABIS stlport binaries..."
run $BUILDTOOLS/build-cxx-stl.sh --stl=stlport --abis="$ABIS,$UNKNOWN_ABIS" $FLAGS
fail_panic "Could not build stlport!"
+run $BUILDTOOLS/build-cxx-stl.sh --stl=stlport --abis="$ABIS,$UNKNOWN_ABIS" $FLAGS --with-debug-info
+fail_panic "Could not build stlport with debug info!"
dump "Building $ABIS $UNKNOWN_ABIS libc++ binaries..."
run $BUILDTOOLS/build-cxx-stl.sh --stl=libc++ --abis="$ABIS,$UNKNOWN_ABIS" $FLAGS
fail_panic "Could not build libc++!"
+run $BUILDTOOLS/build-cxx-stl.sh --stl=libc++ --abis="$ABIS,$UNKNOWN_ABIS" $FLAGS --with-debug-info
+fail_panic "Could not build libc++ with debug info!"
if [ ! -z $VISIBLE_LIBGNUSTL_STATIC ]; then
GNUSTL_STATIC_VIS_FLAG=--visible-libgnustl-static
@@ -115,13 +133,16 @@
dump "Building $ABIS gnustl binaries..."
run $BUILDTOOLS/build-gnu-libstdc++.sh --abis="$ABIS" $FLAGS $GNUSTL_STATIC_VIS_FLAG "$SRC_DIR"
fail_panic "Could not build gnustl!"
+run $BUILDTOOLS/build-gnu-libstdc++.sh --abis="$ABIS" $FLAGS $GNUSTL_STATIC_VIS_FLAG "$SRC_DIR" --with-debug-info
+fail_panic "Could not build gnustl with debug info!"
dump "Building $ABIS libportable binaries..."
run $BUILDTOOLS/build-libportable.sh --abis="$ABIS" $FLAGS
fail_panic "Could not build libportable!"
dump "Building $ABIS compiler-rt binaries..."
-run $BUILDTOOLS/build-compiler-rt.sh --abis="$ABIS" $FLAGS --src-dir="$SRC_DIR/llvm-$DEFAULT_LLVM_VERSION/compiler-rt"
+run $BUILDTOOLS/build-compiler-rt.sh --abis="$ABIS" $FLAGS --src-dir="$SRC_DIR/llvm-$DEFAULT_LLVM_VERSION/compiler-rt" \
+ --llvm-version=$DEFAULT_LLVM_VERSION
fail_panic "Could not build compiler-rt!"
if [ "$PACKAGE_DIR" ]; then
diff --git a/build/tools/builder-funcs.sh b/build/tools/builder-funcs.sh
index 1dfdfd4..ed28bda 100644
--- a/build/tools/builder-funcs.sh
+++ b/build/tools/builder-funcs.sh
@@ -318,7 +318,7 @@
fi
builder_log "${_BUILD_PREFIX}Archive: $libname"
rm -f "$lib"
- builder_command ${_BUILD_AR} crs "$lib" "$_BUILD_OBJECTS"
+ builder_command ${_BUILD_AR} crsD "$lib" "$_BUILD_OBJECTS"
fail_panic "Could not archive ${_BUILD_PREFIX}$libname objects!"
}
@@ -340,18 +340,24 @@
fi
builder_log "${_BUILD_PREFIX}Archive: $libname"
rm -f "$lib"
- builder_command ${_BUILD_AR} crs "$lib" "$_BUILD_OBJECTS"
+ builder_command ${_BUILD_AR} crsD "$lib" "$_BUILD_OBJECTS"
fail_panic "Could not archive ${_BUILD_PREFIX}$libname objects!"
}
builder_shared_library ()
{
- local lib libname suffix
+ local lib libname suffix libm
libname=$1
suffix=$2
+ armeabi_v7a_float_abi=$3
+
if [ -z "$suffix" ]; then
suffix=".so"
fi
+ libm="-lm"
+ if [ "$armeabi_v7a_float_abi" = "hard" ]; then
+ libm="-lm_hard"
+ fi
lib=$_BUILD_DSTDIR/$libname
lib=${lib%%${suffix}}${suffix}
if [ "$_BUILD_MK" ]; then
@@ -365,13 +371,13 @@
# for other platforms.
builder_command ${_BUILD_CXX} \
-Wl,-soname,$(basename $lib) \
- -Wl,-shared,-Bsymbolic \
+ -Wl,-shared \
$_BUILD_LDFLAGS_BEGIN_SO \
$_BUILD_OBJECTS \
$_BUILD_STATIC_LIBRARIES \
-lgcc \
$_BUILD_SHARED_LIBRARIES \
- -lc -lm \
+ -lc $libm \
$_BUILD_LDFLAGS \
$_BUILD_LDFLAGS_END_SO \
-o $lib
@@ -397,7 +403,7 @@
builder_command ${_BUILD_CXX} \
-Wl,-soname,$(basename $lib) \
- -Wl,-shared,-Bsymbolic \
+ -Wl,-shared \
$_BUILD_LDFLAGS_BEGIN_SO \
$_BUILD_OBJECTS \
$_BUILD_STATIC_LIBRARIES \
@@ -543,7 +549,7 @@
armeabi)
LLVM_TRIPLE=armv5te-none-linux-androideabi
;;
- armeabi-v7a)
+ armeabi-v7a|armeabi-v7a-hard)
LLVM_TRIPLE=armv7-none-linux-androideabi
;;
x86)
@@ -588,9 +594,15 @@
builder_cflags "-mthumb"
fi
;;
- armeabi-v7a)
- builder_cflags "-mthumb -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16"
+ armeabi-v7a|armeabi-v7a-hard)
+ builder_cflags "-mthumb -march=armv7-a -mfpu=vfpv3-d16"
builder_ldflags "-march=armv7-a -Wl,--fix-cortex-a8"
+ if [ "$ABI" != "armeabi-v7a-hard" ]; then
+ builder_cflags "-mfloat-abi=softfp"
+ else
+ builder_cflags "-mhard-float -D_NDK_MATH_NO_SOFTFP=1"
+ builder_ldflags "-Wl,--no-warn-mismatch -lm_hard"
+ fi
;;
esac
}
diff --git a/build/tools/deploy-host-mcld.sh b/build/tools/deploy-host-mcld.sh
index e871a47..7deb36a 100755
--- a/build/tools/deploy-host-mcld.sh
+++ b/build/tools/deploy-host-mcld.sh
@@ -31,13 +31,15 @@
Running after completion of both build-llvm.sh and build-[host-]gcc.sh,
this script copy toolchains/llvm-$DEFAULT_LLVM_VERSION/prebuilt/$SYSTEM/bin/ld.mcld[.exe]
-to be sibling of ld in all GCC directories with same HOST_OS and bitness,
+to be sibling of ld in all GCC and LLVM directories with same HOST_OS and bitness,
ie. {linux, darwin, windows} x {64, 32}
If --systems isn't specified, this script discovers all ld.mcld[.exe] in
toolchains/llvm-$DEFAULT_LLVM_VERSION
-Note that one copy of ld.mcld serves all GCC {4.8, 4.7, 4.6, 4.4.3} x {arm, x86, mips}.
+Note that one copy of ld.mcld serves all GCC {4.8, 4.7, 4.6, 4.4.3} x {arm, x86, mips} and
+LLVM {3.3, 3.4}.
+
GCC passes -m flag for ld.mcld to figure out the right target.
"
NDK_DIR=
@@ -89,10 +91,10 @@
MCLD=toolchains/llvm-$DEFAULT_LLVM_VERSION/prebuilt/$SYSTEM/bin/ld.mcld$HOST_EXE
test -f "$MCLD" || fail_panic "Could not find $MCLD"
+ ALL_LD_MCLDS=
+
# find all GNU ld with the same SYSTEM
ALL_LDS=`find toolchains \( -name "*-ld" -o -name "ld" -o -name "*-ld.exe" -o -name "ld.exe" \) | egrep "/arm|/x86|/mips" | grep $SYSTEM/`
-
- ALL_LD_MCLDS=
for LD in $ALL_LDS; do
LD_NOEXE=${LD%%.exe}
LD_MCLD=${LD_NOEXE}.mcld$HOST_EXE
@@ -107,6 +109,16 @@
ALL_LD_MCLDS=$ALL_LD_MCLDS" $LD_MCLD"
done
+ # find all llvm-* which isn't llvm-$DEFAULT_LLVM_VERSION
+ for LLVM in $DEFAULT_LLVM_VERSION_LIST; do
+ if [ "$LLVM" != "$DEFAULT_LLVM_VERSION" ]; then
+ LD_MCLD=toolchains/llvm-$LLVM/prebuilt/$SYSTEM/bin/ld.mcld$HOST_EXE
+ run rm -f "$LD_MCLD"
+ run ln -s "../../../../../$MCLD" "$LD_MCLD"
+ ALL_LD_MCLDS=$ALL_LD_MCLDS" $LD_MCLD"
+ fi
+ done
+
# package
if [ "$PACKAGE_DIR" ]; then
ARCHIVE="ld.mcld-$SYSTEM.tar.bz2"
diff --git a/build/tools/dev-defaults.sh b/build/tools/dev-defaults.sh
index 5f1b859..e81753b 100644
--- a/build/tools/dev-defaults.sh
+++ b/build/tools/dev-defaults.sh
@@ -6,10 +6,10 @@
# Note: levels 6 and 7 are omitted since they have the same native
# APIs as level 5. Same for levels 10, 11 and 12
#
-API_LEVELS="3 4 5 8 9 13 14 15 16 17 18 19"
+API_LEVELS="3 4 5 8 9 12 13 14 15 16 17 18 19"
# Default ABIs for the target prebuilt binaries.
-PREBUILT_ABIS="armeabi armeabi-v7a x86 mips"
+PREBUILT_ABIS="armeabi armeabi-v7a x86 mips armeabi-v7a-hard"
# Location of the STLport sources, relative to the NDK root directory
STLPORT_SUBDIR=sources/cxx-stl/stlport
@@ -34,6 +34,9 @@
# Location of the compiler-rt sources, relative to the NDK root directory
COMPILER_RT_SUBDIR=sources/android/compiler-rt
+# Location of the support sources for libc++, relative to the NDK root directory
+SUPPORT_SUBDIR=sources/android/support
+
# The date to use when downloading toolchain sources from AOSP servers
# Leave it empty for tip of tree.
TOOLCHAIN_GIT_DATE=now
@@ -57,6 +60,8 @@
DEFAULT_PYTHON_VERSION=2.7.5
DEFAULT_PERL_VERSION=5.16.2
+RECENT_BINUTILS_VERSION=2.23
+
# Default platform to build target binaries against.
DEFAULT_PLATFORM=android-9
@@ -80,7 +85,7 @@
DEFAULT_ARCH_TOOLCHAIN_PREFIX_mips=mipsel-linux-android
# The space-separated list of all LLVM versions we support in NDK
-DEFAULT_LLVM_VERSION_LIST="3.3"
+DEFAULT_LLVM_VERSION_LIST="3.4 3.3"
# The default LLVM version (first item in the list)
DEFAULT_LLVM_VERSION=$(echo "$DEFAULT_LLVM_VERSION_LIST" | tr ' ' '\n' | head -n 1)
@@ -124,7 +129,7 @@
local RET
case $1 in
arm)
- RET="armeabi armeabi-v7a"
+ RET="armeabi armeabi-v7a armeabi-v7a-hard"
;;
x86|x86_64|mips)
RET="$1"
@@ -212,6 +217,22 @@
esac
}
+# Return the binutils version to be used by default when
+# building a given version of llvm. For llvm-3.4 or later,
+# we use binutils-2.23 to ensure the LLVMgold.so could be
+# built properly. For llvm-3.3, we use binutils-2.21 as default.
+#
+# $1: toolchain with version numer (e.g. 'llvm-3.3')
+#
+get_default_binutils_version_for_llvm ()
+{
+ case $1 in
+ *-3.3|*-3.2) echo "2.21";;
+ *-3.4) echo "2.23";;
+ *) echo "2.23";;
+ esac
+}
+
# Return the gdb version to be used by default when building a given
# version of GCC.
#
@@ -220,7 +241,7 @@
get_default_gdb_version_for_gcc ()
{
case $1 in
- aarch64-*) echo "7.6";;
+ x86*|aarch64-*) echo "7.6";;
*) echo "$DEFAULT_GDB_VERSION";;
esac
}
diff --git a/build/tools/dev-rebuild-ndk.sh b/build/tools/dev-rebuild-ndk.sh
index 1c2ea91..3acc329 100755
--- a/build/tools/dev-rebuild-ndk.sh
+++ b/build/tools/dev-rebuild-ndk.sh
@@ -156,14 +156,14 @@
# Build the platform
echo
echo "Build the ndk/platforms directory"
-logfile="$TOP/build-platforms.log"
+logfile="$TOP/gen-platforms.log"
rotate_log $logfile
$PROGDIR/gen-platforms.sh \
$VERBOSE \
--arch=$(spaces_to_commas $ARCHS) \
--minimal \
--fast-copy > $logfile 2>&1
-fail_panic "build-platforms.sh failed. Logfile in $logfile"
+fail_panic "gen-platforms.sh failed. Logfile in $logfile"
logfile="$TOP/rebuild-all.log"
rotate_log $logfile
diff --git a/build/tools/download-toolchain-sources.sh b/build/tools/download-toolchain-sources.sh
index 09de574..0e42c25 100755
--- a/build/tools/download-toolchain-sources.sh
+++ b/build/tools/download-toolchain-sources.sh
@@ -205,6 +205,7 @@
toolchain_clone llvm
toolchain_clone compiler-rt
toolchain_clone mclinker
+toolchain_clone yasm
toolchain_checkout "" $BRANCH build .
toolchain_checkout "" $BRANCH gmp .
@@ -220,6 +221,7 @@
toolchain_checkout "" $BRANCH python Python-2.7.5
toolchain_checkout "" $BRANCH perl perl-5.16.2
toolchain_checkout "" $BRANCH mclinker .
+toolchain_checkout "" $BRANCH yasm .
for LLVM_VERSION in $LLVM_VERSION_LIST; do
# Check-out and Adjust directory structure a bit
@@ -237,8 +239,6 @@
if [ "$LLVM_VERSION" != "3.1" ]; then
# compiler-rt only exists on and after 3.2
toolchain_checkout "llvm-$LLVM_VERSION" $LLVM_BRANCH compiler-rt .
- (cd "$TMPDIR/llvm-$LLVM_VERSION/llvm" && \
- test -d ../compiler-rt && ln -s ../../compiler-rt projects)
fi
# In polly/utils/cloog_src, touch Makefile.in, aclocal.m4, and configure to
# make sure they are not regenerated.
diff --git a/build/tools/gen-platforms.sh b/build/tools/gen-platforms.sh
index d709360..1cb839f 100755
--- a/build/tools/gen-platforms.sh
+++ b/build/tools/gen-platforms.sh
@@ -530,12 +530,10 @@
log "Generating $ARCH C runtime object: $DST_FILE"
(cd "$SRC_DIR" && $CC \
-I$SRCDIR/../../bionic/libc/include \
- -I$SRCDIR/../../bionic/libc/private \
-I$SRCDIR/../../bionic/libc/arch-common/bionic \
-I$SRCDIR/../../bionic/libc/arch-$ARCH/include \
- -isystem $SRCDIR/../../bionic/libc/kernel/common \
- -isystem $SRCDIR/../../bionic/libc/kernel/common/linux \
- -O2 -fpic -Wl,-r -nostdlib -nostdinc -o "$DST_DIR/$DST_FILE" $SRC_FILE) 1>>$TMPL 2>&1
+ -DPLATFORM_SDK_VERSION=$API \
+ -O2 -fpic -Wl,-r -nostdlib -o "$DST_DIR/$DST_FILE" $SRC_FILE) 1>>$TMPL 2>&1
if [ $? != 0 ]; then
dump "ERROR: Could not generate $DST_FILE from $SRC_DIR/$SRC_FILE"
dump "Please see the content of $TMPL for details!"
diff --git a/build/tools/make-standalone-toolchain.sh b/build/tools/make-standalone-toolchain.sh
index 35aa264..9527147 100755
--- a/build/tools/make-standalone-toolchain.sh
+++ b/build/tools/make-standalone-toolchain.sh
@@ -420,6 +420,7 @@
if ERRORLEVEL 1 exit /b 1
:done
EOF
+ chmod 0755 "$TMPDIR/bin/clang.cmd" "$TMPDIR/bin/clang++.cmd"
cp -a "$TMPDIR/bin/clang.cmd" "$TMPDIR/bin/$TOOLCHAIN_PREFIX-clang.cmd"
cp -a "$TMPDIR/bin/clang++.cmd" "$TMPDIR/bin/$TOOLCHAIN_PREFIX-clang++.cmd"
fi
@@ -449,6 +450,12 @@
STLPORT_DIR=$NDK_DIR/$STLPORT_SUBDIR
STLPORT_LIBS=$STLPORT_DIR/libs
+LIBCXX_DIR=$NDK_DIR/$LIBCXX_SUBDIR
+LIBCXX_LIBS=$LIBCXX_DIR/libs
+
+COMPILER_RT_DIR=$NDK_DIR/$COMPILER_RT_SUBDIR
+COMPILER_RT_LIBS=$COMPILER_RT_DIR/libs
+
ABI_STL="$TMPDIR/$ABI_CONFIGURE_TARGET"
ABI_STL_INCLUDE="$TMPDIR/include/c++/$GCC_BASE_VERSION"
ABI_STL_INCLUDE_TARGET="$ABI_STL_INCLUDE/$ABI_CONFIGURE_TARGET"
@@ -466,6 +473,10 @@
gnustl)
copy_directory "$GNUSTL_DIR/include" "$ABI_STL_INCLUDE"
;;
+ libcxx|libc++)
+ copy_directory "$LIBCXX_DIR/libcxx/include" "$ABI_STL_INCLUDE"
+ copy_directory "$SUPPORT_SUBDIR/include" "$ABI_STL_INCLUDE"
+ ;;
stlport)
copy_directory "$STLPORT_DIR/stlport" "$ABI_STL_INCLUDE"
copy_directory "$STLPORT_DIR/../gabi++/include" "$ABI_STL_INCLUDE/../../gabi++/include"
@@ -475,32 +486,47 @@
}
# $1: Source ABI (e.g. 'armeabi')
-# $2: Optional extra ABI variant, or empty (e.g. "", "thumb", "armv7-a/thumb")
+# $2: Optional destination directory, default to empty (e.g. "", "thumb", "armv7-a/thumb")
+# $3: Optional source directory, default to empty (e.g. "", "thumb", "armv7-a/thumb")
+# $4: Optional "yes" (default) or "no" about whether to copy additional header (eg. include/bits)
copy_stl_libs () {
local ABI=$1
- local ABI2=$2
+ local DEST_DIR=$2
+ local SRC_DIR=$3
+ local COPY_ADDITIONAL_HEADER=yes
case $STL in
gnustl)
- # gnustl has thumb version of libraries. Append ABI with basename($ABI2) if $ABI2 contain '/'
- ABI1=$ABI
- if [ "$ABI2" != "${ABI2%%/*}" ] ; then
- ABI1=$ABI/`basename $ABI2`
+ # gnustl has thumb version of libraries. Append ABI with basename($DEST_DIR) if $DEST_DIR contain '/'
+ ABI_SRC_DIR=$ABI
+ if [ -n "$SRC_DIR" ]; then
+ ABI_SRC_DIR=$ABI/$SRC_DIR
+ else
+ if [ "$DEST_DIR" != "${DEST_DIR%%/*}" ] ; then
+ ABI_SRC_DIR=$ABI/`basename $DEST_DIR`
+ fi
+ fi
+ if [ "$COPY_ADDITIONAL_HEADER" != "no" ]; then
+ copy_directory "$GNUSTL_LIBS/$ABI/include/bits" "$ABI_STL_INCLUDE_TARGET/$DEST_DIR/bits"
fi
- copy_directory "$GNUSTL_LIBS/$ABI/include/bits" "$ABI_STL_INCLUDE_TARGET/$ABI2/bits"
- copy_file_list "$GNUSTL_LIBS/$ABI1" "$ABI_STL/lib/$ABI2" "libgnustl_shared.so"
- copy_file_list "$GNUSTL_LIBS/$ABI1" "$ABI_STL/lib/$ABI2" "libsupc++.a"
- cp -p "$GNUSTL_LIBS/$ABI1/libgnustl_static.a" "$ABI_STL/lib/$ABI2/libstdc++.a"
+ copy_file_list "$GNUSTL_LIBS/$ABI_SRC_DIR" "$ABI_STL/lib/$DEST_DIR" "libgnustl_shared.so"
+ copy_file_list "$GNUSTL_LIBS/$ABI_SRC_DIR" "$ABI_STL/lib/$DEST_DIR" "libsupc++.a"
+ cp -p "$GNUSTL_LIBS/$ABI_SRC_DIR/libgnustl_static.a" "$ABI_STL/lib/$DEST_DIR/libstdc++.a"
+ ;;
+ libcxx|libc++)
+ copy_file_list "$COMPILER_RT_LIBS/$ABI" "$ABI_STL/lib/$DEST_DIR" "libcompiler_rt_shared.so" "libcompiler_rt_static.a"
+ copy_file_list "$LIBCXX_LIBS/$ABI" "$ABI_STL/lib/$DEST_DIR" "libc++_shared.so"
+ cp -p "$LIBCXX_LIBS/$ABI/libc++_static.a" "$ABI_STL/lib/$DEST_DIR/libstdc++.a"
;;
stlport)
if [ "$ARCH_STL" != "$ARCH" ]; then
tmp_lib_dir=$TMPDIR/stl
$NDK_DIR/build/tools/build-cxx-stl.sh --stl=stlport --out-dir=$tmp_lib_dir --abis=unknown
- cp -p "`ls $tmp_lib_dir/sources/cxx-stl/stlport/libs/*/libstlport_static.a`" "$ABI_STL/lib/$ABI2/libstdc++.a"
- cp -p "`ls $tmp_lib_dir/sources/cxx-stl/stlport/libs/*/libstlport_shared.bc`" "$ABI_STL/lib/$ABI2/libstlport_shared.so"
+ cp -p "`ls $tmp_lib_dir/sources/cxx-stl/stlport/libs/*/libstlport_static.a`" "$ABI_STL/lib/$DEST_DIR/libstdc++.a"
+ cp -p "`ls $tmp_lib_dir/sources/cxx-stl/stlport/libs/*/libstlport_shared.bc`" "$ABI_STL/lib/$DEST_DIR/libstlport_shared.so"
rm -rf $tmp_lib_dir
else
- copy_file_list "$STLPORT_LIBS/$ABI" "$ABI_STL/lib/$ABI2" "libstlport_shared.so"
- cp -p "$STLPORT_LIBS/$ABI/libstlport_static.a" "$ABI_STL/lib/$ABI2/libstdc++.a"
+ copy_file_list "$STLPORT_LIBS/$ABI" "$ABI_STL/lib/$DEST_DIR" "libstlport_shared.so"
+ cp -p "$STLPORT_LIBS/$ABI/libstlport_static.a" "$ABI_STL/lib/$DEST_DIR/libstdc++.a"
fi
;;
*)
@@ -519,6 +545,8 @@
copy_stl_libs armeabi "/thumb"
copy_stl_libs armeabi-v7a "armv7-a"
copy_stl_libs armeabi-v7a "armv7-a/thumb"
+ copy_stl_libs armeabi-v7a-hard "armv7-a/hard" "." "no"
+ copy_stl_libs armeabi-v7a-hard "armv7-a/thumb/hard" "thumb" "no"
;;
x86|mips)
copy_stl_libs "$ARCH" ""
diff --git a/build/tools/package-release.sh b/build/tools/package-release.sh
index e08d1c2..ae1063b 100755
--- a/build/tools/package-release.sh
+++ b/build/tools/package-release.sh
@@ -562,6 +562,7 @@
unpack_prebuilt ndk-awk-$SYSTEM "$DSTDIR" "$DSTDIR64"
unpack_prebuilt ndk-perl-$SYSTEM "$DSTDIR" "$DSTDIR64"
unpack_prebuilt ndk-python-$SYSTEM "$DSTDIR" "$DSTDIR64"
+ unpack_prebuilt ndk-yasm-$SYSTEM "$DSTDIR" "$DSTDIR64"
if [ "$SYSTEM" = "windows" ]; then
unpack_prebuilt toolbox-$SYSTEM "$DSTDIR" "$DSTDIR64"
diff --git a/build/tools/patch-sources.sh b/build/tools/patch-sources.sh
index 828c736..6fc0274 100755
--- a/build/tools/patch-sources.sh
+++ b/build/tools/patch-sources.sh
@@ -29,6 +29,9 @@
Patches are applied in the order they are found by 'find'."
+OPTION_REVERSE=no
+register_var_option "--reverse" OPTION_REVERSE "Reverse the patches applied previously"
+
parse_parameters ()
{
SRC_DIR=$1
@@ -57,7 +60,13 @@
extract_parameters "$@"
parse_parameters $PARAMETERS
-PATCHES=`(cd $PATCHES_DIR && find . -name "*.patch" | sort ) 2> /dev/null`
+if [ "$OPTION_REVERSE" = "yes" ]; then
+ SORT="-r"
+ REVERSE="-R"
+fi
+
+PATCHES=`(cd $PATCHES_DIR && find . -name "*.patch" | sort $SORT) 2> /dev/null`
+
if [ -z "$PATCHES" ] ; then
log "No patches files in $PATCHES_DIR"
exit 0
@@ -67,7 +76,7 @@
PATCHDIR=`dirname $PATCH`
PATCHNAME=`basename $PATCH`
log "Applying $PATCHNAME into $SRC_DIR/$PATCHDIR"
- cd $SRC_DIR/$PATCHDIR && patch -p1 < $PATCHES_DIR/$PATCH
+ cd $SRC_DIR/$PATCHDIR && patch $REVERSE -p1 < $PATCHES_DIR/$PATCH
fail_panic "Patch failure with $PATCHES_DIR/$PATCH!! !! Please check your patches directory!"
done
diff --git a/build/tools/prebuilt-common.sh b/build/tools/prebuilt-common.sh
index 03be0ed..3341bd7 100644
--- a/build/tools/prebuilt-common.sh
+++ b/build/tools/prebuilt-common.sh
@@ -1015,7 +1015,7 @@
ABI_CONFIGURE_EXTRA_FLAGS="--with-arch=armv5te --disable-gold --disable-libgomp"
;;
aarch64-linux-android-*)
- ARCH="aarch64"
+ ARCH="arm64"
ABI="aarch64-v8a"
ABI_CONFIGURE_TARGET="aarch64-linux-android"
# Note:
@@ -1198,9 +1198,9 @@
find_ndk_unknown_archs()
{
local FOUND_ARCHS=$(find_ndk_archs)
- # TODO: aarch64, x86_64 is here just to be found as known arch.
+ # TODO: arm64, x86_64 is here just to be found as known arch.
# It can be removed as soon as it is added into $DEFAULT_ARCHS
- echo "$(filter_out "$DEFAULT_ARCHS aarch64 x86_64 mips64" "$FOUND_ARCHS")"
+ echo "$(filter_out "$DEFAULT_ARCHS arm64 x86_64 mips64" "$FOUND_ARCHS")"
}
# Determine whether given arch is in unknown archs list
@@ -1237,7 +1237,7 @@
local RET
local ABI=$1
case $ABI in
- armeabi|armeabi-v7a)
+ armeabi|armeabi-v7a|armeabi-v7a-hard)
RET=arm
;;
x86)
@@ -1250,7 +1250,7 @@
if [ "$(arch_in_unknown_archs $ABI)" = "yes" ]; then
RET=$ABI
else
- >&2 echo "ERROR: Unsupported ABI name: $ABI, use one of: armeabi, armeabi-v7a or x86 or mips"
+ >&2 echo "ERROR: Unsupported ABI name: $ABI, use one of: armeabi, armeabi-v7a, x86, mips or armeabi-v7a-hard"
exit 1
fi
;;
@@ -1268,7 +1268,7 @@
local ARCH=$1
case $ARCH in
arm)
- RET=armeabi,armeabi-v7a
+ RET=armeabi,armeabi-v7a,armeabi-v7a-hard
;;
x86)
RET=x86
diff --git a/build/tools/rebuild-all-prebuilt.sh b/build/tools/rebuild-all-prebuilt.sh
index 1db0d39..9592ba7 100755
--- a/build/tools/rebuild-all-prebuilt.sh
+++ b/build/tools/rebuild-all-prebuilt.sh
@@ -31,6 +31,9 @@
ARCHS="$DEFAULT_ARCHS $ARCHS"
register_var_option "--arch=<arch>" ARCHS "Specify target architectures"
+NO_GEN_PLATFORMS=
+register_var_option "--no-gen-platforms" NO_GEN_PLATFORMS "Don't generate platforms/ directory, use existing one"
+
SYSTEMS=$HOST_TAG32
if [ "$HOST_TAG32" = "linux-x86" ]; then
SYSTEMS=$SYSTEMS",windows"
@@ -95,6 +98,10 @@
FLAGS=$FLAGS" --package-dir=$PACKAGE_DIR"
FLAGS=$FLAGS" --arch=$(spaces_to_commas $ARCHS)"
+if [ ! -z "$NO_GEN_PLATFORMS" ]; then
+ FLAGS=$FLAGS" --no-gen-platforms"
+fi
+
HOST_FLAGS=$FLAGS" --systems=$(spaces_to_commas $SYSTEMS)"
if [ "$TRY64" = "yes" ]; then
HOST_FLAGS=$HOST_FLAGS" --try-64"
diff --git a/build/tools/toolchain-patches/mclinker/0001-Compile-against-llvm-3.3.patch b/build/tools/toolchain-patches/mclinker/0001-Compile-against-llvm-3.3.patch
deleted file mode 100644
index 6bbdc58..0000000
--- a/build/tools/toolchain-patches/mclinker/0001-Compile-against-llvm-3.3.patch
+++ /dev/null
@@ -1,204 +0,0 @@
-From e144ea2749d880e707977c62b0a958e544603f86 Mon Sep 17 00:00:00 2001
-From: Andrew Hsieh <andrewhsieh@google.com>
-Date: Sun, 22 Sep 2013 12:18:46 +0800
-Subject: [PATCH 1/3] Compile against llvm-3.3
-
-instead of against LLVM trunk@187732
-
-Change-Id: Ibe45c9100421a2b937219fa7c9d69be59014379f
----
- include/mcld/Support/raw_ostream.h | 3 ++-
- lib/CodeGen/MCLDTargetMachine.cpp | 6 ++---
- lib/Support/ToolOutputFile.cpp | 5 ++--
- lib/Support/Windows/PathV3.inc | 1 +
- lib/Support/raw_ostream.cpp | 2 +-
- lib/Target/Mips/MipsELFDynamic.cpp | 48 +++++++++++++++++++++++++++-----------
- 6 files changed, 44 insertions(+), 21 deletions(-)
-
-diff --git a/include/mcld/Support/raw_ostream.h b/include/mcld/Support/raw_ostream.h
-index 0e2cc40..ee063fa 100644
---- a/include/mcld/Support/raw_ostream.h
-+++ b/include/mcld/Support/raw_ostream.h
-@@ -13,6 +13,7 @@
- #endif
- #include <string>
- #include <llvm/Support/raw_ostream.h>
-+#include <llvm/Support/FileSystem.h>
-
- namespace mcld {
-
-@@ -31,7 +32,7 @@ public:
- /// output errors).
- raw_fd_ostream(const char *pFilename,
- std::string &pErrorInfo,
-- llvm::sys::fs::OpenFlags pFlags = llvm::sys::fs::F_None);
-+ unsigned pFlags = 0);
-
- /// raw_fd_ostream ctor - FD is the file descriptor that this writes to. If
- /// ShouldClose is true, this closes the file when the stream is destroyed.
-diff --git a/lib/CodeGen/MCLDTargetMachine.cpp b/lib/CodeGen/MCLDTargetMachine.cpp
-index 964a5be..03bdfa3 100644
---- a/lib/CodeGen/MCLDTargetMachine.cpp
-+++ b/lib/CodeGen/MCLDTargetMachine.cpp
-@@ -125,7 +125,7 @@ static void addPassesToHandleExceptions(llvm::TargetMachine *TM,
- // removed from the parent invoke(s). This could happen when a landing
- // pad is shared by multiple invokes and is also a target of a normal
- // edge from elsewhere.
-- PM.add(createSjLjEHPreparePass(TM));
-+ PM.add(createSjLjEHPreparePass(TM->getTargetLowering()));
- // FALLTHROUGH
- case llvm::ExceptionHandling::DwarfCFI:
- case llvm::ExceptionHandling::ARM:
-@@ -133,7 +133,7 @@ static void addPassesToHandleExceptions(llvm::TargetMachine *TM,
- PM.add(createDwarfEHPass(TM));
- break;
- case llvm::ExceptionHandling::None:
-- PM.add(createLowerInvokePass(TM));
-+ PM.add(createLowerInvokePass(TM->getTargetLowering()));
-
- // The lower invoke pass may create unreachable code. Remove it.
- PM.add(createUnreachableBlockEliminationPass());
-@@ -288,7 +288,7 @@ bool mcld::MCLDTargetMachine::addCompilerPasses(PassManagerBase &pPM,
- MCInstPrinter *InstPrinter =
- m_pLLVMTarget->createMCInstPrinter(MAI.getAssemblerDialect(), MAI,
- MII,
-- *Context->getRegisterInfo(), STI);
-+ Context->getRegisterInfo(), STI);
-
- MCCodeEmitter* MCE = 0;
- MCAsmBackend *MAB = 0;
-diff --git a/lib/Support/ToolOutputFile.cpp b/lib/Support/ToolOutputFile.cpp
-index 2b97f25..70ee997 100644
---- a/lib/Support/ToolOutputFile.cpp
-+++ b/lib/Support/ToolOutputFile.cpp
-@@ -18,6 +18,7 @@
-
- #include <llvm/Support/Signals.h>
- #include <llvm/Support/Path.h>
-+#include <llvm/Support/FileSystem.h>
- #include <llvm/Support/FormattedStream.h>
-
- using namespace mcld;
-@@ -29,7 +30,7 @@ ToolOutputFile::CleanupInstaller::CleanupInstaller(const sys::fs::Path& pPath)
- : Keep(false), m_Path(pPath) {
- // Arrange for the file to be deleted if the process is killed.
- if ("-" != m_Path.native())
-- llvm::sys::RemoveFileOnSignal(m_Path.native());
-+ llvm::sys::RemoveFileOnSignal(llvm::sys::Path(m_Path.native()));
- }
-
- ToolOutputFile::CleanupInstaller::~CleanupInstaller()
-@@ -45,7 +46,7 @@ ToolOutputFile::CleanupInstaller::~CleanupInstaller()
- // Ok, the file is successfully written and closed, or deleted. There's no
- // further need to clean it up on signals.
- if ("_" != m_Path.native())
-- llvm::sys::DontRemoveFileOnSignal(m_Path.native());
-+ llvm::sys::DontRemoveFileOnSignal(llvm::sys::Path(m_Path.native()));
- }
-
- //===----------------------------------------------------------------------===//
-diff --git a/lib/Support/Windows/PathV3.inc b/lib/Support/Windows/PathV3.inc
-index 2f36c93..02a400a 100644
---- a/lib/Support/Windows/PathV3.inc
-+++ b/lib/Support/Windows/PathV3.inc
-@@ -7,6 +7,7 @@
- //
- //===----------------------------------------------------------------------===//
- #include <mcld/Support/Path.h>
-+#include <llvm/Support/ErrorHandling.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <stack>
-diff --git a/lib/Support/raw_ostream.cpp b/lib/Support/raw_ostream.cpp
-index 32e362a..34e37ef 100644
---- a/lib/Support/raw_ostream.cpp
-+++ b/lib/Support/raw_ostream.cpp
-@@ -37,7 +37,7 @@ using namespace mcld;
- //===----------------------------------------------------------------------===//
- mcld::raw_fd_ostream::raw_fd_ostream(const char *pFilename,
- std::string &pErrorInfo,
-- llvm::sys::fs::OpenFlags pFlags)
-+ unsigned pFlags)
- : llvm::raw_fd_ostream(pFilename, pErrorInfo, pFlags),
- m_bConfigColor(false),
- m_bSetColor(false) {
-diff --git a/lib/Target/Mips/MipsELFDynamic.cpp b/lib/Target/Mips/MipsELFDynamic.cpp
-index b532b03..c0822b5 100644
---- a/lib/Target/Mips/MipsELFDynamic.cpp
-+++ b/lib/Target/Mips/MipsELFDynamic.cpp
-@@ -17,6 +17,26 @@
-
- using namespace mcld;
-
-+
-+// MIPS mandatory dynamic section entries
-+enum {
-+ DT_MIPS_RLD_VERSION = 0x70000001,
-+ DT_MIPS_FLAGS = 0x70000005,
-+ DT_MIPS_BASE_ADDRESS = 0x70000006,
-+ DT_MIPS_LOCAL_GOTNO = 0x7000000a,
-+ DT_MIPS_SYMTABNO = 0x70000011,
-+ DT_MIPS_GOTSYM = 0x70000013,
-+ DT_MIPS_PLTGOT = 0x70000032,
-+};
-+
-+// Dynamic section MIPS flags
-+enum {
-+ RHF_NONE = 0x00000000, // None
-+ RHF_QUICKSTART = 0x00000001, // Use shortcut pointers
-+ RHF_NOTPOT = 0x00000002, // Hash size not power of two
-+ RHF_NO_LIBRARY_REPLACEMENT = 0x00000004 // Ignore LD_LIBRARY_PATH
-+};
-+
- MipsELFDynamic::MipsELFDynamic(const MipsGNULDBackend& pParent,
- const LinkerConfig& pConfig)
- : ELFDynamic(pParent, pConfig),
-@@ -30,15 +50,15 @@ void MipsELFDynamic::reserveTargetEntries(const ELFFileFormat& pFormat)
- if (pFormat.hasGOT())
- reserveOne(llvm::ELF::DT_PLTGOT);
-
-- reserveOne(llvm::ELF::DT_MIPS_RLD_VERSION);
-- reserveOne(llvm::ELF::DT_MIPS_FLAGS);
-- reserveOne(llvm::ELF::DT_MIPS_BASE_ADDRESS);
-- reserveOne(llvm::ELF::DT_MIPS_LOCAL_GOTNO);
-- reserveOne(llvm::ELF::DT_MIPS_SYMTABNO);
-- reserveOne(llvm::ELF::DT_MIPS_GOTSYM);
-+ reserveOne(DT_MIPS_RLD_VERSION);
-+ reserveOne(DT_MIPS_FLAGS);
-+ reserveOne(DT_MIPS_BASE_ADDRESS);
-+ reserveOne(DT_MIPS_LOCAL_GOTNO);
-+ reserveOne(DT_MIPS_SYMTABNO);
-+ reserveOne(DT_MIPS_GOTSYM);
-
- if (pFormat.hasGOTPLT())
-- reserveOne(llvm::ELF::DT_MIPS_PLTGOT);
-+ reserveOne(DT_MIPS_PLTGOT);
- }
-
- void MipsELFDynamic::applyTargetEntries(const ELFFileFormat& pFormat)
-@@ -46,15 +66,15 @@ void MipsELFDynamic::applyTargetEntries(const ELFFileFormat& pFormat)
- if (pFormat.hasGOT())
- applyOne(llvm::ELF::DT_PLTGOT, pFormat.getGOT().addr());
-
-- applyOne(llvm::ELF::DT_MIPS_RLD_VERSION, 1);
-- applyOne(llvm::ELF::DT_MIPS_FLAGS, llvm::ELF::RHF_NOTPOT);
-- applyOne(llvm::ELF::DT_MIPS_BASE_ADDRESS, getBaseAddress());
-- applyOne(llvm::ELF::DT_MIPS_LOCAL_GOTNO, getLocalGotNum(pFormat));
-- applyOne(llvm::ELF::DT_MIPS_SYMTABNO, getSymTabNum(pFormat));
-- applyOne(llvm::ELF::DT_MIPS_GOTSYM, getGotSym(pFormat));
-+ applyOne(DT_MIPS_RLD_VERSION, 1);
-+ applyOne(DT_MIPS_FLAGS, RHF_NOTPOT);
-+ applyOne(DT_MIPS_BASE_ADDRESS, getBaseAddress());
-+ applyOne(DT_MIPS_LOCAL_GOTNO, getLocalGotNum(pFormat));
-+ applyOne(DT_MIPS_SYMTABNO, getSymTabNum(pFormat));
-+ applyOne(DT_MIPS_GOTSYM, getGotSym(pFormat));
-
- if (pFormat.hasGOTPLT())
-- applyOne(llvm::ELF::DT_MIPS_PLTGOT, pFormat.getGOTPLT().addr());
-+ applyOne(DT_MIPS_PLTGOT, pFormat.getGOTPLT().addr());
- }
-
- size_t MipsELFDynamic::getSymTabNum(const ELFFileFormat& pFormat) const
---
-1.8.4
-
diff --git a/build/tools/toolchain-patches/mclinker/0002-Fixed-darwin-ld.mcld-GNU-m-emulation-fail.patch b/build/tools/toolchain-patches/mclinker/0001-Fixed-darwin-ld.mcld-GNU-m-emulation-fail.patch
similarity index 83%
rename from build/tools/toolchain-patches/mclinker/0002-Fixed-darwin-ld.mcld-GNU-m-emulation-fail.patch
rename to build/tools/toolchain-patches/mclinker/0001-Fixed-darwin-ld.mcld-GNU-m-emulation-fail.patch
index 5ce03ad..b062599 100644
--- a/build/tools/toolchain-patches/mclinker/0002-Fixed-darwin-ld.mcld-GNU-m-emulation-fail.patch
+++ b/build/tools/toolchain-patches/mclinker/0001-Fixed-darwin-ld.mcld-GNU-m-emulation-fail.patch
@@ -1,19 +1,19 @@
-From 35896d8e00372e9c20ff54c29eb888fb9ffae430 Mon Sep 17 00:00:00 2001
+From db1cf96ebd1c8b8749b4c5b4461aac5af98558ea Mon Sep 17 00:00:00 2001
From: Andrew Hsieh <andrewhsieh@google.com>
-Date: Sun, 22 Sep 2013 12:20:23 +0800
-Subject: [PATCH 2/3] Fixed darwin ld.mcld GNU -m emulation fail
+Date: Tue, 14 Jan 2014 14:45:14 -0800
+Subject: [PATCH 1/3] Fixed darwin ld.mcld GNU -m emulation fail
-Change-Id: Ie0bb6b40687052026b458d4beea35f5a4859a51b
+Change-Id: I95fb07db7b58db94328f24a46f8e6b292c38dd21
---
tools/lite/lib/TripleOptions.cpp | 4 ++--
tools/mcld/main.cpp | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/tools/lite/lib/TripleOptions.cpp b/tools/lite/lib/TripleOptions.cpp
-index 3fbf069..5036e26 100644
+index 20ab3b1..3a20e2b 100644
--- a/tools/lite/lib/TripleOptions.cpp
+++ b/tools/lite/lib/TripleOptions.cpp
-@@ -84,12 +84,12 @@ ParseEmulation(llvm::Triple& pTriple, const std::string& pEmulation)
+@@ -85,12 +85,12 @@ ParseEmulation(llvm::Triple& pTriple, const std::string& pEmulation)
{
llvm::Triple triple = llvm::StringSwitch<llvm::Triple>(pEmulation)
.Case("armelf_linux_eabi", llvm::Triple("arm", "", "linux", "gnueabi"))
@@ -29,10 +29,10 @@
if (triple.getArch() == llvm::Triple::UnknownArch &&
diff --git a/tools/mcld/main.cpp b/tools/mcld/main.cpp
-index aceb0f4..f6a1e5f 100644
+index dcb8140..854aaa9 100644
--- a/tools/mcld/main.cpp
+++ b/tools/mcld/main.cpp
-@@ -1018,12 +1018,12 @@ static Triple ParseEmulation(const std::string& pEmulation)
+@@ -1037,12 +1037,12 @@ static Triple ParseEmulation(const std::string& pEmulation)
{
Triple result = StringSwitch<Triple>(pEmulation)
.Case("armelf_linux_eabi", Triple("arm", "", "linux", "gnueabi"))
@@ -48,5 +48,5 @@
if (result.getArch() == Triple::UnknownArch &&
--
-1.8.4
+1.8.5.2
diff --git a/build/tools/toolchain-patches/mclinker/0002-Compile-only-lite-mclinker.patch b/build/tools/toolchain-patches/mclinker/0002-Compile-only-lite-mclinker.patch
new file mode 100644
index 0000000..b156e39
--- /dev/null
+++ b/build/tools/toolchain-patches/mclinker/0002-Compile-only-lite-mclinker.patch
@@ -0,0 +1,22 @@
+From c2c44f326a82ffab6208edf08f7e4c91610a4607 Mon Sep 17 00:00:00 2001
+From: Andrew Hsieh <andrewhsieh@google.com>
+Date: Tue, 14 Jan 2014 14:45:54 -0800
+Subject: [PATCH 2/3] Compile only "lite" mclinker
+
+Change-Id: I91ccf3a2280bbb0cf56957da1552e7e59052a4b8
+---
+ tools/Makefile.am | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/Makefile.am b/tools/Makefile.am
+index fa91a8b..ebddaf4 100644
+--- a/tools/Makefile.am
++++ b/tools/Makefile.am
+@@ -1,3 +1,3 @@
+ AUTOMAKE_OPTIONS = foreign
+
+-SUBDIRS = lite mcld
++SUBDIRS = lite # mcld
+--
+1.8.5.2
+
diff --git a/build/tools/toolchain-patches/mclinker/0003-Allow-multiple-no-warn-mismatch.patch b/build/tools/toolchain-patches/mclinker/0003-Allow-multiple-no-warn-mismatch.patch
new file mode 100644
index 0000000..470ca1f
--- /dev/null
+++ b/build/tools/toolchain-patches/mclinker/0003-Allow-multiple-no-warn-mismatch.patch
@@ -0,0 +1,38 @@
+From c3f91ccde6e77a4349c7fa0a67a95eebc0151a5c Mon Sep 17 00:00:00 2001
+From: Andrew Hsieh <andrewhsieh@google.com>
+Date: Tue, 14 Jan 2014 14:46:16 -0800
+Subject: [PATCH 3/3] Allow multiple --no-warn-mismatch
+
+Change-Id: I28eba502b7ff63bb5bb994eabe63cf75458ee4b4
+---
+ tools/lite/lib/OutputFormatOptions.cpp | 1 +
+ tools/mcld/main.cpp | 1 +
+ 2 files changed, 2 insertions(+)
+
+diff --git a/tools/lite/lib/OutputFormatOptions.cpp b/tools/lite/lib/OutputFormatOptions.cpp
+index cfc6c04..f2cfb87 100644
+--- a/tools/lite/lib/OutputFormatOptions.cpp
++++ b/tools/lite/lib/OutputFormatOptions.cpp
+@@ -148,6 +148,7 @@ llvm::cl::opt<mcld::GeneralOptions::HashStyle> ArgHashStyle("hash-style",
+ clEnumValEnd));
+
+ llvm::cl::opt<bool> ArgNoWarnMismatch("no-warn-mismatch",
++ llvm::cl::ZeroOrMore,
+ llvm::cl::desc("Allow linking together mismatched input files."),
+ llvm::cl::init(false));
+
+diff --git a/tools/mcld/main.cpp b/tools/mcld/main.cpp
+index 854aaa9..38e2531 100644
+--- a/tools/mcld/main.cpp
++++ b/tools/mcld/main.cpp
+@@ -731,6 +731,7 @@ ArgARMCompatibility("p",
+
+ static cl::opt<bool>
+ ArgNoWarnMismatch("no-warn-mismatch",
++ cl::ZeroOrMore,
+ cl::desc("Allow linking together mismatched input files."),
+ cl::init(false));
+
+--
+1.8.5.2
+
diff --git a/build/tools/toolchain-patches/mclinker/0003-Compile-only-lite-mclinker.patch b/build/tools/toolchain-patches/mclinker/0003-Compile-only-lite-mclinker.patch
deleted file mode 100644
index 543dff0..0000000
--- a/build/tools/toolchain-patches/mclinker/0003-Compile-only-lite-mclinker.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From 07478536239d505e654d88636a6400b3b7fe87b0 Mon Sep 17 00:00:00 2001
-From: Andrew Hsieh <andrewhsieh@google.com>
-Date: Sun, 22 Sep 2013 12:20:51 +0800
-Subject: [PATCH 3/3] Compile only "lite" mclinker
-
-Change-Id: I753730dc983e7b72aa164b2a0f331a63412fde79
----
- tools/Makefile.am | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/tools/Makefile.am b/tools/Makefile.am
-index 1c6bed1..b5c6335 100644
---- a/tools/Makefile.am
-+++ b/tools/Makefile.am
-@@ -1,3 +1,3 @@
- AUTOMAKE_OPTIONS = foreign
-
--SUBDIRS = bcc lite mcld
-+SUBDIRS = lite # bcc mcld
---
-1.8.4
-
diff --git a/build/tools/toolchain-patches/mclinker/0004-ARM-Bypass-R_ARM_V4BX-relocation-now.patch b/build/tools/toolchain-patches/mclinker/0004-ARM-Bypass-R_ARM_V4BX-relocation-now.patch
deleted file mode 100644
index fdc86d2..0000000
--- a/build/tools/toolchain-patches/mclinker/0004-ARM-Bypass-R_ARM_V4BX-relocation-now.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From 7d6b3a763d7dc78eb70a3e4570c4f155f3019b45 Mon Sep 17 00:00:00 2001
-From: Chinyen Chou <petechou@gmail.com>
-Date: Tue, 8 Oct 2013 14:26:48 +0800
-Subject: [PATCH] [ARM] Bypass R_ARM_V4BX relocation now.
-
-Upstream 824a0b515c437abe3e5c59d1e143e9552668e710
-
-Change-Id: I2b04ec08c3660ee8904748a4c306ed49777808a6
----
- lib/Target/ARM/ARMLDBackend.cpp | 6 ++++--
- lib/Target/ARM/ARMRelocationFunctions.h | 2 +-
- 2 files changed, 5 insertions(+), 3 deletions(-)
-
-diff --git a/lib/Target/ARM/ARMLDBackend.cpp b/lib/Target/ARM/ARMLDBackend.cpp
-index 8082426..f159c46 100644
---- a/lib/Target/ARM/ARMLDBackend.cpp
-+++ b/lib/Target/ARM/ARMLDBackend.cpp
-@@ -536,8 +536,7 @@ ARMGNULDBackend::doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished)
- case llvm::ELF::R_ARM_THM_CALL:
- case llvm::ELF::R_ARM_THM_XPC22:
- case llvm::ELF::R_ARM_THM_JUMP24:
-- case llvm::ELF::R_ARM_THM_JUMP19:
-- case llvm::ELF::R_ARM_V4BX: {
-+ case llvm::ELF::R_ARM_THM_JUMP19: {
- // calculate the possible symbol value
- uint64_t sym_value = 0x0;
- LDSymbol* symbol = relocation->symInfo()->outSymbol();
-@@ -576,6 +575,9 @@ ARMGNULDBackend::doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished)
- }
- break;
- }
-+ case llvm::ELF::R_ARM_V4BX:
-+ /* FIXME: bypass R_ARM_V4BX relocation now */
-+ break;
- default:
- break;
- } // end of switch
-diff --git a/lib/Target/ARM/ARMRelocationFunctions.h b/lib/Target/ARM/ARMRelocationFunctions.h
-index 94df077..364815b 100644
---- a/lib/Target/ARM/ARMRelocationFunctions.h
-+++ b/lib/Target/ARM/ARMRelocationFunctions.h
-@@ -77,7 +77,7 @@ DECL_ARM_APPLY_RELOC_FUNC(unsupport)
- { &unsupport, 37, "R_ARM_ALU_SBREL_27_20_CK"}, \
- { &abs32, 38, "R_ARM_TARGET1" }, \
- { &unsupport, 39, "R_ARM_SBREL31" }, \
-- { &unsupport, 40, "R_ARM_V4BX" }, \
-+ { &none, 40, "R_ARM_V4BX" }, \
- { &got_prel, 41, "R_ARM_TARGET2" }, \
- { &prel31, 42, "R_ARM_PREL31" }, \
- { &movw_abs_nc, 43, "R_ARM_MOVW_ABS_NC" }, \
---
-1.8.4
-
diff --git a/build/tools/toolchain-patches/mclinker/0005-add-no-warn-mismatch-option-support.patch b/build/tools/toolchain-patches/mclinker/0005-add-no-warn-mismatch-option-support.patch
deleted file mode 100644
index 3c34d59..0000000
--- a/build/tools/toolchain-patches/mclinker/0005-add-no-warn-mismatch-option-support.patch
+++ /dev/null
@@ -1,141 +0,0 @@
-commit 69dc7d5ef1c74a60b9391441924f7a25078457a6
-Author: Chinyen Chou <petechou@gmail.com>
-Date: Mon Oct 21 14:29:15 2013 +0800
-
- [Linker Option] Add --no-warn-mismatch option support.
-
-diff --git a/include/mcld/GeneralOptions.h b/include/mcld/GeneralOptions.h
-index 46a1e57..60487c0 100644
---- a/include/mcld/GeneralOptions.h
-+++ b/include/mcld/GeneralOptions.h
-@@ -274,6 +274,12 @@ public:
- bool printMap() const
- { return m_bPrintMap; }
-
-+ void setWarnMismatch(bool pEnable = true)
-+ { m_bWarnMismatch = pEnable; }
-+
-+ bool warnMismatch() const
-+ { return m_bWarnMismatch; }
-+
- // -G, max GP size option
- void setGPSize(int gpsize)
- { m_GPSize = gpsize; }
-@@ -371,6 +377,7 @@ private:
- bool m_bNewDTags: 1; // --enable-new-dtags
- bool m_bNoStdlib: 1; // -nostdlib
- bool m_bPrintMap: 1; // --print-map
-+ bool m_bWarnMismatch: 1; // --no-warn-mismatch
- uint32_t m_GPSize; // -G, --gpsize
- StripSymbolMode m_StripSymbols;
- RpathList m_RpathList;
-diff --git a/lib/Core/GeneralOptions.cpp b/lib/Core/GeneralOptions.cpp
-index c0196e5..b4c1f22 100644
---- a/lib/Core/GeneralOptions.cpp
-+++ b/lib/Core/GeneralOptions.cpp
-@@ -53,6 +53,7 @@ GeneralOptions::GeneralOptions()
- m_bFatalWarnings(false),
- m_bNewDTags(false),
- m_bNoStdlib(false),
-+ m_bWarnMismatch(true),
- m_GPSize(8),
- m_StripSymbols(KeepAllSymbols),
- m_HashStyle(SystemV) {
-diff --git a/lib/Object/ObjectLinker.cpp b/lib/Object/ObjectLinker.cpp
-index 67fd1d5..1becc30 100644
---- a/lib/Object/ObjectLinker.cpp
-+++ b/lib/Object/ObjectLinker.cpp
-@@ -185,8 +185,9 @@ void ObjectLinker::normalize()
- }
- }
- else {
-- warning(diag::warn_unrecognized_input_file) << (*input)->path()
-- << m_Config.targets().triple().str();
-+ if (m_Config.options().warnMismatch())
-+ warning(diag::warn_unrecognized_input_file) << (*input)->path()
-+ << m_Config.targets().triple().str();
- }
- } // end of for
- }
-diff --git a/tools/lite/include/lite/OutputFormatOptions.h b/tools/lite/include/lite/OutputFormatOptions.h
-index 99ce54e..c9982d5 100644
---- a/tools/lite/include/lite/OutputFormatOptions.h
-+++ b/tools/lite/include/lite/OutputFormatOptions.h
-@@ -51,6 +51,8 @@ private:
- llvm::cl::opt<bool>& m_ExportDynamic;
- llvm::cl::opt<std::string>& m_BuildID;
- llvm::cl::list<std::string>& m_ExcludeLIBS;
-+
-+ llvm::cl::opt<bool>& m_NoWarnMismatch;
- };
-
- } // namespace of mcld
-diff --git a/tools/lite/lib/OutputFormatOptions.cpp b/tools/lite/lib/OutputFormatOptions.cpp
-index 7ee8248..cfc6c04 100644
---- a/tools/lite/lib/OutputFormatOptions.cpp
-+++ b/tools/lite/lib/OutputFormatOptions.cpp
-@@ -147,6 +147,10 @@ llvm::cl::opt<mcld::GeneralOptions::HashStyle> ArgHashStyle("hash-style",
- "both the classic ELF and new style GNU hash tables"),
- clEnumValEnd));
-
-+llvm::cl::opt<bool> ArgNoWarnMismatch("no-warn-mismatch",
-+ llvm::cl::desc("Allow linking together mismatched input files."),
-+ llvm::cl::init(false));
-+
- // Not supported yet {
- llvm::cl::opt<bool> ArgExportDynamic("export-dynamic",
- llvm::cl::desc("Export all dynamic symbols"),
-@@ -193,7 +197,8 @@ OutputFormatOptions::OutputFormatOptions()
- m_HashStyle(ArgHashStyle),
- m_ExportDynamic(ArgExportDynamic),
- m_BuildID(ArgBuildID),
-- m_ExcludeLIBS(ArgExcludeLIBS) {
-+ m_ExcludeLIBS(ArgExcludeLIBS),
-+ m_NoWarnMismatch(ArgNoWarnMismatch) {
- }
-
- bool OutputFormatOptions::parse(mcld::Module& pModule, LinkerConfig& pConfig)
-@@ -222,6 +227,10 @@ bool OutputFormatOptions::parse(mcld::Module& pModule, LinkerConfig& pConfig)
- pConfig.options().setOMagic(m_OMagic);
- pConfig.options().setHashStyle(m_HashStyle);
- pConfig.options().setExportDynamic(m_ExportDynamic);
-+ if (m_NoWarnMismatch)
-+ pConfig.options().setWarnMismatch(false);
-+ else
-+ pConfig.options().setWarnMismatch(true);
- // build-id
- // exclude-libs
-
-diff --git a/tools/mcld/main.cpp b/tools/mcld/main.cpp
-index aceb0f4..3fc1a7b 100644
---- a/tools/mcld/main.cpp
-+++ b/tools/mcld/main.cpp
-@@ -707,13 +707,14 @@ ArgARMCompatibility("p",
- cl::desc("Ignore for ARM backward compatibility"),
- cl::init(false));
-
-+/// @{
-+/// @name FIXME: end of unsupported options
-+/// @}
-+
- static cl::opt<bool>
- ArgNoWarnMismatch("no-warn-mismatch",
- cl::desc("Allow linking together mismatched input files."),
- cl::init(false));
--/// @{
--/// @name FIXME: end of unsupported options
--/// @}
-
- static cl::opt<bool>
- ArgNoStdlib("nostdlib",
-@@ -1144,6 +1145,10 @@ static bool ProcessLinkerOptionsFromCommand(mcld::LinkerScript& pScript,
- pConfig.options().setNoStdlib(ArgNoStdlib);
- pConfig.options().setPrintMap(ArgPrintMap);
- pConfig.options().setGPSize(ArgGPSize);
-+ if (ArgNoWarnMismatch)
-+ pConfig.options().setWarnMismatch(false);
-+ else
-+ pConfig.options().setWarnMismatch(true);
-
- if (ArgStripAll)
- pConfig.options().setStripSymbols(mcld::GeneralOptions::StripAllSymbols);
diff --git a/docs/text/ANDROID-MK.text b/docs/text/ANDROID-MK.text
index 8c9684f..ffe8247 100644
--- a/docs/text/ANDROID-MK.text
+++ b/docs/text/ANDROID-MK.text
@@ -774,8 +774,13 @@
> that are provided by module 'foo'.
- - - -
+LOCAL_EXPORT_LDFLAGS
+> Same as LOCAL_EXPORT_CFLAGS, but for linker flags.
+
+- - - -
LOCAL_EXPORT_LDLIBS
-> Same as LOCAL_EXPORT_CFLAGS, but for linker flags. Note that the
+> Same as LOCAL_EXPORT_CFLAGS, but for passing the name of specific
+> system libraries with the '`-l`' prefix. Note that the
> imported linker flags will be appended to your module's LOCAL_LDLIBS
> though, due to the way Unix linkers work.
>
diff --git a/docs/text/CHANGES.text b/docs/text/CHANGES.text
index 1e5c693..9165936 100644
--- a/docs/text/CHANGES.text
+++ b/docs/text/CHANGES.text
@@ -1,6 +1,94 @@
Android NDK ChangeLog:
----------------------------------------------------------------------------
+android-ndk-r9c
+===
+
+IMPORTANT CHANGES:
+---
+
+- This is a bug-fix-only release.
+
+
+IMPORTANT BUG FIXES:
+---
+
+- Fixed GCC 4.8 ARM where stack pointer is restored too early than access
+ to varaible in stack frame via frame pointer.
+ See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58854
+
+- Fixed GCC 4.8 libstdc++ where the generated code random segfault on std::nth_element
+ See https://code.google.com/p/android/issues/detail?id=62910
+
+- Fixed GCC 4.8 ICE in cc1/cc1plus with -fuse-ld=mcld. Message reads:
+> cc1: internal compiler error: in common_handle_option, at opts.c:1774
+
+- Fixed -mhard-float support for __builtin math functions.
+ See http://b.android.com/62496. Please track comment of http://b.android.com/61784
+ for on-going fixes for -mhard-float with STL
+
+
+OTHER BUG FIXES:
+---
+
+- Fixed headers
+> 1. Fixed prototype of poll to poll(struct pollfd *, nfds_t, int); in poll.h
+> 2. Added utimensat and futimens to libc.so to API level >=12 and >=19, respectively.
+> 3. Added missing clock_settime() and clock_nanosleep() in time.h for API>=8.
+> 4. Added CLOCK_MONOTONIC_RAW, CLOCK_REALTIME_COARSE, CLOCK_MONOTONIC_COARSE,
+ CLOCK_BOOTTIME, CLOCK_REALTIME_ALARM, and CLOCK_BOOTTIME_ALARM in time.h.
+ Removed obsolete CLOCK_REALTIME_HR and CLOCK_MONOTONIC_HR.
+
+- Refactored samples Teapot, MoreTeapots and source/android/ndk_helper.
+ Use hard float-abi for armeabi-v7a, added immersive mode in android-19, etc.
+ Also fix crash on X86 device in /system/lib/libdvm.so Check_ReleaseStringUTFChars
+
+- Fixed ndk-build fails in cygwin if NDK package is referenced via symlink
+
+- Fixed ndk-build.cmd fails in windows cmd.exe if LOCAL_SRC_FILES
+ contain absolute path.
+ See https://android-review.googlesource.com/#/c/69992
+
+- Fixed ndk-stack to proceed even when it can't parse a frame due to
+ unable to locate routine, filename, or line number, in which case "??"
+ is printed.
+
+- Fixed ndk-stack windows-x64_64 erroneously matches frame line with in "stack:"
+ section even when the line has no word "pc", "eip", or "ip" in it, eg.
+> I/DEBUG ( 1151): #00 5f09db68 401f01c4 /system/lib/libc.so
+
+- Fixed gabi++ to not use malloc() to allocate C++ thread-local
+ objects, and avoid dead-lock in gabi++ when libc.debug.malloc is non-zero in
+ userdebug/eng Android platform builds
+
+
+OTHER CHANGES:
+---
+
+- Added LOCAL_EXPORT_LDFLAGS
+
+- Introducing NDK_PROJECT_PATH=null for use in an integrated build system
+ where options are explicitly passed to ndk-build. With it ndk-build
+ make no attempt to look for NDK_PROJECT_PATH, and as a result the following
+ variables depending on NDK_PROJECT_PATH to be explicitly specified
+ (since they can on longer derive default value from NDK_PROJECT_PATH when it's null):
+ NDK_OUT, NDK_LIBS_OUT, APP_BUILD_SCRIPT, NDK_DEBUG (optional, default to 0),
+ and other APP_* used to be in Application.mk
+
+- Allow APP_ABI to be comma-delimited list, eg. APP_ABI := "armeabi,armeabi-v7a"
+
+- Rebuild all STL with debugging info (ie. "-g") in separate optional package
+ android-ndk-r9c-cxx-stl-libs-with-debugging-info.zip.
+ This helps ndk-stack to provide better stack dump across STL.
+ The code/size of the final stripped shouldn't be affected.
+
+- Enhanced hello-jni samples to report APP_ABI at compilation
+
+- Static libraries are built with Deterministic (option D) mode of ar
+ tool. See http://b.android.com/60705
+
+
+----------------------------------------------------------------------------
android-ndk-r9b
===
@@ -87,7 +175,7 @@
- Fixed cpu-features not to assume all VFPv4 devices support IDIV.
Now it only adds IDIV to white-listed devices (Nexus 4 at this moment)
- b.android.com/57637
+ http://b.android.com/57637
- Fixed android_native_app_glue.c to stop errors being logged erroneously on event predispatch
diff --git a/docs/text/CPU-ARCH-ABIS.text b/docs/text/CPU-ARCH-ABIS.text
index 2abb27e..3b7d9a0 100644
--- a/docs/text/CPU-ARCH-ABIS.text
+++ b/docs/text/CPU-ARCH-ABIS.text
@@ -110,14 +110,18 @@
building NEON-capable machine code too.
IMPORTANT NOTE: This ABI enforces that all double values are passed during
- function calls in 'core' register pairs, instead of dedicated FP ones.
- However, all internal computations can be performed with the FP registers
- and will be greatly sped up.
+ function calls in 'core' register pairs, instead of dedicated FP ones, via
+ switch -mfloat-abi=softfp. However, all internal computations can be performed
+ with the FP registers and will be greatly sped up.
This little constraint, while resulting in a slight decrease of
performance, ensures binary compatibility with all existing 'armeabi'
binaries.
+ Starting from r9b, it's possible to compile code in -mhard-float and still link
+ with Android native APIs which follow softfp. Please see
+ tests/device/hard-float/jni/Android.mk for details
+
IMPORTANT NOTE: The 'armeabi-v7a' machine code will *not* run on ARMv5 or
ARMv6 based devices.
@@ -286,6 +290,11 @@
lib/x86/libfoo.so
lib/mips/libfoo.so
+IMPORTANT NOTE: ARMv7-based Android device running 4.0.3 or before installs native
+library from the 'armeabi' directory instead of 'armeabi-v7a' directory if both
+exist and 'lib/armeabi' is listed after 'lib/armeabi-v7a' in apk. This issue is
+fixed in 4.0.4 or later.
+
III.2. Android Platform ABI support:
------------------------------------
diff --git a/docs/text/DEVELOPMENT.text b/docs/text/DEVELOPMENT.text
index 7e1fd4d..fbc1b54 100644
--- a/docs/text/DEVELOPMENT.text
+++ b/docs/text/DEVELOPMENT.text
@@ -30,14 +30,14 @@
You need to do that once if you want to use the content of $NDK to build
samples, tests or anything else:
- $NDK/build/tools/build-platforms.sh
+ $NDK/build/tools/gen-platforms.sh
What the script does is populate the $NDK/platforms and $NDK/samples
directories from the content of development/ndk.
What is under development/ndk is segregated by API level. This makes it
easier to add a new platform to the tree, but is not well-suited to building
-stuff. The build-platforms.sh script will gather all files appropriately
+stuff. The gen-platforms.sh script will gather all files appropriately
and place the result inside $NDK/platforms and $NDK/samples.
Note: These directories are listed by $NDK/.gitignore, so they won't appear
diff --git a/find-win-host.cmd b/find-win-host.cmd
old mode 100644
new mode 100755
diff --git a/ndk-build b/ndk-build
index 95520f5..62d6dc8 100755
--- a/ndk-build
+++ b/ndk-build
@@ -38,7 +38,7 @@
# ./ndk-build -C <project-path>
#
PROGDIR=`dirname $0`
-PROGDIR=`cd $PROGDIR && pwd`
+PROGDIR=`cd $PROGDIR && pwd -P`
# Check if absolute NDK path contain space
#
diff --git a/ndk-build.cmd b/ndk-build.cmd
old mode 100644
new mode 100755
diff --git a/ndk-gdb b/ndk-gdb
index 2faa7df..1bb4234 100755
--- a/ndk-gdb
+++ b/ndk-gdb
@@ -25,7 +25,7 @@
# after doing ndk-build && ant install && <start-application-on-device>
#
PROGDIR=`dirname $0`
-PROGDIR=`cd $PROGDIR && pwd`
+PROGDIR=`cd $PROGDIR && pwd -P`
# Check if absolute NDK path contain space
#
@@ -35,6 +35,8 @@
;;
esac
+NDK_BUILDTOOLS_PATH=$PROGDIR/build/tools
+. $PROGDIR/build/tools/prebuilt-common.sh
. $PROGDIR/build/tools/ndk-common.sh
force_32bit_binaries
@@ -79,6 +81,8 @@
DEBUG_PORT=5039
JDB_PORT=65534
+UNKNOWN_ABI=$(find_ndk_unknown_archs)
+
# Delay in seconds between launching the activity and attaching gdbserver on it.
# This is needed because there is no way to know when the activity has really
# started, and sometimes this takes a few seconds.
@@ -502,6 +506,8 @@
APP_ABIS_BACK="${APP_ABIS#*all}"
APP_ABIS="${APP_ABIS_FRONT}${ALL_ABIS}${APP_ABIS_BACK}"
fi
+# replace "armeabi-v7a-hard" with "armeabi-v7a"
+APP_ABIS=`echo $APP_ABIS | sed -e 's/armeabi-v7a-hard/armeabi-v7a/g'`
log "ABIs targetted by application: $APP_ABIS"
# Check the ADB command, and that we can connect to the device/emulator
@@ -544,13 +550,18 @@
log "Device CPU ABIs: $CPU_ABIS"
APP_ABIS=$APP_ABIS" "
-for CPU_ABI in $CPU_ABIS; do
- if [ "$APP_ABIS" != "${APP_ABIS%$CPU_ABI *}" ] ; then
- COMPAT_ABI=$CPU_ABI
- break
- fi
-done
+adb_var_shell BCFILES run-as $PACKAGE_NAME /system/bin/sh -c "ls lib/*.bc"
+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
+fi
if [ "$COMPAT_ABI" = none ] ; then
echo "ERROR: The device does not support the application's targetted CPU ABIs!"
echo " Device supports: $CPU_ABIS"
@@ -563,7 +574,13 @@
GDBSETUP_INIT=`get_build_var_for_abi NDK_APP_GDBSETUP $COMPAT_ABI`
log "Using gdb setup init: $GDBSETUP_INIT"
-TOOLCHAIN_PREFIX=`get_build_var_for_abi TOOLCHAIN_PREFIX $COMPAT_ABI`
+# Find the prefix for gdb-client
+if [ "$COMPAT_ABI" != "$UNKNOWN_ABI" ]; then
+ TOOLCHAIN_PREFIX=`get_build_var_for_abi TOOLCHAIN_PREFIX $COMPAT_ABI`
+else
+ TOOLCHAIN_ABI=$(echo $CPU_ABIS | awk '{print $NF}')
+ TOOLCHAIN_PREFIX=`get_build_var_for_abi TOOLCHAIN_PREFIX $TOOLCHAIN_ABI`
+fi
log "Using toolchain prefix: $TOOLCHAIN_PREFIX"
APP_OUT=`get_build_var_for_abi TARGET_OUT $COMPAT_ABI`
@@ -573,11 +590,11 @@
DEBUGGABLE=`run_awk_manifest_script extract-debuggable.awk`
log "Found debuggable flag: $DEBUGGABLE"
if [ $? != 0 -o "$DEBUGGABLE" != "true" ] ; then
- # If gdbserver exists, then we built with 'ndk-build NDK_DEBUG=1' and it's
+ # If gdb.setup exists, then we built with 'ndk-build NDK_DEBUG=1' and it's
# ok to not have android:debuggable set to true in the original manifest.
# However, if this is not the case, then complain!!
- if [ -f $PROJECT/libs/$COMPAT_ABI/gdbserver ] ; then
- log "Found gdbserver under libs/$COMPAT_ABI, assuming app was built with NDK_DEBUG=1"
+ if [ -f $PROJECT/libs/$COMPAT_ABI/gdb.setup ] ; then
+ log "Found gdb.setup under libs/$COMPAT_ABI, assuming app was built with NDK_DEBUG=1"
else
echo "ERROR: Package $PACKAGE_NAME is not debuggable ! You can fix that in two ways:"
echo ""
@@ -592,8 +609,8 @@
else
# DEBUGGABLE is true in the manifest. Let's check that the user didn't change the
# debuggable flag in the manifest without calling ndk-build afterwards.
- if [ ! -f $PROJECT/libs/$COMPAT_ABI/gdbserver ] ; then
- echo "ERROR: Could not find gdbserver binary under $PROJECT/libs/$COMPAT_ABI"
+ if [ ! -f $PROJECT/libs/$COMPAT_ABI/gdb.setup ] ; then
+ echo "ERROR: Could not find gdb.setup under $PROJECT/libs/$COMPAT_ABI"
echo " This usually means you modified your AndroidManifest.xml to set"
echo " the android:debuggable flag to 'true' but did not rebuild the"
echo " native binaries. Please call 'ndk-build' to do so,"
@@ -602,17 +619,6 @@
fi
fi
-# Let's check that 'gdbserver' is properly installed on the device too. If this
-# is not the case, the user didn't install the proper package after rebuilding.
-#
-adb_var_shell2 DEVICE_GDBSERVER ls /data/data/$PACKAGE_NAME/lib/gdbserver
-if [ $? != 0 ]; then
- echo "ERROR: Non-debuggable application installed on the target device."
- echo " Please re-install the debuggable version!"
- exit 1
-fi
-log "Found device gdbserver: $DEVICE_GDBSERVER"
-
# Find the <dataDir> of the package on the device
adb_var_shell2 DATA_DIR run-as $PACKAGE_NAME /system/bin/sh -c pwd
if [ $? != 0 -o -z "$DATA_DIR" ] ; then
@@ -622,6 +628,39 @@
fi
log "Found data directory: '$DATA_DIR'"
+# Let's check that 'gdbserver' is properly installed on the device too. If 'gdbserver'
+# is not there, push 'gdbserver' found in prebuilt.
+#
+DEVICE_GDBSERVER=$DATA_DIR/lib/gdbserver
+adb_var_shell2 GDBSERVER_RESULT ls $DEVICE_GDBSERVER
+if [ $? != 0 ]; then
+
+ # Figure out what's the target-arch and find gdbserver in prebuilt.
+ 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
+ TARGET_ARCH=$ANDROID_ARCH
+ break;
+ fi
+ done
+
+ if [ $TARGET_ARCH != "none" ]; then
+ DEVICE_GDBSERVER=/data/local/tmp/gdbserver
+
+ adb shell mkdir -p /data/local/tmp
+ adb push ${ANDROID_NDK_ROOT}/prebuilt/android-${TARGET_ARCH}/gdbserver/gdbserver \
+ $DEVICE_GDBSERVER
+ log "Push gdbserver in device"
+ else
+ echo "ERROR: Non-debuggable application installed on the target device."
+ echo " Please re-install the debuggable version!"
+ exit 1
+ fi
+fi
+log "Found device gdbserver: $DEVICE_GDBSERVER"
+
# Launch the activity if needed
if [ "$OPTION_START" = "yes" ] ; then
# If --launch is used, ignore --start, otherwise extract the first
@@ -689,7 +728,7 @@
# Launch gdbserver now
DEBUG_SOCKET=debug-socket
-run adb_cmd shell run-as $PACKAGE_NAME lib/gdbserver +$DEBUG_SOCKET --attach $PID &
+run adb_cmd shell run-as $PACKAGE_NAME $DEVICE_GDBSERVER +$DEBUG_SOCKET --attach $PID &
if [ $? != 0 ] ; then
echo "ERROR: Could not launch gdbserver on the device?"
exit 1
@@ -727,6 +766,15 @@
fi
fi
+# If we are debugging UNKNOWN_ABI, download compiled *.so from device.
+#
+if [ $COMPAT_ABI == $UNKNOWN_ABI ]; then
+ for bc in $BCFILES; do
+ log "Pulled $(basename $bc .bc).so from device/emulator."
+ adb pull $DATA_DIR/lib/$(basename $bc .bc).so $PROJECT/obj/local/$UNKNOWN_ABI/
+ done
+fi
+
# Now launch the appropriate gdb client with the right init commands
#
GDBCLIENT=${TOOLCHAIN_PREFIX}gdb
diff --git a/ndk-gdb-py b/ndk-gdb-py
index 11643d4..b2001b8 100755
--- a/ndk-gdb-py
+++ b/ndk-gdb-py
@@ -1,7 +1,7 @@
#!/bin/sh
PROGDIR=`dirname $0`
-PROGDIR=`cd $PROGDIR && pwd`
+PROGDIR=`cd $PROGDIR && pwd -P`
# Check if absolute NDK path contain space
#
diff --git a/ndk-gdb-py.cmd b/ndk-gdb-py.cmd
old mode 100644
new mode 100755
index 07065e4..265ca55
--- a/ndk-gdb-py.cmd
+++ b/ndk-gdb-py.cmd
@@ -2,5 +2,8 @@
rem This is a Windows cmd.exe script used to invoke the NDK-specific Python executable
call "%~dp0find-win-host.cmd" NDK_WIN_HOST
if ERRORLEVEL 1 (exit /b 1)
+setlocal
set NDK_ROOT=%~dp0
-"%NDK_ROOT%prebuilt/%NDK_WIN_HOST%/bin/python.exe" -u "%~dp0ndk-gdb.py" SHELL=cmd %*
+set SHELL=cmd
+"%NDK_ROOT%prebuilt/%NDK_WIN_HOST%/bin/python.exe" -u "%~dp0ndk-gdb.py" %*
+endlocal
diff --git a/ndk-gdb.py b/ndk-gdb.py
index 5f3b35b..37a3073 100755
--- a/ndk-gdb.py
+++ b/ndk-gdb.py
@@ -215,9 +215,12 @@
help='Do not wait for debugger to attach (may miss early JNI breakpoints)',
action='store_true', dest='nowait')
- stdcxx_pypr_versions = [ 'gnustdcxx'+d.replace('gcc','')
- for d in os.listdir(PYPRPR_GNUSTDCXX_BASE)
- if os.path.isdir(os.path.join(PYPRPR_GNUSTDCXX_BASE, d)) ]
+ if os.path.isdir(PYPRPR_GNUSTDCXX_BASE):
+ stdcxx_pypr_versions = [ 'gnustdcxx'+d.replace('gcc','')
+ for d in os.listdir(PYPRPR_GNUSTDCXX_BASE)
+ if os.path.isdir(os.path.join(PYPRPR_GNUSTDCXX_BASE, d)) ]
+ else:
+ stdcxx_pypr_versions = []
parser.add_argument( '--stdcxx-py-pr',
help='Specify stdcxx python pretty-printer',
diff --git a/sources/android/cpufeatures/cpu-features.c b/sources/android/cpufeatures/cpu-features.c
index 7ab1730..ea5d40c 100644
--- a/sources/android/cpufeatures/cpu-features.c
+++ b/sources/android/cpufeatures/cpu-features.c
@@ -556,6 +556,12 @@
g_cpuFamily = ANDROID_CPU_FAMILY_X86;
#elif defined(__mips__)
g_cpuFamily = ANDROID_CPU_FAMILY_MIPS;
+#elif defined(__aarch64__)
+ g_cpuFamily = ANDROID_CPU_FAMILY_ARM64;
+#elif defined(__x86_64__)
+ g_cpuFamily = ANDROID_CPU_FAMILY_X86_64;
+#elif defined(__mips64)
+ g_cpuFamily = ANDROID_CPU_FAMILY_MIPS64;
#else
g_cpuFamily = ANDROID_CPU_FAMILY_UNKNOWN;
#endif
diff --git a/sources/android/cpufeatures/cpu-features.h b/sources/android/cpufeatures/cpu-features.h
index 0beef3f..97ebd62 100644
--- a/sources/android/cpufeatures/cpu-features.h
+++ b/sources/android/cpufeatures/cpu-features.h
@@ -38,6 +38,9 @@
ANDROID_CPU_FAMILY_ARM,
ANDROID_CPU_FAMILY_X86,
ANDROID_CPU_FAMILY_MIPS,
+ ANDROID_CPU_FAMILY_ARM64,
+ ANDROID_CPU_FAMILY_X86_64,
+ ANDROID_CPU_FAMILY_MIPS64,
ANDROID_CPU_FAMILY_MAX /* do not remove */
diff --git a/sources/android/crazy_linker/src/elf_traits.h b/sources/android/crazy_linker/src/elf_traits.h
index afd69da..166cdb1 100644
--- a/sources/android/crazy_linker/src/elf_traits.h
+++ b/sources/android/crazy_linker/src/elf_traits.h
@@ -8,7 +8,6 @@
// NOTE: <stdint.h> is required here before <elf.h>. This is a NDK header bug.
#include <stdint.h>
#include <elf.h>
-#include <sys/exec_elf.h>
// ELF is a traits structure used to provide convenient aliases for
// 32/64 bit Elf types, depending on the target CPU bitness.
diff --git a/sources/android/libthread_db/gdb-6.6/libthread_db.c b/sources/android/libthread_db/gdb-6.6/libthread_db.c
index 6939780..64d7256 100644
--- a/sources/android/libthread_db/gdb-6.6/libthread_db.c
+++ b/sources/android/libthread_db/gdb-6.6/libthread_db.c
@@ -215,10 +215,8 @@
static int
_event_getmsg_helper(td_thrhandle_t const * handle, void * bkpt_addr)
{
- void * pc;
-
- pc = (void *)ptrace(PTRACE_PEEKUSR, handle->tid, (void *)60 /* r15/pc */, NULL);
-
+#if defined(__arm__)
+ void* pc = (void *)ptrace(PTRACE_PEEKUSR, handle->tid, (void *)60 /* r15/pc */, NULL);
if (pc == bkpt_addr) {
// The hook function takes the id of the new thread as it's first param,
// so grab it from r0.
@@ -226,6 +224,31 @@
gEventMsgHandle.tid = gEventMsgHandle.pid;
return 0x42;
}
+#elif defined(__i386__)
+ // Get the eip from offset 12*4 = 48 as defined in the struct
+ // user_regs_struct in user_32.h
+ void* pc = (void *)ptrace(PTRACE_PEEKUSR, handle->tid, (void *)48 /* eip */, NULL);
+ // FIXME - pc is a non-decremented breakpoint address, hence the
+ // addition of 1 on test. This seems to work for the thread hook
+ // function in libc.so but should be properly fixed.
+ if (pc == ((int)bkpt_addr + 1)) {
+ // The hook function takes the id of the new thread as it's first
+ // param, so grab it from ecx at offset 4 in struct user_regs_struct
+ // (using fastcall convention for x86)
+ gEventMsgHandle.pid = ptrace(PTRACE_PEEKUSR, handle->tid, (void *)4 /* ecx */, NULL);
+ gEventMsgHandle.tid = gEventMsgHandle.pid;
+ return 0x42;
+ }
+#elif defined(__mips__)
+ void* pc = (void *)ptrace(PTRACE_PEEKUSR, handle->tid, (void *)(64*4) /* pc */, NULL);
+ if (pc == bkpt_addr) {
+ // The hook function takes the id of the new thread as it's first param,
+ // so grab it from a0
+ gEventMsgHandle.pid = ptrace(PTRACE_PEEKUSR, handle->tid, (void *)(4*4) /* a0 */, NULL);
+ gEventMsgHandle.tid = gEventMsgHandle.pid;
+ return 0x42;
+ }
+#endif
return 0;
}
diff --git a/sources/android/libthread_db/gdb-7.3.x/libthread_db.c b/sources/android/libthread_db/gdb-7.3.x/libthread_db.c
index 6d57f01..864f426 100644
--- a/sources/android/libthread_db/gdb-7.3.x/libthread_db.c
+++ b/sources/android/libthread_db/gdb-7.3.x/libthread_db.c
@@ -226,10 +226,8 @@
static int
_event_getmsg_helper(td_thrhandle_t const * handle, void * bkpt_addr)
{
- void * pc;
-
- pc = (void *)ptrace(PTRACE_PEEKUSR, handle->tid, (void *)60 /* r15/pc */, NULL);
-
+#if defined(__arm__)
+ void* pc = (void *)ptrace(PTRACE_PEEKUSR, handle->tid, (void *)60 /* r15/pc */, NULL);
if (pc == bkpt_addr) {
// The hook function takes the id of the new thread as it's first param,
// so grab it from r0.
@@ -237,6 +235,31 @@
gEventMsgHandle.tid = gEventMsgHandle.pid;
return 0x42;
}
+#elif defined(__i386__)
+ // Get the eip from offset 12*4 = 48 as defined in the struct
+ // user_regs_struct in user_32.h
+ void* pc = (void *)ptrace(PTRACE_PEEKUSR, handle->tid, (void *)48 /* eip */, NULL);
+ // FIXME - pc is a non-decremented breakpoint address, hence the
+ // addition of 1 on test. This seems to work for the thread hook
+ // function in libc.so but should be properly fixed.
+ if (pc == ((int)bkpt_addr + 1)) {
+ // The hook function takes the id of the new thread as it's first
+ // param, so grab it from ecx at offset 4 in struct user_regs_struct
+ // (using fastcall convention for x86)
+ gEventMsgHandle.pid = ptrace(PTRACE_PEEKUSR, handle->tid, (void *)4 /* ecx */, NULL);
+ gEventMsgHandle.tid = gEventMsgHandle.pid;
+ return 0x42;
+ }
+#elif defined(__mips__)
+ void* pc = (void *)ptrace(PTRACE_PEEKUSR, handle->tid, (void *)(64*4) /* pc */, NULL);
+ if (pc == bkpt_addr) {
+ // The hook function takes the id of the new thread as it's first param,
+ // so grab it from a0
+ gEventMsgHandle.pid = ptrace(PTRACE_PEEKUSR, handle->tid, (void *)(4*4) /* a0 */, NULL);
+ gEventMsgHandle.tid = gEventMsgHandle.pid;
+ return 0x42;
+ }
+#endif
return 0;
}
diff --git a/sources/android/libthread_db/gdb-7.6/libthread_db.c b/sources/android/libthread_db/gdb-7.6/libthread_db.c
index 9c95a07..a25ce87 100644
--- a/sources/android/libthread_db/gdb-7.6/libthread_db.c
+++ b/sources/android/libthread_db/gdb-7.6/libthread_db.c
@@ -239,10 +239,8 @@
static int
_event_getmsg_helper(td_thrhandle_t const * handle, void * bkpt_addr)
{
- void * pc;
-
- pc = (void *)ptrace(PTRACE_PEEKUSR, handle->tid, (void *)60 /* r15/pc */, NULL);
-
+#if defined(__arm__)
+ void* pc = (void *)ptrace(PTRACE_PEEKUSR, handle->tid, (void *)60 /* r15/pc */, NULL);
if (pc == bkpt_addr) {
// The hook function takes the id of the new thread as it's first param,
// so grab it from r0.
@@ -250,6 +248,31 @@
gEventMsgHandle.tid = gEventMsgHandle.pid;
return 0x42;
}
+#elif defined(__i386__)
+ // Get the eip from offset 12*4 = 48 as defined in the struct
+ // user_regs_struct in user_32.h
+ void* pc = (void *)ptrace(PTRACE_PEEKUSR, handle->tid, (void *)48 /* eip */, NULL);
+ // FIXME - pc is a non-decremented breakpoint address, hence the
+ // addition of 1 on test. This seems to work for the thread hook
+ // function in libc.so but should be properly fixed.
+ if (pc == ((int)bkpt_addr + 1)) {
+ // The hook function takes the id of the new thread as it's first
+ // param, so grab it from ecx at offset 4 in struct user_regs_struct
+ // (using fastcall convention for x86)
+ gEventMsgHandle.pid = ptrace(PTRACE_PEEKUSR, handle->tid, (void *)4 /* ecx */, NULL);
+ gEventMsgHandle.tid = gEventMsgHandle.pid;
+ return 0x42;
+ }
+#elif defined(__mips__)
+ void* pc = (void *)ptrace(PTRACE_PEEKUSR, handle->tid, (void *)(64*4) /* pc */, NULL);
+ if (pc == bkpt_addr) {
+ // The hook function takes the id of the new thread as it's first param,
+ // so grab it from a0
+ gEventMsgHandle.pid = ptrace(PTRACE_PEEKUSR, handle->tid, (void *)(4*4) /* a0 */, NULL);
+ gEventMsgHandle.tid = gEventMsgHandle.pid;
+ return 0x42;
+ }
+#endif
return 0;
}
diff --git a/sources/android/support/Android.mk b/sources/android/support/Android.mk
index 6b1208d..ef1884b 100644
--- a/sources/android/support/Android.mk
+++ b/sources/android/support/Android.mk
@@ -11,6 +11,8 @@
src/locale/localeconv.c \
src/locale/newlocale.c \
src/locale/uselocale.c \
+ src/stdio/stdio_impl.c \
+ src/stdio/vfprintf.c \
src/stdio/vfwprintf.c \
src/musl-multibyte/btowc.c \
src/musl-multibyte/internal.c \
@@ -97,6 +99,14 @@
src/musl-locale/wcsxfrm_l.c \
src/musl-locale/wctrans_l.c \
src/musl-locale/wctype_l.c \
+ src/musl-math/frexp.c \
+ src/musl-math/frexpf.c \
+ src/musl-math/frexpl.c \
+ src/musl-stdio/printf.c \
+ src/musl-stdio/snprintf.c \
+ src/musl-stdio/sprintf.c \
+ src/musl-stdio/vprintf.c \
+ src/musl-stdio/vsprintf.c \
src/musl-stdio/swprintf.c \
src/musl-stdio/vwprintf.c \
src/musl-stdio/wprintf.c \
@@ -107,6 +117,19 @@
LOCAL_SRC_FILES := $(android_support_sources)
LOCAL_C_INCLUDES := $(android_support_c_includes)
LOCAL_CFLAGS += -Drestrict=__restrict__ -ffunction-sections -fdata-sections
+
+# These Clang warnings are triggered by the Musl sources. The code is fine,
+# but we don't want to modify it. TODO(digit): This is potentially dangerous,
+# see if there is a way to build the Musl sources in a separate static library
+# and have the main one depend on it, or include its object files.
+ifneq ($(TARGET_TOOLCHAIN),$(subst clang,,$(TARGET_TOOLCHAIN)))
+LOCAL_CFLAGS += \
+ -Wno-shift-op-parentheses \
+ -Wno-string-plus-int \
+ -Wno-dangling-else \
+ -Wno-bitwise-op-parentheses
+endif
+
LOCAL_CFLAGS += $(android_support_cflags)
LOCAL_EXPORT_CFLAGS := $(android_support_cflags)
LOCAL_EXPORT_C_INCLUDES := $(android_support_c_includes)
diff --git a/sources/android/support/include/ctype.h b/sources/android/support/include/ctype.h
index 6e0c8c0..af5909a 100644
--- a/sources/android/support/include/ctype.h
+++ b/sources/android/support/include/ctype.h
@@ -30,14 +30,12 @@
// Get the system header first.
#include_next <ctype.h>
+#include <xlocale.h> // for locale_t
#ifdef __cplusplus
extern "C" {
#endif
-// Add missing declarations.
-typedef struct locale_struct* locale_t;
-
int isalnum_l(int, locale_t);
int isalpha_l(int, locale_t);
int isblank_l(int, locale_t);
diff --git a/sources/android/support/include/iconv.h b/sources/android/support/include/iconv.h
index 3a67d95..0796888 100644
--- a/sources/android/support/include/iconv.h
+++ b/sources/android/support/include/iconv.h
@@ -40,7 +40,7 @@
size_t iconv(iconv_t, char**, size_t*, char**, size_t*);
int iconv_close(iconv_t);
-#ifdef __cplus_plus
+#ifdef __cplusplus
} // extern "C"
#endif
diff --git a/sources/android/support/include/wchar.h b/sources/android/support/include/wchar.h
index e5308ff..44c2622 100644
--- a/sources/android/support/include/wchar.h
+++ b/sources/android/support/include/wchar.h
@@ -69,15 +69,11 @@
#include <stdio.h> // for FILE
#include <stddef.h> // for size_t
#include <wctype.h>
-
-typedef int wint_t;
+#include <xlocale.h> // for locale_t
#define __need___wchar_t
#include <stddef.h>
-typedef int wctype_t;
-typedef struct locale_struct* locale_t;
-
// See http://b.android.com/This is tricky: <stdio.h> indirectly includes <stdint.h>, which will
// already have defined WCHAR_MIN / WCHAR_MAX in the following cases:
// - When compiling C sources
diff --git a/sources/android/support/src/math_support.c b/sources/android/support/src/math_support.c
index 57429a8..a86913f 100644
--- a/sources/android/support/src/math_support.c
+++ b/sources/android/support/src/math_support.c
@@ -53,3 +53,41 @@
return 0;
}
+long double acosl(long double x) { return acos((double)x); }
+long double asinl(long double x) { return asin((double)x); }
+long double atanl(long double x) { return atan((double)x); }
+long double atan2l(long double x, long double y) { return atan2((double)x, (double)y); }
+long double cosl(long double x) { return cos((double)x); }
+long double coshl(long double x) { return cosh((double)x); }
+long double expl(long double x) { return exp((double)x); }
+long double fmodl(long double x, long double y) { return fmod((double)x, (double)y); }
+long double powl(long double x, long double y) { return pow((double)x, (double)y); }
+long double sinl(long double x) { return sin((double)x); }
+long double sinhl(long double x) { return sinh((double)x); }
+long double sqrtl(long double x) { return sqrt((double)x); }
+long double tanl(long double x) { return tan((double)x); }
+long double tanhl(long double x) { return tanh((double)x); }
+long double acoshl(long double x) { return acosh((double)x); }
+long double asinhl(long double x) { return asinh((double)x); }
+long double atanhl(long double x) { return atanh((double)x); }
+long double cbrtl(long double x) { return cbrt((double)x); }
+long double erfl(long double x) { return erf((double)x); }
+long double erfcl(long double x) { return erfc((double)x); }
+long double expm1l(long double x) { return expm1((double)x); }
+long double hypotl(long double x, long double y) { return hypot((double)x, (double)y); }
+long double lgammal(long double x) { return lgamma((double)x); }
+long long int llrintl(long double x) { return llrint((double)x); }
+long double logl(long double x) { return log((double)x); }
+long double log1pl(long double x) { return log1p((double)x); }
+long double log2l(long double x) { return log2((double)x); }
+long double logbl(long double x) { return logb((double)x); }
+long double log10l(long double x) { return log10((double)x); }
+long double nanl(const char* s) { return nan(s); }
+long double nearbyintl(long double x) { return nearbyint((double)x); }
+long double remainderl(long double x, long double y) { return remainder((double)x, (double)y); }
+long double remquol(long double x, long double y, int* i) { return remquo((double)x, (double)y, i); }
+long double rintl(long double x) { return rint((double)x); }
+long int lrintl(long double x) { return lrint((double)x); }
+long double tgammal(long double x) { return tgamma((double)x); }
+long double modfl(long double x, long double* y) { return modf((double)x, (double *)y); }
+long double exp2l(long double x) { return exp2((double)x); }
diff --git a/sources/android/support/src/musl-math/frexp.c b/sources/android/support/src/musl-math/frexp.c
new file mode 100644
index 0000000..27b6266
--- /dev/null
+++ b/sources/android/support/src/musl-math/frexp.c
@@ -0,0 +1,23 @@
+#include <math.h>
+#include <stdint.h>
+
+double frexp(double x, int *e)
+{
+ union { double d; uint64_t i; } y = { x };
+ int ee = y.i>>52 & 0x7ff;
+
+ if (!ee) {
+ if (x) {
+ x = frexp(x*0x1p64, e);
+ *e -= 64;
+ } else *e = 0;
+ return x;
+ } else if (ee == 0x7ff) {
+ return x;
+ }
+
+ *e = ee - 0x3fe;
+ y.i &= 0x800fffffffffffffull;
+ y.i |= 0x3fe0000000000000ull;
+ return y.d;
+}
diff --git a/sources/android/support/src/musl-math/frexpf.c b/sources/android/support/src/musl-math/frexpf.c
new file mode 100644
index 0000000..0787097
--- /dev/null
+++ b/sources/android/support/src/musl-math/frexpf.c
@@ -0,0 +1,23 @@
+#include <math.h>
+#include <stdint.h>
+
+float frexpf(float x, int *e)
+{
+ union { float f; uint32_t i; } y = { x };
+ int ee = y.i>>23 & 0xff;
+
+ if (!ee) {
+ if (x) {
+ x = frexpf(x*0x1p64, e);
+ *e -= 64;
+ } else *e = 0;
+ return x;
+ } else if (ee == 0xff) {
+ return x;
+ }
+
+ *e = ee - 0x7e;
+ y.i &= 0x807ffffful;
+ y.i |= 0x3f000000ul;
+ return y.f;
+}
diff --git a/sources/android/support/src/musl-math/frexpl.c b/sources/android/support/src/musl-math/frexpl.c
new file mode 100644
index 0000000..f9d90a6
--- /dev/null
+++ b/sources/android/support/src/musl-math/frexpl.c
@@ -0,0 +1,37 @@
+#include <math.h>
+#include <stdint.h>
+#include <float.h>
+
+#if LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+
+/* This version is for 80-bit little endian long double */
+
+long double frexpl(long double x, int *e)
+{
+ union { long double ld; uint16_t hw[5]; } y = { x };
+ int ee = y.hw[4]&0x7fff;
+
+ if (!ee) {
+ if (x) {
+ x = frexpl(x*0x1p64, e);
+ *e -= 64;
+ } else *e = 0;
+ return x;
+ } else if (ee == 0x7fff) {
+ return x;
+ }
+
+ *e = ee - 0x3ffe;
+ y.hw[4] &= 0x8000;
+ y.hw[4] |= 0x3ffe;
+ return y.ld;
+}
+
+#else
+
+long double frexpl(long double x, int *e)
+{
+ return frexp(x, e);
+}
+
+#endif
diff --git a/sources/android/support/src/musl-stdio/printf.c b/sources/android/support/src/musl-stdio/printf.c
new file mode 100644
index 0000000..cebfe40
--- /dev/null
+++ b/sources/android/support/src/musl-stdio/printf.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+int printf(const char *restrict fmt, ...)
+{
+ int ret;
+ va_list ap;
+ va_start(ap, fmt);
+ ret = vfprintf(stdout, fmt, ap);
+ va_end(ap);
+ return ret;
+}
diff --git a/sources/android/support/src/musl-stdio/snprintf.c b/sources/android/support/src/musl-stdio/snprintf.c
new file mode 100644
index 0000000..771503b
--- /dev/null
+++ b/sources/android/support/src/musl-stdio/snprintf.c
@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+int snprintf(char *restrict s, size_t n, const char *restrict fmt, ...)
+{
+ int ret;
+ va_list ap;
+ va_start(ap, fmt);
+ ret = vsnprintf(s, n, fmt, ap);
+ va_end(ap);
+ return ret;
+}
+
diff --git a/sources/android/support/src/musl-stdio/sprintf.c b/sources/android/support/src/musl-stdio/sprintf.c
new file mode 100644
index 0000000..9dff524
--- /dev/null
+++ b/sources/android/support/src/musl-stdio/sprintf.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+int sprintf(char *restrict s, const char *restrict fmt, ...)
+{
+ int ret;
+ va_list ap;
+ va_start(ap, fmt);
+ ret = vsprintf(s, fmt, ap);
+ va_end(ap);
+ return ret;
+}
diff --git a/sources/android/support/src/musl-stdio/vprintf.c b/sources/android/support/src/musl-stdio/vprintf.c
new file mode 100644
index 0000000..30d2bff
--- /dev/null
+++ b/sources/android/support/src/musl-stdio/vprintf.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int vprintf(const char *restrict fmt, va_list ap)
+{
+ return vfprintf(stdout, fmt, ap);
+}
diff --git a/sources/android/support/src/musl-stdio/vsprintf.c b/sources/android/support/src/musl-stdio/vsprintf.c
new file mode 100644
index 0000000..c57349d
--- /dev/null
+++ b/sources/android/support/src/musl-stdio/vsprintf.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+#include <limits.h>
+
+int vsprintf(char *restrict s, const char *restrict fmt, va_list ap)
+{
+ return vsnprintf(s, INT_MAX, fmt, ap);
+}
diff --git a/sources/android/support/src/stdio/stdio_impl.c b/sources/android/support/src/stdio/stdio_impl.c
new file mode 100644
index 0000000..e3c442d
--- /dev/null
+++ b/sources/android/support/src/stdio/stdio_impl.c
@@ -0,0 +1,129 @@
+#include <stdio.h>
+#include <wchar.h>
+#include <string.h>
+
+#define _STDIO_IMPL_NO_REDIRECT_MACROS
+#include "stdio_impl.h"
+
+void fake_file_init_file(FakeFILE* file, FILE* f) {
+ memset(file, 0, sizeof(*file));
+ file->file = f;
+}
+
+void fake_file_init_buffer(FakeFILE* file, char* buffer, size_t buffer_size) {
+ memset(file, 0, sizeof(*file));
+ file->buffer = buffer;
+ file->buffer_pos = 0;
+ file->buffer_size = buffer_size;
+}
+
+void fake_file_init_wbuffer(FakeFILE* file,
+ wchar_t* buffer,
+ size_t buffer_size) {
+ fake_file_init_buffer(file, (char*)buffer, buffer_size * sizeof(wchar_t));
+}
+
+void fake_file_out(FakeFILE* file, const char* text, size_t length) {
+ if (length == 0) {
+ // Happens pretty often, so bail immediately.
+ return;
+ }
+ if (file->file != NULL) {
+ fwrite(text, 1, length, file->file);
+ } else {
+ // Write into a bounded buffer.
+ size_t avail = file->buffer_size - file->buffer_pos;
+ if (length > avail)
+ length = avail;
+ memcpy((char*)(file->buffer + file->buffer_pos),
+ (const char*)text,
+ length);
+ file->buffer_pos += length;
+ }
+}
+
+void fake_file_outw(FakeFILE* file, const wchar_t* text, size_t length) {
+ if (length == 0)
+ return;
+ if (file->file != NULL) {
+ // Write into a file the UTF-8 encoded version.
+ // Original source calls fputwc() in a loop, which is slightly inefficient
+ // for large strings.
+ // TODO(digit): Support locale-specific encoding?
+ size_t mb_len = wcstombs(NULL, text, length);
+ char* mb_buffer = malloc(mb_len);
+ wcstombs(mb_buffer, text, length);
+ fwrite(mb_buffer, 1, mb_len, file->file);
+ free(mb_buffer);
+ } else {
+ // Write into a bounded buffer. This assumes the buffer really
+ // holds wchar_t items.
+ size_t avail = (file->buffer_size - file->buffer_pos) / sizeof(wchar_t);
+ if (length > avail)
+ length = avail;
+ memcpy((char*)(file->buffer + file->buffer_pos),
+ (const char*)text,
+ length * sizeof(wchar_t));
+ file->buffer_pos += length * sizeof(wchar_t);
+ }
+}
+
+int fake_feof(FakeFILE* file) {
+ if (file->file != NULL)
+ return feof(file->file);
+ else
+ return (file->buffer_pos >= file->buffer_size);
+}
+
+int fake_ferror(FakeFILE* file) {
+ if (file->file != NULL)
+ return ferror(file->file);
+
+ return 0;
+}
+
+int fake_fprintf(FakeFILE* file, const char* format, ...) {
+ va_list args;
+ va_start(args, format);
+ if (file->file)
+ return vfprintf(file->file, format, args);
+ else {
+ // TODO(digit): Make this faster.
+ // First, generate formatted byte output.
+ int mb_len = vsnprintf(NULL, 0, format, args);
+ char* mb_buffer = malloc(mb_len + 1);
+ vsnprintf(mb_buffer, mb_len + 1, format, args);
+ // Then convert to wchar_t buffer.
+ size_t wide_len = mbstowcs(NULL, mb_buffer, mb_len);
+ wchar_t* wide_buffer = malloc((wide_len + 1) * sizeof(wchar_t));
+ mbstowcs(wide_buffer, mb_buffer, mb_len);
+ // Add to buffer.
+ fake_file_outw(file, wide_buffer, wide_len);
+ // finished
+ free(wide_buffer);
+ free(mb_buffer);
+
+ return wide_len;
+ }
+ va_end(args);
+}
+
+void fake_fputc(char ch, FakeFILE* file) {
+ if (file->file)
+ fputc(ch, file->file);
+ else {
+ if (file->buffer_pos < file->buffer_size)
+ file->buffer[file->buffer_pos++] = ch;
+ }
+}
+
+void fake_fputwc(wchar_t wc, FakeFILE* file) {
+ if (file->file)
+ fputwc(wc, file->file);
+ else {
+ if (file->buffer_pos + sizeof(wchar_t) - 1U < file->buffer_size) {
+ *(wchar_t*)(&file->buffer[file->buffer_pos]) = wc;
+ file->buffer_pos += sizeof(wchar_t);
+ }
+ }
+}
diff --git a/sources/android/support/src/stdio/stdio_impl.h b/sources/android/support/src/stdio/stdio_impl.h
new file mode 100644
index 0000000..51ce59c
--- /dev/null
+++ b/sources/android/support/src/stdio/stdio_impl.h
@@ -0,0 +1,63 @@
+// The Musl sources for snprintf(), sscanf() assume they can use a specially
+// crafted FILE object to represent the output/input buffers. However, this
+// doesn't work when using FILE handle from Bionic.
+//
+// This header is used to 'cheat' by redefining FILE and a few other macro
+// redefinitions for functions used in the sources in this directory.
+
+#ifndef STDIO_IMPL_H
+#define STDIO_IMPL_H
+
+#define __HIDDEN__ __attribute__((__visibility__("hidden")))
+
+// A structure that wraps either a real FILE* handle, or an input/output
+// buffer.
+typedef struct {
+ FILE* file;
+ unsigned char* buffer;
+ size_t buffer_size;
+ size_t buffer_pos;
+} FakeFILE;
+
+// Initialize FakeFILE wrapper |file| to use a FILE* handle |f|
+void fake_file_init_file(FakeFILE* file, FILE* f) __HIDDEN__;
+
+// Initialize FakeFILE wrapper |file| to use a |buffer| of |buffer_size| chars.
+void fake_file_init_buffer(FakeFILE* file, char* buffer, size_t buffer_size)
+ __HIDDEN__;
+
+// Initialize FakeFILE wrapper |file| to use a wchar_t |buffer| of
+// |buffer_size| wide-chars.
+void fake_file_init_wbuffer(FakeFILE* file, wchar_t* buffer, size_t buffer_size)
+ __HIDDEN__;
+
+// Replacement for out() in vfprintf.c
+void fake_file_out(FakeFILE* file, const char* s, size_t l) __HIDDEN__;
+
+// Replacement for out() in fvwprintf.c
+void fake_file_outw(FakeFILE* file, const wchar_t* s, size_t l) __HIDDEN__;
+
+// Fake replacement for stdio functions of similar names.
+int fake_feof(FakeFILE* file) __HIDDEN__;
+int fake_ferror(FakeFILE* file) __HIDDEN__;
+int fake_fprintf(FakeFILE* file, const char* fmt, ...) __HIDDEN__;
+void fake_fputc(char ch, FakeFILE* file) __HIDDEN__;
+void fake_fputwc(wchar_t wc, FakeFILE* file) __HIDDEN__;
+
+#ifndef _STDIO_IMPL_NO_REDIRECT_MACROS
+
+// Macro redirection - ugly but necessary to minimize changes to the sources.
+#define FILE FakeFILE
+
+#undef feof
+#define feof fake_feof
+
+#undef ferror
+#define ferror fake_ferror
+#define fprintf fake_fprintf
+#define fputc fake_fputc
+#define fputwc fake_fputwc
+
+#endif /* _STDIO_IMPL_NO_REDIRECT_MACROS */
+
+#endif /* STDIO_IMPL_H */
diff --git a/sources/android/support/src/stdio/vfprintf.c b/sources/android/support/src/stdio/vfprintf.c
new file mode 100644
index 0000000..5789acf
--- /dev/null
+++ b/sources/android/support/src/stdio/vfprintf.c
@@ -0,0 +1,780 @@
+/*
+ Copyright (C) 2005-2012 Rich Felker
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ Modified in 2013 for the Android Open Source Project.
+ */
+#include <errno.h>
+#include <ctype.h>
+#include <limits.h>
+#include <string.h>
+#include <stdarg.h>
+#include <wchar.h>
+#include <inttypes.h>
+#include <math.h>
+#include <float.h>
+
+#include "stdio_impl.h"
+
+/* Some useful macros */
+
+#define MAX(a,b) ((a)>(b) ? (a) : (b))
+#define MIN(a,b) ((a)<(b) ? (a) : (b))
+#define CONCAT2(x,y) x ## y
+#define CONCAT(x,y) CONCAT2(x,y)
+
+/* Convenient bit representation for modifier flags, which all fall
+ * within 31 codepoints of the space character. */
+
+#define ALT_FORM (1U<<'#'-' ')
+#define ZERO_PAD (1U<<'0'-' ')
+#define LEFT_ADJ (1U<<'-'-' ')
+#define PAD_POS (1U<<' '-' ')
+#define MARK_POS (1U<<'+'-' ')
+#define GROUPED (1U<<'\''-' ')
+
+#define FLAGMASK (ALT_FORM|ZERO_PAD|LEFT_ADJ|PAD_POS|MARK_POS|GROUPED)
+
+#if UINT_MAX == ULONG_MAX
+#define LONG_IS_INT
+#endif
+
+#if SIZE_MAX != ULONG_MAX || UINTMAX_MAX != ULLONG_MAX
+#define ODD_TYPES
+#endif
+
+/* State machine to accept length modifiers + conversion specifiers.
+ * Result is 0 on failure, or an argument type to pop on success. */
+
+enum {
+ BARE, LPRE, LLPRE, HPRE, HHPRE, BIGLPRE,
+ ZTPRE, JPRE,
+ STOP,
+ PTR, INT, UINT, ULLONG,
+#ifndef LONG_IS_INT
+ LONG, ULONG,
+#else
+#define LONG INT
+#define ULONG UINT
+#endif
+ SHORT, USHORT, CHAR, UCHAR,
+#ifdef ODD_TYPES
+ LLONG, SIZET, IMAX, UMAX, PDIFF, UIPTR,
+#else
+#define LLONG ULLONG
+#define SIZET ULONG
+#define IMAX LLONG
+#define UMAX ULLONG
+#define PDIFF LONG
+#define UIPTR ULONG
+#endif
+ DBL, LDBL,
+ NOARG,
+ MAXSTATE
+};
+
+#define S(x) [(x)-'A']
+
+static const unsigned char states[]['z'-'A'+1] = {
+ { /* 0: bare types */
+ S('d') = INT, S('i') = INT,
+ S('o') = UINT, S('u') = UINT, S('x') = UINT, S('X') = UINT,
+ S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,
+ S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL,
+ S('c') = CHAR, S('C') = INT,
+ S('s') = PTR, S('S') = PTR, S('p') = UIPTR, S('n') = PTR,
+ S('m') = NOARG,
+ S('l') = LPRE, S('h') = HPRE, S('L') = BIGLPRE,
+ S('z') = ZTPRE, S('j') = JPRE, S('t') = ZTPRE,
+ }, { /* 1: l-prefixed */
+ S('d') = LONG, S('i') = LONG,
+ S('o') = ULONG, S('u') = ULONG, S('x') = ULONG, S('X') = ULONG,
+ S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,
+ S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL,
+ S('c') = INT, S('s') = PTR, S('n') = PTR,
+ S('l') = LLPRE,
+ }, { /* 2: ll-prefixed */
+ S('d') = LLONG, S('i') = LLONG,
+ S('o') = ULLONG, S('u') = ULLONG,
+ S('x') = ULLONG, S('X') = ULLONG,
+ S('n') = PTR,
+ }, { /* 3: h-prefixed */
+ S('d') = SHORT, S('i') = SHORT,
+ S('o') = USHORT, S('u') = USHORT,
+ S('x') = USHORT, S('X') = USHORT,
+ S('n') = PTR,
+ S('h') = HHPRE,
+ }, { /* 4: hh-prefixed */
+ S('d') = CHAR, S('i') = CHAR,
+ S('o') = UCHAR, S('u') = UCHAR,
+ S('x') = UCHAR, S('X') = UCHAR,
+ S('n') = PTR,
+ }, { /* 5: L-prefixed */
+ S('e') = LDBL, S('f') = LDBL, S('g') = LDBL, S('a') = LDBL,
+ S('E') = LDBL, S('F') = LDBL, S('G') = LDBL, S('A') = LDBL,
+ S('n') = PTR,
+ }, { /* 6: z- or t-prefixed (assumed to be same size) */
+ S('d') = PDIFF, S('i') = PDIFF,
+ S('o') = SIZET, S('u') = SIZET,
+ S('x') = SIZET, S('X') = SIZET,
+ S('n') = PTR,
+ }, { /* 7: j-prefixed */
+ S('d') = IMAX, S('i') = IMAX,
+ S('o') = UMAX, S('u') = UMAX,
+ S('x') = UMAX, S('X') = UMAX,
+ S('n') = PTR,
+ }
+};
+
+#define OOB(x) ((unsigned)(x)-'A' > 'z'-'A')
+
+union arg
+{
+ uintmax_t i;
+ long double f;
+ void *p;
+};
+
+static void pop_arg(union arg *arg, int type, va_list *ap)
+{
+ /* Give the compiler a hint for optimizing the switch. */
+ if ((unsigned)type > MAXSTATE) return;
+ switch (type) {
+ case PTR: arg->p = va_arg(*ap, void *);
+ break; case INT: arg->i = va_arg(*ap, int);
+ break; case UINT: arg->i = va_arg(*ap, unsigned int);
+#ifndef LONG_IS_INT
+ break; case LONG: arg->i = va_arg(*ap, long);
+ break; case ULONG: arg->i = va_arg(*ap, unsigned long);
+#endif
+ break; case ULLONG: arg->i = va_arg(*ap, unsigned long long);
+ break; case SHORT: arg->i = (short)va_arg(*ap, int);
+ break; case USHORT: arg->i = (unsigned short)va_arg(*ap, int);
+ break; case CHAR: arg->i = (signed char)va_arg(*ap, int);
+ break; case UCHAR: arg->i = (unsigned char)va_arg(*ap, int);
+#ifdef ODD_TYPES
+ break; case LLONG: arg->i = va_arg(*ap, long long);
+ break; case SIZET: arg->i = va_arg(*ap, size_t);
+ break; case IMAX: arg->i = va_arg(*ap, intmax_t);
+ break; case UMAX: arg->i = va_arg(*ap, uintmax_t);
+ break; case PDIFF: arg->i = va_arg(*ap, ptrdiff_t);
+ break; case UIPTR: arg->i = (uintptr_t)va_arg(*ap, void *);
+#endif
+ break; case DBL: arg->f = va_arg(*ap, double);
+ break; case LDBL: arg->f = va_arg(*ap, long double);
+ }
+}
+
+static void out(FILE *f, const char *s, size_t l)
+{
+#if defined(__ANDROID__)
+ fake_file_out(f, s, l);
+#else
+ __fwritex((void *)s, l, f);
+#endif
+}
+
+static void pad(FILE *f, char c, int w, int l, int fl)
+{
+ char pad[256];
+ if (fl & (LEFT_ADJ | ZERO_PAD) || l >= w) return;
+ l = w - l;
+ memset(pad, c, l>sizeof pad ? sizeof pad : l);
+ for (; l >= sizeof pad; l -= sizeof pad)
+ out(f, pad, sizeof pad);
+ out(f, pad, l);
+}
+
+static const char xdigits[16] = {
+ "0123456789ABCDEF"
+};
+
+static char *fmt_x(uintmax_t x, char *s, int lower)
+{
+ for (; x; x>>=4) *--s = xdigits[(x&15)]|lower;
+ return s;
+}
+
+static char *fmt_o(uintmax_t x, char *s)
+{
+ for (; x; x>>=3) *--s = '0' + (x&7);
+ return s;
+}
+
+static char *fmt_u(uintmax_t x, char *s)
+{
+ unsigned long y;
+ for ( ; x>ULONG_MAX; x/=10) *--s = '0' + x%10;
+ for (y=x; y; y/=10) *--s = '0' + y%10;
+ return s;
+}
+
+static int fmt_fp(FILE *f, long double y, int w, int p, int fl, int t)
+{
+ uint32_t big[(LDBL_MAX_EXP+LDBL_MANT_DIG)/9+1];
+ uint32_t *a, *d, *r, *z;
+ int e2=0, e, i, j, l;
+ char buf[9+LDBL_MANT_DIG/4], *s;
+ const char *prefix="-0X+0X 0X-0x+0x 0x";
+ int pl;
+ char ebuf0[3*sizeof(int)], *ebuf=&ebuf0[3*sizeof(int)], *estr;
+
+ pl=1;
+ if (signbit(y)) {
+ y=-y;
+ } else if (fl & MARK_POS) {
+ prefix+=3;
+ } else if (fl & PAD_POS) {
+ prefix+=6;
+ } else prefix++, pl=0;
+
+ if (!isfinite(y)) {
+ char *s = (t&32)?"inf":"INF";
+ if (y!=y) s=(t&32)?"nan":"NAN", pl=0;
+ pad(f, ' ', w, 3+pl, fl&~ZERO_PAD);
+ out(f, prefix, pl);
+ out(f, s, 3);
+ pad(f, ' ', w, 3+pl, fl^LEFT_ADJ);
+ return MAX(w, 3+pl);
+ }
+
+ y = frexpl(y, &e2) * 2;
+ if (y) e2--;
+
+ if ((t|32)=='a') {
+ long double round = 8.0;
+ int re;
+
+ if (t&32) prefix += 9;
+ pl += 2;
+
+ if (p<0 || p>=LDBL_MANT_DIG/4-1) re=0;
+ else re=LDBL_MANT_DIG/4-1-p;
+
+ if (re) {
+ while (re--) round*=16;
+ if (*prefix=='-') {
+ y=-y;
+ y-=round;
+ y+=round;
+ y=-y;
+ } else {
+ y+=round;
+ y-=round;
+ }
+ }
+
+ estr=fmt_u(e2<0 ? -e2 : e2, ebuf);
+ if (estr==ebuf) *--estr='0';
+ *--estr = (e2<0 ? '-' : '+');
+ *--estr = t+('p'-'a');
+
+ s=buf;
+ do {
+ int x=y;
+ *s++=xdigits[x]|(t&32);
+ y=16*(y-x);
+ if (s-buf==1 && (y||p>0||(fl&ALT_FORM))) *s++='.';
+ } while (y);
+
+ if (p && s-buf-2 < p)
+ l = (p+2) + (ebuf-estr);
+ else
+ l = (s-buf) + (ebuf-estr);
+
+ pad(f, ' ', w, pl+l, fl);
+ out(f, prefix, pl);
+ pad(f, '0', w, pl+l, fl^ZERO_PAD);
+ out(f, buf, s-buf);
+ pad(f, '0', l-(ebuf-estr)-(s-buf), 0, 0);
+ out(f, estr, ebuf-estr);
+ pad(f, ' ', w, pl+l, fl^LEFT_ADJ);
+ return MAX(w, pl+l);
+ }
+ if (p<0) p=6;
+
+ if (y) y *= 0x1p28, e2-=28;
+
+ if (e2<0) a=r=z=big;
+ else a=r=z=big+sizeof(big)/sizeof(*big) - LDBL_MANT_DIG - 1;
+
+ do {
+ *z = y;
+ y = 1000000000*(y-*z++);
+ } while (y);
+
+ while (e2>0) {
+ uint32_t carry=0;
+ int sh=MIN(29,e2);
+ for (d=z-1; d>=a; d--) {
+ uint64_t x = ((uint64_t)*d<<sh)+carry;
+ *d = x % 1000000000;
+ carry = x / 1000000000;
+ }
+ if (!z[-1] && z>a) z--;
+ if (carry) *--a = carry;
+ e2-=sh;
+ }
+ while (e2<0) {
+ uint32_t carry=0, *b;
+ int sh=MIN(9,-e2);
+ for (d=a; d<z; d++) {
+ uint32_t rm = *d & (1<<sh)-1;
+ *d = (*d>>sh) + carry;
+ carry = (1000000000>>sh) * rm;
+ }
+ if (!*a) a++;
+ if (carry) *z++ = carry;
+ /* Avoid (slow!) computation past requested precision */
+ b = (t|32)=='f' ? r : a;
+ if (z-b > 2+p/9) z = b+2+p/9;
+ e2+=sh;
+ }
+
+ if (a<z) for (i=10, e=9*(r-a); *a>=i; i*=10, e++);
+ else e=0;
+
+ /* Perform rounding: j is precision after the radix (possibly neg) */
+ j = p - ((t|32)!='f')*e - ((t|32)=='g' && p);
+ if (j < 9*(z-r-1)) {
+ uint32_t x;
+ /* We avoid C's broken division of negative numbers */
+ d = r + 1 + ((j+9*LDBL_MAX_EXP)/9 - LDBL_MAX_EXP);
+ j += 9*LDBL_MAX_EXP;
+ j %= 9;
+ for (i=10, j++; j<9; i*=10, j++);
+ x = *d % i;
+ /* Are there any significant digits past j? */
+ if (x || d+1!=z) {
+ long double round = CONCAT(0x1p,LDBL_MANT_DIG);
+ long double small;
+ if (*d/i & 1) round += 2;
+ if (x<i/2) small=0x0.8p0;
+ else if (x==i/2 && d+1==z) small=0x1.0p0;
+ else small=0x1.8p0;
+ if (pl && *prefix=='-') round*=-1, small*=-1;
+ *d -= x;
+ /* Decide whether to round by probing round+small */
+ if (round+small != round) {
+ *d = *d + i;
+ while (*d > 999999999) {
+ *d--=0;
+ (*d)++;
+ }
+ if (d<a) a=d;
+ for (i=10, e=9*(r-a); *a>=i; i*=10, e++);
+ }
+ }
+ if (z>d+1) z=d+1;
+ for (; !z[-1] && z>a; z--);
+ }
+
+ if ((t|32)=='g') {
+ if (!p) p++;
+ if (p>e && e>=-4) {
+ t--;
+ p-=e+1;
+ } else {
+ t-=2;
+ p--;
+ }
+ if (!(fl&ALT_FORM)) {
+ /* Count trailing zeros in last place */
+ if (z>a && z[-1]) for (i=10, j=0; z[-1]%i==0; i*=10, j++);
+ else j=9;
+ if ((t|32)=='f')
+ p = MIN(p,MAX(0,9*(z-r-1)-j));
+ else
+ p = MIN(p,MAX(0,9*(z-r-1)+e-j));
+ }
+ }
+ l = 1 + p + (p || (fl&ALT_FORM));
+ if ((t|32)=='f') {
+ if (e>0) l+=e;
+ } else {
+ estr=fmt_u(e<0 ? -e : e, ebuf);
+ while(ebuf-estr<2) *--estr='0';
+ *--estr = (e<0 ? '-' : '+');
+ *--estr = t;
+ l += ebuf-estr;
+ }
+
+ pad(f, ' ', w, pl+l, fl);
+ out(f, prefix, pl);
+ pad(f, '0', w, pl+l, fl^ZERO_PAD);
+
+ if ((t|32)=='f') {
+ if (a>r) a=r;
+ for (d=a; d<=r; d++) {
+ char *s = fmt_u(*d, buf+9);
+ if (d!=a) while (s>buf) *--s='0';
+ else if (s==buf+9) *--s='0';
+ out(f, s, buf+9-s);
+ }
+ if (p || (fl&ALT_FORM)) out(f, ".", 1);
+ for (; d<z && p>0; d++, p-=9) {
+ char *s = fmt_u(*d, buf+9);
+ while (s>buf) *--s='0';
+ out(f, s, MIN(9,p));
+ }
+ pad(f, '0', p+9, 9, 0);
+ } else {
+ if (z<=a) z=a+1;
+ for (d=a; d<z && p>=0; d++) {
+ char *s = fmt_u(*d, buf+9);
+ if (s==buf+9) *--s='0';
+ if (d!=a) while (s>buf) *--s='0';
+ else {
+ out(f, s++, 1);
+ if (p>0||(fl&ALT_FORM)) out(f, ".", 1);
+ }
+ out(f, s, MIN(buf+9-s, p));
+ p -= buf+9-s;
+ }
+ pad(f, '0', p+18, 18, 0);
+ out(f, estr, ebuf-estr);
+ }
+
+ pad(f, ' ', w, pl+l, fl^LEFT_ADJ);
+
+ return MAX(w, pl+l);
+}
+
+static int getint(char **s) {
+ int i;
+ for (i=0; isdigit(**s); (*s)++)
+ i = 10*i + (**s-'0');
+ return i;
+}
+
+static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg, int *nl_type)
+{
+ char *a, *z, *s=(char *)fmt;
+ unsigned l10n=0, fl;
+ int w, p;
+ union arg arg;
+ int argpos;
+ unsigned st, ps;
+ int cnt=0, l=0;
+ int i;
+ char buf[sizeof(uintmax_t)*3+3+LDBL_MANT_DIG/4];
+ const char *prefix;
+ int t, pl;
+ wchar_t wc[2], *ws;
+ char mb[4];
+
+ for (;;) {
+ /* Update output count, end loop when fmt is exhausted */
+ if (cnt >= 0) {
+ if (l > INT_MAX - cnt) {
+ errno = EOVERFLOW;
+ cnt = -1;
+ } else cnt += l;
+ }
+ if (!*s) break;
+
+ /* Handle literal text and %% format specifiers */
+ for (a=s; *s && *s!='%'; s++);
+ for (z=s; s[0]=='%' && s[1]=='%'; z++, s+=2);
+ l = z-a;
+ if (f) out(f, a, l);
+ if (l) continue;
+
+ if (isdigit(s[1]) && s[2]=='$') {
+ l10n=1;
+ argpos = s[1]-'0';
+ s+=3;
+ } else {
+ argpos = -1;
+ s++;
+ }
+
+ /* Read modifier flags */
+ for (fl=0; (unsigned)*s-' '<32 && (FLAGMASK&(1U<<*s-' ')); s++)
+ fl |= 1U<<*s-' ';
+
+ /* Read field width */
+ if (*s=='*') {
+ if (isdigit(s[1]) && s[2]=='$') {
+ l10n=1;
+ nl_type[s[1]-'0'] = INT;
+ w = nl_arg[s[1]-'0'].i;
+ s+=3;
+ } else if (!l10n) {
+ w = f ? va_arg(*ap, int) : 0;
+ s++;
+ } else return -1;
+ if (w<0) fl|=LEFT_ADJ, w=-w;
+ } else if ((w=getint(&s))<0) return -1;
+
+ /* Read precision */
+ if (*s=='.' && s[1]=='*') {
+ if (isdigit(s[2]) && s[3]=='$') {
+ nl_type[s[2]-'0'] = INT;
+ p = nl_arg[s[2]-'0'].i;
+ s+=4;
+ } else if (!l10n) {
+ p = f ? va_arg(*ap, int) : 0;
+ s+=2;
+ } else return -1;
+ } else if (*s=='.') {
+ s++;
+ p = getint(&s);
+ } else p = -1;
+
+ /* Format specifier state machine */
+ st=0;
+ do {
+ if (OOB(*s)) return -1;
+ ps=st;
+ st=states[st]S(*s++);
+ } while (st-1<STOP);
+ if (!st) return -1;
+
+ /* Check validity of argument type (nl/normal) */
+ if (st==NOARG) {
+ if (argpos>=0) return -1;
+ else if (!f) continue;
+ } else {
+ if (argpos>=0) nl_type[argpos]=st, arg=nl_arg[argpos];
+ else if (f) pop_arg(&arg, st, ap);
+ else return 0;
+ }
+
+ if (!f) continue;
+
+ z = buf + sizeof(buf);
+ prefix = "-+ 0X0x";
+ pl = 0;
+ t = s[-1];
+
+ /* Transform ls,lc -> S,C */
+ if (ps && (t&15)==3) t&=~32;
+
+ /* - and 0 flags are mutually exclusive */
+ if (fl & LEFT_ADJ) fl &= ~ZERO_PAD;
+
+ switch(t) {
+ case 'n':
+#ifndef __ANDROID__ /* Disabled on Android for security reasons. */
+ switch(ps) {
+ case BARE: *(int *)arg.p = cnt; break;
+ case LPRE: *(long *)arg.p = cnt; break;
+ case LLPRE: *(long long *)arg.p = cnt; break;
+ case HPRE: *(unsigned short *)arg.p = cnt; break;
+ case HHPRE: *(unsigned char *)arg.p = cnt; break;
+ case ZTPRE: *(size_t *)arg.p = cnt; break;
+ case JPRE: *(uintmax_t *)arg.p = cnt; break;
+ }
+#endif /* !__ANDROID__ */
+ continue;
+ case 'p':
+ p = MAX(p, 2*sizeof(void*));
+ t = 'x';
+ fl |= ALT_FORM;
+ case 'x': case 'X':
+ a = fmt_x(arg.i, z, t&32);
+ if (arg.i && (fl & ALT_FORM)) prefix+=(t>>4), pl=2;
+ if (0) {
+ case 'o':
+ a = fmt_o(arg.i, z);
+ if ((fl&ALT_FORM) && arg.i) prefix+=5, pl=1;
+ } if (0) {
+ case 'd': case 'i':
+ pl=1;
+ if (arg.i>INTMAX_MAX) {
+ arg.i=-arg.i;
+ } else if (fl & MARK_POS) {
+ prefix++;
+ } else if (fl & PAD_POS) {
+ prefix+=2;
+ } else pl=0;
+ case 'u':
+ a = fmt_u(arg.i, z);
+ }
+ if (p>=0) fl &= ~ZERO_PAD;
+ if (!arg.i && !p) {
+ a=z;
+ break;
+ }
+ p = MAX(p, z-a + !arg.i);
+ break;
+ case 'c':
+ *(a=z-(p=1))=arg.i;
+ fl &= ~ZERO_PAD;
+ break;
+ case 'm':
+ if (1) a = strerror(errno); else
+ case 's':
+ a = arg.p ? arg.p : "(null)";
+#if defined(__ANDROID__)
+ /* On Android, memchr() will return NULL for
+ * out-of-bound requests, e.g. if |p == -1|. */
+ if (p >= 0) {
+ z = memchr(a, 0, p);
+ if (!z) z=a+p;
+ else p=z-a;
+ } else {
+ p=strlen(a);
+ z=a+p;
+ }
+#else /* !__ANDROID__ */
+ if (!z) z=a+p;
+ else p=z-a;
+#endif /* !__ANDROID__ */
+ fl &= ~ZERO_PAD;
+ break;
+ case 'C':
+ wc[0] = arg.i;
+ wc[1] = 0;
+ arg.p = wc;
+ p = -1;
+ case 'S':
+ ws = arg.p;
+ for (i=l=0; i<0U+p && *ws && (l=wctomb(mb, *ws++))>=0 && l<=0U+p-i; i+=l);
+ if (l<0) return -1;
+ p = i;
+ pad(f, ' ', w, p, fl);
+ ws = arg.p;
+ for (i=0; i<0U+p && *ws && i+(l=wctomb(mb, *ws++))<=p; i+=l)
+ out(f, mb, l);
+ pad(f, ' ', w, p, fl^LEFT_ADJ);
+ l = w>p ? w : p;
+ continue;
+ case 'e': case 'f': case 'g': case 'a':
+ case 'E': case 'F': case 'G': case 'A':
+ l = fmt_fp(f, arg.f, w, p, fl, t);
+ continue;
+ }
+
+ if (p < z-a) p = z-a;
+ if (w < pl+p) w = pl+p;
+
+ pad(f, ' ', w, pl+p, fl);
+ out(f, prefix, pl);
+ pad(f, '0', w, pl+p, fl^ZERO_PAD);
+ pad(f, '0', p, z-a, 0);
+ out(f, a, z-a);
+ pad(f, ' ', w, pl+p, fl^LEFT_ADJ);
+
+ l = w;
+ }
+
+ if (f) return cnt;
+ if (!l10n) return 0;
+
+ for (i=1; i<=NL_ARGMAX && nl_type[i]; i++)
+ pop_arg(nl_arg+i, nl_type[i], ap);
+ for (; i<=NL_ARGMAX && !nl_type[i]; i++);
+ if (i<=NL_ARGMAX) return -1;
+ return 1;
+}
+
+#ifdef __ANDROID__
+#undef FILE /* no longer needed */
+
+int vfprintf(FILE *restrict f, const char *restrict fmt, va_list ap)
+{
+ va_list ap2;
+ int nl_type[NL_ARGMAX+1] = {0};
+ union arg nl_arg[NL_ARGMAX+1];
+ int ret;
+ FakeFILE out[1];
+ fake_file_init_file(out, f);
+
+ va_copy(ap2, ap);
+ ret = printf_core(0, fmt, &ap2, nl_arg, nl_type);
+ va_end(ap2);
+ if (ret < 0)
+ return -1;
+
+ va_copy(ap2, ap);
+ ret = printf_core(out, fmt, &ap2, nl_arg, nl_type);
+ va_end(ap2);
+ return ret;
+}
+
+int vsnprintf(char *restrict s, size_t n, const char *restrict fmt, va_list ap)
+{
+ va_list ap2;
+ int nl_type[NL_ARGMAX+1] = {0};
+ union arg nl_arg[NL_ARGMAX+1];
+ int r;
+ char b;
+ FakeFILE out[1];
+
+ if (n-1 > INT_MAX-1) {
+ if (n) {
+ errno = EOVERFLOW;
+ return -1;
+ }
+ s = &b;
+ n = 1;
+ }
+
+ /* Ensure pointers don't wrap if "infinite" n is passed in */
+ if (n > (char *)0+SIZE_MAX-s-1) n = (char *)0+SIZE_MAX-s-1;
+ fake_file_init_buffer(out, s, n);
+
+ va_copy(ap2, ap);
+ r = printf_core(out, fmt, &ap2, nl_arg, nl_type);
+ va_end(ap2);
+
+ if (r < n)
+ s[r] = '\0';
+ else
+ s[n - 1] = '\0';
+
+ return r;
+}
+
+#else /* !__ANDROID__ */
+int vfprintf(FILE *restrict f, const char *restrict fmt, va_list ap)
+{
+ va_list ap2;
+ int nl_type[NL_ARGMAX+1] = {0};
+ union arg nl_arg[NL_ARGMAX+1];
+ unsigned char internal_buf[80], *saved_buf = 0;
+ int ret;
+
+ va_copy(ap2, ap);
+ if (printf_core(0, fmt, &ap2, nl_arg, nl_type) < 0) return -1;
+
+ FLOCK(f);
+ if (!f->buf_size) {
+ saved_buf = f->buf;
+ f->wpos = f->wbase = f->buf = internal_buf;
+ f->buf_size = sizeof internal_buf;
+ f->wend = internal_buf + sizeof internal_buf;
+ }
+ ret = printf_core(f, fmt, &ap2, nl_arg, nl_type);
+ if (saved_buf) {
+ f->write(f, 0, 0);
+ if (!f->wpos) ret = -1;
+ f->buf = saved_buf;
+ f->buf_size = 0;
+ f->wpos = f->wbase = f->wend = 0;
+ }
+ FUNLOCK(f);
+ va_end(ap2);
+ return ret;
+}
+#endif /* !__ANDROID__ */
diff --git a/sources/android/support/src/stdio/vfwprintf.c b/sources/android/support/src/stdio/vfwprintf.c
index 56e5c48..241cf0c 100644
--- a/sources/android/support/src/stdio/vfwprintf.c
+++ b/sources/android/support/src/stdio/vfwprintf.c
@@ -23,104 +23,16 @@
Modified in 2013 for the Android Open Source Project.
*/
-//#include "stdio_impl.h"
#include <errno.h>
#include <ctype.h>
#include <limits.h>
#include <string.h>
#include <stdarg.h>
+#include <stdlib.h>
#include <wchar.h>
#include <inttypes.h>
-// A wrapper around either a FILE* or a string buffer, used to output
-// the result of formatted expansion.
-typedef struct {
- FILE* file;
- wchar_t* buffer;
- size_t buffer_pos;
- size_t buffer_size;
-} Out;
-
-void out_init_file(Out* out, FILE* f) {
- memset(out, 0, sizeof(*out));
- out->file = f;
-}
-
-void out_init_buffer(Out* out, wchar_t* buffer, size_t buffer_size) {
- memset(out, 0, sizeof(*out));
- out->buffer = buffer;
- out->buffer_pos = 0;
- out->buffer_size = buffer_size;
-}
-
-void out_write(Out* out, const wchar_t* text, size_t length) {
- if (out->file != NULL) {
- // Write into a file the UTF-8 encoded version.
- // TODO(digit): Support locale-specific encoding.
- size_t mb_len = wcstombs(NULL, text, length);
- char* mb_buffer = malloc(mb_len);
- wcstombs(mb_buffer, text, length);
- fwrite(mb_buffer, 1, mb_len, out->file);
- free(mb_buffer);
- } else {
- // Write into a bounded buffer.
- size_t avail = out->buffer_size - out->buffer_pos;
- if (length > avail)
- length = avail;
- memcpy((char*)(out->buffer + out->buffer_pos),
- (const char*)text,
- length * sizeof(wchar_t));
- out->buffer_pos += length;
- }
-}
-
-void out_putwc(Out* out, wchar_t wc) {
- if (out->file)
- fputwc(wc, out->file);
- else {
- if (out->buffer_pos < out->buffer_size)
- out->buffer[out->buffer_pos++] = wc;
- }
-}
-
-int out_printf(Out* out, const char* format, ...) {
- va_list args;
- va_start(args, format);
- if (out->file)
- return vfprintf(out->file, format, args);
- else {
- // TODO(digit): Make this faster.
- // First, generate formatted byte output.
- int mb_len = vsnprintf(NULL, 0, format, args);
- char* mb_buffer = malloc(mb_len + 1);
- vsnprintf(mb_buffer, mb_len + 1, format, args);
- // Then convert to wchar_t buffer.
- size_t wide_len = mbstowcs(NULL, mb_buffer, mb_len);
- wchar_t* wide_buffer = malloc((wide_len + 1) * sizeof(wchar_t));
- mbstowcs(wide_buffer, mb_buffer, mb_len);
- // Add to buffer.
- out_write(out, wide_buffer, wide_len);
- // finished
- free(wide_buffer);
- free(mb_buffer);
-
- return wide_len;
- }
- va_end(args);
-}
-int out_error(Out* out) {
- if (out->file != NULL)
- return ferror(out->file);
-
- return 0;
-}
-
-int out_overflow(Out* out) {
- if (out->file != NULL)
- return feof(out->file);
- else
- return (out->buffer_pos >= out->buffer_size);
-}
+#include "stdio_impl.h"
/* Convenient bit representation for modifier flags, which all fall
* within 31 codepoints of the space character. */
@@ -262,6 +174,15 @@
}
}
+static void out(FILE *f, const wchar_t *s, size_t l)
+{
+#if defined(__ANDROID__)
+ fake_file_outw(f, s, l);
+#else
+ while (l--) fputwc(*s++, f);
+#endif
+}
+
static int getint(wchar_t **s) {
int i;
for (i=0; iswdigit(**s); (*s)++)
@@ -275,7 +196,7 @@
['p'-'a']='j'
};
-static int wprintf_core(Out *out, const wchar_t *fmt, va_list *ap, union arg *nl_arg, int *nl_type)
+static int wprintf_core(FILE *f, const wchar_t *fmt, va_list *ap, union arg *nl_arg, int *nl_type)
{
wchar_t *a, *z, *s=(wchar_t *)fmt, *s0;
unsigned l10n=0, litpct, fl;
@@ -294,7 +215,7 @@
/* Update output count, end loop when fmt is exhausted */
if (cnt >= 0) {
if (l > INT_MAX - cnt) {
- if (!out_error(out)) errno = EOVERFLOW;
+ if (!ferror(f)) errno = EOVERFLOW;
cnt = -1;
} else cnt += l;
}
@@ -306,7 +227,7 @@
z = s+litpct;
s += 2*litpct;
l = z-a;
- if (out) out_write(out, a, l);
+ if (f) out(f, a, l);
if (l) continue;
if (iswdigit(s[1]) && s[2]=='$') {
@@ -330,7 +251,7 @@
w = nl_arg[s[1]-'0'].i;
s+=3;
} else if (!l10n) {
- w = out ? va_arg(*ap, int) : 0;
+ w = f ? va_arg(*ap, int) : 0;
s++;
} else return -1;
if (w<0) fl|=LEFT_ADJ, w=-w;
@@ -343,7 +264,7 @@
p = nl_arg[s[2]-'0'].i;
s+=4;
} else if (!l10n) {
- p = out ? va_arg(*ap, int) : 0;
+ p = f ? va_arg(*ap, int) : 0;
s+=2;
} else return -1;
} else if (*s=='.') {
@@ -364,19 +285,20 @@
/* Check validity of argument type (nl/normal) */
if (st==NOARG) {
if (argpos>=0) return -1;
- else if (!out) continue;
+ else if (!f) continue;
} else {
if (argpos>=0) nl_type[argpos]=st, arg=nl_arg[argpos];
- else if (out) pop_arg(&arg, st, ap);
+ else if (f) pop_arg(&arg, st, ap);
else return 0;
}
- if (!out) continue;
+ if (!f) continue;
t = s[-1];
if (ps && (t&15)==3) t&=~32;
switch (t) {
case 'n':
+#ifndef __ANDROID__ /* Disabled on Android for security reasons. */
switch(ps) {
case BARE: *(int *)arg.p = cnt; break;
case LPRE: *(long *)arg.p = cnt; break;
@@ -386,13 +308,14 @@
case ZTPRE: *(size_t *)arg.p = cnt; break;
case JPRE: *(uintmax_t *)arg.p = cnt; break;
}
+#endif /* !__ANDROID__ */
continue;
case 'c':
- out_putwc(out, btowc(arg.i));
+ fputwc(btowc(arg.i), f);
l = 1;
continue;
case 'C':
- out_putwc(out, arg.i);
+ fputwc(arg.i, f);
l = 1;
continue;
case 'S':
@@ -401,9 +324,9 @@
if (!z) z=a+p;
else p=z-a;
if (w<p) w=p;
- if (!(fl&LEFT_ADJ)) out_printf(out, "%.*s", w-p, "");
- out_write(out, a, p);
- if ((fl&LEFT_ADJ)) out_printf(out, "%.*s", w-p, "");
+ if (!(fl&LEFT_ADJ)) fprintf(f, "%.*s", w-p, "");
+ out(f, a, p);
+ if ((fl&LEFT_ADJ)) fprintf(f, "%.*s", w-p, "");
l=w;
continue;
case 's':
@@ -413,14 +336,14 @@
if (i<0) return -1;
p=l;
if (w<p) w=p;
- if (!(fl&LEFT_ADJ)) out_printf(out, "%.*s", w-p, "");
+ if (!(fl&LEFT_ADJ)) fprintf(f, "%.*s", w-p, "");
bs = arg.p;
while (l--) {
i=mbtowc(&wc, bs, MB_LEN_MAX);
bs+=i;
- out_putwc(out, wc);
+ fputwc(wc, f);
}
- if ((fl&LEFT_ADJ)) out_printf(out, "%.*s", w-p, "");
+ if ((fl&LEFT_ADJ)) fprintf(f, "%.*s", w-p, "");
l=w;
continue;
}
@@ -435,15 +358,15 @@
switch (t|32) {
case 'a': case 'e': case 'f': case 'g':
- l = out_printf(out, charfmt, w, p, arg.f);
+ l = fprintf(f, charfmt, w, p, arg.f);
break;
case 'd': case 'i': case 'o': case 'u': case 'x': case 'p':
- l = out_printf(out, charfmt, w, p, arg.i);
+ l = fprintf(f, charfmt, w, p, arg.i);
break;
}
}
- if (out) return cnt;
+ if (f) return cnt;
if (!l10n) return 0;
for (i=1; i<=NL_ARGMAX && nl_type[i]; i++)
@@ -453,14 +376,16 @@
return 1;
}
+#ifdef __ANDROID__
+#undef FILE /* no longer needed */
int vfwprintf(FILE *restrict f, const wchar_t *restrict fmt, va_list ap)
{
va_list ap2;
int nl_type[NL_ARGMAX] = {0};
union arg nl_arg[NL_ARGMAX];
int ret;
- Out out[1];
- out_init_file(out, f);
+ FakeFILE out[1];
+ fake_file_init_file(out, f);
va_copy(ap2, ap);
// Check for error in format string before writing anything to file.
if (wprintf_core(0, fmt, &ap2, nl_arg, nl_type) < 0) {
@@ -478,11 +403,29 @@
int nl_type[NL_ARGMAX] = {0};
union arg nl_arg[NL_ARGMAX];
int ret;
- Out out[1];
- out_init_buffer(out, s, l);
+ FakeFILE out[1];
+ fake_file_init_wbuffer(out, s, l);
va_copy(ap2, ap);
ret = wprintf_core(out, fmt, &ap2, nl_arg, nl_type);
va_end(ap2);
- if (out_overflow(out)) return -1;
+ if (fake_feof(out)) return -1;
return ret;
}
+#else /* !__ANDROID__ */
+int vfwprintf(FILE *restrict f, const wchar_t *restrict fmt, va_list ap)
+{
+ va_list ap2;
+ int nl_type[NL_ARGMAX] = {0};
+ union arg nl_arg[NL_ARGMAX];
+ int ret;
+
+ va_copy(ap2, ap);
+ if (wprintf_core(0, fmt, &ap2, nl_arg, nl_type) < 0) return -1;
+
+ FLOCK(f);
+ ret = wprintf_core(f, fmt, &ap2, nl_arg, nl_type);
+ FUNLOCK(f);
+ va_end(ap2);
+ return ret;
+}
+#endif /* !__ANDROID__ */
diff --git a/sources/android/support/tests/stdio_unittest.cc b/sources/android/support/tests/stdio_unittest.cc
index 08ace9a..fca503d 100644
--- a/sources/android/support/tests/stdio_unittest.cc
+++ b/sources/android/support/tests/stdio_unittest.cc
@@ -16,6 +16,9 @@
EXPECT_EQ(L'\0', char_buff[11]);
EXPECT_EQ(12, snprintf(char_buff, 1, "%s", kString));
EXPECT_EQ(L'\0', char_buff[0]);
+
+ EXPECT_EQ(20, snprintf(char_buff, char_buff_len, "%a", 3.1415926535));
+ EXPECT_STREQ("0x1.921fb54411744p+1", char_buff);
}
TEST(stdio,swprintf) {
diff --git a/sources/cxx-stl/gabi++/Android.mk b/sources/cxx-stl/gabi++/Android.mk
index 3842a45..0b16663 100644
--- a/sources/cxx-stl/gabi++/Android.mk
+++ b/sources/cxx-stl/gabi++/Android.mk
@@ -9,6 +9,7 @@
LOCAL_SRC_FILES:= libs/$(TARGET_ARCH_ABI)/lib$(LOCAL_MODULE)$(TARGET_SONAME_EXTENSION)
LOCAL_EXPORT_C_INCLUDES := $(libgabi++_c_includes)
LOCAL_CPP_FEATURES := rtti exceptions
+ LOCAL_CFLAGS := -Wall -Werror
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
@@ -16,6 +17,7 @@
LOCAL_SRC_FILES:= libs/$(TARGET_ARCH_ABI)/lib$(LOCAL_MODULE)$(TARGET_LIB_EXTENSION)
LOCAL_EXPORT_C_INCLUDES := $(libgabi++_c_includes)
LOCAL_CPP_FEATURES := rtti exceptions
+ LOCAL_CFLAGS := -Wall -Werror
include $(PREBUILT_STATIC_LIBRARY)
else # ! GABIXX_FORCE_REBUILD
diff --git a/sources/cxx-stl/gabi++/include/cxxabi.h b/sources/cxx-stl/gabi++/include/cxxabi.h
index 0cd9eb8..5684afb 100644
--- a/sources/cxx-stl/gabi++/include/cxxabi.h
+++ b/sources/cxx-stl/gabi++/include/cxxabi.h
@@ -74,6 +74,12 @@
#include <typeinfo>
#include <unwind.h>
+// When LIBCXXABI, gabi++ should emulate libc++abi. _LIBCPPABI_VERSION must
+// be defined in cxxabi.h to complete this abstraction for libc++.
+#if defined(LIBCXXABI)
+#define _LIBCPPABI_VERSION 1001
+#endif
+
namespace __cxxabiv1
{
extern "C" {
@@ -84,33 +90,45 @@
struct __cxa_exception;
struct __cxa_eh_globals;
- __cxa_eh_globals* __cxa_get_globals();
- __cxa_eh_globals* __cxa_get_globals_fast();
+ __cxa_eh_globals* __cxa_get_globals() _GABIXX_NOEXCEPT ;
+ __cxa_eh_globals* __cxa_get_globals_fast() _GABIXX_NOEXCEPT;
- void* __cxa_allocate_exception(size_t thrown_size);
- void __cxa_free_exception(void* thrown_exception);
+ void* __cxa_allocate_exception(size_t thrown_size) _GABIXX_NOEXCEPT;
+ void __cxa_free_exception(void* thrown_exception) _GABIXX_NOEXCEPT;
- void __cxa_throw(void* thrown_exception, std::type_info* tinfo, void (*dest)(void*));
- void __cxa_rethrow();
+ void __cxa_throw(void* thrown_exception,
+ std::type_info* tinfo,
+ void (*dest)(void*)) _GABIXX_NORETURN;
- void* __cxa_begin_catch(void* exceptionObject);
- void __cxa_end_catch();
+ void __cxa_rethrow() _GABIXX_NORETURN;
+ void* __cxa_begin_catch(void* exceptionObject) _GABIXX_NOEXCEPT;
+ void __cxa_end_catch() _GABIXX_NOEXCEPT;
+
+#ifdef __arm__
bool __cxa_begin_cleanup(_Unwind_Exception*);
void __cxa_end_cleanup();
+#endif
- void __cxa_bad_cast();
- void __cxa_bad_typeid();
+ void __cxa_bad_cast() _GABIXX_NORETURN;
+ void __cxa_bad_typeid() _GABIXX_NORETURN;
- void* __cxa_get_exception_ptr(void* exceptionObject);
+ void* __cxa_get_exception_ptr(void* exceptionObject) _GABIXX_NOEXCEPT;
- void __cxa_pure_virtual();
+ void __cxa_pure_virtual() _GABIXX_NORETURN;
+ void __cxa_deleted_virtual() _GABIXX_NORETURN;
// Missing libcxxabi functions.
bool __cxa_uncaught_exception() _GABIXX_NOEXCEPT;
- void __cxa_decrement_exception_refcount(void* exceptionObject) _GABIXX_NOEXCEPT;
- void __cxa_increment_exception_refcount(void* exceptionObject) _GABIXX_NOEXCEPT;
+
+ void __cxa_decrement_exception_refcount(void* exceptionObject)
+ _GABIXX_NOEXCEPT;
+
+ void __cxa_increment_exception_refcount(void* exceptionObject)
+ _GABIXX_NOEXCEPT;
+
void __cxa_rethrow_primary_exception(void* exceptionObject);
+
void* __cxa_current_primary_exception() _GABIXX_NOEXCEPT;
// The ARM ABI mandates that constructors and destructors
diff --git a/sources/cxx-stl/gabi++/include/exception b/sources/cxx-stl/gabi++/include/exception
index ca3eb30..7c18c57 100644
--- a/sources/cxx-stl/gabi++/include/exception
+++ b/sources/cxx-stl/gabi++/include/exception
@@ -30,38 +30,38 @@
#include "gabixx_config.h"
-#if !defined(GABIXX_LIBCXX)
+#if !defined(LIBCXXABI)
namespace std {
class exception {
public:
- exception() throw();
- virtual ~exception() throw();
- virtual const char* what() const throw();
+ exception() _GABIXX_NOEXCEPT;
+ virtual ~exception() _GABIXX_NOEXCEPT;
+ virtual const char* what() const _GABIXX_NOEXCEPT;
};
class bad_exception : public exception {
public:
- bad_exception() throw();
- virtual ~bad_exception() throw();
- virtual const char* what() const throw();
+ bad_exception() _GABIXX_NOEXCEPT;
+ virtual ~bad_exception() _GABIXX_NOEXCEPT;
+ virtual const char* what() const _GABIXX_NOEXCEPT;
};
typedef void (*terminate_handler)();
- terminate_handler get_terminate();
- terminate_handler set_terminate(terminate_handler f);
- _GABIXX_NORETURN void terminate();
+ terminate_handler get_terminate() _GABIXX_NOEXCEPT;
+ terminate_handler set_terminate(terminate_handler f) _GABIXX_NOEXCEPT;
+ void terminate() _GABIXX_NOEXCEPT_CXX11_ONLY _GABIXX_NORETURN;
typedef void (*unexpected_handler)();
- unexpected_handler get_unexpected();
- unexpected_handler set_unexpected(unexpected_handler f);
- _GABIXX_NORETURN void unexpected();
+ unexpected_handler get_unexpected() _GABIXX_NOEXCEPT;
+ unexpected_handler set_unexpected(unexpected_handler f) _GABIXX_NOEXCEPT;
+ void unexpected() _GABIXX_NORETURN;
- bool uncaught_exception() throw();
+ bool uncaught_exception() _GABIXX_NOEXCEPT;
} // namespace std
-#endif // !defined(GABIXX_LIBCXX)
+#endif // !defined(LIBCXXABI)
#endif // __GABIXX_EXCEPTION__
diff --git a/sources/cxx-stl/gabi++/include/gabixx_config.h b/sources/cxx-stl/gabi++/include/gabixx_config.h
index b727497..718b919 100644
--- a/sources/cxx-stl/gabi++/include/gabixx_config.h
+++ b/sources/cxx-stl/gabi++/include/gabixx_config.h
@@ -38,12 +38,15 @@
// qualifier at the end of function declarations.
//
// _GABIXX_NOEXCEPT_() only in C++11 mode to use the noexcept() operator.
+// _GABIXX_NOEXCEPT_CXX11_ONLY uses noexcept in C++11, nothing otherwise.
#if __cplusplus >= 201103L
# define _GABIXX_NOEXCEPT noexcept
# define _GABIXX_NOEXCEPT_(x) noexcept(x)
+# define _GABIXX_NOEXCEPT_CXX11_ONLY noexcept
#else
# define _GABIXX_NOEXCEPT throw()
# define _GABIXX_NOEXCEPT_(x) /* nothing */
+# define _GABIXX_NOEXCEPT_CXX11_ONLY /* nothing */
#endif
// Use _GABIXX_HIDDEN to declare internal functions of GAbi++ that should
@@ -74,7 +77,7 @@
// TODO(digit): Use __atomic_load_acq_rel when available.
#define __gabixx_sync_load(address) \
- __sync_fetch_and_add((address), (typeof(*(address)))0)
+ __sync_fetch_and_add((address), (__typeof__(*(address)))0)
// Clang provides __sync_swap(), but GCC does not.
// IMPORTANT: For GCC, __sync_lock_test_and_set has acquire semantics only
@@ -85,7 +88,7 @@
#else
# define __gabixx_sync_swap(address, value) \
__extension__ ({ \
- typeof(*(address)) __ret = __sync_lock_test_and_set((address),(value)); \
+ __typeof__(*(address)) __ret = __sync_lock_test_and_set((address),(value)); \
__sync_synchronize(); \
__ret; \
})
diff --git a/sources/cxx-stl/gabi++/include/new b/sources/cxx-stl/gabi++/include/new
index d66fef7..1643e01 100644
--- a/sources/cxx-stl/gabi++/include/new
+++ b/sources/cxx-stl/gabi++/include/new
@@ -30,7 +30,7 @@
#ifndef __GABIXX_NEW__
#define __GABIXX_NEW__
-#if !defined(GABIXX_LIBCXX)
+#if !defined(LIBCXXABI)
#include <cstddef>
#include <exception>
@@ -50,6 +50,7 @@
typedef void (*new_handler)();
new_handler set_new_handler(new_handler) throw();
+new_handler get_new_handler() throw();
}
@@ -68,6 +69,6 @@
inline void operator delete(void*, void*) throw() {}
inline void operator delete[](void*, void*) throw() {}
-#endif // !defined(GABIXX_LIBCXX)
+#endif // !defined(LIBCXXABI)
#endif // __GABIXX_NEW__
diff --git a/sources/cxx-stl/gabi++/include/typeinfo b/sources/cxx-stl/gabi++/include/typeinfo
index 486eb40..8dcc9dd 100644
--- a/sources/cxx-stl/gabi++/include/typeinfo
+++ b/sources/cxx-stl/gabi++/include/typeinfo
@@ -35,7 +35,7 @@
#ifndef __GABIXX_TYPEINFO__
#define __GABIXX_TYPEINFO__
-#if !defined(GABIXX_LIBCXX)
+#if !defined(LIBCXXABI)
#include <exception>
@@ -93,6 +93,6 @@
} // namespace std
-#endif // !defined(GABIXX_LIBCXX)
+#endif // !defined(LIBCXXABI)
#endif // _GABIXX_TYPEINFO_
diff --git a/sources/cxx-stl/gabi++/sources.mk b/sources/cxx-stl/gabi++/sources.mk
index dee2440..e37e7dc 100644
--- a/sources/cxx-stl/gabi++/sources.mk
+++ b/sources/cxx-stl/gabi++/sources.mk
@@ -23,6 +23,7 @@
src/pointer_to_member_type_info.cc \
src/call_unexpected.cc \
src/si_class_type_info.cc \
+ src/stdexcept.cc \
src/terminate.cc \
src/type_info.cc \
src/vmi_class_type_info.cc
diff --git a/sources/cxx-stl/gabi++/src/cxxabi.cc b/sources/cxx-stl/gabi++/src/cxxabi.cc
index 34f7f97..3f428d9 100644
--- a/sources/cxx-stl/gabi++/src/cxxabi.cc
+++ b/sources/cxx-stl/gabi++/src/cxxabi.cc
@@ -25,6 +25,9 @@
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
+#include <limits.h>
+#include <sys/mman.h>
+
#include <cassert>
#include <cstdio>
#include <cstdlib>
@@ -48,6 +51,142 @@
__cxa_free_exception(exc+1);
}
+ // Helper class used to ensure a lock is acquire immediately, and released
+ // on scope exit. Usage example:
+ //
+ // {
+ // AutoLock lock(some_mutex); // acquires the mutex.
+ // ... do stuff
+ // if (error)
+ // return; // releases mutex before returning.
+ // ... do other stuff.
+ // } // releases mutex before exiting scope.
+ //
+ class AutoLock {
+ public:
+ AutoLock(pthread_mutex_t& lock) : lock_(lock) {
+ pthread_mutex_lock(&lock_);
+ }
+
+ ~AutoLock(void) {
+ pthread_mutex_unlock(&lock_);
+ }
+ private:
+ pthread_mutex_t& lock_;
+
+ AutoLock(const AutoLock&);
+ AutoLock& operator=(const AutoLock&);
+ };
+
+ // MMap-based memory allocator for fixed-sized items.
+ //
+ // IMPORTANT: This must be POD-struct compatible, which means:
+ // - No constructor or destructor.
+ // - No virtual methods.
+ //
+ // This allocates large blocks of memory, called 'slabs' that can contain
+ // several items of the same size. A slab contains an array of item slots,
+ // followed by a pointer, used to put all slabs in a single linked list.
+ class PageBasedAllocator {
+ public:
+ // Used to initialize this allocator to hold items of type |T|.
+ template <typename T>
+ void Init() {
+ InitExplicit(sizeof(T), __alignof__(T));
+ }
+
+ // Used to initialize this instance to hold items of |item_size| bytes,
+ // with alignment |align_size|.
+ void InitExplicit(size_t item_size, size_t align_size) {
+ const size_t ptr_size = sizeof(void*);
+ if (align_size < ptr_size)
+ align_size = ptr_size;
+ item_size_ = (item_size + align_size - 1) & ~(align_size - 1);
+ slab_next_offset_ = kSlabSize - ptr_size;
+ item_slab_count_ = slab_next_offset_ / item_size_;
+
+ pthread_mutex_init(&lock_, NULL);
+ free_items_ = NULL;
+ slab_list_ = NULL;
+ }
+
+ // Call this to deallocate this instance. This releases all pages directly.
+ // Ensure that all items are freed first, or bad things could happen.
+ void Deinit() {
+ pthread_mutex_lock(&lock_);
+ while (slab_list_) {
+ void* slab = slab_list_;
+ void* next_slab = *(void**)((char*)slab + slab_next_offset_);
+ slab_list_ = next_slab;
+ ::munmap(slab, PAGE_SIZE);
+ }
+ pthread_mutex_unlock(&lock_);
+ pthread_mutex_destroy(&lock_);
+ }
+
+ // Allocate a new item, or NULL in case of failure.
+ void* Alloc() {
+ AutoLock lock(lock_);
+
+ if (!free_items_ && !AllocateSlab())
+ return NULL;
+
+ FreeItem* item = free_items_;
+ free_items_ = item->next;
+ ::memset(item, 0, item_size_);
+ return item;
+ }
+
+ void Release(void* obj) {
+ if (!obj)
+ return;
+
+ AutoLock lock(lock_);
+ FreeItem* item = reinterpret_cast<FreeItem*>(obj);
+ item->next = free_items_;
+ free_items_ = item;
+ }
+
+ private:
+ static const size_t kSlabSize = PAGE_SIZE;
+
+ bool AllocateSlab() {
+ // No more free items, allocate a new slab with mmap().
+ void* new_slab = mmap(NULL, kSlabSize, PROT_READ|PROT_WRITE,
+ MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+ if (new_slab == MAP_FAILED)
+ return false;
+
+ // Prepend to the slab list.
+ *((void**)((char*)new_slab + slab_next_offset_)) = slab_list_;
+ slab_list_ = new_slab;
+
+ // Put all item slots in the new slab into the free item list.
+ FreeItem** pparent = &free_items_;
+ FreeItem* item = reinterpret_cast<FreeItem*>(new_slab);
+ for (size_t n = 0; n < item_slab_count_; ++n) {
+ *pparent = item;
+ pparent = &item->next;
+ item = reinterpret_cast<FreeItem*>((char*)item + item_size_);
+ }
+ *pparent = NULL;
+
+ // Done.
+ return true;
+ }
+
+ struct FreeItem {
+ FreeItem* next;
+ };
+
+ size_t item_size_; // size of each item in bytes.
+ size_t item_slab_count_; // number of items in each slab.
+ size_t slab_next_offset_; // offset of pointer to next slab in list.
+ pthread_mutex_t lock_; // mutex synchronizing access to data below.
+ void* slab_list_; // Linked list of slabs.
+ FreeItem* free_items_; // Linked list of free items.
+ };
+
// Technical note:
// Use a pthread_key_t to hold the key used to store our thread-specific
// __cxa_eh_globals objects. The key is created and destroyed through
@@ -58,22 +197,25 @@
// static C++ destructor may be called with a value of NULL for the
// 'this' pointer. As such, any attempt to access any field in the
// object there will result in a crash. To work-around this, store
- // the key object as a 'static' variable outside of the C++ object.
+ // the members of CxaThreadKey as static variables outside of the
+ // C++ object.
static pthread_key_t __cxa_thread_key;
+ static PageBasedAllocator __cxa_eh_globals_allocator;
class CxaThreadKey {
public:
// Called at program initialization time, or when the shared library
// is loaded through dlopen().
CxaThreadKey() {
- if (pthread_key_create(&__cxa_thread_key, freeObject) != 0) {
+ if (pthread_key_create(&__cxa_thread_key, freeObject) != 0)
__gabixx::__fatal_error("Can't allocate C++ runtime pthread_key_t");
- }
+ __cxa_eh_globals_allocator.Init<__cxa_eh_globals>();
}
// Called at program exit time, or when the shared library is
// unloaded through dlclose(). See note above.
~CxaThreadKey() {
+ __cxa_eh_globals_allocator.Deinit();
pthread_key_delete(__cxa_thread_key);
}
@@ -85,13 +227,20 @@
static __cxa_eh_globals* getSlow() {
void* obj = pthread_getspecific(__cxa_thread_key);
if (obj == NULL) {
- obj = malloc(sizeof(__cxa_eh_globals));
+ // malloc() cannot be used here because this method is sometimes
+ // called from malloc() on Android, and this would dead-lock.
+ //
+ // More specifically, if the libc.debug.malloc system property is not 0
+ // on a userdebug or eng build of the platform, malloc() will call
+ // backtrace() to record stack traces of allocation. On ARM, this
+ // forces an unwinding operation which will call this function at
+ // some point.
+ obj = __cxa_eh_globals_allocator.Alloc();
if (!obj) {
// Shouldn't happen, but better be safe than sorry.
__gabixx::__fatal_error(
"Can't allocate thread-specific C++ runtime info block.");
}
- memset(obj, 0, sizeof(__cxa_eh_globals));
pthread_setspecific(__cxa_thread_key, obj);
}
return reinterpret_cast<__cxa_eh_globals*>(obj);
@@ -100,7 +249,7 @@
private:
// Called when a thread is destroyed.
static void freeObject(void* obj) {
- free(obj);
+ __cxa_eh_globals_allocator.Release(obj);
}
};
@@ -110,7 +259,7 @@
// file. They handle the pthread_key_t allocation/deallocation.
static CxaThreadKey instance;
- void throwException(__cxa_exception *header) {
+ _GABIXX_NORETURN void throwException(__cxa_exception *header) {
__cxa_eh_globals* globals = __cxa_get_globals();
header->unexpectedHandler = std::get_unexpected();
header->terminateHandler = std::get_terminate();
@@ -127,22 +276,25 @@
namespace __cxxabiv1 {
__shim_type_info::~__shim_type_info() {
- }
+} // namespace __cxxabiv1
extern "C" void __cxa_pure_virtual() {
__gabixx::__fatal_error("Pure virtual function called!");
}
- extern "C" __cxa_eh_globals* __cxa_get_globals() {
+ extern "C" void __cxa_deleted_virtual() {
+ __gabixx::__fatal_error("Deleted virtual function called!");
+ }
+
+ extern "C" __cxa_eh_globals* __cxa_get_globals() _GABIXX_NOEXCEPT {
return CxaThreadKey::getSlow();
}
- extern "C" __cxa_eh_globals* __cxa_get_globals_fast() {
+ extern "C" __cxa_eh_globals* __cxa_get_globals_fast() _GABIXX_NOEXCEPT {
return CxaThreadKey::getFast();
}
-
- extern "C" void *__cxa_allocate_exception(size_t thrown_size) {
+ extern "C" void *__cxa_allocate_exception(size_t thrown_size) _GABIXX_NOEXCEPT {
size_t size = thrown_size + sizeof(__cxa_exception);
__cxa_exception *buffer = static_cast<__cxa_exception*>(malloc(size));
if (!buffer) {
@@ -152,11 +304,11 @@
__gabixx::__fatal_error("Not enough memory to allocate exception!");
}
- memset(buffer, 0, sizeof(__cxa_exception));
+ ::memset(buffer, 0, sizeof(__cxa_exception));
return buffer + 1;
}
- extern "C" void __cxa_free_exception(void* thrown_exception) {
+ extern "C" void __cxa_free_exception(void* thrown_exception) _GABIXX_NOEXCEPT {
__cxa_exception *exc = static_cast<__cxa_exception*>(thrown_exception)-1;
if (exc->exceptionDestructor) {
@@ -170,7 +322,6 @@
free(exc);
}
-
extern "C" void __cxa_throw(void* thrown_exc,
std::type_info* tinfo,
void (*dest)(void*)) {
@@ -202,8 +353,7 @@
throwException(header);
}
-
- extern "C" void* __cxa_begin_catch(void* exc) {
+ extern "C" void* __cxa_begin_catch(void* exc) _GABIXX_NOEXCEPT {
_Unwind_Exception *exception = static_cast<_Unwind_Exception*>(exc);
__cxa_exception* header = reinterpret_cast<__cxa_exception*>(exception+1)-1;
__cxa_eh_globals* globals = __cxa_get_globals();
@@ -227,7 +377,7 @@
return header->adjustedPtr;
}
- extern "C" void __cxa_end_catch() {
+ extern "C" void __cxa_end_catch() _GABIXX_NOEXCEPT {
__cxa_eh_globals *globals = __cxa_get_globals_fast();
__cxa_exception *header = globals->caughtExceptions;
_Unwind_Exception* exception = &header->unwindHeader;
@@ -258,7 +408,7 @@
header->handlerCount = count;
}
- extern "C" void* __cxa_get_exception_ptr(void* exceptionObject) {
+ extern "C" void* __cxa_get_exception_ptr(void* exceptionObject) _GABIXX_NOEXCEPT {
__cxa_exception* header =
reinterpret_cast<__cxa_exception*>(
reinterpret_cast<_Unwind_Exception *>(exceptionObject)+1)-1;
@@ -294,19 +444,19 @@
}
extern "C" void __cxa_rethrow_primary_exception(void* primary_exception) {
-#if defined(GABIXX_LIBCXX)
+#if defined(LIBCXXABI)
// Only warn if we're building for libcxx since other libraries do not use
// this.
#warning "not implemented."
-#endif /* defined(GABIXX_LIBCXX) */
+#endif /* defined(LIBCXXABI) */
}
extern "C" void* __cxa_current_primary_exception() _GABIXX_NOEXCEPT {
-#if defined(GABIXX_LIBCXX)
+#if defined(LIBCXXABI)
// Only warn if we're building for libcxx since other libraries do not use
// this.
#warning "not implemented."
-#endif /* defined(GABIXX_LIBCXX) */
+#endif /* defined(LIBCXXABI) */
return NULL;
}
diff --git a/sources/cxx-stl/gabi++/src/cxxabi_defines.h b/sources/cxx-stl/gabi++/src/cxxabi_defines.h
index a48c7c0..335baa3 100644
--- a/sources/cxx-stl/gabi++/src/cxxabi_defines.h
+++ b/sources/cxx-stl/gabi++/src/cxxabi_defines.h
@@ -316,6 +316,9 @@
namespace __gabixx {
+// Default unexpected handler.
+_GABIXX_NORETURN void __default_unexpected(void) _GABIXX_HIDDEN;
+
// Default terminate handler.
_GABIXX_NORETURN void __default_terminate(void) _GABIXX_HIDDEN;
diff --git a/sources/cxx-stl/gabi++/src/delete.cc b/sources/cxx-stl/gabi++/src/delete.cc
index ae673fe..f567658 100644
--- a/sources/cxx-stl/gabi++/src/delete.cc
+++ b/sources/cxx-stl/gabi++/src/delete.cc
@@ -27,6 +27,7 @@
//
// delete.cc: delete operator
+#if !defined(LIBCXXABI)
#include <gabixx_config.h>
#include <stdlib.h>
#include <new>
@@ -56,3 +57,4 @@
{
::operator delete(ptr, nt);
}
+#endif // !defined(LIBCXXABI)
diff --git a/sources/cxx-stl/gabi++/src/exception.cc b/sources/cxx-stl/gabi++/src/exception.cc
index 73c0ffc..6c19e6f 100644
--- a/sources/cxx-stl/gabi++/src/exception.cc
+++ b/sources/cxx-stl/gabi++/src/exception.cc
@@ -32,10 +32,10 @@
namespace std {
-#if !defined(GABIXX_LIBCXX)
+#if !defined(LIBCXXABI)
exception::exception() _GABIXX_NOEXCEPT {
}
-#endif // !defined(GABIXX_LIBCXX)
+#endif // !defined(LIBCXXABI)
exception::~exception() _GABIXX_NOEXCEPT {
}
@@ -44,9 +44,10 @@
return "std::exception";
}
-#if !defined(GABIXX_LIBCXX)
+#if !defined(LIBCXXABI)
bad_exception::bad_exception() _GABIXX_NOEXCEPT {
}
+#endif // !defined(LIBCXXABI)
bad_exception::~bad_exception() _GABIXX_NOEXCEPT {
}
@@ -54,33 +55,14 @@
const char* bad_exception::what() const _GABIXX_NOEXCEPT {
return "std::bad_exception";
}
-#endif // !defined(GABIXX_LIBCXX)
-bad_cast::bad_cast() _GABIXX_NOEXCEPT {
-}
-
-bad_cast::~bad_cast() _GABIXX_NOEXCEPT {
-}
-
-const char* bad_cast::what() const _GABIXX_NOEXCEPT {
- return "std::bad_cast";
-}
-
-bad_typeid::bad_typeid() _GABIXX_NOEXCEPT {
-}
-
-bad_typeid::~bad_typeid() _GABIXX_NOEXCEPT {
-}
-
-const char* bad_typeid::what() const _GABIXX_NOEXCEPT {
- return "std::bad_typeid";
-}
-
+#if !defined(LIBCXXABI)
bool uncaught_exception() _GABIXX_NOEXCEPT {
using namespace __cxxabiv1;
__cxa_eh_globals* globals = __cxa_get_globals();
return globals->uncaughtExceptions != 0;
}
+#endif // !defined(LIBCXXABI)
} // namespace std
diff --git a/sources/cxx-stl/gabi++/src/helper_func_internal.cc b/sources/cxx-stl/gabi++/src/helper_func_internal.cc
index 5f02866..581b657 100644
--- a/sources/cxx-stl/gabi++/src/helper_func_internal.cc
+++ b/sources/cxx-stl/gabi++/src/helper_func_internal.cc
@@ -49,7 +49,7 @@
uint8_t ttypeEncoding,
_Unwind_Exception* unwind_exception);
- void call_terminate(_Unwind_Exception* unwind_exception) {
+ _GABIXX_NORETURN void call_terminate(_Unwind_Exception* unwind_exception) {
__cxa_begin_catch(unwind_exception); // terminate is also a handler
std::terminate();
}
@@ -342,7 +342,8 @@
}
// lower-level runtime library API function that unwinds the frame
- extern "C" bool __gnu_unwind_frame(_Unwind_Exception*, _Unwind_Context*);
+ extern "C" _Unwind_Reason_Code __gnu_unwind_frame(_Unwind_Exception*,
+ _Unwind_Context*);
void setRegisters(_Unwind_Exception* unwind_exception,
_Unwind_Context* context,
diff --git a/sources/cxx-stl/gabi++/src/helper_func_internal.h b/sources/cxx-stl/gabi++/src/helper_func_internal.h
index 0b2f107..a67b69b 100644
--- a/sources/cxx-stl/gabi++/src/helper_func_internal.h
+++ b/sources/cxx-stl/gabi++/src/helper_func_internal.h
@@ -36,7 +36,7 @@
// Target-independent helper functions
namespace __cxxabiv1 {
- void call_terminate(_Unwind_Exception* unwind_exception) _GABIXX_HIDDEN;
+ _GABIXX_NORETURN void call_terminate(_Unwind_Exception* unwind_exception) _GABIXX_HIDDEN;
#if __arm__
uint32_t decodeRelocTarget2 (uint32_t ptr) _GABIXX_HIDDEN;
diff --git a/sources/cxx-stl/gabi++/src/new.cc b/sources/cxx-stl/gabi++/src/new.cc
index de535d2..a3f610e 100644
--- a/sources/cxx-stl/gabi++/src/new.cc
+++ b/sources/cxx-stl/gabi++/src/new.cc
@@ -37,9 +37,9 @@
namespace std {
-#if !defined(GABIXX_LIBCXX)
+#if !defined(LIBCXXABI)
const nothrow_t nothrow = {};
-#endif // !defined(GABIXX_LIBCXX)
+#endif
bad_alloc::bad_alloc() _GABIXX_NOEXCEPT {
}
@@ -52,14 +52,16 @@
}
new_handler set_new_handler(new_handler next_handler) _GABIXX_NOEXCEPT {
- return __sync_lock_test_and_set(&cur_handler, next_handler);
+ return __gabixx_sync_swap(&cur_handler, next_handler);
}
+
new_handler get_new_handler() _GABIXX_NOEXCEPT {
- return __sync_fetch_and_add(&cur_handler, (new_handler)0);
+ return __gabixx_sync_load(&cur_handler);
}
} // namespace std
+#if !defined(LIBCXXABI)
_GABIXX_WEAK
void* operator new(std::size_t size) throw(std::bad_alloc) {
void* space;
@@ -68,7 +70,7 @@
if (space) {
return space;
}
- new_handler handler = cur_handler;
+ new_handler handler = std::get_new_handler();
if (handler == NULL) {
throw std::bad_alloc();
}
@@ -97,3 +99,5 @@
_GABIXX_NOEXCEPT {
return ::operator new(size, no);
}
+
+#endif // !defined(LIBCXXABI)
diff --git a/sources/cxx-stl/gabi++/src/pbase_type_info.cc b/sources/cxx-stl/gabi++/src/pbase_type_info.cc
index 9a7f215..a68d348 100644
--- a/sources/cxx-stl/gabi++/src/pbase_type_info.cc
+++ b/sources/cxx-stl/gabi++/src/pbase_type_info.cc
@@ -28,6 +28,11 @@
// pbase_type_info.cc: Methods for __pbase_type_info.
#include "cxxabi_defines.h"
+#include "typeinfo"
+
+#if __cplusplus < 201103L
+extern "C" std::type_info _ZTIDn;
+#endif
namespace __cxxabiv1
{
@@ -37,8 +42,18 @@
bool __pbase_type_info::can_catch(const __shim_type_info* thr_type,
void*& adjustedPtr) const {
- unsigned tracker = first_time_init;
- return can_catch_typeinfo_wrapper(thr_type, adjustedPtr, tracker);
+ if (can_catch_typeinfo_wrapper(thr_type, adjustedPtr, first_time_init)) {
+ return true;
+ }
+
+#if __cplusplus >= 201103L
+ // In C++ 11, the type of nullptr is std::nullptr_t, but nullptr can be
+ // casted to every pointer types. Thus, we can return true whenever
+ // the exception object is an instance of std::nullptr_t.
+ return (*thr_type == typeid(decltype(nullptr)));
+#else
+ return (*thr_type == _ZTIDn);
+#endif
}
bool __pbase_type_info::can_catch_typeinfo_wrapper(const __shim_type_info* thr_type,
diff --git a/sources/cxx-stl/gabi++/src/stdexcept.cc b/sources/cxx-stl/gabi++/src/stdexcept.cc
new file mode 100644
index 0000000..85e978d
--- /dev/null
+++ b/sources/cxx-stl/gabi++/src/stdexcept.cc
@@ -0,0 +1,173 @@
+//===------------------------ stdexcept.cpp -------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(LIBCXXABI)
+
+#include "stdexcept"
+#include "new"
+#include <cstdlib>
+#include <cstring>
+#include <cstdint>
+#include <cstddef>
+
+#if __APPLE__
+#include <dlfcn.h>
+#include <mach-o/dyld.h>
+#endif
+
+// Note: optimize for size
+
+#pragma GCC visibility push(hidden)
+
+namespace
+{
+
+class __libcpp_nmstr
+{
+private:
+ const char* str_;
+
+ typedef int count_t;
+
+ struct _Rep_base
+ {
+ std::size_t len;
+ std::size_t cap;
+ count_t count;
+ };
+
+ static const std::ptrdiff_t offset = static_cast<std::ptrdiff_t>(sizeof(_Rep_base));
+
+ count_t& count() const _NOEXCEPT {return ((_Rep_base*)(str_ - offset))->count;}
+
+#if __APPLE__
+ static
+ const void*
+ compute_gcc_empty_string_storage() _NOEXCEPT
+ {
+ void* handle = dlopen("/usr/lib/libstdc++.6.dylib", RTLD_NOLOAD);
+ if (handle == 0)
+ return 0;
+ return (const char*)dlsym(handle, "_ZNSs4_Rep20_S_empty_rep_storageE") + offset;
+ }
+
+ static
+ const void*
+ get_gcc_empty_string_storage() _NOEXCEPT
+ {
+ static const void* p = compute_gcc_empty_string_storage();
+ return p;
+ }
+#endif
+
+public:
+ explicit __libcpp_nmstr(const char* msg);
+ __libcpp_nmstr(const __libcpp_nmstr& s) _NOEXCEPT;
+ __libcpp_nmstr& operator=(const __libcpp_nmstr& s) _NOEXCEPT;
+ ~__libcpp_nmstr();
+ const char* c_str() const _NOEXCEPT {return str_;}
+};
+
+__libcpp_nmstr::__libcpp_nmstr(const char* msg)
+{
+ std::size_t len = strlen(msg);
+ str_ = static_cast<const char*>(::operator new(len + 1 + offset));
+ _Rep_base* c = (_Rep_base*)str_;
+ c->len = c->cap = len;
+ str_ += offset;
+ count() = 0;
+ std::memcpy(const_cast<char*>(c_str()), msg, len + 1);
+}
+
+inline
+__libcpp_nmstr::__libcpp_nmstr(const __libcpp_nmstr& s) _NOEXCEPT
+ : str_(s.str_)
+{
+#if __APPLE__
+ if (str_ != get_gcc_empty_string_storage())
+#endif
+ __sync_add_and_fetch(&count(), 1);
+}
+
+__libcpp_nmstr&
+__libcpp_nmstr::operator=(const __libcpp_nmstr& s) _NOEXCEPT
+{
+ const char* p = str_;
+ str_ = s.str_;
+#if __APPLE__
+ if (str_ != get_gcc_empty_string_storage())
+#endif
+ __sync_add_and_fetch(&count(), 1);
+#if __APPLE__
+ if (p != get_gcc_empty_string_storage())
+#endif
+ if (__sync_add_and_fetch((count_t*)(p-sizeof(count_t)), count_t(-1)) < 0)
+ {
+ ::operator delete(const_cast<char*>(p-offset));
+ }
+ return *this;
+}
+
+inline
+__libcpp_nmstr::~__libcpp_nmstr()
+{
+#if __APPLE__
+ if (str_ != get_gcc_empty_string_storage())
+#endif
+ if (__sync_add_and_fetch(&count(), count_t(-1)) < 0)
+ {
+ ::operator delete(const_cast<char*>(str_ - offset));
+ }
+}
+
+}
+
+#pragma GCC visibility pop
+
+namespace std // purposefully not using versioning namespace
+{
+
+logic_error::~logic_error() _NOEXCEPT
+{
+ __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_;
+ s.~__libcpp_nmstr();
+}
+
+const char*
+logic_error::what() const _NOEXCEPT
+{
+ __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_;
+ return s.c_str();
+}
+
+runtime_error::~runtime_error() _NOEXCEPT
+{
+ __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_;
+ s.~__libcpp_nmstr();
+}
+
+const char*
+runtime_error::what() const _NOEXCEPT
+{
+ __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_;
+ return s.c_str();
+}
+
+domain_error::~domain_error() _NOEXCEPT {}
+invalid_argument::~invalid_argument() _NOEXCEPT {}
+length_error::~length_error() _NOEXCEPT {}
+out_of_range::~out_of_range() _NOEXCEPT {}
+
+range_error::~range_error() _NOEXCEPT {}
+overflow_error::~overflow_error() _NOEXCEPT {}
+underflow_error::~underflow_error() _NOEXCEPT {}
+
+} // std
+
+#endif // LIBCXXABI
diff --git a/sources/cxx-stl/gabi++/src/terminate.cc b/sources/cxx-stl/gabi++/src/terminate.cc
index 0a03242..7268001 100644
--- a/sources/cxx-stl/gabi++/src/terminate.cc
+++ b/sources/cxx-stl/gabi++/src/terminate.cc
@@ -32,13 +32,21 @@
namespace {
std::terminate_handler current_terminate = __gabixx::__default_terminate;
-std::unexpected_handler current_unexpected = __gabixx::__default_terminate;
+std::unexpected_handler current_unexpected = __gabixx::__default_unexpected;
} // namespace
namespace __gabixx {
+// The default std::unexpected() implementation will delegate to
+// std::terminate() so that the user-defined std::terminate() handler can
+// get the chance to be invoked.
+//
+_GABIXX_NORETURN void __default_unexpected(void) {
+ std::terminate();
+}
+
// The default std::terminate() implementation will crash the process.
// This is done to help debugging, i.e.:
// - When running the program in a debugger, it's trivial to get
@@ -87,26 +95,26 @@
namespace std {
-terminate_handler get_terminate() {
+terminate_handler get_terminate() _GABIXX_NOEXCEPT {
return __gabixx_sync_load(¤t_terminate);
}
-terminate_handler set_terminate(terminate_handler f) {
+terminate_handler set_terminate(terminate_handler f) _GABIXX_NOEXCEPT {
if (!f)
f = __gabixx::__default_terminate;
return __gabixx_sync_swap(¤t_terminate, f);
}
-_GABIXX_NORETURN void terminate() {
+_GABIXX_NORETURN void terminate() _GABIXX_NOEXCEPT_CXX11_ONLY {
__gabixx::__terminate(std::get_terminate());
}
-unexpected_handler get_unexpected() {
+unexpected_handler get_unexpected() _GABIXX_NOEXCEPT {
return __gabixx_sync_load(¤t_unexpected);
}
-unexpected_handler set_unexpected(unexpected_handler f) {
+unexpected_handler set_unexpected(unexpected_handler f) _GABIXX_NOEXCEPT {
if (!f)
f = __gabixx::__default_terminate;
@@ -114,7 +122,11 @@
}
_GABIXX_NORETURN void unexpected() {
- (*get_unexpected())();
+ unexpected_handler handler = std::get_unexpected();
+ if (handler)
+ (*handler)();
+
+ // If the handler returns, then call terminate().
terminate();
}
diff --git a/sources/cxx-stl/gabi++/src/type_info.cc b/sources/cxx-stl/gabi++/src/type_info.cc
index fedc144..3830b72 100644
--- a/sources/cxx-stl/gabi++/src/type_info.cc
+++ b/sources/cxx-stl/gabi++/src/type_info.cc
@@ -43,7 +43,7 @@
{
}
-#if !defined(GABIXX_LIBCXX)
+#if !defined(LIBCXXABI)
bool
type_info::operator==(const type_info& rhs) const
{
@@ -73,6 +73,26 @@
return this < &rhs;
#endif
}
+#endif // !defined(LIBCXXABI)
-#endif // !defined(GABIXX_LIBCXX)
+bad_cast::bad_cast() _GABIXX_NOEXCEPT {
+}
+
+bad_cast::~bad_cast() _GABIXX_NOEXCEPT {
+}
+
+const char* bad_cast::what() const _GABIXX_NOEXCEPT {
+ return "std::bad_cast";
+}
+
+bad_typeid::bad_typeid() _GABIXX_NOEXCEPT {
+}
+
+bad_typeid::~bad_typeid() _GABIXX_NOEXCEPT {
+}
+
+const char* bad_typeid::what() const _GABIXX_NOEXCEPT {
+ return "std::bad_typeid";
+}
+
} // end namespace std
diff --git a/sources/cxx-stl/gabi++/tests/Android.mk b/sources/cxx-stl/gabi++/tests/Android.mk
index df61317..3cda291 100644
--- a/sources/cxx-stl/gabi++/tests/Android.mk
+++ b/sources/cxx-stl/gabi++/tests/Android.mk
@@ -41,10 +41,24 @@
$(call do_test_simple,test_vector1)
$(call do_test_simple,test_vector2)
$(call do_test_simple,test_vector3)
+$(call do_test_simple,unexpected_01,-std=c++11)
+$(call do_test_simple,unexpected_02,-std=c++11)
+$(call do_test_simple,unexpected_03)
$(call do_test_simple,unwind_01)
$(call do_test_simple,unwind_02)
$(call do_test_simple,unwind_03)
$(call do_test_simple,unwind_04)
$(call do_test_simple,unwind_05)
+include $(CLEAR_VARS)
+LOCAL_MODULE := libtest_malloc_lockup
+LOCAL_SRC_FILES := libtest_malloc_lockup.cpp
+LOCAL_STATIC_LIBRARIES := gabi++_static
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := malloc_lockup
+LOCAL_SRC_FILES := malloc_lockup.cpp
+include $(BUILD_EXECUTABLE)
+
$(call import-module,cxx-stl/gabi++)
diff --git a/sources/cxx-stl/gabi++/tests/dynamic_cast3.cpp b/sources/cxx-stl/gabi++/tests/dynamic_cast3.cpp
index a4c946b..8872257 100644
--- a/sources/cxx-stl/gabi++/tests/dynamic_cast3.cpp
+++ b/sources/cxx-stl/gabi++/tests/dynamic_cast3.cpp
@@ -1041,7 +1041,7 @@
};
struct A2
- : private virtual A1
+ : protected virtual A1
{
char _[34981];
virtual ~A2() {}
@@ -1216,7 +1216,7 @@
};
struct A2
- : private virtual A1
+ : protected virtual A1
{
char _[34981];
virtual ~A2() {}
@@ -1330,7 +1330,7 @@
};
struct A2
- : private virtual A1
+ : protected virtual A1
{
char _[34981];
virtual ~A2() {}
@@ -1387,7 +1387,7 @@
};
struct A2
- : private virtual A1
+ : protected virtual A1
{
char _[34981];
virtual ~A2() {}
diff --git a/sources/cxx-stl/gabi++/tests/libtest_malloc_lockup.cpp b/sources/cxx-stl/gabi++/tests/libtest_malloc_lockup.cpp
new file mode 100644
index 0000000..107e877
--- /dev/null
+++ b/sources/cxx-stl/gabi++/tests/libtest_malloc_lockup.cpp
@@ -0,0 +1,55 @@
+// Copyright (C) 2011 The Android Open Source Project
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the project nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+// SUCH DAMAGE.
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <cxxabi.h>
+
+#define PAYLOAD(s) s, sizeof(s) - 1
+
+// Override malloc() and free() to ensure they are never called!
+//
+// Because GAbi++ is statically linked into this shared library with -Bsymbolic,
+// any malloc() and free() calls it contains will be compiled as direct calls to
+// this function, bypassing the dynamic linker's PLT indirections and avoiding
+// the symbols from the C library.
+extern "C" void* malloc(size_t size) {
+ write(2, PAYLOAD("ERROR: malloc called!"));
+ exit(1);
+}
+
+extern "C" void free(void*) {
+ write(2, PAYLOAD("ERROR: free called!"));
+ exit(2);
+}
+
+// Called by the test program to force creation of a thread-specific
+// C++ runtime object.
+extern "C" void* get_globals() {
+ return (void*) __cxxabiv1::__cxa_get_globals();
+}
diff --git a/sources/cxx-stl/gabi++/tests/malloc_lockup.cpp b/sources/cxx-stl/gabi++/tests/malloc_lockup.cpp
new file mode 100644
index 0000000..12bf5b1
--- /dev/null
+++ b/sources/cxx-stl/gabi++/tests/malloc_lockup.cpp
@@ -0,0 +1,175 @@
+// Copyright (C) 2013 The Android Open Source Project
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the project nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+// SUCH DAMAGE.
+
+// A test used to check that __cxa_get_globals() does not use malloc.
+// This will do the following:
+//
+// - Lazily load libtest_malloc_lockup.so, which includes a copy of
+// GAbi++ linked with malloc() / free() functions that exit() with
+// an error if called.
+//
+// - Create a large number of concurrent threads, and have each one
+// call the library's 'get_globals' function, which returns the
+// result of __cxa_get_globals() linked against the special mallocs,
+// then store the value in a global array.
+//
+// - Tell all the threads to stop, wait for them to complete.
+//
+// - Look at the values stored in the global arrays. They should not be NULL
+// (to indicate succesful allocation), and all different (each one should
+// correspond to a thread-specific instance of __cxa_eh_globals).
+//
+// - Unload the library.
+//
+
+#include <dlfcn.h>
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+typedef void* (*get_globals_fn)();
+
+static get_globals_fn g_get_globals;
+
+// Number of threads to create. Must be > 4096 to really check slab allocation.
+static const size_t kMaxThreads = 5000;
+
+static pthread_t g_threads[kMaxThreads];
+static void* g_thread_objects[kMaxThreads];
+
+static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t g_cond_exit = PTHREAD_COND_INITIALIZER;
+static pthread_cond_t g_cond_counter = PTHREAD_COND_INITIALIZER;
+static unsigned g_thread_count = 0;
+static bool g_can_exit = false;
+
+// Thread routine, just call 'get_globals' and store the result in our global
+// array, then wait for an event from the main thread. This guarantees that
+// no thread exits before another one starts, and thus that allocation slots
+// are not reused.
+static void* my_thread(void* param) {
+ // Get thread-specific object pointer, store it in global array.
+ int id = (int)param;
+ g_thread_objects[id] = (*g_get_globals)();
+
+ // Increment global thread counter and tell the main thread about this.
+ pthread_mutex_lock(&g_lock);
+ g_thread_count += 1;
+ pthread_cond_signal(&g_cond_counter);
+
+ // The thread object will be automatically released/recycled when the thread
+ // exits. Wait here until signaled by the main thread to avoid this.
+ while (!g_can_exit)
+ pthread_cond_wait(&g_cond_exit, &g_lock);
+ pthread_mutex_unlock(&g_lock);
+
+ return NULL;
+}
+
+int main(void) {
+ // Load the library.
+ void* lib = dlopen("libtest_malloc_lockup.so", RTLD_NOW);
+ if (!lib) {
+ fprintf(stderr, "ERROR: Can't find library: %s\n", strerror(errno));
+ return 1;
+ }
+
+ // Extract 'get_globals' function address.
+ g_get_globals = reinterpret_cast<get_globals_fn>(dlsym(lib, "get_globals"));
+ if (!g_get_globals) {
+ fprintf(stderr, "ERROR: Could not find 'get_globals' function: %s\n",
+ dlerror());
+ dlclose(lib);
+ return 1;
+ }
+
+ // Use a smaller stack per thread to be able to create lots of them.
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setstacksize(&attr, 16384);
+
+ // Start as many threads as needed.
+ printf("Creating %d threads\n", kMaxThreads);
+ for (size_t n = 0; n < kMaxThreads; ++n) {
+ int ret = pthread_create(&g_threads[n], &attr, my_thread, (void*)n);
+ if (ret != 0) {
+ fprintf(stderr, "ERROR: Thread #%d creation error: %s\n",
+ n + 1, strerror(errno));
+ return 2;
+ }
+ }
+
+ // Wait until they all ran, then tell them to exit.
+ printf("Waiting for all threads to run\n");
+ pthread_mutex_lock(&g_lock);
+ while (g_thread_count < kMaxThreads)
+ pthread_cond_wait(&g_cond_counter, &g_lock);
+
+ printf("Waking up threads\n");
+ g_can_exit = true;
+ pthread_cond_broadcast(&g_cond_exit);
+ pthread_mutex_unlock(&g_lock);
+
+ // Wait for them to complete.
+ printf("Waiting for all threads to complete\n");
+ for (size_t n = 0; n < kMaxThreads; ++n) {
+ void* dummy;
+ pthread_join(g_threads[n], &dummy);
+ }
+
+ // Verify that the thread objects are all non-NULL and different.
+ printf("Checking results\n");
+ size_t failures = 0;
+ const size_t kMaxFailures = 16;
+ for (size_t n = 0; n < kMaxThreads; ++n) {
+ void* obj = g_thread_objects[n];
+ if (obj == NULL) {
+ if (++failures < kMaxFailures)
+ printf("Thread %d got a NULL object!\n", n + 1);
+ } else {
+ for (size_t m = n + 1; m < kMaxThreads; ++m) {
+ if (g_thread_objects[m] == obj) {
+ if (++failures < kMaxFailures)
+ printf("Thread %d has same object as thread %d (%p)\n",
+ n + 1, m + 1, obj);
+ }
+ }
+ }
+ }
+
+ // We're done.
+ dlclose(lib);
+ if (failures > 0) {
+ fprintf(stderr, "%d failures detected!\n", failures);
+ return 1;
+ }
+
+ printf("All OK!\n");
+ return 0;
+}
diff --git a/sources/cxx-stl/gabi++/tests/unexpected_01.cpp b/sources/cxx-stl/gabi++/tests/unexpected_01.cpp
new file mode 100644
index 0000000..6522263
--- /dev/null
+++ b/sources/cxx-stl/gabi++/tests/unexpected_01.cpp
@@ -0,0 +1,19 @@
+#include <cassert>
+#include <exception>
+
+void throw_exception() {
+ throw 1;
+}
+
+int main() {
+ std::set_unexpected(throw_exception);
+ try {
+ std::unexpected(); // it is OK to throw exception from std::unexpected()
+ assert(false);
+ } catch (int) {
+ assert(true);
+ } catch (...) {
+ assert(false);
+ }
+ return 0;
+}
diff --git a/sources/cxx-stl/gabi++/tests/unexpected_02.cpp b/sources/cxx-stl/gabi++/tests/unexpected_02.cpp
new file mode 100644
index 0000000..ea3b9cd
--- /dev/null
+++ b/sources/cxx-stl/gabi++/tests/unexpected_02.cpp
@@ -0,0 +1,24 @@
+#include <cassert>
+#include <cstdlib>
+#include <exception>
+
+void expected_terminate() {
+ exit(0);
+}
+
+void throw_exception() {
+ // do nothing and return, so that std::terminate() can be invoked.
+}
+
+int main() {
+ std::set_terminate(expected_terminate);
+ std::set_unexpected(throw_exception);
+ try {
+ std::unexpected();
+ assert(false);
+ } catch (...) {
+ assert(false);
+ }
+ assert(false);
+ return 1;
+}
diff --git a/sources/cxx-stl/gabi++/tests/unexpected_03.cpp b/sources/cxx-stl/gabi++/tests/unexpected_03.cpp
new file mode 100644
index 0000000..cf4d90e
--- /dev/null
+++ b/sources/cxx-stl/gabi++/tests/unexpected_03.cpp
@@ -0,0 +1,19 @@
+#include <cassert>
+#include <cstdlib>
+#include <exception>
+
+void expected_terminate() {
+ exit(0);
+}
+
+int main() {
+ std::set_terminate(expected_terminate);
+ try {
+ std::unexpected();
+ assert(false);
+ } catch (...) {
+ assert(false);
+ }
+ assert(false);
+ return 1;
+}
diff --git a/sources/cxx-stl/llvm-libc++/Android.mk b/sources/cxx-stl/llvm-libc++/Android.mk
index 33b4a8b..5d4c935 100644
--- a/sources/cxx-stl/llvm-libc++/Android.mk
+++ b/sources/cxx-stl/llvm-libc++/Android.mk
@@ -44,20 +44,9 @@
#
llvm_libc++_cxxflags += -fno-rtti
-# LIBCXXRT tells the library to support building against the libcxxrt
-# C++ runtime, instead of GNU libsupc++.
+# Gabi++ emulates libcxxabi when building libcxx.
#
-llvm_libc++_cxxflags += -DLIBCXXRT=1
-
-# Since libcxxrt seems to hard to port to Android, use GAbi++ instead.
-# The GAbi++ sources are compiled with the GABIXX_LIBCXX macro defined
-# to tell them they'll be part of libc++.
-#
-# This is also used in a couple of places inside of libc++ to deal with
-# a few cases where GAbi++ doesn't support the libcxxrt ABI perfectly
-# yet.
-#
-llvm_libc++_cxxflags += -DGABIXX_LIBCXX
+llvm_libc++_cxxflags += -DLIBCXXABI=1
# Find the GAbi++ sources to include them here.
# The voodoo below is to allow building libc++ out of the NDK source
diff --git a/sources/cxx-stl/llvm-libc++/libcxx/include/exception b/sources/cxx-stl/llvm-libc++/libcxx/include/exception
index 37bfc57..22bea11 100644
--- a/sources/cxx-stl/llvm-libc++/libcxx/include/exception
+++ b/sources/cxx-stl/llvm-libc++/libcxx/include/exception
@@ -112,7 +112,11 @@
typedef void (*terminate_handler)();
_LIBCPP_FUNC_VIS terminate_handler set_terminate(terminate_handler) _NOEXCEPT;
_LIBCPP_FUNC_VIS terminate_handler get_terminate() _NOEXCEPT;
+#if __cplusplus >= 201103L
_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void terminate() _NOEXCEPT;
+#else
+_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void terminate();
+#endif
_LIBCPP_FUNC_VIS bool uncaught_exception() _NOEXCEPT;
diff --git a/sources/cxx-stl/llvm-libc++/libcxx/src/exception.cpp b/sources/cxx-stl/llvm-libc++/libcxx/src/exception.cpp
index 1d2f6b2..a01c193 100644
--- a/sources/cxx-stl/llvm-libc++/libcxx/src/exception.cpp
+++ b/sources/cxx-stl/llvm-libc++/libcxx/src/exception.cpp
@@ -27,7 +27,7 @@
#define __terminate_handler __cxxabiapple::__cxa_terminate_handler
#define __unexpected_handler __cxxabiapple::__cxa_unexpected_handler
#endif // _LIBCPPABI_VERSION
-#elif defined(LIBCXXRT) || __has_include(<cxxabi.h>)
+#elif defined(LIBCXXRT) || __has_include(<cxxabi.h>) || defined(__ANDROID__)
#include <cxxabi.h>
using namespace __cxxabiv1;
#if defined(LIBCXXRT) || defined(_LIBCPPABI_VERSION)
diff --git a/sources/cxx-stl/llvm-libc++/libcxx/src/new.cpp b/sources/cxx-stl/llvm-libc++/libcxx/src/new.cpp
index 472c54f..0219fbf 100644
--- a/sources/cxx-stl/llvm-libc++/libcxx/src/new.cpp
+++ b/sources/cxx-stl/llvm-libc++/libcxx/src/new.cpp
@@ -25,7 +25,7 @@
#define __new_handler __cxxabiapple::__cxa_new_handler
#endif
#else // __APPLE__
- #if defined(LIBCXXRT) || __has_include(<cxxabi.h>)
+ #if defined(LIBCXXRT) || __has_include(<cxxabi.h>) || defined(__ANDROID__)
#include <cxxabi.h>
#endif // __has_include(<cxxabi.h>)
#ifndef _LIBCPPABI_VERSION
@@ -144,13 +144,10 @@
namespace std
{
-#ifndef GABIXX_LIBCXX
const nothrow_t nothrow = {};
-#endif
#if !defined(_LIBCPPABI_VERSION)
-#if !defined(GABIXX_LIBCXX)
new_handler
set_new_handler(new_handler handler) _NOEXCEPT
{
@@ -162,7 +159,6 @@
{
return __sync_fetch_and_add(&__new_handler, (new_handler)0);
}
-#endif
#if !defined(LIBCXXRT)
@@ -196,7 +192,7 @@
return "bad_array_new_length";
}
-#endif // !_LIBCPPABI_VERSION && !GABIXX_LIBCXX
+#endif // !_LIBCPPABI_VERSION
void
__throw_bad_alloc()
diff --git a/sources/cxx-stl/llvm-libc++/libcxx/src/stdexcept.cpp b/sources/cxx-stl/llvm-libc++/libcxx/src/stdexcept.cpp
index 8d25f3e..3213f26 100644
--- a/sources/cxx-stl/llvm-libc++/libcxx/src/stdexcept.cpp
+++ b/sources/cxx-stl/llvm-libc++/libcxx/src/stdexcept.cpp
@@ -22,7 +22,7 @@
#ifdef __APPLE__
#include <cxxabi.h>
-#elif defined(LIBCXXRT) || __has_include(<cxxabi.h>)
+#elif defined(LIBCXXRT) || __has_include(<cxxabi.h>) || defined(__ANDROID__)
#include <cxxabi.h>
#endif
diff --git a/sources/cxx-stl/llvm-libc++/libcxx/src/support/android/locale_android.cpp b/sources/cxx-stl/llvm-libc++/libcxx/src/support/android/locale_android.cpp
index 4224231..7193028 100644
--- a/sources/cxx-stl/llvm-libc++/libcxx/src/support/android/locale_android.cpp
+++ b/sources/cxx-stl/llvm-libc++/libcxx/src/support/android/locale_android.cpp
@@ -17,7 +17,7 @@
// Note that the header does define a _B flag (as 0x80), but it
// is only set on the space (32) character, and used to implement
// isprint() properly. The implementation of isblank() relies on
-// direct comparisons with 7 and 32 instead.
+// direct comparisons with 9 and 32 instead.
//
// The following is a local copy of the Bionic _ctype_ array that has
// been modified in the following way:
@@ -25,7 +25,7 @@
// - It stores 16-bit unsigned values, instead of 8-bit char ones.
//
// - Bit flag _BLANK (0x100) is used to indicate blank characters.
-// It is only set for indices 7 (TAB) and 32 (SPACE).
+// It is only set for indices 9 (TAB) and 32 (SPACE).
//
// - Support signed char properly for indexing.
diff --git a/sources/cxx-stl/llvm-libc++/libcxx/src/typeinfo.cpp b/sources/cxx-stl/llvm-libc++/libcxx/src/typeinfo.cpp
index 6082894..19556fe 100644
--- a/sources/cxx-stl/llvm-libc++/libcxx/src/typeinfo.cpp
+++ b/sources/cxx-stl/llvm-libc++/libcxx/src/typeinfo.cpp
@@ -14,7 +14,7 @@
#ifdef __APPLE__
#include <cxxabi.h>
-#elif defined(LIBCXXRT) || __has_include(<cxxabi.h>)
+#elif defined(LIBCXXRT) || __has_include(<cxxabi.h>) || defined(__ANDROID__)
#include <cxxabi.h>
#endif
diff --git a/sources/cxx-stl/llvm-libc++/libcxx/test/testit_android b/sources/cxx-stl/llvm-libc++/libcxx/test/testit_android
index ee25f19..9c78f5f 100755
--- a/sources/cxx-stl/llvm-libc++/libcxx/test/testit_android
+++ b/sources/cxx-stl/llvm-libc++/libcxx/test/testit_android
@@ -222,24 +222,13 @@
if [ -z "$OPTIONS" ]
then
- OPTIONS="-std=c++11 -O2 -g"
+ OPTIONS="-std=c++11 -O0 -g"
fi
OPTIONS="$OPTIONS $TOOLCHAIN_CFLAGS $TOOLCHAIN_LDFLAGS"
OPTIONS="$OPTIONS -I$LIBCXX_ROOT/test/support"
# llvm-libc++/libcxx/test/lit.cfg line #294 defineds the following for testing on Linux
OPTIONS="$OPTIONS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS"
-if [ -z "$HEADER_INCLUDE" ]
-then
- HEADER_INCLUDE="-I$LIBCXX_ROOT/include -I$ANDROID_SUPPORT/include"
-fi
-
-if [ -z "$SOURCE_LIB" ]
-then
- SOURCE_LIB="-L$LIBCXX_LIBS"
-fi
-SOURCE_LIB="$SOURCE_LIB -L$LIBCOMPILER_RT_LIBS"
-
if [ -z "$ADB" ]
then
ADB=adb
@@ -289,7 +278,7 @@
if [ "$DO_STATIC" ]; then
# Statically link to ensure the executable can be run easily through ADB
- LIBS="-lc++_static -lcompiler_rt_static -latomic"
+ LIBS="-lcompiler_rt_static -latomic"
else
run2 $ADB push $LIBCXX_LIBS/libc++_shared.so $TARGET_PATH 2>/dev/null
if [ $? != 0 ]; then
diff --git a/sources/host-tools/ndk-stack/GNUmakefile b/sources/host-tools/ndk-stack/GNUmakefile
index 3f7db51..24ee8f5 100644
--- a/sources/host-tools/ndk-stack/GNUmakefile
+++ b/sources/host-tools/ndk-stack/GNUmakefile
@@ -47,6 +47,8 @@
elff/elff_api.cc \
elff/mapfile.c
+BINUTILS_SOURCES := binutils/addr2line.c
+
REGEX_SOURCES := regex/regcomp.c \
regex/regerror.c \
regex/regexec.c \
@@ -55,7 +57,11 @@
NDK_STACK_SOURCES := ndk-stack.c \
ndk-stack-parser.c
+ifdef WITH_LIBBFD
+SOURCES := $(NDK_STACK_SOURCES) $(BINUTILS_SOURCES) $(REGEX_SOURCES)
+else
SOURCES := $(NDK_STACK_SOURCES) $(ELFF_SOURCES) $(REGEX_SOURCES)
+endif
OBJECTS=
@@ -85,5 +91,5 @@
rm -f $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
- $(CXX) $(LDFLAGS) $(OBJECTS) -o $@ $(EXTRA_LDFLAGS)
+ $(CXX) $(OBJECTS) $(LDFLAGS) -o $@ $(EXTRA_LDFLAGS)
$(call strip-cmd,$@)
diff --git a/sources/host-tools/ndk-stack/binutils/COPYING3 b/sources/host-tools/ndk-stack/binutils/COPYING3
new file mode 100644
index 0000000..94a9ed0
--- /dev/null
+++ b/sources/host-tools/ndk-stack/binutils/COPYING3
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/sources/host-tools/ndk-stack/binutils/addr2line.c b/sources/host-tools/ndk-stack/binutils/addr2line.c
new file mode 100644
index 0000000..b87713e
--- /dev/null
+++ b/sources/host-tools/ndk-stack/binutils/addr2line.c
@@ -0,0 +1,491 @@
+/* addr2line.c -- convert addresses to line number and function name
+ Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+ 2007, 2009 Free Software Foundation, Inc.
+ Contributed by Ulrich Lauther <Ulrich.Lauther@mchp.siemens.de>
+
+ This file is part of GNU Binutils.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+
+/* Derived from objdump.c and nm.c by Ulrich.Lauther@mchp.siemens.de
+
+ Usage:
+ addr2line [options] addr addr ...
+ or
+ addr2line [options]
+
+ both forms write results to stdout, the second form reads addresses
+ to be converted from stdin. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "getopt.h"
+#include "libiberty.h"
+#include "demangle.h"
+#include "bucomm.h"
+#include "elf-bfd.h"
+
+static bfd_boolean unwind_inlines; /* -i, unwind inlined functions. */
+static bfd_boolean with_addresses; /* -a, show addresses. */
+static bfd_boolean with_functions; /* -f, show function names. */
+static bfd_boolean do_demangle; /* -C, demangle names. */
+static bfd_boolean pretty_print; /* -p, print on one line. */
+static bfd_boolean base_names; /* -s, strip directory names. */
+
+static int naddr; /* Number of addresses to process. */
+static char **addr; /* Hex addresses to process. */
+
+static asymbol **syms; /* Symbol table. */
+
+static struct option long_options[] =
+{
+ {"addresses", no_argument, NULL, 'a'},
+ {"basenames", no_argument, NULL, 's'},
+ {"demangle", optional_argument, NULL, 'C'},
+ {"exe", required_argument, NULL, 'e'},
+ {"functions", no_argument, NULL, 'f'},
+ {"inlines", no_argument, NULL, 'i'},
+ {"pretty-print", no_argument, NULL, 'p'},
+ {"section", required_argument, NULL, 'j'},
+ {"target", required_argument, NULL, 'b'},
+ {"help", no_argument, NULL, 'H'},
+ {"version", no_argument, NULL, 'V'},
+ {0, no_argument, 0, 0}
+};
+
+static void usage (FILE *, int);
+static void slurp_symtab (bfd *);
+static void find_address_in_section (bfd *, asection *, void *);
+static void find_offset_in_section (bfd *, asection *);
+static void translate_addresses (bfd *, asection *);
+
+/* Print a usage message to STREAM and exit with STATUS. */
+
+static void
+usage (FILE *stream, int status)
+{
+ fprintf (stream, _("Usage: %s [option(s)] [addr(s)]\n"), program_name);
+ fprintf (stream, _(" Convert addresses into line number/file name pairs.\n"));
+ fprintf (stream, _(" If no addresses are specified on the command line, they will be read from stdin\n"));
+ fprintf (stream, _(" The options are:\n\
+ @<file> Read options from <file>\n\
+ -a --addresses Show addresses\n\
+ -b --target=<bfdname> Set the binary file format\n\
+ -e --exe=<executable> Set the input file name (default is a.out)\n\
+ -i --inlines Unwind inlined functions\n\
+ -j --section=<name> Read section-relative offsets instead of addresses\n\
+ -p --pretty-print Make the output easier to read for humans\n\
+ -s --basenames Strip directory names\n\
+ -f --functions Show function names\n\
+ -C --demangle[=style] Demangle function names\n\
+ -h --help Display this information\n\
+ -v --version Display the program's version\n\
+\n"));
+
+ list_supported_targets (program_name, stream);
+ if (REPORT_BUGS_TO[0] && status == 0)
+ fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
+ exit (status);
+}
+
+/* Read in the symbol table. */
+
+static void
+slurp_symtab (bfd *abfd)
+{
+ long storage;
+ long symcount;
+ bfd_boolean dynamic = FALSE;
+
+ if ((bfd_get_file_flags (abfd) & HAS_SYMS) == 0)
+ return;
+
+ storage = bfd_get_symtab_upper_bound (abfd);
+ if (storage == 0)
+ {
+ storage = bfd_get_dynamic_symtab_upper_bound (abfd);
+ dynamic = TRUE;
+ }
+ if (storage < 0)
+ bfd_fatal (bfd_get_filename (abfd));
+
+ syms = (asymbol **) xmalloc (storage);
+ if (dynamic)
+ symcount = bfd_canonicalize_dynamic_symtab (abfd, syms);
+ else
+ symcount = bfd_canonicalize_symtab (abfd, syms);
+ if (symcount < 0)
+ bfd_fatal (bfd_get_filename (abfd));
+}
+
+/* These global variables are used to pass information between
+ translate_addresses and find_address_in_section. */
+
+static bfd_vma pc;
+static const char *filename;
+static const char *functionname;
+static unsigned int line;
+static unsigned int discriminator;
+static bfd_boolean found;
+
+/* Look for an address in a section. This is called via
+ bfd_map_over_sections. */
+
+static void
+find_address_in_section (bfd *abfd, asection *section,
+ void *data ATTRIBUTE_UNUSED)
+{
+ bfd_vma vma;
+ bfd_size_type size;
+
+ if (found)
+ return;
+
+ if ((bfd_get_section_flags (abfd, section) & SEC_ALLOC) == 0)
+ return;
+
+ vma = bfd_get_section_vma (abfd, section);
+ if (pc < vma)
+ return;
+
+ size = bfd_get_section_size (section);
+ if (pc >= vma + size)
+ return;
+
+ found = bfd_find_nearest_line_discriminator (abfd, section, syms, pc - vma,
+ &filename, &functionname,
+ &line, &discriminator);
+}
+
+/* Look for an offset in a section. This is directly called. */
+
+static void
+find_offset_in_section (bfd *abfd, asection *section)
+{
+ bfd_size_type size;
+
+ if (found)
+ return;
+
+ if ((bfd_get_section_flags (abfd, section) & SEC_ALLOC) == 0)
+ return;
+
+ size = bfd_get_section_size (section);
+ if (pc >= size)
+ return;
+
+ found = bfd_find_nearest_line_discriminator (abfd, section, syms, pc,
+ &filename, &functionname,
+ &line, &discriminator);
+}
+
+/* Read hexadecimal addresses from stdin, translate into
+ file_name:line_number and optionally function name. */
+
+static void
+translate_addresses (bfd *abfd, asection *section)
+{
+ int read_stdin = (naddr == 0);
+
+ for (;;)
+ {
+ if (read_stdin)
+ {
+ char addr_hex[100];
+
+ if (fgets (addr_hex, sizeof addr_hex, stdin) == NULL)
+ break;
+ pc = bfd_scan_vma (addr_hex, NULL, 16);
+ }
+ else
+ {
+ if (naddr <= 0)
+ break;
+ --naddr;
+ pc = bfd_scan_vma (*addr++, NULL, 16);
+ }
+
+ if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
+ {
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ bfd_vma sign = (bfd_vma) 1 << (bed->s->arch_size - 1);
+
+ pc &= (sign << 1) - 1;
+ if (bed->sign_extend_vma)
+ pc = (pc ^ sign) - sign;
+ }
+
+ if (with_addresses)
+ {
+ printf ("0x");
+ bfd_printf_vma (abfd, pc);
+
+ if (pretty_print)
+ printf (": ");
+ else
+ printf ("\n");
+ }
+
+ found = FALSE;
+ if (section)
+ find_offset_in_section (abfd, section);
+ else
+ bfd_map_over_sections (abfd, find_address_in_section, NULL);
+
+ if (! found)
+ {
+ if (with_functions)
+ printf ("??\n");
+ printf ("??:0\n");
+ }
+ else
+ {
+ while (1)
+ {
+ if (with_functions)
+ {
+ const char *name;
+ char *alloc = NULL;
+
+ name = functionname;
+ if (name == NULL || *name == '\0')
+ name = "??";
+ else if (do_demangle)
+ {
+ alloc = bfd_demangle (abfd, name, DMGL_ANSI | DMGL_PARAMS);
+ if (alloc != NULL)
+ name = alloc;
+ }
+
+ printf ("%s", name);
+ if (pretty_print)
+ /* Note for translators: This printf is used to join the
+ function name just printed above to the line number/
+ file name pair that is about to be printed below. Eg:
+
+ foo at 123:bar.c */
+ printf (_(" at "));
+ else
+ printf ("\n");
+
+ if (alloc != NULL)
+ free (alloc);
+ }
+
+ if (base_names && filename != NULL)
+ {
+ char *h;
+
+ h = strrchr (filename, '/');
+ if (h != NULL)
+ filename = h + 1;
+ }
+
+ printf ("%s:", filename ? filename : "??");
+ if (line != 0)
+ {
+ if (discriminator != 0)
+ printf ("%u (discriminator %u)\n", line, discriminator);
+ else
+ printf ("%u\n", line);
+ }
+ else
+ printf ("?\n");
+ if (!unwind_inlines)
+ found = FALSE;
+ else
+ found = bfd_find_inliner_info (abfd, &filename, &functionname,
+ &line);
+ if (! found)
+ break;
+ if (pretty_print)
+ /* Note for translators: This printf is used to join the
+ line number/file name pair that has just been printed with
+ the line number/file name pair that is going to be printed
+ by the next iteration of the while loop. Eg:
+
+ 123:bar.c (inlined by) 456:main.c */
+ printf (_(" (inlined by) "));
+ }
+ }
+
+ /* fflush() is essential for using this command as a server
+ child process that reads addresses from a pipe and responds
+ with line number information, processing one address at a
+ time. */
+ fflush (stdout);
+ }
+}
+
+/* Process a file. Returns an exit value for main(). */
+
+static int
+process_file (const char *file_name, const char *section_name,
+ const char *target)
+{
+ bfd *abfd;
+ asection *section;
+ char **matching;
+
+ if (get_file_size (file_name) < 1)
+ return 1;
+
+ abfd = bfd_openr (file_name, target);
+ if (abfd == NULL)
+ bfd_fatal (file_name);
+
+ /* Decompress sections. */
+ abfd->flags |= BFD_DECOMPRESS;
+
+ if (bfd_check_format (abfd, bfd_archive))
+ fatal (_("%s: cannot get addresses from archive"), file_name);
+
+ if (! bfd_check_format_matches (abfd, bfd_object, &matching))
+ {
+ bfd_nonfatal (bfd_get_filename (abfd));
+ if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
+ {
+ list_matching_formats (matching);
+ free (matching);
+ }
+ xexit (1);
+ }
+
+ if (section_name != NULL)
+ {
+ section = bfd_get_section_by_name (abfd, section_name);
+ if (section == NULL)
+ fatal (_("%s: cannot find section %s"), file_name, section_name);
+ }
+ else
+ section = NULL;
+
+ slurp_symtab (abfd);
+
+ translate_addresses (abfd, section);
+
+ if (syms != NULL)
+ {
+ free (syms);
+ syms = NULL;
+ }
+
+ bfd_close (abfd);
+
+ return 0;
+}
+
+int
+#if defined(WITH_LIBBFD)
+addr2line_main (int argc, char **argv)
+#else
+main (int argc, char **argv)
+#endif
+{
+ const char *file_name;
+ const char *section_name;
+ char *target;
+ int c;
+
+#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
+ setlocale (LC_MESSAGES, "");
+#endif
+#if defined (HAVE_SETLOCALE)
+ setlocale (LC_CTYPE, "");
+#endif
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+
+ program_name = *argv;
+ xmalloc_set_program_name (program_name);
+
+ expandargv (&argc, &argv);
+
+ bfd_init ();
+ set_default_bfd_target ();
+
+ file_name = NULL;
+ section_name = NULL;
+ target = NULL;
+ optind = 1; /* make getopt_* reentrant */
+ while ((c = getopt_long (argc, argv, "ab:Ce:sfHhij:pVv", long_options, (int *) 0))
+ != EOF)
+ {
+ switch (c)
+ {
+ case 0:
+ break; /* We've been given a long option. */
+ case 'a':
+ with_addresses = TRUE;
+ break;
+ case 'b':
+ target = optarg;
+ break;
+ case 'C':
+ do_demangle = TRUE;
+ if (optarg != NULL)
+ {
+ enum demangling_styles style;
+
+ style = cplus_demangle_name_to_style (optarg);
+ if (style == unknown_demangling)
+ fatal (_("unknown demangling style `%s'"),
+ optarg);
+
+ cplus_demangle_set_style (style);
+ }
+ break;
+ case 'e':
+ file_name = optarg;
+ break;
+ case 's':
+ base_names = TRUE;
+ break;
+ case 'f':
+ with_functions = TRUE;
+ break;
+ case 'p':
+ pretty_print = TRUE;
+ break;
+ case 'v':
+ case 'V':
+ print_version ("addr2line");
+ break;
+ case 'h':
+ case 'H':
+ usage (stdout, 0);
+ break;
+ case 'i':
+ unwind_inlines = TRUE;
+ break;
+ case 'j':
+ section_name = optarg;
+ break;
+ default:
+ usage (stderr, 1);
+ break;
+ }
+ }
+
+ if (file_name == NULL)
+ file_name = "a.out";
+
+ addr = argv + optind;
+ naddr = argc - optind;
+
+ return process_file (file_name, section_name, target);
+}
diff --git a/sources/host-tools/ndk-stack/ndk-stack-parser.c b/sources/host-tools/ndk-stack/ndk-stack-parser.c
index 5f9946a..9ac6934 100755
--- a/sources/host-tools/ndk-stack/ndk-stack-parser.c
+++ b/sources/host-tools/ndk-stack/ndk-stack-parser.c
@@ -15,6 +15,7 @@
* access to a log file.
*/
+#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -123,6 +124,14 @@
*/
static const char* get_next_token(const char* str, char* token, size_t size);
+/* Return pointer to first word "pc", "eip", or "ip" in string "frame"
+ * param:
+ * frame - a line from dump
+ * Return:
+ * The first occurrence of "pc", "eip", or "ip"
+ */
+static const char* find_pc(const char *frame);
+
NdkCrashParser*
CreateNdkCrashParser(FILE* out_handle, const char* sym_root)
{
@@ -170,6 +179,7 @@
ParseLine(NdkCrashParser* parser, const char* line)
{
regmatch_t match;
+ int found = 0;
if (line == NULL || *line == '\0') {
// Nothing to parse.
@@ -196,6 +206,7 @@
fprintf(parser->out_handle, "%s\n",
strstr(line, _build_fingerprint_header));
parser->state = EXPECTS_PID;
+ found = 1;
}
// Let it fall through to the EXPECTS_PID, in case the dump doesn't
// contain build fingerprint.
@@ -205,23 +216,34 @@
parser->state = EXPECTS_SIGNAL_OR_FRAME;
return 0;
} else {
- return 1;
+ return !found;
}
case EXPECTS_SIGNAL_OR_FRAME:
if (MatchRegex(line, &parser->re_sig_header, &match)) {
fprintf(parser->out_handle, "%s\n", line + match.rm_so);
parser->state = EXPECTS_FRAME;
+ found = 1;
}
// Let it fall through to the EXPECTS_FRAME, in case the dump doesn't
// contain signal fingerprint.
case EXPECTS_FRAME:
- if (MatchRegex(line, &parser->re_frame_header, &match)) {
- parser->state = EXPECTS_FRAME;
- return ParseFrame(parser, line + match.rm_so);
- } else {
- return 1;
- }
+ if (!MatchRegex(line, &parser->re_frame_header, &match))
+ return !found;
+ // Regex generated by x86_64-w64-mingw32 compiler erroneously match
+ // frame line with #[0-9]+ in "stack:" section even when the line has
+ // no word "pc", "eip", or "ip" in it.
+ //
+ // stack:
+ // I/DEBUG ( 1151): #00 5f09db68 401f01c4 /system/lib/libc.so
+ //
+ // To workaround, let's double check if pc is found!
+ //
+ if (!(find_pc(line)))
+ return !found;
+
+ parser->state = EXPECTS_FRAME;
+ return ParseFrame(parser, line + match.rm_so);
default:
return 1;
@@ -271,6 +293,24 @@
}
}
+static const char *
+find_pc(const char *frame)
+{
+ const char *pcstrs[] = { "pc", "eip", "ip" };
+ int i;
+ for (i=0; i<sizeof(pcstrs)/sizeof(pcstrs[0]); i++) {
+ const char *p = strstr(frame, pcstrs[i]);
+ // check it's a word, not part of filename or something
+ if (p && p!=frame) {
+ char l = p[-1];
+ char r = p[strlen(pcstrs[i])];
+ if ((l==' ' || l=='\t') && (r==' ' || r=='\t'))
+ return p;
+ }
+ }
+ return NULL;
+}
+
int
ParseFrame(NdkCrashParser* parser, const char* frame)
{
@@ -281,23 +321,22 @@
char module_path[2048];
char* module_name;
char sym_file[2048];
+#if !defined(WITH_LIBBFD)
ELFF_HANDLE elff_handle;
Elf_AddressInfo pc_info;
+#else
+ const int ac = 5;
+ char *av[ac];
+ FILE *f;
+#endif
fprintf(parser->out_handle, "Stack frame %s", frame);
// Advance to the instruction pointer token.
- wrk = strstr(frame, "pc");
- if (wrk == NULL) {
- wrk = strstr(frame, "eip");
- if (wrk == NULL) {
- wrk = strstr(frame, "ip");
- if (wrk == NULL) {
- fprintf(parser->out_handle,
- "Parser is unable to locate instruction pointer token.\n");
- return -1;
- }
- }
+ if ((wrk=find_pc(frame)) == NULL) {
+ fprintf(parser->out_handle,
+ "Parser is unable to locate instruction pointer token.\n");
+ return -1;
}
// Next token after the instruction pointer token is its address.
@@ -326,6 +365,30 @@
// Build path to the symbol file.
snprintf(sym_file, sizeof(sym_file), "%s/%s", parser->sym_root, module_name);
+#if defined(WITH_LIBBFD)
+ if ((f=fopen(sym_file, "r")) == NULL) {
+ if (errno == ENOENT) {
+ printf("\n");
+ } else {
+ printf(": Unable to open symbol file %s. Error (%d): %s\n",
+ sym_file, errno, strerror(errno));
+ }
+ return -1;
+ }
+
+ // call addr2line if sym_file exist
+ extern int addr2line_main (int argc, char **argv);
+
+ av[0] = "ndk-stack";
+ av[1] = "-fpC"; // f:function, p:pretty-print, C:demangle
+ av[2] = "-e"; // e:exe-filename
+ av[3] = sym_file;
+ av[4] = pc_address;
+ (void)address;
+
+ printf(": Routine ");
+ return addr2line_main(ac, av);
+#else
// Init ELFF wrapper for the symbol file.
elff_handle = elff_init(sym_file);
if (elff_handle == NULL) {
@@ -358,4 +421,5 @@
elff_close(elff_handle);
return -1;
}
+#endif // WITH_LIBBFD
}
diff --git a/tests/abcc/jni/Abcc.cpp b/tests/abcc/jni/Abcc.cpp
index 300e16f..f57f634 100644
--- a/tests/abcc/jni/Abcc.cpp
+++ b/tests/abcc/jni/Abcc.cpp
@@ -21,6 +21,15 @@
#include <stdint.h>
#include <unistd.h>
#include "Abcc.h"
+
+#if !defined(_WIN32)
+#include <sys/mman.h>
+#else
+#include "mman.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
using namespace abcc;
TargetAbi::TargetAbi(const std::string &abi) {
@@ -46,58 +55,55 @@
int BitcodeInfo::readWrapper(BitcodeCompiler &compiler) {
int fd = open(mBCPath.c_str(), O_RDONLY);
+
if (fd < 0) {
return -1;
}
- unsigned char buffer[5] = {'\0', '\0', '\0', '\0', '\0'};
- read(fd, buffer, 4); // Skip magic number, we have checked
- read(fd, buffer, 4); // version
- read(fd, buffer, 4); // offset
- swapEndian(buffer, 4);
- int offset = transferBytesToNum(buffer, 4);
- lseek(fd, 4*7, SEEK_SET);
- offset -= 4*7; // Useless, skip
+ unsigned char *buf, *p;
+ struct stat st;
+ int bc_offset;
- while (offset > 0) {
- read(fd, buffer, 4);
- swapEndian(buffer, 4);
- uint16_t length = transferBytesToNum(buffer, 2);
- uint16_t tag = transferBytesToNum(buffer+2, 2);
- LOGV("length: %d", length);
- LOGV("tag: %d", tag);
- length = (length + 3) & ~3;
+ fstat (fd, &st);
+ buf = (unsigned char *) mmap (NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ close (fd);
- unsigned char *large_buffer = (unsigned char*) malloc(length+1);
- if (large_buffer == 0) {
- LOGE("Cannot create buffer for wrapper field");
- close(fd);
- return -1;
- }
- large_buffer[length] = '\0';
- int n = read(fd, large_buffer, length);
- if (n != length) {
- LOGE("Read wrapper field error");
- close(fd);
- return -1;
+ bc_offset = transferBytesToNumLe (buf+ 8, 4);
+ p = buf + 4 * 7; // Offset to tag fields.
+
+ while (p < buf + bc_offset) {
+ uint16_t tag, length;
+
+ tag = transferBytesToNumLe (p, 2);
+ length = transferBytesToNumLe (p + 2, 2);
+ p += 4;
+ switch (tag) {
+ case 0x4002: // Optimization Level,. e.g., 2 for -O2
+ mOptimizationLevel = transferBytesToNumLe (p, 4);
+ LOGV("Wrapper field: -O%d", mOptimizationLevel);
+ break;
+
+ case 0x5002: // LDFLAGS string
+ LOGV("Wrapper field: %s", p);
+ if (compiler.parseLDFlags (*this, reinterpret_cast<const char *>(p)) != 0) {
+ LOGE("Cannot parse ldflags from wrapper");
+ close(fd);
+ return -1;
+ }
+ break;
+
+ case 0x4001: // Compiler Version, e.g., 3300 for llvm-3.3.
+ case 0x5001: // Bitcode Type, e.g., rel, shared, or exec.
+ default:
+ // Some field maybe useful, but we use wrapper to encode command line,
+ // this is not necessary for now.
+ break;
}
- if (tag == 0x5002) {
- const char* ldflags = reinterpret_cast<char*>(large_buffer);
- LOGV("Wrapper field: %s", ldflags);
- if (compiler.parseLDFlags(*this, ldflags) != 0) {
- LOGE("Cannot parse ldflags from wrapper");
- close(fd);
- return -1;
- }
- } else {
- // Some field maybe useful, but we use wrapper to encode command line,
- // this is not necessary for now.
- }
- offset -= (length + 4);
- free(large_buffer);
- } // while
- close(fd);
+ p += (length + 3) & ~3; // Data are always padding to 4-byte boundary.
+ }
+
+ munmap (buf, st.st_size);
return 0;
}
@@ -116,24 +122,17 @@
}
}
-void BitcodeInfo::swapEndian(unsigned char *buffer, size_t n) {
- // We uses le32, so it must be LITTLE ENDIAN
- for (size_t i = 0; i < n/2; ++i) {
- char tmp = buffer[i];
- buffer[i] = buffer[n-i-1];
- buffer[n-i-1] =tmp;
- }
-}
-
-int BitcodeInfo::transferBytesToNum(const unsigned char *buffer, size_t n) {
+// This function reads N bytes from BUFFER in little endian.
+int BitcodeInfo::transferBytesToNumLe(const unsigned char *buffer, size_t n) {
int ret = 0;
- for (size_t i = 0; i < n; ++i) {
- ret = ret * 0x100 + buffer[i];
- }
+ const unsigned char *p = buffer + n;
+
+ while (--p >= buffer)
+ ret = ret * 0x100 + *p;
+
return ret;
}
-
BitcodeCompiler::BitcodeCompiler(const std::string &abi, const std::string &sysroot, const std::string &working_dir, const bool savetemps)
: mAbi(abi), mSysroot(sysroot), mWorkingDir(working_dir), mRet(RET_OK), mSaveTemps(savetemps) {
// CFlags
@@ -142,12 +141,6 @@
mGlobalCFlags += " -filetype=obj -relocation-model=pic -code-model=small";
mGlobalCFlags += " -use-init-array -mc-relax-all";
-#ifdef DEBUG
- mGlobalCFlags += std::string(" ") + "-O0";
-#else
- mGlobalCFlags += std::string(" ") + "-O2";
-#endif
-
if (mAbi == TargetAbi::ARMEABI || mAbi == TargetAbi::ARMEABI_V7A)
mGlobalCFlags += std::string(" ") + "-arm-enable-ehabi -arm-enable-ehabi-descriptors -float-abi=soft";
@@ -182,14 +175,19 @@
for (std::vector<BitcodeInfo>::const_iterator i = mBitcodeFiles.begin(),
e = mBitcodeFiles.end(); i != e; ++i) {
const BitcodeInfo &bc = *i;
- std::string cmd = mExecutableToolsPath[(unsigned)CMD_COMPILE];
- cmd += " " + mGlobalCFlags;
- cmd += " " + bc.mTargetBCPath + " -o " + bc.mObjPath;
+ std::ostringstream os;
+
+ os << mExecutableToolsPath[(unsigned)CMD_COMPILE]
+ << " " << mGlobalCFlags
+ << " -O" << bc.mOptimizationLevel
+ << " " << bc.mTargetBCPath
+ << " -o " << bc.mObjPath;
+
#if ON_DEVICE && VERBOSE
Timer t_llc;
t_llc.start();
#endif
- runCmd(cmd, /*dump=*/true);
+ runCmd(os.str(), /*dump=*/true);
#if ON_DEVICE && VERBOSE
llc_usec += t_llc.stop();
#endif
diff --git a/tests/abcc/jni/Abcc.h b/tests/abcc/jni/Abcc.h
index 8f9e779..033dc96 100644
--- a/tests/abcc/jni/Abcc.h
+++ b/tests/abcc/jni/Abcc.h
@@ -105,6 +105,7 @@
static void dropExternalLDLibs(SONameMap &map);
bool mShared;
+ int mOptimizationLevel;
std::string mBCPath;
std::string mTargetBCPath;
std::string mObjPath;
@@ -115,8 +116,7 @@
std::string mLDLibsStr; // Immutable once read in
public:
- static void swapEndian(unsigned char *buffer, size_t n);
- static int transferBytesToNum(const unsigned char *buffer, size_t n);
+ static int transferBytesToNumLe(const unsigned char *buffer, size_t n);
};
diff --git a/tests/abcc/jni/device/Abcc_device.cpp b/tests/abcc/jni/device/Abcc_device.cpp
index 0bdd468..ddaca36 100644
--- a/tests/abcc/jni/device/Abcc_device.cpp
+++ b/tests/abcc/jni/device/Abcc_device.cpp
@@ -128,8 +128,7 @@
unsigned char buffer[4];
read(fd, buffer, 4);
close(fd);
- BitcodeInfo::swapEndian(buffer, 4);
- int magic = BitcodeInfo::transferBytesToNum(buffer, 4);
+ int magic = BitcodeInfo::transferBytesToNumLe(buffer, 4);
if (magic != 0x0b17c0de) {
LOGV("Found file %s magic: %x, but we need a wrapped bitcode.", full_path.c_str(), magic);
diff --git a/tests/abcc/jni/mman-win32/LICENSE.TXT b/tests/abcc/jni/mman-win32/LICENSE.TXT
new file mode 100644
index 0000000..d159169
--- /dev/null
+++ b/tests/abcc/jni/mman-win32/LICENSE.TXT
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/tests/abcc/jni/mman-win32/Makefile b/tests/abcc/jni/mman-win32/Makefile
new file mode 100644
index 0000000..79b4516
--- /dev/null
+++ b/tests/abcc/jni/mman-win32/Makefile
@@ -0,0 +1,48 @@
+#
+# mman-win32 (mingw32) Makefile
+#
+include config.mak
+
+ifeq ($(BUILD_STATIC),yes)
+ TARGETS+=libmman.a
+ INSTALL+=static-install
+endif
+ifeq ($(BUILD_MSVC),yes)
+ SHFLAGS+=-Wl,--output-def,libmman.def
+ INSTALL+=lib-install
+endif
+
+all: $(TARGETS)
+
+mman.o: mman.c mman.h
+ $(CC) -o mman.o -c mman.c -Wall -O3 -fomit-frame-pointer
+
+libmman.a: mman.o
+ $(AR) cru libmman.a mman.o
+ $(RANLIB) libmman.a
+
+static-install:
+ mkdir -p $(DESTDIR)$(libdir)
+ cp libmman.a $(DESTDIR)$(libdir)
+ mkdir -p $(DESTDIR)$(incdir)
+ cp mman.h $(DESTDIR)$(incdir)
+
+lib-install:
+ mkdir -p $(DESTDIR)$(libdir)
+ cp libmman.lib $(DESTDIR)$(libdir)
+
+install: $(INSTALL)
+
+test.exe: test.c mman.c mman.h
+ $(CC) -o test.exe test.c -L. -lmman
+
+test: $(TARGETS) test.exe
+ test.exe
+
+clean::
+ rm -f mman.o libmman.a libmman.def libmman.lib test.exe *.dat
+
+distclean: clean
+ rm -f config.mak
+
+.PHONY: clean distclean install test
diff --git a/tests/abcc/jni/mman-win32/README.TXT b/tests/abcc/jni/mman-win32/README.TXT
new file mode 100644
index 0000000..af2254f
--- /dev/null
+++ b/tests/abcc/jni/mman-win32/README.TXT
@@ -0,0 +1,3 @@
+1. mmman-win32 project page: https://code.google.com/p/mman-win32/
+2. checkout: svn checkout http://mman-win32.googlecode.com/svn/trunk/ mman-win32-read-only
+3. Add LICENSE.TXT (GNU GPL v2)
diff --git a/tests/abcc/jni/mman-win32/configure b/tests/abcc/jni/mman-win32/configure
new file mode 100644
index 0000000..c928f11
--- /dev/null
+++ b/tests/abcc/jni/mman-win32/configure
@@ -0,0 +1,157 @@
+#!/bin/sh
+# mmap-win32 configure script
+#
+# Parts copied from FFmpeg's configure
+#
+
+set_all(){
+ value=$1
+ shift
+ for var in $*; do
+ eval $var=$value
+ done
+}
+
+enable(){
+ set_all yes $*
+}
+
+disable(){
+ set_all no $*
+}
+
+enabled(){
+ eval test "x\$$1" = "xyes"
+}
+
+disabled(){
+ eval test "x\$$1" = "xno"
+}
+
+show_help(){
+ echo "Usage: configure [options]"
+ echo "Options: [defaults in brackets after descriptions]"
+ echo "All \"enable\" options have \"disable\" counterparts"
+ echo
+ echo " --help print this message"
+ echo " --prefix=PREFIX install in PREFIX [$PREFIX]"
+ echo " --libdir=DIR install libs in DIR [$PREFIX/lib]"
+ echo " --incdir=DIR install includes in DIR [$PREFIX/include]"
+ echo " --enable-static build static libraries [yes]"
+ echo " --enable-msvc create msvc-compatible import lib [auto]"
+ echo
+ echo " --cc=CC use C compiler CC [$cc_default]"
+ echo " --cross-prefix=PREFIX use PREFIX for compilation tools [$cross_prefix]"
+ exit 1
+}
+
+die_unknown(){
+ echo "Unknown option \"$1\"."
+ echo "See $0 --help for available options."
+ exit 1
+}
+
+PREFIX="/mingw"
+libdir="${PREFIX}/lib"
+incdir="${PREFIX}/include/sys"
+ar="ar"
+cc_default="gcc"
+ranlib="ranlib"
+strip="strip"
+
+DEFAULT="msvc
+"
+
+DEFAULT_YES="static
+ stripping
+"
+
+CMDLINE_SELECT="$DEFAULT
+ $DEFAULT_NO
+ $DEFAULT_YES
+"
+
+enable $DEFAULT_YES
+disable $DEFAULT_NO
+
+for opt do
+ optval="${opt#*=}"
+ case "$opt" in
+ --help)
+ show_help
+ ;;
+ --prefix=*)
+ PREFIX="$optval"
+ ;;
+ --libdir=*)
+ libdir="$optval"
+ ;;
+ --incdir=*)
+ incdir="$optval"
+ ;;
+ --cc=*)
+ cc="$optval"
+ ;;
+ --cross-prefix=*)
+ cross_prefix="$optval"
+ ;;
+ --enable-?*|--disable-?*)
+ eval `echo "$opt" | sed 's/--/action=/;s/-/ option=/;s/-/_/g'`
+ echo "$CMDLINE_SELECT" | grep -q "^ *$option\$" || die_unknown $opt
+ $action $option
+ ;;
+ *)
+ die_unknown $opt
+ ;;
+ esac
+done
+
+ar="${cross_prefix}${ar}"
+cc_default="${cross_prefix}${cc_default}"
+ranlib="${cross_prefix}${ranlib}"
+strip="${cross_prefix}${strip}"
+
+if ! test -z $cc; then
+ cc_default="${cc}"
+fi
+cc="${cc_default}"
+
+disabled static && {
+ echo "At least one library type must be set.";
+ exit 1;
+}
+
+if enabled msvc; then
+ lib /? > /dev/null 2>&1 /dev/null || {
+ echo "MSVC's lib command not found."
+ echo "Make sure MSVC is installed and its bin folder is in your \$PATH."
+ exit 1
+ }
+fi
+
+if ! enabled stripping; then
+ strip="echo ignoring strip"
+fi
+
+enabled msvc && libcmd="lib" || libcmd="echo ignoring lib"
+
+echo "# Automatically generated by configure" > config.mak
+echo "PREFIX=$PREFIX" >> config.mak
+echo "libdir=$libdir" >> config.mak
+echo "incdir=$incdir" >> config.mak
+echo "AR=$ar" >> config.mak
+echo "CC=$cc" >> config.mak
+echo "RANLIB=$ranlib" >> config.mak
+echo "STRIP=$strip" >> config.mak
+echo "BUILD_STATIC=$static" >> config.mak
+echo "BUILD_MSVC=$msvc" >> config.mak
+echo "LIBCMD=$libcmd" >> config.mak
+
+echo "prefix: $PREFIX"
+echo "libdir: $libdir"
+echo "incdir: $incdir"
+echo "ar: $ar"
+echo "cc: $cc"
+echo "ranlib: $ranlib"
+echo "strip: $strip"
+echo "static: $static"
diff --git a/tests/abcc/jni/mman-win32/mman.c b/tests/abcc/jni/mman-win32/mman.c
new file mode 100644
index 0000000..9791ac5
--- /dev/null
+++ b/tests/abcc/jni/mman-win32/mman.c
@@ -0,0 +1,183 @@
+#ifdef _WIN32
+
+#include <windows.h>
+#include <errno.h>
+#include <io.h>
+
+#include "mman.h"
+
+#ifndef FILE_MAP_EXECUTE
+#define FILE_MAP_EXECUTE 0x0020
+#endif /* FILE_MAP_EXECUTE */
+
+static int __map_mman_error(const DWORD err, const int deferr)
+{
+ if (err == 0)
+ return 0;
+ //TODO: implement
+ return err;
+}
+
+static DWORD __map_mmap_prot_page(const int prot)
+{
+ DWORD protect = 0;
+
+ if (prot == PROT_NONE)
+ return protect;
+
+ if ((prot & PROT_EXEC) != 0)
+ {
+ protect = ((prot & PROT_WRITE) != 0) ?
+ PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ;
+ }
+ else
+ {
+ protect = ((prot & PROT_WRITE) != 0) ?
+ PAGE_READWRITE : PAGE_READONLY;
+ }
+
+ return protect;
+}
+
+static DWORD __map_mmap_prot_file(const int prot)
+{
+ DWORD desiredAccess = 0;
+
+ if (prot == PROT_NONE)
+ return desiredAccess;
+
+ if ((prot & PROT_READ) != 0)
+ desiredAccess |= FILE_MAP_READ;
+ if ((prot & PROT_WRITE) != 0)
+ desiredAccess |= FILE_MAP_WRITE;
+ if ((prot & PROT_EXEC) != 0)
+ desiredAccess |= FILE_MAP_EXECUTE;
+
+ return desiredAccess;
+}
+
+void* mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off)
+{
+ HANDLE fm, h;
+
+ void * map = MAP_FAILED;
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable: 4293)
+#endif
+
+ const DWORD dwFileOffsetLow = (sizeof(off_t) <= sizeof(DWORD)) ?
+ (DWORD)off : (DWORD)(off & 0xFFFFFFFFL);
+ const DWORD dwFileOffsetHigh = (sizeof(off_t) <= sizeof(DWORD)) ?
+ (DWORD)0 : (DWORD)((off >> 32) & 0xFFFFFFFFL);
+ const DWORD protect = __map_mmap_prot_page(prot);
+ const DWORD desiredAccess = __map_mmap_prot_file(prot);
+
+ const off_t maxSize = off + (off_t)len;
+
+ const DWORD dwMaxSizeLow = (sizeof(off_t) <= sizeof(DWORD)) ?
+ (DWORD)maxSize : (DWORD)(maxSize & 0xFFFFFFFFL);
+ const DWORD dwMaxSizeHigh = (sizeof(off_t) <= sizeof(DWORD)) ?
+ (DWORD)0 : (DWORD)((maxSize >> 32) & 0xFFFFFFFFL);
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+ errno = 0;
+
+ if (len == 0
+ /* Unsupported flag combinations */
+ || (flags & MAP_FIXED) != 0
+ /* Usupported protection combinations */
+ || prot == PROT_EXEC)
+ {
+ errno = EINVAL;
+ return MAP_FAILED;
+ }
+
+ h = ((flags & MAP_ANONYMOUS) == 0) ?
+ (HANDLE)_get_osfhandle(fildes) : INVALID_HANDLE_VALUE;
+
+ if ((flags & MAP_ANONYMOUS) == 0 && h == INVALID_HANDLE_VALUE)
+ {
+ errno = EBADF;
+ return MAP_FAILED;
+ }
+
+ fm = CreateFileMapping(h, NULL, protect, dwMaxSizeHigh, dwMaxSizeLow, NULL);
+
+ if (fm == NULL)
+ {
+ errno = __map_mman_error(GetLastError(), EPERM);
+ return MAP_FAILED;
+ }
+
+ map = MapViewOfFile(fm, desiredAccess, dwFileOffsetHigh, dwFileOffsetLow, len);
+
+ CloseHandle(fm);
+
+ if (map == NULL)
+ {
+ errno = __map_mman_error(GetLastError(), EPERM);
+ return MAP_FAILED;
+ }
+
+ return map;
+}
+
+int munmap(void *addr, size_t len)
+{
+ if (UnmapViewOfFile(addr))
+ return 0;
+
+ errno = __map_mman_error(GetLastError(), EPERM);
+
+ return -1;
+}
+
+int mprotect(void *addr, size_t len, int prot)
+{
+ DWORD newProtect = __map_mmap_prot_page(prot);
+ DWORD oldProtect = 0;
+
+ if (VirtualProtect(addr, len, newProtect, &oldProtect))
+ return 0;
+
+ errno = __map_mman_error(GetLastError(), EPERM);
+
+ return -1;
+}
+
+int msync(void *addr, size_t len, int flags)
+{
+ if (FlushViewOfFile(addr, len))
+ return 0;
+
+ errno = __map_mman_error(GetLastError(), EPERM);
+
+ return -1;
+}
+
+int mlock(const void *addr, size_t len)
+{
+ if (VirtualLock((LPVOID)addr, len))
+ return 0;
+
+ errno = __map_mman_error(GetLastError(), EPERM);
+
+ return -1;
+}
+
+int munlock(const void *addr, size_t len)
+{
+ if (VirtualUnlock((LPVOID)addr, len))
+ return 0;
+
+ errno = __map_mman_error(GetLastError(), EPERM);
+
+ return -1;
+}
+
+#endif // _WIN32
\ No newline at end of file
diff --git a/tests/abcc/jni/mman-win32/mman.h b/tests/abcc/jni/mman-win32/mman.h
new file mode 100644
index 0000000..96f68b2
--- /dev/null
+++ b/tests/abcc/jni/mman-win32/mman.h
@@ -0,0 +1,55 @@
+/*
+ * sys/mman.h
+ * mman-win32
+ */
+
+#ifndef _SYS_MMAN_H_
+#define _SYS_MMAN_H_
+
+#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later.
+#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows.
+#endif
+
+/* All the headers include this file. */
+#ifndef _MSC_VER
+#include <_mingw.h>
+#endif
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PROT_NONE 0
+#define PROT_READ 1
+#define PROT_WRITE 2
+#define PROT_EXEC 4
+
+#define MAP_FILE 0
+#define MAP_SHARED 1
+#define MAP_PRIVATE 2
+#define MAP_TYPE 0xf
+#define MAP_FIXED 0x10
+#define MAP_ANONYMOUS 0x20
+#define MAP_ANON MAP_ANONYMOUS
+
+#define MAP_FAILED ((void *)-1)
+
+/* Flags for msync. */
+#define MS_ASYNC 1
+#define MS_SYNC 2
+#define MS_INVALIDATE 4
+
+void* mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off);
+int munmap(void *addr, size_t len);
+int mprotect(void *addr, size_t len, int prot);
+int msync(void *addr, size_t len, int flags);
+int mlock(const void *addr, size_t len);
+int munlock(const void *addr, size_t len);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif /* _SYS_MMAN_H_ */
diff --git a/tests/abcc/jni/mman-win32/mman.vcproj b/tests/abcc/jni/mman-win32/mman.vcproj
new file mode 100644
index 0000000..caed612
--- /dev/null
+++ b/tests/abcc/jni/mman-win32/mman.vcproj
@@ -0,0 +1,172 @@
+<?xml version="1.0" encoding="windows-1251"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="mman"
+ ProjectGUID="{F118CC2E-9AED-4DB0-9BF4-028781D97AD1}"
+ RootNamespace="mman"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(ProjectDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(ProjectDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\mman.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\mman.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/tests/abcc/jni/mman-win32/test.c b/tests/abcc/jni/mman-win32/test.c
new file mode 100644
index 0000000..0762ae4
--- /dev/null
+++ b/tests/abcc/jni/mman-win32/test.c
@@ -0,0 +1,235 @@
+
+#include "mman.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#ifndef NULL
+#define NULL (void*)0
+#endif
+
+const char* map_file_name = "map_file.dat";
+
+int test_anon_map_readwrite()
+{
+ void* map = mmap(NULL, 1024, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (map == MAP_FAILED)
+ {
+ printf("mmap (MAP_ANONYMOUS, PROT_READ | PROT_WRITE) returned unexpected error: %d\n", errno);
+ return -1;
+ }
+
+ *((unsigned char*)map) = 1;
+
+ int result = munmap(map, 1024);
+
+ if (result != 0)
+ printf("munmap (MAP_ANONYMOUS, PROT_READ | PROT_WRITE) returned unexpected error: %d\n", errno);
+
+ return result;
+}
+
+int test_anon_map_readonly()
+{
+ void* map = mmap(NULL, 1024, PROT_READ,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (map == MAP_FAILED)
+ {
+ printf("mmap (MAP_ANONYMOUS, PROT_READ) returned unexpected error: %d\n", errno);
+ return -1;
+ }
+
+ *((unsigned char*)map) = 1;
+
+ int result = munmap(map, 1024);
+
+ if (result != 0)
+ printf("munmap (MAP_ANONYMOUS, PROT_READ) returned unexpected error: %d\n", errno);
+
+ return result;
+}
+
+int test_anon_map_writeonly()
+{
+ void* map = mmap(NULL, 1024, PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (map == MAP_FAILED)
+ {
+ printf("mmap (MAP_ANONYMOUS, PROT_WRITE) returned unexpected error: %d\n", errno);
+ return -1;
+ }
+
+ *((unsigned char*)map) = 1;
+
+ int result = munmap(map, 1024);
+
+ if (result != 0)
+ printf("munmap (MAP_ANONYMOUS, PROT_WRITE) returned unexpected error: %d\n", errno);
+
+ return result;
+}
+
+int test_anon_map_readonly_nowrite()
+{
+ void* map = mmap(NULL, 1024, PROT_READ,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (map == MAP_FAILED)
+ {
+ printf("mmap (MAP_ANONYMOUS, PROT_READ) returned unexpected error: %d\n", errno);
+ return -1;
+ }
+
+ if (*((unsigned char*)map) != 0)
+ printf("test_anon_map_readonly_nowrite (MAP_ANONYMOUS, PROT_READ) returned unexpected value: %d\n",
+ (int)*((unsigned char*)map));
+
+ int result = munmap(map, 1024);
+
+ if (result != 0)
+ printf("munmap (MAP_ANONYMOUS, PROT_READ) returned unexpected error: %d\n", errno);
+
+ return result;
+}
+
+int test_file_map_readwrite()
+{
+ mode_t mode = S_IRUSR | S_IWUSR;
+ int o = open(map_file_name, O_TRUNC | O_BINARY | O_RDWR | O_CREAT, mode);
+
+ void* map = mmap(NULL, 1024, PROT_READ | PROT_WRITE, MAP_PRIVATE, o, 0);
+ if (map == MAP_FAILED)
+ {
+ printf("mmap returned unexpected error: %d\n", errno);
+ return -1;
+ }
+
+ *((unsigned char*)map) = 1;
+
+ int result = munmap(map, 1024);
+
+ if (result != 0)
+ printf("munmap returned unexpected error: %d\n", errno);
+
+ close(o);
+
+ /*TODO: get file info and content and compare it with the sources conditions */
+ unlink(map_file_name);
+
+ return result;
+}
+
+int test_file_map_mlock_munlock()
+{
+ const size_t map_size = 1024;
+
+ int result = 0;
+ mode_t mode = S_IRUSR | S_IWUSR;
+ int o = open(map_file_name, O_TRUNC | O_BINARY | O_RDWR | O_CREAT, mode);
+ if (o == -1)
+ {
+ printf("unable to create file %s: %d\n", map_file_name, errno);
+ return -1;
+ }
+
+ void* map = mmap(NULL, map_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, o, 0);
+ if (map == MAP_FAILED)
+ {
+ printf("mmap returned unexpected error: %d\n", errno);
+ result = -1;
+ goto done_close;
+ }
+
+ if (mlock(map, map_size) != 0)
+ {
+ printf("mlock returned unexpected error: %d\n", errno);
+ result = -1;
+ goto done_munmap;
+ }
+
+ *((unsigned char*)map) = 1;
+
+ if (munlock(map, map_size) != 0)
+ {
+ printf("munlock returned unexpected error: %d\n", errno);
+ result = -1;
+ }
+
+done_munmap:
+ result = munmap(map, map_size);
+
+ if (result != 0)
+ printf("munmap returned unexpected error: %d\n", errno);
+
+done_close:
+ close(o);
+
+ unlink(map_file_name);
+done:
+ return result;
+}
+
+int test_file_map_msync()
+{
+ const size_t map_size = 1024;
+
+ int result = 0;
+ mode_t mode = S_IRUSR | S_IWUSR;
+ int o = open(map_file_name, O_TRUNC | O_BINARY | O_RDWR | O_CREAT, mode);
+ if (o == -1)
+ {
+ printf("unable to create file %s: %d\n", map_file_name, errno);
+ return -1;
+ }
+
+ void* map = mmap(NULL, map_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, o, 0);
+ if (map == MAP_FAILED)
+ {
+ printf("mmap returned unexpected error: %d\n", errno);
+ result = -1;
+ goto done_close;
+ }
+
+ *((unsigned char*)map) = 1;
+
+ if (msync(map, map_size, MS_SYNC) != 0)
+ {
+ printf("msync returned unexpected error: %d\n", errno);
+ result = -1;
+ }
+
+ result = munmap(map, map_size);
+
+ if (result != 0)
+ printf("munmap returned unexpected error: %d\n", errno);
+
+done_close:
+ close(o);
+
+ unlink(map_file_name);
+done:
+ return result;
+}
+
+#define EXEC_TEST(name) \
+ if (name() != 0) { result = -1; printf( #name ": fail\n"); } \
+ else { printf(#name ": pass\n"); }
+
+int main()
+{
+ int result = 0;
+
+ EXEC_TEST(test_anon_map_readwrite);
+ //NOTE: this test must cause an access violation exception
+ //EXEC_TEST(test_anon_map_readonly);
+ EXEC_TEST(test_anon_map_readonly_nowrite);
+ EXEC_TEST(test_anon_map_writeonly);
+
+ EXEC_TEST(test_file_map_readwrite);
+ EXEC_TEST(test_file_map_mlock_munlock);
+ EXEC_TEST(test_file_map_msync);
+ //TODO: EXEC_TEST(test_file_map_mprotect);
+
+ return result;
+}
diff --git a/tests/build/b9193874-neon/BROKEN_BUILD b/tests/build/b9193874-neon/BROKEN_BUILD
index e7b612f..24b8be9 100644
--- a/tests/build/b9193874-neon/BROKEN_BUILD
+++ b/tests/build/b9193874-neon/BROKEN_BUILD
@@ -1 +1 @@
-clang3.1 clang3.2 clang3.3
\ No newline at end of file
+clang3.1 clang3.2 clang3.3 clang3.4
diff --git a/tests/build/fenv/BROKEN_BUILD b/tests/build/fenv/BROKEN_BUILD
index 2f3fcfe..876c976 100644
--- a/tests/build/fenv/BROKEN_BUILD
+++ b/tests/build/fenv/BROKEN_BUILD
@@ -1 +1 @@
-clang3.1 clang3.2 clang3.3 4.4.3
\ No newline at end of file
+clang3.1 clang3.2 clang3.3 clang3.4 4.4.3
diff --git a/tests/build/graphite-loop/BROKEN_BUILD b/tests/build/graphite-loop/BROKEN_BUILD
index f0f76fb..6bf60c7 100644
--- a/tests/build/graphite-loop/BROKEN_BUILD
+++ b/tests/build/graphite-loop/BROKEN_BUILD
@@ -1 +1 @@
-4.4.3
\ No newline at end of file
+4.4.3 clang3.4
diff --git a/tests/build/issue-gcc59052-partial-specialization-of-template/jni/Android.mk b/tests/build/issue-gcc59052-partial-specialization-of-template/jni/Android.mk
new file mode 100644
index 0000000..4a4695e
--- /dev/null
+++ b/tests/build/issue-gcc59052-partial-specialization-of-template/jni/Android.mk
@@ -0,0 +1,6 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := issue-gcc59052-partial-specialization-of-template
+LOCAL_SRC_FILES := issue-gcc59052-partial-specialization-of-template.cc
+include $(BUILD_EXECUTABLE)
diff --git a/tests/build/issue-gcc59052-partial-specialization-of-template/jni/Application.mk b/tests/build/issue-gcc59052-partial-specialization-of-template/jni/Application.mk
new file mode 100644
index 0000000..a252a72
--- /dev/null
+++ b/tests/build/issue-gcc59052-partial-specialization-of-template/jni/Application.mk
@@ -0,0 +1 @@
+APP_ABI := all
diff --git a/tests/build/issue-gcc59052-partial-specialization-of-template/jni/issue-gcc59052-partial-specialization-of-template.cc b/tests/build/issue-gcc59052-partial-specialization-of-template/jni/issue-gcc59052-partial-specialization-of-template.cc
new file mode 100644
index 0000000..5dc878b
--- /dev/null
+++ b/tests/build/issue-gcc59052-partial-specialization-of-template/jni/issue-gcc59052-partial-specialization-of-template.cc
@@ -0,0 +1,19 @@
+namespace N {
+
+template <class T>
+struct C {
+ template <class U, T t>
+ struct Implementation {};
+};
+
+template <class T>
+template <T t>
+struct C<T>::Implementation<void, t> {
+ static void method() {}
+};
+
+}
+
+int main() {
+ N::C<int>::Implementation<void, 0>::method();
+}
diff --git a/tests/build/issue41770-_GLIBCXX_HAS_GTHREADS/BROKEN_BUILD b/tests/build/issue41770-_GLIBCXX_HAS_GTHREADS/BROKEN_BUILD
index b5298ed..5abbb49 100644
--- a/tests/build/issue41770-_GLIBCXX_HAS_GTHREADS/BROKEN_BUILD
+++ b/tests/build/issue41770-_GLIBCXX_HAS_GTHREADS/BROKEN_BUILD
@@ -1 +1 @@
-clang3.1 clang3.2 clang3.3 4.4.3 4.6
\ No newline at end of file
+clang3.1 clang3.2 clang3.3 clang3.4 4.4.3 4.6
diff --git a/tests/build/issue64679-prctl/build.sh b/tests/build/issue64679-prctl/build.sh
new file mode 100755
index 0000000..8195cfe
--- /dev/null
+++ b/tests/build/issue64679-prctl/build.sh
@@ -0,0 +1,30 @@
+# Check if some platform headers can be included alone
+# See b.android.com/64679 for one of them
+#
+
+export ANDROID_NDK_ROOT=$NDK
+
+NDK_BUILDTOOLS_PATH=$NDK/build/tools
+. $NDK/build/tools/prebuilt-common.sh
+
+INTERNAL_HEADERS="sys/_errdefs.h sys/_sigdefs.h sys/_system_properties.h"
+
+for API_LEVEL in $API_LEVELS; do
+ for ARCH in $DEFAULT_ARCHS; do
+ if [ -d $ANDROID_NDK_ROOT/platforms/android-$API_LEVEL/arch-$ARCH ]; then
+ HEADERS=`cd $ANDROID_NDK_ROOT/platforms/android-$API_LEVEL/arch-$ARCH/usr/include ; ls *.h sys/*.h android/*.h EGL/*.h GLES/*.h GLES2/*.h GLES3/*.h OMXAL/*.h SLES/*.h 2> /dev/null`
+ #echo $API_LEVEL $ARCH HEADERS=$HEADERS
+ ABIS=$(commas_to_spaces $(convert_arch_to_abi $ARCH))
+ for ABI in $ABIS; do
+ for HEADER in $HEADERS; do
+ if [ "$INTERNAL_HEADERS" = "${INTERNAL_HEADERS%%$HEADER*}" ] ; then
+ #echo Compiling with $HEADER
+ $ANDROID_NDK_ROOT/ndk-build -B APP_CFLAGS=-DHEADER=\"\<$HEADER\>\" APP_PLATFORM=android-$API_LEVEL APP_ABI=$ABI 1>/dev/null 2>&1
+ fail_panic "Can't compile header $ANDROID_NDK_ROOT/platforms/android-$API_LEVEL/arch-$ARCH/usr/include/$HEADER alone.
+To reproduce: $ANDROID_NDK_ROOT/ndk-build -B APP_CFLAGS=-DHEADER=\"\<$HEADER\>\" APP_PLATFORM=android-$API_LEVEL APP_ABI=$ABI"
+ fi
+ done
+ done
+ fi
+ done
+done
diff --git a/tests/build/issue64679-prctl/jni/Android.mk b/tests/build/issue64679-prctl/jni/Android.mk
new file mode 100644
index 0000000..cbe73c7
--- /dev/null
+++ b/tests/build/issue64679-prctl/jni/Android.mk
@@ -0,0 +1,6 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := issue64679-prctl
+LOCAL_SRC_FILES := issue64679-prctl.c
+include $(BUILD_EXECUTABLE)
diff --git a/tests/build/issue64679-prctl/jni/Application.mk b/tests/build/issue64679-prctl/jni/Application.mk
new file mode 100644
index 0000000..a252a72
--- /dev/null
+++ b/tests/build/issue64679-prctl/jni/Application.mk
@@ -0,0 +1 @@
+APP_ABI := all
diff --git a/tests/build/issue64679-prctl/jni/issue64679-prctl.c b/tests/build/issue64679-prctl/jni/issue64679-prctl.c
new file mode 100644
index 0000000..b76b193
--- /dev/null
+++ b/tests/build/issue64679-prctl/jni/issue64679-prctl.c
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#undef linux
+#define linux linux
+
+#include HEADER
+
+int main()
+{
+}
diff --git a/tests/build/lambda-defarg3/BROKEN_BUILD b/tests/build/lambda-defarg3/BROKEN_BUILD
index fc07746..3a7bd20 100644
--- a/tests/build/lambda-defarg3/BROKEN_BUILD
+++ b/tests/build/lambda-defarg3/BROKEN_BUILD
@@ -1 +1 @@
-4.4.3 4.6 4.7
\ No newline at end of file
+4.4.3 4.6 4.7 clang3.4
diff --git a/tests/build/merge-string-literals/BROKEN_BUILD b/tests/build/merge-string-literals/BROKEN_BUILD
index e7b612f..24b8be9 100644
--- a/tests/build/merge-string-literals/BROKEN_BUILD
+++ b/tests/build/merge-string-literals/BROKEN_BUILD
@@ -1 +1 @@
-clang3.1 clang3.2 clang3.3
\ No newline at end of file
+clang3.1 clang3.2 clang3.3 clang3.4
diff --git a/tests/build/mips-fp4/BROKEN_BUILD b/tests/build/mips-fp4/BROKEN_BUILD
index e7b612f..24b8be9 100644
--- a/tests/build/mips-fp4/BROKEN_BUILD
+++ b/tests/build/mips-fp4/BROKEN_BUILD
@@ -1 +1 @@
-clang3.1 clang3.2 clang3.3
\ No newline at end of file
+clang3.1 clang3.2 clang3.3 clang3.4
diff --git a/tests/device/hard-float/jni/Android.mk b/tests/device/hard-float/jni/Android.mk
index 0f38d7f..7ebe9ae 100644
--- a/tests/device/hard-float/jni/Android.mk
+++ b/tests/device/hard-float/jni/Android.mk
@@ -41,7 +41,10 @@
# declaration like "extern double sin(double)" w/o proper __attribute__ in
# your code instead of including math.h, etc. See the end of sys/cdefs.h
# the conditions upon which __NDK_FPABI__ and __NDK_FPABI_MATH__ are defined
-# 3. If you use undocumented APIs which takes/returns float/double, be careful
+#
+# 3. All JNI functions should have JNICALL which is defined to __NDK_FPABI__ in jni.h.
+#
+# 4. If you use undocumented APIs which takes/returns float/double, be careful
# to add __attribute__((pcs("aapcs"))) for arm
#
# Note that "--no-warn-mismatch" is needed for linker (except mclinker which check correctly)
@@ -85,7 +88,7 @@
include $(CLEAR_VARS)
LOCAL_MODULE := hard-float-hard-abi
LOCAL_CFLAGS += -mhard-float -D_NDK_MATH_NO_SOFTFP=1
-LOCAL_LDFLAGS += -lm_hard
+LOCAL_LDLIBS += -lm_hard
ifeq (,$(filter -fuse-ld=mcld,$(APP_LDFLAGS) $(LOCAL_LDFLAGS)))
LOCAL_LDFLAGS += -Wl,--no-warn-mismatch
endif
diff --git a/tests/device/hard-float/jni/test-float.c b/tests/device/hard-float/jni/test-float.c
index 694d14a..83004be 100644
--- a/tests/device/hard-float/jni/test-float.c
+++ b/tests/device/hard-float/jni/test-float.c
@@ -24,11 +24,24 @@
double d1 = M_PI;
double d2 = 2.0;
+double d3 = -0.007;
+double d4 = 0.5;
+
int main()
{
- double d = foo(d1,d2);
- const double expected = 4.483853;
- printf("%lf\n", d);
- return (fabs(d-expected) < 0.00001)? 0 : 1;
+ int fail_count = 0;
+ {
+ double d0 = foo(d1,d2);
+ const double expected0 = 4.483853;
+ printf("%lf\n", d0);
+ fail_count += !(fabs(d0-expected0) < 0.00001);
+ }
+ {
+ double d1 = __builtin_atan2(d3, d4);
+ const double expected1 = -0.013999;
+ printf("%lf\n", d1);
+ fail_count += !(fabs(d1-expected1) < 0.00001);
+ }
+ return fail_count;
}
diff --git a/tests/device/issue61659-neon-assignment/jni/Android.mk b/tests/device/issue61659-neon-assignment/jni/Android.mk
new file mode 100644
index 0000000..5eb1bb0
--- /dev/null
+++ b/tests/device/issue61659-neon-assignment/jni/Android.mk
@@ -0,0 +1,6 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := issue61659-neon-assignment
+LOCAL_SRC_FILES := issue61659-neon-assignment.c.neon
+include $(BUILD_EXECUTABLE)
diff --git a/tests/device/issue61659-neon-assignment/jni/Application.mk b/tests/device/issue61659-neon-assignment/jni/Application.mk
new file mode 100644
index 0000000..bbcfb6b
--- /dev/null
+++ b/tests/device/issue61659-neon-assignment/jni/Application.mk
@@ -0,0 +1,2 @@
+APP_ABI := armeabi-v7a
+APP_PLATFORM := android-18
diff --git a/tests/device/issue61659-neon-assignment/jni/issue61659-neon-assignment.c b/tests/device/issue61659-neon-assignment/jni/issue61659-neon-assignment.c
new file mode 100644
index 0000000..71ccc48
--- /dev/null
+++ b/tests/device/issue61659-neon-assignment/jni/issue61659-neon-assignment.c
@@ -0,0 +1,58 @@
+#include <stdio.h>
+#include <arm_neon.h>
+
+int fail_count = 0;
+
+void dump_and_check(unsigned long long v, unsigned long long expected)
+{
+ printf("%016llx\n", v);
+ fail_count += (v != expected);
+}
+
+static const uint8x8_t v00FF8 = { 0,0,0,0, 0xff,0xff,0xff,0xff }; // wrong
+static const uint8x8_t vFF008 = { 0xff,0xff,0xff,0xff, 0,0,0,0 };
+
+void test1()
+{
+ uint8x8_t v = v00FF8;
+ dump_and_check(*(unsigned long long *)&v, 0xffffffff00000000ULL);
+}
+
+void test2()
+{
+ static const uint64_t local_Mask2 = { 0xffffffff00000000ULL };
+ uint8x8_t v00FF8 = vcreate_u8(local_Mask2); //{ 0,0,0,0,0xff,0xff,0xff,0xff };
+ dump_and_check(*(unsigned long long *)&v00FF8, 0xffffffff00000000ULL);
+}
+
+void test3()
+{
+ static const uint32_t vFF_ = { 0xFFFFFFFF };
+ static const uint32_t v00_ = { 0x00000000 };
+ static uint32x2_t v00FF_;
+ v00FF_ = vset_lane_u32( vFF_, v00FF_, 1);
+ v00FF_ = vset_lane_u32( v00_, v00FF_, 0);
+ uint8x8_t v00FF8 = (uint8x8_t)v00FF_;
+ dump_and_check(*(unsigned long long *)&v00FF8, 0xffffffff00000000ULL);
+}
+
+void test4()
+{
+ uint8x8_t mask_high = vcreate_u8(0xFFFFFFFF00000000ULL);
+ uint8x8_t mask_low = vcreate_u8(0x00000000FFFFFFFFULL);
+ uint8x8_t va = vdup_n_u8 ('a');
+ uint8x8_t vb = vdup_n_u8 ('b');
+ uint8x8_t in = vorr_u8(vand_u8 (va, mask_low), vand_u8 (vb, mask_high));
+ dump_and_check(*(unsigned long long *)&in, 0x6262626261616161ULL);
+}
+
+
+int main()
+{
+ test1();
+ test2();
+ test3();
+ test4();
+ printf("fail_count = %d\n", fail_count);
+ return (fail_count == 0)? 0 : 1;
+}
diff --git a/tests/device/issue62910-gcc4.8.2-libstdc++-nth-element-segfault/jni/Android.mk b/tests/device/issue62910-gcc4.8.2-libstdc++-nth-element-segfault/jni/Android.mk
new file mode 100644
index 0000000..af97a27
--- /dev/null
+++ b/tests/device/issue62910-gcc4.8.2-libstdc++-nth-element-segfault/jni/Android.mk
@@ -0,0 +1,7 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := issue62910-gcc4.8.2-libstdc++-nth-element-segfault
+LOCAL_SRC_FILES := issue62910-gcc4.8.2-libstdc++-nth-element-segfault.cpp
+LOCAL_CPPFLAGS += -std=gnu++11
+include $(BUILD_EXECUTABLE)
diff --git a/tests/device/issue62910-gcc4.8.2-libstdc++-nth-element-segfault/jni/Application.mk b/tests/device/issue62910-gcc4.8.2-libstdc++-nth-element-segfault/jni/Application.mk
new file mode 100644
index 0000000..d736092
--- /dev/null
+++ b/tests/device/issue62910-gcc4.8.2-libstdc++-nth-element-segfault/jni/Application.mk
@@ -0,0 +1,2 @@
+APP_ABI := all
+APP_STL := gnustl_static
\ No newline at end of file
diff --git a/tests/device/issue62910-gcc4.8.2-libstdc++-nth-element-segfault/jni/issue62910-gcc4.8.2-libstdc++-nth-element-segfault.cpp b/tests/device/issue62910-gcc4.8.2-libstdc++-nth-element-segfault/jni/issue62910-gcc4.8.2-libstdc++-nth-element-segfault.cpp
new file mode 100644
index 0000000..984705b
--- /dev/null
+++ b/tests/device/issue62910-gcc4.8.2-libstdc++-nth-element-segfault/jni/issue62910-gcc4.8.2-libstdc++-nth-element-segfault.cpp
@@ -0,0 +1,29 @@
+#include <algorithm>
+#include <stdint.h>
+#include <iostream>
+
+double to_double(uint64_t x)
+{
+ union {double d; uint64_t x;} u;
+ u.x = x;
+ return u.d;
+}
+
+int main()
+{
+ std::vector<double> v = {
+ to_double(4606672070890243784),
+ to_double(4606672025854247510),
+ to_double(4606671800674266141),
+ to_double(4606671575494284772),
+ to_double(4606672115926240057),
+ to_double(4606672160962236330),
+ to_double(4606672070890243784),
+ };
+
+ for (auto i : v)
+ std::cout << i << std::endl;
+
+ std::nth_element(v.begin(), v.begin() + 3, v.end());
+ return 0;
+}
diff --git a/tests/device/math/jni/Android.mk b/tests/device/math/jni/Android.mk
new file mode 100644
index 0000000..eb621dd
--- /dev/null
+++ b/tests/device/math/jni/Android.mk
@@ -0,0 +1,11 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := math_c
+LOCAL_SRC_FILES := math.c
+include $(BUILD_EXECUTABLE)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := math_cpp
+LOCAL_SRC_FILES := math.cpp
+include $(BUILD_EXECUTABLE)
diff --git a/tests/device/math/jni/Application.mk b/tests/device/math/jni/Application.mk
new file mode 100644
index 0000000..6dcff3d
--- /dev/null
+++ b/tests/device/math/jni/Application.mk
@@ -0,0 +1,2 @@
+APP_ABI := all
+APP_PLATFORM := android-18
diff --git a/tests/device/math/jni/math.c b/tests/device/math/jni/math.c
new file mode 100644
index 0000000..a6eb0f3
--- /dev/null
+++ b/tests/device/math/jni/math.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2010 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 <android/api-level.h>
+#include <features.h>
+#include <math.h>
+#include <stdio.h>
+
+long double ld, ld1, ldn;
+double d, d1, dn;
+float f, f1, fn;
+int fail_count = 0;
+
+void TEST_EQ(long double a, long double b)
+{
+ long double diff = a - b;
+ if (diff < 0)
+ diff = -diff;
+ if (diff > 0.0000001)
+ fail_count ++;
+}
+
+int main()
+{
+#if __ANDROID_API__ >= 9
+ sincosl(0.73, &ld, &ld1);
+ sincos(0.72, &d, &d1);
+ sincosf(0.71f, &f, &f1);
+ TEST_EQ(ld, 0.6668696L);
+ TEST_EQ(ld1, 0.7451744L);
+ TEST_EQ(d, 0.6593847);
+ TEST_EQ(d1, 0.7518057);
+ TEST_EQ(f, 0.6518338f);
+ TEST_EQ(f1, 0.7583619f);
+#if __ANDROID_API__ >= 13
+ ldn = nanl("");
+ dn = nan("");
+ fn = nanf("");
+#if __ANDROID_API__ >= 18
+ ld = 1234L;
+ ld = logbl(ld);
+ TEST_EQ(ld, 10L);
+ ld = log2l(ld);
+ TEST_EQ(ld, 3.321928L);
+ d = 56.78;
+ d = log2(d);
+ TEST_EQ(d, 5.827311);
+ f = 0.9012f;
+ f = log2f(f);
+ TEST_EQ(f, -.1500808f);
+ ld = nexttowardl(ld, 0);
+ d = nexttoward(d, 0);
+#endif
+#endif
+#endif
+ if (fail_count)
+ printf("fail_count = %d\n", fail_count);
+
+ return fail_count;
+}
diff --git a/tests/device/math/jni/math.cpp b/tests/device/math/jni/math.cpp
new file mode 120000
index 0000000..8a27507
--- /dev/null
+++ b/tests/device/math/jni/math.cpp
@@ -0,0 +1 @@
+math.c
\ No newline at end of file
diff --git a/tests/device/test-cpufeatures/jni/test_cpufeatures.c b/tests/device/test-cpufeatures/jni/test_cpufeatures.c
index 8b73645..c5fe0c7 100644
--- a/tests/device/test-cpufeatures/jni/test_cpufeatures.c
+++ b/tests/device/test-cpufeatures/jni/test_cpufeatures.c
@@ -29,6 +29,15 @@
case ANDROID_CPU_FAMILY_MIPS:
printf("CPU family is MIPS\n");
break;
+ case ANDROID_CPU_FAMILY_ARM64:
+ printf("CPU family is ARM64\n");
+ break;
+ case ANDROID_CPU_FAMILY_X86_64:
+ printf("CPU family is x86_64\n");
+ break;
+ case ANDROID_CPU_FAMILY_MIPS64:
+ printf("CPU family is MIPS64\n");
+ break;
default:
fprintf(stderr, "Unsupported CPU family: %d\n", family);
return 1;
diff --git a/tests/device/test-openmp/BROKEN_BUILD b/tests/device/test-openmp/BROKEN_BUILD
index e7b612f..24b8be9 100644
--- a/tests/device/test-openmp/BROKEN_BUILD
+++ b/tests/device/test-openmp/BROKEN_BUILD
@@ -1 +1 @@
-clang3.1 clang3.2 clang3.3
\ No newline at end of file
+clang3.1 clang3.2 clang3.3 clang3.4
diff --git a/tests/device/test-stlport_shared-exception/jni/delete2.cpp b/tests/device/test-stlport_shared-exception/jni/delete2.cpp
index 8a486be..c595698 100644
--- a/tests/device/test-stlport_shared-exception/jni/delete2.cpp
+++ b/tests/device/test-stlport_shared-exception/jni/delete2.cpp
@@ -1,3 +1,5 @@
+#include <stdio.h>
+
// PR c++/15097
// { dg-do run }
@@ -18,8 +20,20 @@
void operator delete (void *p)
{
- if (p != saved)
- abort ();
+// Note that since STL is built w/o -Bsymbolic a lots of other code in STL
+// may use the customized new/delete in this file. We only save one copy of
+// poitner in variable "saved", but because this testcase new and immediately
+// delete in single thread, this single-copy serves well, provided that we only
+// check saved==p once and set saved to NULL to prevent further comparison of
+// unrelated delete from within STL
+ if (saved) {
+ if (p == saved) {
+ saved = NULL;
+ } else {
+ abort ();
+ }
+ }
+
free (p);
}
diff --git a/tests/device/test-stlport_static-exception/jni/delete2.cpp b/tests/device/test-stlport_static-exception/jni/delete2.cpp
index 8a486be..c595698 100644
--- a/tests/device/test-stlport_static-exception/jni/delete2.cpp
+++ b/tests/device/test-stlport_static-exception/jni/delete2.cpp
@@ -1,3 +1,5 @@
+#include <stdio.h>
+
// PR c++/15097
// { dg-do run }
@@ -18,8 +20,20 @@
void operator delete (void *p)
{
- if (p != saved)
- abort ();
+// Note that since STL is built w/o -Bsymbolic a lots of other code in STL
+// may use the customized new/delete in this file. We only save one copy of
+// poitner in variable "saved", but because this testcase new and immediately
+// delete in single thread, this single-copy serves well, provided that we only
+// check saved==p once and set saved to NULL to prevent further comparison of
+// unrelated delete from within STL
+ if (saved) {
+ if (p == saved) {
+ saved = NULL;
+ } else {
+ abort ();
+ }
+ }
+
free (p);
}
diff --git a/tests/device/test-wait/jni/Android.mk b/tests/device/test-wait/jni/Android.mk
index 94d662a..2693ab0 100644
--- a/tests/device/test-wait/jni/Android.mk
+++ b/tests/device/test-wait/jni/Android.mk
@@ -10,4 +10,3 @@
LOCAL_SRC_FILES := test_wait.c
LOCAL_LDFLAGS += -static -Wl,--eh-frame-hdr
include $(BUILD_EXECUTABLE)
-
diff --git a/tests/device/test-wait/jni/test_wait.c b/tests/device/test-wait/jni/test_wait.c
index 3e16dfd..701c17e 100644
--- a/tests/device/test-wait/jni/test_wait.c
+++ b/tests/device/test-wait/jni/test_wait.c
@@ -26,127 +26,100 @@
* SUCH DAMAGE.
*/
-#include <sys/wait.h>
-#include <stdlib.h>
-#include <unistd.h>
+#include <errno.h>
#include <stdio.h>
+#include <stdlib.h>
+#include <sys/wait.h>
+
+#define CHILD_EXIT_CODE 111
+
+typedef int (*wait_call_function)(pid_t child_pid);
+
+static int check_wait_call(const char* title,
+ wait_call_function wait_func,
+ int expected_exit_code) {
+ printf("Testing %s(): ", title);
+ int cpid = fork();
+ if (cpid < 0) {
+ fprintf(stderr, "ERROR: fork() failed: %s\n", strerror(errno));
+ return -1;
+ }
+
+ if (cpid == 0) { /* in the chid process */
+ printf("Child created pid=%d parent_pid=%d\n", getpid(), getppid());
+ exit(expected_exit_code);
+ }
+
+ /* in the parent process */
+ printf("Parent waiting for child with pid=%d\n", cpid);
+ int exit_code = wait_func(cpid);
+ if (exit_code < 0)
+ return -1;
+
+ if (exit_code != expected_exit_code) {
+ fprintf(stderr, "ERROR: Child exited with code %d, expected %d\n",
+ exit_code, expected_exit_code);
+ return -1;
+ }
+ printf("Testing %s(): OK\n", title);
+ return 0;
+}
+
+// To be called by check_wait_call() to check wait().
+static int check_wait(pid_t child_pid) {
+ int status = 0;
+ pid_t ret = wait(&status);
+ if (ret != child_pid) {
+ fprintf(stderr, "ERROR: wait() returned %d, expected %d\n", ret, child_pid);
+ return -1;
+ }
+ return WEXITSTATUS(status);
+}
+
+// To be called by check_wait_call() to check waitpid()
+static int check_waitpid(pid_t child_pid) {
+ int status = 0;
+ pid_t ret = waitpid((pid_t)-1, &status, 0);
+ if (ret != child_pid) {
+ fprintf(stderr, "ERROR: waitpid() returned %d, expected %d\n", ret, child_pid);
+ return -1;
+ }
+ return WEXITSTATUS(status);
+}
+
+// To be called by check_wait_call() to check wait3()
+static int check_wait3(pid_t child_pid) {
+ int status = 0;
+ struct rusage ru;
+ pid_t ret = wait3(&status, 0, &ru);
+ if (ret != child_pid) {
+ fprintf(stderr, "ERROR: wait3() returned %d, expected %d\n", ret, child_pid);
+ return -1;
+ }
+ return WEXITSTATUS(status);
+}
+
+// To be called by check_wait_call() to check wait3()
+static int check_wait4(pid_t child_pid) {
+ int status = 0;
+ struct rusage ru;
+ pid_t ret = wait4(-1, &status, 0, &ru);
+ if (ret != child_pid) {
+ fprintf(stderr, "ERROR: wait3() returned %d, expected %d\n", ret, child_pid);
+ return -1;
+ }
+ return WEXITSTATUS(status);
+}
int main(int argc, char *argv[]) {
+ printf("Testing for API level %d\n", __ANDROID_API__);
+ if (check_wait_call("wait", check_wait, CHILD_EXIT_CODE + 0) < 0 ||
+ check_wait_call("waitpid", check_waitpid, CHILD_EXIT_CODE + 1) < 0 ||
+ check_wait_call("wait3", check_wait3, CHILD_EXIT_CODE + 2) < 0 ||
+ check_wait_call("wait4", check_wait4, CHILD_EXIT_CODE + 3)) {
+ return 1;
+ }
- pid_t cpid;
- int status;
- struct rusage usage;
-
-//----------------------------------------------------
-//----------------- Wait(); System Call --------------
-//----------------------------------------------------
- printf("Testing Wait(); System Call\n");
- printf("\n");
-
- cpid = fork(); /* Creates fork */
- if (cpid == -1) {
- printf("For has failed, returned = %d\n", EXIT_FAILURE);
- }
-
- if (cpid == 0) { /* This is the child operation */
- printf("Child Created\n");
- printf("Child = %d\n", getpid());
- printf("Parent = %d\n", getppid());
- sleep(2);
- exit(3);
-
- } else { /* This is the parent operation */
- printf("Waiting for child\n");
- wait(&status);
- printf("Waiting Complete\n");
- printf("Child Exit Code: %d\n", WEXITSTATUS(status));
- }
-
- printf("\n"); /* Just console space */
-//----------------------------------------------------
-//-------------- Waitpid(); System Call --------------
-//----------------------------------------------------
- printf("Testing Waitpid(); System Call\n");
- printf("\n");
-
-
- cpid = fork(); /* Creates fork */
- if (cpid == -1) {
- printf("Fork has failed, returned = %d\n", EXIT_FAILURE);
- }
-
- if (cpid == 0) { /* This is the child operation */
- printf("Child Created\n");
- printf("Child = %d\n", getpid());
- printf("Parent = %d\n", getppid());
- sleep(2);
- exit(3);
-
- } else { /* This is the parent operation */
- printf("Waiting for child %d\n", cpid);
- waitpid(cpid, NULL, 0);
- printf("Waiting Complete\n");
- printf("Child Exit Code: %d\n", WEXITSTATUS(status));
- }
-
- printf("\n");
-//----------------------------------------------------
-//---------------- Wait3(); System Call --------------
-//----------------------------------------------------
- printf("Testing Wait3(); System Call\n");
- printf("\n");
-
- cpid = fork(); /* Creates fork */
- if (cpid == -1) {
- printf("For has failed, returned = %d\n", EXIT_FAILURE);
- }
-
- if (cpid == 0) { /* This is the child operation */
- printf("Child Created\n");
- printf("Child = %d\n", getpid());
- printf("Parent = %d\n", getppid());
- sleep(2);
- exit(3);
-
- } else { /* This is the parent operation */
- printf("Waiting for child\n");
- wait3(&status, 0, &usage);
- printf("Waiting Complete\n");
- printf("Child Exit Code: %d\n", WEXITSTATUS(status));
- }
-
- printf("\n");
- sleep(1);
-//----------------------------------------------------
-//---------------- Wait4(); System Call --------------
-//----------------------------------------------------
- printf("Testing Wait4(); System Call\n");
- printf("\n");
-
- cpid = fork(); /* Creates fork */
- if (cpid == -1) {
- printf("For has failed, returned = %d\n", EXIT_FAILURE);
- }
-
- if (cpid == 0) { /* This is the child operation */
- printf("Child Created\n");
- printf("Child = %d\n", getpid());
- printf("Parent = %d\n", getppid());
- sleep(2);
- exit(3);
-
- } else { /* This is the parent operation */
- printf("Waiting for child\n");
- wait4(cpid, &status, 0, &usage);
- //__wait4(cpid, &status, 0, &usage); // This function will work, the above which is delcared will not.
- printf("Waiting Complete\n");
- printf("Child Exit Code: %d\n", WEXITSTATUS(status));
- }
-
- printf("\n");
- sleep(1);
-
- return EXIT_SUCCESS;
-
+ return EXIT_SUCCESS;
}
diff --git a/tests/device/test-yasm/jni/Android.mk b/tests/device/test-yasm/jni/Android.mk
new file mode 100644
index 0000000..26b6fa7
--- /dev/null
+++ b/tests/device/test-yasm/jni/Android.mk
@@ -0,0 +1,8 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := test-yasm
+LOCAL_SRC_FILES := \
+ test-yasm.c \
+ print_hello.asm
+include $(BUILD_EXECUTABLE)
diff --git a/tests/device/test-yasm/jni/Application.mk b/tests/device/test-yasm/jni/Application.mk
new file mode 100644
index 0000000..5eaff6d
--- /dev/null
+++ b/tests/device/test-yasm/jni/Application.mk
@@ -0,0 +1 @@
+APP_ABI := x86
diff --git a/tests/device/test-yasm/jni/print_hello.asm b/tests/device/test-yasm/jni/print_hello.asm
new file mode 100644
index 0000000..5d7a12e
--- /dev/null
+++ b/tests/device/test-yasm/jni/print_hello.asm
@@ -0,0 +1,15 @@
+section .rodata
+ fmt db "Hello, %s!", 10, 0
+
+section .text
+ global print_hello
+ extern printf
+
+ print_hello:
+ sub esp, 28
+ mov eax, [esp+32]
+ mov [esp], dword fmt
+ mov [esp+4], eax
+ call printf
+ add esp, 28
+ ret
diff --git a/tests/device/test-yasm/jni/test-yasm.c b/tests/device/test-yasm/jni/test-yasm.c
new file mode 100644
index 0000000..76c78ae
--- /dev/null
+++ b/tests/device/test-yasm/jni/test-yasm.c
@@ -0,0 +1,6 @@
+void print_hello(char *s);
+int main()
+{
+ print_hello("Android");
+ return 0;
+}
diff --git a/tests/rs/cppallocation/jni/Android.mk b/tests/rs/cppallocation/jni/Android.mk
new file mode 100644
index 0000000..726e3f2
--- /dev/null
+++ b/tests/rs/cppallocation/jni/Android.mk
@@ -0,0 +1,18 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ multiply.rs \
+ compute.cpp
+
+LOCAL_LDFLAGS += -L$(call host-path,$(TARGET_C_INCLUDES)/../lib/rs)
+LOCAL_LDLIBS := -llog -ldl -lRScpp_static
+
+LOCAL_MODULE:= rstest-cppallocation
+
+LOCAL_C_INCLUDES += $(TARGET_C_INCLUDES)/rs/cpp
+LOCAL_C_INCLUDES += $(TARGET_C_INCLUDES)/rs
+LOCAL_C_INCLUDES += $(TARGET_OBJS)/$(LOCAL_MODULE)
+
+include $(BUILD_EXECUTABLE)
+
diff --git a/tests/rs/cppallocation/jni/Application.mk b/tests/rs/cppallocation/jni/Application.mk
new file mode 100644
index 0000000..adf5697
--- /dev/null
+++ b/tests/rs/cppallocation/jni/Application.mk
@@ -0,0 +1,3 @@
+APP_ABI := armeabi-v7a x86 #mips
+APP_PLATFORM := android-19
+APP_STL := stlport_static
diff --git a/tests/rs/cppallocation/jni/compute.cpp b/tests/rs/cppallocation/jni/compute.cpp
new file mode 100644
index 0000000..d176958
--- /dev/null
+++ b/tests/rs/cppallocation/jni/compute.cpp
@@ -0,0 +1,63 @@
+
+#include "RenderScript.h"
+
+#include "ScriptC_multiply.h"
+
+using namespace android;
+using namespace RSC;
+
+int main(int argc, char** argv)
+{
+
+ uint32_t numElems = 1024;
+
+ if (argc >= 2) {
+ int tempNumElems = atoi(argv[1]);
+ if (tempNumElems < 1) {
+ printf("numElems must be greater than 0\n");
+ return 1;
+ }
+ numElems = (uint32_t) tempNumElems;
+ }
+
+ sp<RS> rs = new RS();
+
+ bool r = rs->init("/system/bin");
+
+ sp<const Element> e = Element::U32(rs);
+
+ Type::Builder tb(rs, e);
+ tb.setX(numElems);
+ sp<const Type> t = tb.create();
+
+ sp<Allocation> ain = Allocation::createTyped(rs, t);
+ sp<Allocation> aout = Allocation::createTyped(rs, t);
+
+ sp<ScriptC_multiply> sc = new ScriptC_multiply(rs);
+
+ uint32_t* buf = new uint32_t[numElems];
+ for (uint32_t ct=0; ct < numElems; ct++) {
+ buf[ct] = (uint32_t)ct;
+ }
+
+ ain->copy1DRangeFrom(0, numElems, buf);
+
+ sc->forEach_multiply(ain, aout);
+
+ aout->copy1DRangeTo(0, numElems, buf);
+
+ for (uint32_t ct=0; ct < numElems; ct++) {
+ if (buf[ct] != ct * 2) {
+ printf("Mismatch at location %d: %u\n", ct, buf[ct]);
+ return 1;
+ }
+ }
+
+ printf("Test successful with %u elems!\n", numElems);
+
+ sc.clear();
+ t.clear();
+ e.clear();
+ ain.clear();
+ aout.clear();
+}
diff --git a/tests/rs/cppallocation/jni/multiply.rs b/tests/rs/cppallocation/jni/multiply.rs
new file mode 100644
index 0000000..d1ffefb
--- /dev/null
+++ b/tests/rs/cppallocation/jni/multiply.rs
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(unused)
+#pragma rs_fp_relaxed
+
+uint32_t __attribute__((kernel)) multiply(uint32_t in) {
+ return in * 2;
+}
+
+
diff --git a/tests/rs/cppbasic/jni/Android.mk b/tests/rs/cppbasic/jni/Android.mk
new file mode 100644
index 0000000..1e5134b
--- /dev/null
+++ b/tests/rs/cppbasic/jni/Android.mk
@@ -0,0 +1,18 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ mono.rs \
+ compute.cpp
+
+LOCAL_LDFLAGS += -L$(call host-path,$(TARGET_C_INCLUDES)/../lib/rs)
+LOCAL_LDLIBS := -llog -ldl -lRScpp_static
+
+LOCAL_MODULE:= rstest-compute
+
+LOCAL_C_INCLUDES += $(TARGET_C_INCLUDES)/rs/cpp
+LOCAL_C_INCLUDES += $(TARGET_C_INCLUDES)/rs
+LOCAL_C_INCLUDES += $(TARGET_OBJS)/$(LOCAL_MODULE)
+
+include $(BUILD_EXECUTABLE)
+
diff --git a/tests/rs/cppbasic/jni/Application.mk b/tests/rs/cppbasic/jni/Application.mk
new file mode 100644
index 0000000..adf5697
--- /dev/null
+++ b/tests/rs/cppbasic/jni/Application.mk
@@ -0,0 +1,3 @@
+APP_ABI := armeabi-v7a x86 #mips
+APP_PLATFORM := android-19
+APP_STL := stlport_static
diff --git a/tests/rs/cppbasic/jni/compute.cpp b/tests/rs/cppbasic/jni/compute.cpp
new file mode 100644
index 0000000..d93b453
--- /dev/null
+++ b/tests/rs/cppbasic/jni/compute.cpp
@@ -0,0 +1,116 @@
+
+#include "RenderScript.h"
+
+#include "ScriptC_mono.h"
+
+using namespace android;
+using namespace RSC;
+
+int test_compute()
+{
+ bool failed = false;
+
+ {
+ sp<RS> rs = new RS();
+ printf("New RS %p\n", rs.get());
+
+ // only legitimate because this is a standalone executable
+ bool r = rs->init("/system/bin");
+ printf("Init returned %i\n", r);
+
+ sp<const Element> e = Element::RGBA_8888(rs);
+ printf("Element %p\n", e.get());
+
+ Type::Builder tb(rs, e);
+ tb.setX(128);
+ tb.setY(128);
+ sp<const Type> t = tb.create();
+ printf("Type %p\n", t.get());
+
+
+ sp<Allocation> a1 = Allocation::createSized(rs, e, 1000);
+ printf("Allocation %p\n", a1.get());
+
+ sp<Allocation> ain = Allocation::createTyped(rs, t);
+ sp<Allocation> aout = Allocation::createTyped(rs, t);
+ printf("Allocation %p %p\n", ain.get(), aout.get());
+
+ sp<ScriptC_mono> sc = new ScriptC_mono(rs);
+ printf("new script\n");
+
+ sc->set_alloc(a1);
+ sc->set_elem(e);
+ sc->set_type(t);
+ sc->set_script(sc);
+ sc->set_script(NULL);
+ sp<const Sampler> samp = Sampler::CLAMP_NEAREST(rs);
+ sc->set_sampler(samp);
+
+ // We read back the status from the script-side via a "failed" allocation.
+ sp<const Element> failed_e = Element::BOOLEAN(rs);
+ Type::Builder failed_tb(rs, failed_e);
+ failed_tb.setX(1);
+ sp<const Type> failed_t = failed_tb.create();
+ sp<Allocation> failed_alloc = Allocation::createTyped(rs, failed_t);
+
+ failed_alloc->copy1DRangeFrom(0, failed_t->getCount(), &failed);
+ sc->bind_failed(failed_alloc);
+
+ uint32_t *buf = new uint32_t[t->getCount()];
+ for (uint32_t ct=0; ct < t->getCount(); ct++) {
+ buf[ct] = ct | (ct << 16);
+ }
+ ain->copy1DRangeFrom(0, t->getCount(), buf);
+ delete [] buf;
+
+ sc->forEach_root(ain, aout);
+
+ sc->invoke_foo(99, 3.1f);
+ sc->set_g_f(39.9f);
+ sc->set_g_i(-14);
+ sc->invoke_foo(99, 3.1f);
+ printf("for each done\n");
+
+ sc->invoke_bar(47, -3, 'c', -7, 14, -8);
+
+ // Verify a simple kernel.
+ {
+ static const uint32_t xDim = 7;
+ static const uint32_t yDim = 7;
+ sp<const Element> e = Element::I32(rs);
+ Type::Builder tb(rs, e);
+ tb.setX(xDim);
+ tb.setY(yDim);
+ sp<const Type> t = tb.create();
+ sp<Allocation> kern1_in = Allocation::createTyped(rs, t);
+ sp<Allocation> kern1_out = Allocation::createTyped(rs, t);
+
+ int *buf = new int[t->getCount()];
+ for (uint32_t ct=0; ct < t->getCount(); ct++) {
+ buf[ct] = 5;
+ }
+ kern1_in->copy2DRangeFrom(0, 0, xDim, yDim, buf);
+ delete [] buf;
+
+ sc->forEach_kern1(kern1_in, kern1_out);
+ sc->forEach_verify_kern1(kern1_out);
+
+ rs->finish();
+ failed_alloc->copy1DTo(&failed);
+ }
+ }
+
+ return failed;
+}
+
+int main() {
+ bool failed = test_compute();
+
+ if (failed) {
+ printf("TEST FAILED!\n");
+ } else {
+ printf("TEST PASSED!\n");
+ }
+
+ return failed;
+}
diff --git a/tests/rs/cppbasic/jni/mono.rs b/tests/rs/cppbasic/jni/mono.rs
new file mode 100644
index 0000000..9e262e7
--- /dev/null
+++ b/tests/rs/cppbasic/jni/mono.rs
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(com.android.rs.cppbasic)
+#pragma rs_fp_relaxed
+
+int g_i = 4;
+
+float g_f = 5.9;
+
+const static float3 gMonoMult = {0.299f, 0.587f, 0.114f};
+
+bool *failed;
+
+#define _RS_ASSERT(b) \
+do { \
+ if (!(b)) { \
+ *failed = true; \
+ rsDebug(#b " FAILED", 0); \
+ } \
+\
+} while (0)
+
+struct myStruct {
+ int i;
+ int j;
+ float f;
+ char c[3];
+};
+
+rs_allocation alloc;
+rs_element elem;
+rs_type type;
+rs_sampler sampler;
+rs_script script;
+
+void root(const uchar4 *v_in, uchar4 *v_out) {
+ float4 f4 = rsUnpackColor8888(*v_in);
+
+ float3 mono = dot(f4.rgb, gMonoMult);
+ *v_out = rsPackColorTo8888(mono);
+}
+
+void foo(int i, float f) {
+ rsDebug("g_i", g_i);
+ rsDebug("g_f", g_f);
+ rsDebug("i", i);
+ rsDebug("f", f);
+}
+
+void bar(int i, int j, char k, int l, int m, int n) {
+ _RS_ASSERT(i == 47);
+ _RS_ASSERT(j == -3);
+ _RS_ASSERT(k == 'c');
+ _RS_ASSERT(l == -7);
+ _RS_ASSERT(m == 14);
+ _RS_ASSERT(n == -8);
+}
+
+int __attribute__((kernel)) kern1(int i, uint32_t x, uint32_t y) {
+ return i + 10 * x + 100 *y;
+}
+
+void __attribute__((kernel)) verify_kern1(int i, uint32_t x, uint32_t y) {
+ _RS_ASSERT(i == (5 + 10 * x + 100 * y));
+ rsDebug("i ", i);
+}
+
diff --git a/tests/rs/cppstrided/jni/Android.mk b/tests/rs/cppstrided/jni/Android.mk
new file mode 100644
index 0000000..d7a0dae
--- /dev/null
+++ b/tests/rs/cppstrided/jni/Android.mk
@@ -0,0 +1,18 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ multiply.rs \
+ compute.cpp
+
+LOCAL_LDFLAGS += -L$(call host-path,$(TARGET_C_INCLUDES)/../lib/rs)
+LOCAL_LDLIBS := -llog -ldl -lRScpp_static
+
+LOCAL_MODULE:= rstest-cppstrided
+
+LOCAL_C_INCLUDES += $(TARGET_C_INCLUDES)/rs/cpp
+LOCAL_C_INCLUDES += $(TARGET_C_INCLUDES)/rs
+LOCAL_C_INCLUDES += $(TARGET_OBJS)/$(LOCAL_MODULE)
+
+include $(BUILD_EXECUTABLE)
+
diff --git a/tests/rs/cppstrided/jni/Application.mk b/tests/rs/cppstrided/jni/Application.mk
new file mode 100644
index 0000000..adf5697
--- /dev/null
+++ b/tests/rs/cppstrided/jni/Application.mk
@@ -0,0 +1,3 @@
+APP_ABI := armeabi-v7a x86 #mips
+APP_PLATFORM := android-19
+APP_STL := stlport_static
diff --git a/tests/rs/cppstrided/jni/compute.cpp b/tests/rs/cppstrided/jni/compute.cpp
new file mode 100644
index 0000000..819bcdc
--- /dev/null
+++ b/tests/rs/cppstrided/jni/compute.cpp
@@ -0,0 +1,74 @@
+
+#include "RenderScript.h"
+
+#include "ScriptC_multiply.h"
+
+using namespace android;
+using namespace RSC;
+
+int main(int argc, char** argv)
+{
+
+ uint32_t numElems = 1024;
+ uint32_t stride = 1025;
+
+ if (argc >= 2) {
+ int tempStride = atoi(argv[1]);
+ if (tempStride < 1024) {
+ printf("stride must be greater than or equal to 1024\n");
+ return 1;
+ }
+ stride = (uint32_t) tempStride;
+ }
+
+ sp<RS> rs = new RS();
+
+ bool r = rs->init("/system/bin");
+
+ sp<const Element> e = Element::U32(rs);
+
+ Type::Builder tb(rs, e);
+ tb.setX(numElems);
+ tb.setY(numElems);
+ sp<const Type> t = tb.create();
+
+ sp<Allocation> ain = Allocation::createTyped(rs, t);
+ sp<Allocation> aout = Allocation::createTyped(rs, t);
+
+ sp<ScriptC_multiply> sc = new ScriptC_multiply(rs);
+
+ uint32_t* buf = (uint32_t*) malloc(stride * numElems * sizeof(uint32_t));
+ if (!buf) {
+ printf("malloc failed\n");
+ return 1;
+ }
+
+ for (uint32_t i = 0; i < numElems; i++) {
+ for (uint32_t ct=0; ct < numElems; ct++) {
+ *(buf+(stride*i)+ct) = (uint32_t)ct + (i * numElems);
+ }
+ }
+
+ ain->copy2DStridedFrom(buf, stride * sizeof(uint32_t));
+
+ sc->forEach_multiply(ain, aout);
+
+ aout->copy2DStridedTo(buf, stride * sizeof(uint32_t));
+
+ for (uint32_t i = 0; i < numElems; i++) {
+ for (uint32_t ct=0; ct < numElems; ct++) {
+ if (*(buf+(stride*i)+ct) != (uint32_t)(ct + (i * numElems)) * 2) {
+ printf("Mismatch at location %d, %d: %u\n", i, ct, *(buf+(stride*i)+ct));
+ return 1;
+ }
+ }
+ }
+
+ printf("Test successful with %u stride!\n", stride);
+
+ sc.clear();
+ t.clear();
+ e.clear();
+ ain.clear();
+ aout.clear();
+}
diff --git a/tests/rs/cppstrided/jni/multiply.rs b/tests/rs/cppstrided/jni/multiply.rs
new file mode 100644
index 0000000..d1ffefb
--- /dev/null
+++ b/tests/rs/cppstrided/jni/multiply.rs
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(unused)
+#pragma rs_fp_relaxed
+
+uint32_t __attribute__((kernel)) multiply(uint32_t in) {
+ return in * 2;
+}
+
+
diff --git a/tests/rs/latency/jni/Android.mk b/tests/rs/latency/jni/Android.mk
new file mode 100644
index 0000000..b4f0b25
--- /dev/null
+++ b/tests/rs/latency/jni/Android.mk
@@ -0,0 +1,18 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ latency.rs \
+ test-latency.cpp
+
+LOCAL_LDFLAGS += -L$(call host-path,$(TARGET_C_INCLUDES)/../lib/rs)
+LOCAL_LDLIBS := -llog -ldl -lRScpp_static
+
+LOCAL_MODULE:= rstest-latency
+
+LOCAL_C_INCLUDES += $(TARGET_C_INCLUDES)/rs/cpp
+LOCAL_C_INCLUDES += $(TARGET_C_INCLUDES)/rs
+LOCAL_C_INCLUDES += $(TARGET_OBJS)/$(LOCAL_MODULE)
+
+include $(BUILD_EXECUTABLE)
+
diff --git a/tests/rs/latency/jni/Application.mk b/tests/rs/latency/jni/Application.mk
new file mode 100644
index 0000000..adf5697
--- /dev/null
+++ b/tests/rs/latency/jni/Application.mk
@@ -0,0 +1,3 @@
+APP_ABI := armeabi-v7a x86 #mips
+APP_PLATFORM := android-19
+APP_STL := stlport_static
diff --git a/tests/rs/latency/jni/latency.rs b/tests/rs/latency/jni/latency.rs
new file mode 100644
index 0000000..6fc4bfd
--- /dev/null
+++ b/tests/rs/latency/jni/latency.rs
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(com.android.rs.cpptests)
+#pragma rs_fp_relaxed
+
+void root(const uint32_t *v_in, uint32_t *v_out) {
+
+}
+
+
diff --git a/tests/rs/latency/jni/test-latency.cpp b/tests/rs/latency/jni/test-latency.cpp
new file mode 100644
index 0000000..05337be
--- /dev/null
+++ b/tests/rs/latency/jni/test-latency.cpp
@@ -0,0 +1,111 @@
+#include "RenderScript.h"
+#include <sys/time.h>
+
+#include "ScriptC_latency.h"
+
+using namespace android;
+using namespace RSC;
+
+int main(int argc, char** argv)
+{
+ int iters = 100;
+ int numElems = 1000;
+ bool forceCpu = false;
+ bool synchronous = false;
+
+ if (argc >= 2) {
+ iters = atoi(argv[1]);
+ if (iters <= 0) {
+ printf("iters must be positive\n");
+ return 1;
+ }
+ }
+
+ printf("iters = %d\n", iters);
+
+ if (argc >= 3) {
+ numElems = atoi(argv[2]);
+ if (numElems <= 0) {
+ printf("numElems must be positive\n");
+ return 1;
+ }
+ }
+
+ if (argc >= 4) {
+ int temp = atoi(argv[3]);
+ if (temp != 0)
+ forceCpu = true;
+ }
+
+ if (argc >= 5) {
+ int temp = atoi(argv[4]);
+ if (temp != 0)
+ synchronous = true;
+ }
+
+ if (forceCpu)
+ printf("forcing CPU\n");
+
+ if (synchronous)
+ printf("forcing synchronous\n");
+
+ printf("numElems = %d\n", numElems);
+
+ sp<RS> rs = new RS();
+
+ uint32_t flags = 0;
+ if (forceCpu) flags |= RS_INIT_LOW_LATENCY;
+ if (synchronous) flags |= RS_INIT_SYNCHRONOUS;
+
+ bool r = rs->init("/system/bin", flags);
+
+ sp<const Element> e = Element::U32(rs);
+
+ Type::Builder tb(rs, e);
+ tb.setX(numElems);
+ sp<const Type> t = tb.create();
+
+ uint32_t *buf = new uint32_t[numElems];
+
+ sp<Allocation> ain = Allocation::createTyped(rs, t);
+ sp<Allocation> aout = Allocation::createTyped(rs, t);
+
+ sp<ScriptC_latency> sc = new ScriptC_latency(rs);
+
+ struct timeval start, stop;
+
+ gettimeofday(&start, NULL);
+
+ for (int i = 0; i < iters; i++) {
+ sc->forEach_root(ain, aout);
+ }
+
+ rs->finish();
+
+ gettimeofday(&stop, NULL);
+
+ long long elapsed = (stop.tv_sec * 1000000) - (start.tv_sec * 1000000) + (stop.tv_usec - start.tv_usec);
+ printf("elapsed time : %lld microseconds\n", elapsed);
+ printf("time per iter: %f microseconds\n", (double)elapsed / iters);
+
+ gettimeofday(&start, NULL);
+
+ for (int i = 0; i < iters; i++) {
+ ain->copy1DFrom(buf);
+ sc->forEach_root(ain, aout);
+ aout->copy1DTo(buf);
+ }
+
+ rs->finish();
+
+ gettimeofday(&stop, NULL);
+ elapsed = (stop.tv_sec * 1000000) - (start.tv_sec * 1000000) + (stop.tv_usec - start.tv_usec);
+ printf("elapsed time with copy : %lld microseconds\n", elapsed);
+ printf("time per iter with copy: %f microseconds\n", (double)elapsed / iters);
+
+ sc.clear();
+ t.clear();
+ e.clear();
+ ain.clear();
+ aout.clear();
+}
diff --git a/tests/rs/typecheck/jni/Android.mk b/tests/rs/typecheck/jni/Android.mk
new file mode 100644
index 0000000..68b9f04
--- /dev/null
+++ b/tests/rs/typecheck/jni/Android.mk
@@ -0,0 +1,18 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ kernels.rs \
+ typecheck.cpp
+
+LOCAL_LDFLAGS += -L$(call host-path,$(TARGET_C_INCLUDES)/../lib/rs)
+LOCAL_LDLIBS := -llog -ldl -lRScpp_static
+
+LOCAL_MODULE:= rstest-typecheck
+
+LOCAL_C_INCLUDES += $(TARGET_C_INCLUDES)/rs/cpp
+LOCAL_C_INCLUDES += $(TARGET_C_INCLUDES)/rs
+LOCAL_C_INCLUDES += $(TARGET_OBJS)/$(LOCAL_MODULE)
+
+include $(BUILD_EXECUTABLE)
+
diff --git a/tests/rs/typecheck/jni/Application.mk b/tests/rs/typecheck/jni/Application.mk
new file mode 100644
index 0000000..adf5697
--- /dev/null
+++ b/tests/rs/typecheck/jni/Application.mk
@@ -0,0 +1,3 @@
+APP_ABI := armeabi-v7a x86 #mips
+APP_PLATFORM := android-19
+APP_STL := stlport_static
diff --git a/tests/rs/typecheck/jni/kernels.rs b/tests/rs/typecheck/jni/kernels.rs
new file mode 100644
index 0000000..5bf3499
--- /dev/null
+++ b/tests/rs/typecheck/jni/kernels.rs
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(com.android.rs.typecheck)
+#pragma rs_fp_relaxed
+
+// Test initialized and uninitialized variables
+char c1;
+char c1i = 1;
+char2 c2;
+char2 c2i = {1, 2};
+char3 c3;
+char3 c3i = {1, 2, 3};
+char4 c4;
+char4 c4i = {1, 2, 3, 4};
+
+uchar uc1;
+uchar uc1i = 1;
+uchar2 uc2;
+uchar2 uc2i = {1, 2};
+uchar3 uc3;
+uchar3 uc3i = {1, 2, 3};
+uchar4 uc4;
+uchar4 uc4i = {1, 2, 3, 4};
+
+short s1;
+short s1i = 1;
+short2 s2;
+short2 s2i = {1, 2};
+short3 s3;
+short3 s3i = {1, 2, 3};
+short4 s4;
+short4 s4i = {1, 2, 3, 4};
+
+ushort us1;
+ushort us1i = 1;
+ushort2 us2;
+ushort2 us2i = {1, 2};
+ushort3 us3;
+ushort3 us3i = {1, 2, 3};
+ushort4 us4;
+ushort4 us4i = {1, 2, 3, 4};
+
+int i1;
+int i1i = 1;
+int2 i2;
+int2 i2i = {1, 2};
+int3 i3;
+int3 i3i = {1, 2, 3};
+int4 i4;
+int4 i4i = {1, 2, 3, 4};
+
+uint ui1;
+uint ui1i = 1;
+uint2 ui2;
+uint2 ui2i = {1, 2};
+uint3 ui3;
+uint3 ui3i = {1, 2, 3};
+uint4 ui4;
+uint4 ui4i = {1, 2, 3, 4};
+
+long l1;
+long l1i = 1;
+long2 l2;
+long2 l2i = {1, 2};
+long3 l3;
+long3 l3i = {1, 2, 3};
+long4 l4;
+long4 l4i = {1, 2, 3, 4};
+
+ulong ul1;
+ulong ul1i = 1;
+ulong2 ul2;
+ulong2 ul2i = {1, 2};
+ulong3 ul3;
+ulong3 ul3i = {1, 2, 3};
+ulong4 ul4;
+ulong4 ul4i = {1, 2, 3, 4};
+
+float f1;
+float f1i = 3.141592265358979f;
+float2 f2;
+float2 f2i = {1.f, 2.f};
+float3 f3;
+float3 f3i = {1.f, 2.f, 3.f};
+float4 f4;
+float4 f4i = {1.f, 2.f, 3.f, 4.f};
+
+double d1;
+double d1i = 3.141592265358979;
+double2 d2;
+double2 d2i = {1, 2};
+double3 d3;
+double3 d3i = {1, 2, 3};
+double4 d4;
+double4 d4i = {1, 2, 3, 4};
+
+
+void __attribute__((kernel)) test_BOOLEAN(bool in) {
+}
+
+void __attribute__((kernel)) test_I8(char in) {
+}
+
+void __attribute__((kernel)) test_U8(uchar in) {
+}
+
+void __attribute__((kernel)) test_I16(short in) {
+}
+
+void __attribute__((kernel)) test_U16(ushort in) {
+}
+
+void __attribute__((kernel)) test_I32(int in) {
+}
+
+void __attribute__((kernel)) test_U32(uint in) {
+}
+
+void __attribute__((kernel)) test_I64(long in) {
+}
+
+void __attribute__((kernel)) test_U64(ulong in) {
+}
+
+void __attribute__((kernel)) test_F32(float in) {
+}
+
+void __attribute__((kernel)) test_F64(double in) {
+}
+
diff --git a/tests/rs/typecheck/jni/typecheck.cpp b/tests/rs/typecheck/jni/typecheck.cpp
new file mode 100644
index 0000000..76ae16f
--- /dev/null
+++ b/tests/rs/typecheck/jni/typecheck.cpp
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2013 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 "RenderScript.h"
+#include "ScriptC_kernels.h"
+
+using namespace android;
+using namespace RSC;
+
+const static uint32_t x = 7;
+
+sp<Allocation> createAlloc(sp<RS> rs, sp<const Element> e) {
+ Type::Builder tb(rs, e);
+ tb.setX(x);
+ sp<const Type> t = tb.create();
+ return Allocation::createTyped(rs, t);
+}
+
+#define TEST_ELEM(KERNELNAME, ENAME) \
+bool test_elem_##KERNELNAME##_##ENAME() { \
+ printf("Verifying forEach_test_" #KERNELNAME "() with " #ENAME "\n"); \
+ sp<RS> rs = new RS(); \
+ bool r = rs->init("/system/bin"); \
+ sp<Allocation> a = createAlloc(rs, Element::ENAME(rs)); \
+ ScriptC_kernels sc(rs); \
+ sc.forEach_test_##KERNELNAME(a); \
+ rs->finish(); \
+ bool shouldPass = !strcmp(#KERNELNAME, #ENAME); \
+ if (shouldPass != (rs->getError() == RS_SUCCESS)) { \
+ printf("Failed forEach_test_" #KERNELNAME "() with " #ENAME "\n"); \
+ return true; \
+ } \
+ return false; \
+}
+
+#define TEST_ELEM_ALL(ENAME) \
+TEST_ELEM(ENAME, BOOLEAN) \
+TEST_ELEM(ENAME, I8) \
+TEST_ELEM(ENAME, U8) \
+TEST_ELEM(ENAME, I16) \
+TEST_ELEM(ENAME, U16) \
+TEST_ELEM(ENAME, I32) \
+TEST_ELEM(ENAME, U32) \
+TEST_ELEM(ENAME, I64) \
+TEST_ELEM(ENAME, U64) \
+TEST_ELEM(ENAME, F32) \
+TEST_ELEM(ENAME, F64)
+
+TEST_ELEM_ALL(BOOLEAN)
+TEST_ELEM_ALL(I8)
+TEST_ELEM_ALL(U8)
+TEST_ELEM_ALL(I16)
+TEST_ELEM_ALL(U16)
+TEST_ELEM_ALL(I32)
+TEST_ELEM_ALL(U32)
+TEST_ELEM_ALL(I64)
+TEST_ELEM_ALL(U64)
+TEST_ELEM_ALL(F32)
+TEST_ELEM_ALL(F64)
+
+int main()
+{
+ bool failed = false;
+
+#define EXECUTE_TEST_ELEM_ALL(ENAME) \
+ failed |= test_elem_##ENAME##_BOOLEAN(); \
+ failed |= test_elem_##ENAME##_I8(); \
+ failed |= test_elem_##ENAME##_U8(); \
+ failed |= test_elem_##ENAME##_I16(); \
+ failed |= test_elem_##ENAME##_U16(); \
+ failed |= test_elem_##ENAME##_I32(); \
+ failed |= test_elem_##ENAME##_U32(); \
+ failed |= test_elem_##ENAME##_I64(); \
+ failed |= test_elem_##ENAME##_U64(); \
+ failed |= test_elem_##ENAME##_F32(); \
+ failed |= test_elem_##ENAME##_F64(); \
+
+ EXECUTE_TEST_ELEM_ALL(BOOLEAN);
+ EXECUTE_TEST_ELEM_ALL(I8);
+ EXECUTE_TEST_ELEM_ALL(U8);
+ EXECUTE_TEST_ELEM_ALL(I16);
+ EXECUTE_TEST_ELEM_ALL(U16);
+ EXECUTE_TEST_ELEM_ALL(I32);
+ EXECUTE_TEST_ELEM_ALL(U32);
+ EXECUTE_TEST_ELEM_ALL(I64);
+ EXECUTE_TEST_ELEM_ALL(U64);
+ EXECUTE_TEST_ELEM_ALL(F32);
+ EXECUTE_TEST_ELEM_ALL(F64);
+
+ if (failed) {
+ printf("TEST FAILED!\n");
+ } else {
+ printf("TEST PASSED!\n");
+ }
+
+ return failed;
+}
diff --git a/tests/run-libcxx.sh b/tests/run-libcxx.sh
new file mode 100755
index 0000000..91e4746
--- /dev/null
+++ b/tests/run-libcxx.sh
@@ -0,0 +1,48 @@
+#!/bin/sh
+
+DEVICE_arm="$1"
+DEVICE_x86="$2"
+DEVICE_mips="$3"
+
+#STATIC="--static"
+
+echo ================ llvm-libc++
+
+ cd $NDK
+ echo "### make standalone toolchain"
+ TOOLCHAIN_DIR_ARM=${MYOPT}/android-ndk-api14-arm-4.8-libc++
+ TOOLCHAIN_DIR_MIPS=${MYOPT}/android-ndk-api14-mips-4.8-libc++
+ TOOLCHAIN_DIR_X86=${MYOPT}/android-ndk-api14-x86-4.8-libc++
+
+ ./build/tools/make-standalone-toolchain.sh --platform=android-14 --llvm-version=3.3 \
+ --install-dir=$TOOLCHAIN_DIR_ARM --toolchain=arm-linux-androideabi-4.8 --stl=libc++
+ ./build/tools/make-standalone-toolchain.sh --platform=android-14 --llvm-version=3.3 \
+ --install-dir=$TOOLCHAIN_DIR_MIPS --toolchain=mipsel-linux-android-4.8 --stl=libc++
+ ./build/tools/make-standalone-toolchain.sh --platform=android-14 --llvm-version=3.3 \
+ --install-dir=$TOOLCHAIN_DIR_X86 --toolchain=x86-4.8 --stl=libc++
+
+ cd $NDK/sources/cxx-stl/llvm-libc++/libcxx/test
+
+ if [ -z "$DEVICE_arm" ]; then
+ echo "### clang3.3 armeabi-v7a: no device"
+ else
+ echo "### clang3.3 armeabi-v7a"
+ ADB="adb -s $DEVICE_arm" PATH=$TOOLCHAIN_DIR_ARM/bin:$PATH \
+ ./testit_android --abi=armeabi-v7a --cxx=arm-linux-androideabi-clang++ $STATIC
+ fi
+
+ if [ -z "$DEVICE_x86" ]; then
+ echo "### clang3.3 x86: no device"
+ else
+ echo "### clang3.3 x86"
+ ADB="adb -s $DEVICE_x86" PATH=$TOOLCHAIN_DIR_X86/bin:$PATH \
+ ./testit_android --abi=x86 --cxx=i686-linux-android-clang++ $STATIC
+ fi
+
+ if [ -z "$DEVICE_mips" ]; then
+ echo "### clang3.3 mips: no device"
+ else
+ echo "### clang3.3 mips"
+ ADB="adb -s $DEVICE_mips" PATH=$TOOLCHAIN_DIR_MIPS/bin:$PATH \
+ ./testit_android --abi=mips --cxx=mipsel-linux-android-clang++ $STATIC
+ fi
diff --git a/tests/run-tests-all.sh b/tests/run-tests-all.sh
index 03f7ee9..496a054 100755
--- a/tests/run-tests-all.sh
+++ b/tests/run-tests-all.sh
@@ -12,34 +12,44 @@
DEVICE_x86=
ADB_CMD=`which adb`
-if [ -n $ADB_CMD ] ; then
- # Get list of online devices, turn ' ' in device into '#'
- DEVICES=`$ADB_CMD devices | grep -v offline | awk 'NR>1 {gsub(/[ \t]+device$/,""); print;}' | sed '/^$/d' | tr ' ' '#'`
- for DEVICE in $DEVICES; do
- # undo previous ' '-to-'#' translation
- DEVICE=$(echo "$DEVICE" | tr '#' ' ')
- # get arch
- ARCH=`$ADB_CMD -s "$DEVICE" shell getprop ro.product.cpu.abi | tr -dc '[:print:]'`
- case "$ARCH" in
- armeabi*)
- DEVICE_arm=$DEVICE
- ;;
- x86)
- DEVICE_x86=$DEVICE
- ;;
- mips*)
- DEVICE_mips=$DEVICE
- ;;
- *)
- echo "ERROR: Unsupported architecture: $ARCH"
- exit 1
- esac
- done
-fi
-echo "DEVICE_arm=$DEVICE_arm"
-echo "DEVICE_x86=$DEVICE_x86"
-echo "DEVICE_mips=$DEVICE_mips"
+if [ -n "$ANDROID_SERIAL" ] ; then
+ echo ANDROID_SERIAL=$ANDROID_SERIAL
+else
+ if [ -n $ADB_CMD ] ; then
+ # Get list of online devices, turn ' ' in device into '#'
+ DEVICES=`$ADB_CMD devices | grep -v offline | awk 'NR>1 {gsub(/[ \t]+device$/,""); print;}' | sed '/^$/d' | tr ' ' '#'`
+ for DEVICE in $DEVICES; do
+ # undo previous ' '-to-'#' translation
+ DEVICE=$(echo "$DEVICE" | tr '#' ' ')
+ # get arch
+ ARCH=`$ADB_CMD -s "$DEVICE" shell getprop ro.product.cpu.abi | tr -dc '[:print:]'`
+ case "$ARCH" in
+ armeabi*)
+ if [ -z "$DEVICE_arm" ]; then
+ DEVICE_arm=$DEVICE
+ fi
+ ;;
+ x86)
+ if [ -z "$DEVICE_x86" ]; then
+ DEVICE_x86=$DEVICE
+ fi
+ ;;
+ mips*)
+ if [ -z "$DEVICE_mips" ]; then
+ DEVICE_mips=$DEVICE
+ fi
+ ;;
+ *)
+ echo "ERROR: Unsupported architecture: $ARCH"
+ exit 1
+ esac
+ done
+ fi
+ echo "DEVICE_arm=$DEVICE_arm"
+ echo "DEVICE_x86=$DEVICE_x86"
+ echo "DEVICE_mips=$DEVICE_mips"
+fi
#
# check if we need to also test 32-bit host toolchain
diff --git a/tests/run-tests.sh b/tests/run-tests.sh
index dfed27a..6deebce 100755
--- a/tests/run-tests.sh
+++ b/tests/run-tests.sh
@@ -81,7 +81,7 @@
--full)
FULL_TESTS=yes;
;;
- --test=*) # Deprecated, but keep it just in case.
+ --test=*)
RUN_TESTS="$RUN_TESTS $optarg"
;;
--package=*)
@@ -420,7 +420,7 @@
case $ABI in
default) # Let the APP_ABI in jni/Application.mk decide what to build
;;
- armeabi|armeabi-v7a|x86|mips)
+ armeabi|armeabi-v7a|x86|mips|armeabi-v7a-hard)
NDK_BUILD_FLAGS="$NDK_BUILD_FLAGS APP_ABI=$ABI"
;;
*)
@@ -905,11 +905,16 @@
else
ADB_DEVICES="$ADB_DEVICES "
if [ -n "$ANDROID_SERIAL" ] ; then
- ADB_SERIAL=$(echo "$ANDROID_SERIAL" | tr ' ' '#') # turn ' ' into '#'
- if [ "$ADB_DEVICES" = "${ADB_DEVICES%$ADB_SERIAL *}" ] ; then
- dump "WARNING: Device $ANDROID_SERIAL cannot be found or offline!"
- SKIP_TESTS=yes
- else
+ # Expect ANDROID_SERIAL is comma-delimited of one or more devices
+ ANDROID_SERIAL=$(echo "$ANDROID_SERIAL" | tr ' ' '#') # turn ' ' into '#'
+ ANDROID_SERIAL=$(commas_to_spaces $ANDROID_SERIAL)
+ for SERIAL in $ANDROID_SERIAL; do
+ if [ "$ADB_DEVICES" = "${ADB_DEVICES%$SERIAL *}" ] ; then
+ dump "WARNING: Device $SERIAL cannot be found or offline!"
+ SKIP_TESTS=yes
+ fi
+ done
+ if [ "$SKIP_TESTS" != "yes" ] ; then
ADB_DEVICES="$ANDROID_SERIAL"
fi
fi
@@ -919,6 +924,10 @@
dump "SKIPPING RUNNING TESTS ON DEVICE!"
else
AT_LEAST_CPU_ABI_MATCH=
+ REAL_ABI=$ABI
+ if [ "$REAL_ABI" = "armeabi-v7a-hard" ]; then
+ REAL_ABI=armeabi-v7a
+ fi
for DEVICE in $ADB_DEVICES; do
# undo earlier ' '-to-'#' translation
DEVICE=$(echo "$DEVICE" | tr '#' ' ')
@@ -927,13 +936,19 @@
adb_var_shell_cmd "$DEVICE" CPU_ABI2 getprop ro.product.cpu.abi2
CPU_ABIS="$CPU_ABI1,$CPU_ABI2"
CPU_ABIS=$(commas_to_spaces $CPU_ABIS)
+ if [ "$_NDK_TESTING_ALL_" = "yes" ]; then
+ if [ "$CPU_ABI1" = "armeabi-v7a" -o "$CPU_ABI2" = "armeabi-v7a" ]; then
+ CPU_ABIS="$CPU_ABIS armeabi-v7a-hard"
+ fi
+ fi
if [ "$CPU_ABIS" = " " ]; then
# Very old cupcake-based Android devices don't have these properties
# defined. Fortunately, they are all armeabi-based.
CPU_ABIS=armeabi
fi
+ log "CPU_ABIS=$CPU_ABIS"
for CPU_ABI in $CPU_ABIS; do
- if [ "$ABI" = "default" -o "$ABI" = "$CPU_ABI" -o "$ABI" = "$(find_ndk_unknown_archs)" ] ; then
+ if [ "$REAL_ABI" = "default" -o "$REAL_ABI" = "$CPU_ABI" -o "$REAL_ABI" = "$(find_ndk_unknown_archs)" ] ; then
AT_LEAST_CPU_ABI_MATCH="yes"
for DIR in `ls -d $ROOTDIR/tests/device/*`; do
if is_buildable $DIR; then
diff --git a/toolchains/arm-linux-androideabi-4.6/config.mk b/toolchains/arm-linux-androideabi-4.6/config.mk
index 23b3025..9f787cd 100644
--- a/toolchains/arm-linux-androideabi-4.6/config.mk
+++ b/toolchains/arm-linux-androideabi-4.6/config.mk
@@ -17,4 +17,4 @@
# the real meat is in the setup.mk file adjacent to this one
#
TOOLCHAIN_ARCH := arm
-TOOLCHAIN_ABIS := armeabi armeabi-v7a
+TOOLCHAIN_ABIS := armeabi armeabi-v7a armeabi-v7a-hard
diff --git a/toolchains/arm-linux-androideabi-4.6/setup.mk b/toolchains/arm-linux-androideabi-4.6/setup.mk
index 97f0218..cfc6875 100644
--- a/toolchains/arm-linux-androideabi-4.6/setup.mk
+++ b/toolchains/arm-linux-androideabi-4.6/setup.mk
@@ -35,13 +35,20 @@
TARGET_C_INCLUDES := \
$(SYSROOT_INC)/usr/include
-ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
+ifneq ($(filter $(TARGET_ARCH_ABI), armeabi-v7a armeabi-v7a-hard),)
TARGET_CFLAGS += -march=armv7-a \
- -mfloat-abi=softfp \
-mfpu=vfpv3-d16
-
TARGET_LDFLAGS += -march=armv7-a \
-Wl,--fix-cortex-a8
+ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
+ TARGET_CFLAGS += -mfloat-abi=softfp
+else
+ TARGET_CFLAGS += -mhard-float \
+ -D_NDK_MATH_NO_SOFTFP=1
+ TARGET_LDFLAGS += -Wl,--no-warn-mismatch \
+ -lm_hard
+endif
+
else
TARGET_CFLAGS += -march=armv5te \
-mtune=xscale \
diff --git a/toolchains/arm-linux-androideabi-4.8/config.mk b/toolchains/arm-linux-androideabi-4.8/config.mk
index c46dace..4df6c95 100644
--- a/toolchains/arm-linux-androideabi-4.8/config.mk
+++ b/toolchains/arm-linux-androideabi-4.8/config.mk
@@ -17,4 +17,4 @@
# the real meat is in the setup.mk file adjacent to this one
#
TOOLCHAIN_ARCH := arm
-TOOLCHAIN_ABIS := armeabi armeabi-v7a
+TOOLCHAIN_ABIS := armeabi armeabi-v7a armeabi-v7a-hard
diff --git a/toolchains/arm-linux-androideabi-4.8/setup.mk b/toolchains/arm-linux-androideabi-4.8/setup.mk
index e20862a..61a06cf 100644
--- a/toolchains/arm-linux-androideabi-4.8/setup.mk
+++ b/toolchains/arm-linux-androideabi-4.8/setup.mk
@@ -35,13 +35,20 @@
TARGET_C_INCLUDES := \
$(SYSROOT_INC)/usr/include
-ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
+ifneq ($(filter $(TARGET_ARCH_ABI), armeabi-v7a armeabi-v7a-hard),)
TARGET_CFLAGS += -march=armv7-a \
- -mfloat-abi=softfp \
-mfpu=vfpv3-d16
-
TARGET_LDFLAGS += -march=armv7-a \
-Wl,--fix-cortex-a8
+ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
+ TARGET_CFLAGS += -mfloat-abi=softfp
+else
+ TARGET_CFLAGS += -mhard-float \
+ -D_NDK_MATH_NO_SOFTFP=1
+ TARGET_LDFLAGS += -Wl,--no-warn-mismatch \
+ -lm_hard
+endif
+
else
TARGET_CFLAGS += -march=armv5te \
-mtune=xscale \
diff --git a/toolchains/arm-linux-androideabi-clang3.3/config.mk b/toolchains/arm-linux-androideabi-clang3.3/config.mk
index 89f6466..fd13c36 100644
--- a/toolchains/arm-linux-androideabi-clang3.3/config.mk
+++ b/toolchains/arm-linux-androideabi-clang3.3/config.mk
@@ -17,4 +17,4 @@
# the real meat is in the setup.mk file adjacent to this one
#
TOOLCHAIN_ARCH := arm
-TOOLCHAIN_ABIS := armeabi armeabi-v7a
+TOOLCHAIN_ABIS := armeabi armeabi-v7a armeabi-v7a-hard
diff --git a/toolchains/arm-linux-androideabi-clang3.3/setup.mk b/toolchains/arm-linux-androideabi-clang3.3/setup.mk
index 24cd081..30d8678 100644
--- a/toolchains/arm-linux-androideabi-clang3.3/setup.mk
+++ b/toolchains/arm-linux-androideabi-clang3.3/setup.mk
@@ -72,6 +72,20 @@
TARGET_LDFLAGS += -target $(LLVM_TRIPLE) \
-Wl,--fix-cortex-a8
else
+ifneq ($(filter %armeabi-v7a-hard,$(TARGET_ARCH_ABI)),)
+ LLVM_TRIPLE := armv7-none-linux-androideabi
+
+ TARGET_CFLAGS += -target $(LLVM_TRIPLE) \
+ -march=armv7-a \
+ -mfpu=vfpv3-d16 \
+ -mhard-float \
+ -D_NDK_MATH_NO_SOFTFP=1
+
+ TARGET_LDFLAGS += -target $(LLVM_TRIPLE) \
+ -Wl,--fix-cortex-a8 \
+ -Wl,--no-warn-mismatch \
+ -lm_hard
+else
LLVM_TRIPLE := armv5te-none-linux-androideabi
TARGET_CFLAGS += -target $(LLVM_TRIPLE) \
@@ -81,6 +95,7 @@
TARGET_LDFLAGS += -target $(LLVM_TRIPLE)
endif
+endif
TARGET_CFLAGS.neon := -mfpu=neon
diff --git a/toolchains/arm-linux-androideabi-clang3.4/config.mk b/toolchains/arm-linux-androideabi-clang3.4/config.mk
new file mode 100644
index 0000000..ef11894
--- /dev/null
+++ b/toolchains/arm-linux-androideabi-clang3.4/config.mk
@@ -0,0 +1,20 @@
+# 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.
+#
+
+# config file for the arm llvm-3.4 toolchain for the Android NDK
+# the real meat is in the setup.mk file adjacent to this one
+#
+TOOLCHAIN_ARCH := arm
+TOOLCHAIN_ABIS := armeabi armeabi-v7a armeabi-v7a-hard
diff --git a/toolchains/arm-linux-androideabi-clang3.4/setup.mk b/toolchains/arm-linux-androideabi-clang3.4/setup.mk
new file mode 100644
index 0000000..f9c351e
--- /dev/null
+++ b/toolchains/arm-linux-androideabi-clang3.4/setup.mk
@@ -0,0 +1,155 @@
+# Copyright (C) 2009 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.
+#
+
+# this file is used to prepare the NDK to build with the arm clang-3.4
+# toolchain any number of source files
+#
+# its purpose is to define (or re-define) templates used to build
+# various sources into target object files, libraries or executables.
+#
+# Note that this file may end up being parsed several times in future
+# revisions of the NDK.
+#
+
+#
+# Override the toolchain prefix
+#
+
+LLVM_VERSION := 3.4
+LLVM_NAME := llvm-$(LLVM_VERSION)
+LLVM_TOOLCHAIN_ROOT := $(NDK_ROOT)/toolchains/$(LLVM_NAME)
+LLVM_TOOLCHAIN_PREBUILT_ROOT := $(call host-prebuilt-tag,$(LLVM_TOOLCHAIN_ROOT))
+LLVM_TOOLCHAIN_PREFIX := $(LLVM_TOOLCHAIN_PREBUILT_ROOT)/bin/
+
+TOOLCHAIN_VERSION := 4.8
+TOOLCHAIN_NAME := arm-linux-androideabi-$(TOOLCHAIN_VERSION)
+TOOLCHAIN_ROOT := $(NDK_ROOT)/toolchains/$(TOOLCHAIN_NAME)
+TOOLCHAIN_PREBUILT_ROOT := $(call host-prebuilt-tag,$(TOOLCHAIN_ROOT))
+TOOLCHAIN_PREFIX := $(TOOLCHAIN_PREBUILT_ROOT)/bin/arm-linux-androideabi-
+
+TARGET_CC := $(LLVM_TOOLCHAIN_PREFIX)clang$(HOST_EXEEXT)
+TARGET_CXX := $(LLVM_TOOLCHAIN_PREFIX)clang++$(HOST_EXEEXT)
+
+#
+# CFLAGS and LDFLAGS
+#
+
+TARGET_CFLAGS := \
+ -gcc-toolchain $(call host-path,$(TOOLCHAIN_PREBUILT_ROOT)) \
+ -fpic \
+ -ffunction-sections \
+ -funwind-tables \
+ -fstack-protector \
+ -no-canonical-prefixes
+
+TARGET_LDFLAGS += \
+ -gcc-toolchain $(call host-path,$(TOOLCHAIN_PREBUILT_ROOT)) \
+ -no-canonical-prefixes
+
+TARGET_C_INCLUDES := \
+ $(SYSROOT_INC)/usr/include
+
+ifneq ($(filter %armeabi-v7a,$(TARGET_ARCH_ABI)),)
+ LLVM_TRIPLE := armv7-none-linux-androideabi
+
+ TARGET_CFLAGS += -target $(LLVM_TRIPLE) \
+ -march=armv7-a \
+ -mfloat-abi=softfp \
+ -mfpu=vfpv3-d16
+
+ TARGET_LDFLAGS += -target $(LLVM_TRIPLE) \
+ -Wl,--fix-cortex-a8
+else
+ifneq ($(filter %armeabi-v7a-hard,$(TARGET_ARCH_ABI)),)
+ LLVM_TRIPLE := armv7-none-linux-androideabi
+
+ TARGET_CFLAGS += -target $(LLVM_TRIPLE) \
+ -march=armv7-a \
+ -mfpu=vfpv3-d16 \
+ -mhard-float \
+ -D_NDK_MATH_NO_SOFTFP=1
+
+ TARGET_LDFLAGS += -target $(LLVM_TRIPLE) \
+ -Wl,--fix-cortex-a8 \
+ -Wl,--no-warn-mismatch \
+ -lm_hard
+else
+ LLVM_TRIPLE := armv5te-none-linux-androideabi
+
+ TARGET_CFLAGS += -target $(LLVM_TRIPLE) \
+ -march=armv5te \
+ -mtune=xscale \
+ -msoft-float
+
+ TARGET_LDFLAGS += -target $(LLVM_TRIPLE)
+endif
+endif
+
+TARGET_CFLAGS.neon := -mfpu=neon
+
+TARGET_arm_release_CFLAGS := -O2 \
+ -g \
+ -DNDEBUG \
+ -fomit-frame-pointer \
+ -fstrict-aliasing
+
+TARGET_thumb_release_CFLAGS := -mthumb \
+ -Os \
+ -g \
+ -DNDEBUG \
+ -fomit-frame-pointer \
+ -fno-strict-aliasing
+
+# When building for debug, compile everything as arm.
+TARGET_arm_debug_CFLAGS := $(TARGET_arm_release_CFLAGS) \
+ -O0 \
+ -UNDEBUG \
+ -fno-omit-frame-pointer \
+ -fno-strict-aliasing
+
+TARGET_thumb_debug_CFLAGS := $(TARGET_thumb_release_CFLAGS) \
+ -O0 \
+ -UNDEBUG \
+ -marm \
+ -fno-omit-frame-pointer
+
+# This function will be called to determine the target CFLAGS used to build
+# a C or Assembler source file, based on its tags.
+#
+TARGET-process-src-files-tags = \
+$(eval __arm_sources := $(call get-src-files-with-tag,arm)) \
+$(eval __thumb_sources := $(call get-src-files-without-tag,arm)) \
+$(eval __debug_sources := $(call get-src-files-with-tag,debug)) \
+$(eval __release_sources := $(call get-src-files-without-tag,debug)) \
+$(call set-src-files-target-cflags, \
+ $(call set_intersection,$(__arm_sources),$(__debug_sources)), \
+ $(TARGET_arm_debug_CFLAGS)) \
+$(call set-src-files-target-cflags,\
+ $(call set_intersection,$(__arm_sources),$(__release_sources)),\
+ $(TARGET_arm_release_CFLAGS)) \
+$(call set-src-files-target-cflags,\
+ $(call set_intersection,$(__arm_sources),$(__debug_sources)),\
+ $(TARGET_arm_debug_CFLAGS)) \
+$(call set-src-files-target-cflags,\
+ $(call set_intersection,$(__thumb_sources),$(__release_sources)),\
+ $(TARGET_thumb_release_CFLAGS)) \
+$(call set-src-files-target-cflags,\
+ $(call set_intersection,$(__thumb_sources),$(__debug_sources)),\
+ $(TARGET_thumb_debug_CFLAGS)) \
+$(call add-src-files-target-cflags,\
+ $(call get-src-files-with-tag,neon),\
+ $(TARGET_CFLAGS.neon)) \
+$(call set-src-files-text,$(__arm_sources),arm) \
+$(call set-src-files-text,$(__thumb_sources),thumb)
diff --git a/toolchains/llvm-3.3/setup-common.mk b/toolchains/llvm-3.3/setup-common.mk
index 1e92b73..c3ec3d5 100644
--- a/toolchains/llvm-3.3/setup-common.mk
+++ b/toolchains/llvm-3.3/setup-common.mk
@@ -23,11 +23,18 @@
TARGET_CXX := $(TOOLCHAIN_PREFIX)clang++$(HOST_EXEEXT)
TARGET_LD := $(TOOLCHAIN_PREFIX)clang++$(HOST_EXEEXT)
TARGET_AR := $(TOOLCHAIN_PREFIX)llvm-ar$(HOST_EXEEXT)
-TARGET_STRIP := $(TOOLCHAIN_PREFIX)$(LLVM_TRIPLE)-strip$(HOST_EXEEXT)
+ifeq ($(APP_OPTIM),debug)
+ TARGET_STRIP := \# dont-strip-for-debugging-bitcode
+else
+ TARGET_STRIP := $(TOOLCHAIN_PREFIX)$(LLVM_TRIPLE)-strip$(HOST_EXEEXT)
+endif
# Compiler runtime is determined in bc2native
TARGET_LIBGCC :=
+# Override the ar flags, llvm-ar does not support D option
+TARGET_ARFLAGS := crs
+
# Only use integrated binary if existed. Otherwise, use python version
ifeq (,$(wildcard $(TOOLCHAIN_PREBUILT_ROOT)/bin/ndk-bc2native$(HOST_EXEEXT)))
BC2NATIVE := $(HOST_PYTHON) $(TOOLCHAIN_PREBUILT_ROOT)/bin/ndk-bc2native.py
@@ -55,6 +62,12 @@
-emit-llvm \
-no-canonical-prefixes
+ifeq ($(APP_OPTIM),debug)
+ TARGET_LDFLAGS += -Wl,-O0 -Wl,--disable-opt
+else
+ TARGET_LDFLAGS += -Wl,-O2
+endif
+
TARGET_C_INCLUDES := \
$(SYSROOT_INC)/usr/include
diff --git a/toolchains/llvm-3.3/setup.mk b/toolchains/llvm-3.3/setup.mk
index cddcb01..f5d7d88 100644
--- a/toolchains/llvm-3.3/setup.mk
+++ b/toolchains/llvm-3.3/setup.mk
@@ -38,6 +38,19 @@
include $(NDK_ROOT)/toolchains/llvm-3.3/setup-common.mk
else
+ifneq ($(filter %bcarmeabi-v7a-hard,$(TARGET_ARCH_ABI)),)
+SYSROOT_LINK := $(NDK_PLATFORMS_ROOT)/$(TARGET_PLATFORM)/arch-arm
+TARGET_GDBSERVER := $(NDK_ROOT)/prebuilt/android-arm/gdbserver/gdbserver
+TARGET_ARCH_ABI := armeabi-v7a-hard
+TARGET_LDFLAGS += -Wl,-link-native-binary
+NDK_APP_DST_DIR := $(NDK_APP_PROJECT_PATH)/libs/$(TARGET_ARCH_ABI)
+
+TARGET_PREBUILT_ROOT = $(call host-prebuilt-tag,$(NDK_ROOT)/toolchains/arm-linux-androideabi-$(TOOLCHAIN_VERSION))
+cmd-strip = $(TARGET_PREBUILT_ROOT)/bin/arm-linux-androideabi-strip$(HOST_EXEEXT) --strip-unneeded $(call host-path,$1)
+
+include $(NDK_ROOT)/toolchains/llvm-3.3/setup-common.mk
+
+else
ifneq ($(filter %bcarmeabi,$(TARGET_ARCH_ABI)),)
SYSROOT_LINK := $(NDK_PLATFORMS_ROOT)/$(TARGET_PLATFORM)/arch-arm
TARGET_GDBSERVER := $(NDK_ROOT)/prebuilt/android-arm/gdbserver/gdbserver
@@ -89,6 +102,17 @@
include $(NDK_ROOT)/toolchains/arm-linux-androideabi-clang3.3/setup.mk
else
+ifneq ($(filter %armeabi-v7a-hard,$(TARGET_ARCH_ABI)),)
+
+SYSROOT_LINK := $(NDK_PLATFORMS_ROOT)/$(TARGET_PLATFORM)/arch-arm
+TARGET_GDBSERVER := $(NDK_ROOT)/prebuilt/android-arm/gdbserver/gdbserver
+TARGET_ARCH_ABI := armeabi-v7a-hard
+NDK_APP_DST_DIR := $(NDK_APP_PROJECT_PATH)/libs/$(TARGET_ARCH_ABI)
+TARGET_LDLIBS := $(NDK_ROOT)/sources/android/libportable/libs/armeabi-v7a-hard/libportable.a $(TARGET_LDLIBS)
+TARGET_LDFLAGS += -Wl,@$(NDK_ROOT)/sources/android/libportable/libs/armeabi-v7a-hard/libportable.wrap
+include $(NDK_ROOT)/toolchains/arm-linux-androideabi-clang3.3/setup.mk
+
+else
ifneq ($(filter %armeabi,$(TARGET_ARCH_ABI)),)
SYSROOT_LINK := $(NDK_PLATFORMS_ROOT)/$(TARGET_PLATFORM)/arch-arm
@@ -137,3 +161,5 @@
endif
endif
endif
+endif
+endif
diff --git a/toolchains/llvm-3.4/config.mk b/toolchains/llvm-3.4/config.mk
new file mode 100644
index 0000000..34d7a69
--- /dev/null
+++ b/toolchains/llvm-3.4/config.mk
@@ -0,0 +1,20 @@
+# Copyright (C) 2009 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.
+#
+
+# config file for the clang-3.4 toolchain for the Android NDK
+# the real meat is in the setup.mk file adjacent to this one
+#
+TOOLCHAIN_ARCH :=
+TOOLCHAIN_ABIS :=
diff --git a/toolchains/llvm-3.4/setup-common.mk b/toolchains/llvm-3.4/setup-common.mk
new file mode 100644
index 0000000..780e23d
--- /dev/null
+++ b/toolchains/llvm-3.4/setup-common.mk
@@ -0,0 +1,131 @@
+# Copyright (C) 2013 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.
+
+TOOLCHAIN_NAME := clang-3.4
+TOOLCHAIN_PREFIX := $(TOOLCHAIN_PREBUILT_ROOT)/bin/
+LLVM_TRIPLE := le32-none-ndk
+
+# For sources/cxx-stl/gnu-libstdc++/$(TOOLCHAIN_VERSION)/libs/*/libsupc++.a
+TOOLCHAIN_VERSION := 4.8
+
+TARGET_CC := $(TOOLCHAIN_PREFIX)clang$(HOST_EXEEXT)
+TARGET_CXX := $(TOOLCHAIN_PREFIX)clang++$(HOST_EXEEXT)
+TARGET_LD := $(TOOLCHAIN_PREFIX)clang++$(HOST_EXEEXT)
+TARGET_AR := $(TOOLCHAIN_PREFIX)llvm-ar$(HOST_EXEEXT)
+ifeq ($(APP_OPTIM),debug)
+ TARGET_STRIP := \# dont-strip-for-debugging-bitcode
+else
+ TARGET_STRIP := $(TOOLCHAIN_PREFIX)$(LLVM_TRIPLE)-strip$(HOST_EXEEXT)
+endif
+
+# Compiler runtime is determined in bc2native
+TARGET_LIBGCC :=
+
+# Override the ar flags, llvm-ar does not support D option
+TARGET_ARFLAGS := crs
+
+# Only use integrated binary if existed. Otherwise, use python version
+ifeq (,$(wildcard $(TOOLCHAIN_PREBUILT_ROOT)/bin/ndk-bc2native$(HOST_EXEEXT)))
+BC2NATIVE := $(HOST_PYTHON) $(TOOLCHAIN_PREBUILT_ROOT)/bin/ndk-bc2native.py
+else
+BC2NATIVE := $(TOOLCHAIN_PREBUILT_ROOT)/bin/ndk-bc2native$(HOST_EXEEXT)
+endif
+
+TARGET_CFLAGS := \
+ -target $(LLVM_TRIPLE) \
+ -emit-llvm \
+ -ffunction-sections \
+ -funwind-tables \
+ -fPIC \
+ -no-canonical-prefixes
+# -nostdlibinc
+
+#TARGET_CXXFLAGS := $(TARGET_CFLAGS) -fno-exceptions -fno-rtti
+
+# reset backend flags
+TARGET_NO_EXECUTE_CFLAGS :=
+
+# Add and LDFLAGS for the target here
+TARGET_LDFLAGS += \
+ -target $(LLVM_TRIPLE) \
+ -no-canonical-prefixes
+
+ifeq ($(APP_OPTIM),debug)
+ TARGET_LDFLAGS += -Wl,-O0 -Wl,--disable-opt
+else
+ TARGET_LDFLAGS += -Wl,-O2
+endif
+
+TARGET_C_INCLUDES := \
+ $(SYSROOT_INC)/usr/include
+
+TARGET_release_CFLAGS := -O2 \
+ -g \
+ -DNDEBUG \
+ -fomit-frame-pointer \
+ -fstrict-aliasing
+
+TARGET_debug_CFLAGS := $(TARGET_release_CFLAGS) \
+ -O0 \
+ -UNDEBUG \
+ -fno-omit-frame-pointer \
+ -fno-strict-aliasing
+
+# This function will be called to determine the target CFLAGS used to build
+# a C or Assembler source file, based on its tags.
+#
+TARGET-process-src-files-tags = \
+$(eval __debug_sources := $(call get-src-files-with-tag,debug)) \
+$(eval __release_sources := $(call get-src-files-without-tag,debug)) \
+$(call set-src-files-target-cflags, $(__debug_sources), $(TARGET_debug_CFLAGS)) \
+$(call set-src-files-target-cflags, $(__release_sources),$(TARGET_release_CFLAGS)) \
+$(call set-src-files-text,$(LOCAL_SRC_FILES),bc) \
+
+ifeq ($(strip $(filter-out $(NDK_KNOWN_ABIS),$(TARGET_ARCH_ABI))),)
+
+define cmd-build-shared-library
+$(PRIVATE_CXX) \
+ -Wl,-soname,$(notdir $(LOCAL_BUILT_MODULE)) \
+ -shared \
+ --sysroot=$(call host-path,$(PRIVATE_SYSROOT_LINK)) \
+ $(PRIVATE_LINKER_OBJECTS_AND_LIBRARIES) \
+ $(PRIVATE_LDFLAGS) \
+ $(PRIVATE_LDLIBS) \
+ -o $(call host-path,$(LOCAL_BUILT_MODULE)) && \
+ $(call host-mv, $(call host-path,$(LOCAL_BUILT_MODULE)), $(call host-path,$(LOCAL_BUILT_MODULE)).bc) && \
+ $(BC2NATIVE) \
+ --ndk-dir=$(NDK_ROOT) \
+ --abi=$(TARGET_ARCH_ABI) \
+ --platform=$(TARGET_PLATFORM) \
+ --file $(call host-path, $(LOCAL_BUILT_MODULE)).bc $(patsubst %.bc,%.so,$(call host-path,$(LOCAL_BUILT_MODULE)))
+endef
+
+define cmd-build-executable
+$(PRIVATE_CXX) \
+ -Wl,--gc-sections \
+ -Wl,-z,nocopyreloc \
+ --sysroot=$(call host-path,$(PRIVATE_SYSROOT_LINK)) \
+ $(PRIVATE_LINKER_OBJECTS_AND_LIBRARIES) \
+ $(PRIVATE_LDFLAGS) \
+ $(PRIVATE_LDLIBS) \
+ -o $(call host-path,$(LOCAL_BUILT_MODULE)) && \
+ $(call host-mv, $(call host-path,$(LOCAL_BUILT_MODULE)), $(call host-path,$(LOCAL_BUILT_MODULE)).bc) && \
+ $(BC2NATIVE) \
+ --ndk-dir=$(NDK_ROOT) \
+ --abi=$(TARGET_ARCH_ABI) \
+ --platform=$(TARGET_PLATFORM) \
+ --file $(call host-path,$(LOCAL_BUILT_MODULE)).bc $(call host-path,$(LOCAL_BUILT_MODULE))
+endef
+
+endif
diff --git a/toolchains/llvm-3.4/setup.mk b/toolchains/llvm-3.4/setup.mk
new file mode 100644
index 0000000..664b31f
--- /dev/null
+++ b/toolchains/llvm-3.4/setup.mk
@@ -0,0 +1,165 @@
+# Copyright (C) 2009 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.
+#
+
+# this file is used to prepare the NDK to build with the clang-3.4
+# toolchain any number of source files
+#
+# its purpose is to define (or re-define) templates used to build
+# various sources into target object files, libraries or executables.
+#
+# Note that this file may end up being parsed several times in future
+# revisions of the NDK.
+#
+
+TOOLCHAIN_VERSION := 4.8
+
+ifneq ($(filter %bcarmeabi-v7a,$(TARGET_ARCH_ABI)),)
+SYSROOT_LINK := $(NDK_PLATFORMS_ROOT)/$(TARGET_PLATFORM)/arch-arm
+TARGET_GDBSERVER := $(NDK_ROOT)/prebuilt/android-arm/gdbserver/gdbserver
+TARGET_ARCH_ABI := armeabi-v7a
+TARGET_LDFLAGS += -Wl,-link-native-binary
+NDK_APP_DST_DIR := $(NDK_APP_PROJECT_PATH)/libs/$(TARGET_ARCH_ABI)
+
+TARGET_PREBUILT_ROOT = $(call host-prebuilt-tag,$(NDK_ROOT)/toolchains/arm-linux-androideabi-$(TOOLCHAIN_VERSION))
+cmd-strip = $(TARGET_PREBUILT_ROOT)/bin/arm-linux-androideabi-strip$(HOST_EXEEXT) --strip-unneeded $(call host-path,$1)
+
+include $(NDK_ROOT)/toolchains/llvm-3.4/setup-common.mk
+
+else
+ifneq ($(filter %bcarmeabi-v7a-hard,$(TARGET_ARCH_ABI)),)
+SYSROOT_LINK := $(NDK_PLATFORMS_ROOT)/$(TARGET_PLATFORM)/arch-arm
+TARGET_GDBSERVER := $(NDK_ROOT)/prebuilt/android-arm/gdbserver/gdbserver
+TARGET_ARCH_ABI := armeabi-v7a-hard
+TARGET_LDFLAGS += -Wl,-link-native-binary
+NDK_APP_DST_DIR := $(NDK_APP_PROJECT_PATH)/libs/$(TARGET_ARCH_ABI)
+
+TARGET_PREBUILT_ROOT = $(call host-prebuilt-tag,$(NDK_ROOT)/toolchains/arm-linux-androideabi-$(TOOLCHAIN_VERSION))
+cmd-strip = $(TARGET_PREBUILT_ROOT)/bin/arm-linux-androideabi-strip$(HOST_EXEEXT) --strip-unneeded $(call host-path,$1)
+
+include $(NDK_ROOT)/toolchains/llvm-3.4/setup-common.mk
+
+else
+ifneq ($(filter %bcarmeabi,$(TARGET_ARCH_ABI)),)
+SYSROOT_LINK := $(NDK_PLATFORMS_ROOT)/$(TARGET_PLATFORM)/arch-arm
+TARGET_GDBSERVER := $(NDK_ROOT)/prebuilt/android-arm/gdbserver/gdbserver
+TARGET_ARCH_ABI := armeabi
+TARGET_LDFLAGS += -Wl,-link-native-binary
+NDK_APP_DST_DIR := $(NDK_APP_PROJECT_PATH)/libs/$(TARGET_ARCH_ABI)
+
+TARGET_PREBUILT_ROOT = $(call host-prebuilt-tag,$(NDK_ROOT)/toolchains/arm-linux-androideabi-$(TOOLCHAIN_VERSION))
+cmd-strip = $(TARGET_PREBUILT_ROOT)/bin/arm-linux-androideabi-strip$(HOST_EXEEXT) --strip-unneeded $(call host-path,$1)
+
+include $(NDK_ROOT)/toolchains/llvm-3.4/setup-common.mk
+
+else
+ifneq ($(filter %bcx86,$(TARGET_ARCH_ABI)),)
+SYSROOT_LINK := $(NDK_PLATFORMS_ROOT)/$(TARGET_PLATFORM)/arch-x86
+TARGET_GDBSERVER := $(NDK_ROOT)/prebuilt/android-x86/gdbserver/gdbserver
+TARGET_ARCH_ABI := x86
+TARGET_LDFLAGS += -Wl,-link-native-binary
+NDK_APP_DST_DIR := $(NDK_APP_PROJECT_PATH)/libs/$(TARGET_ARCH_ABI)
+
+TARGET_PREBUILT_ROOT = $(call host-prebuilt-tag,$(NDK_ROOT)/toolchains/x86-$(TOOLCHAIN_VERSION))
+cmd-strip = $(TARGET_PREBUILT_ROOT)/bin/i686-linux-android-strip$(HOST_EXEEXT) --strip-unneeded $(call host-path,$1)
+
+include $(NDK_ROOT)/toolchains/llvm-3.4/setup-common.mk
+
+else
+ifneq ($(filter %bcmips,$(TARGET_ARCH_ABI)),)
+SYSROOT_LINK := $(NDK_PLATFORMS_ROOT)/$(TARGET_PLATFORM)/arch-mips
+TARGET_GDBSERVER := $(NDK_ROOT)/prebuilt/android-mips/gdbserver/gdbserver
+TARGET_ARCH_ABI := mips
+TARGET_LDFLAGS += -Wl,-link-native-binary
+NDK_APP_DST_DIR := $(NDK_APP_PROJECT_PATH)/libs/$(TARGET_ARCH_ABI)
+
+TARGET_PREBUILT_ROOT = $(call host-prebuilt-tag,$(NDK_ROOT)/toolchains/mipsel-linux-android-$(TOOLCHAIN_VERSION))
+cmd-strip = $(TARGET_PREBUILT_ROOT)/bin/mipsel-linux-android-strip$(HOST_EXEEXT) --strip-unneeded $(call host-path,$1)
+
+include $(NDK_ROOT)/toolchains/llvm-3.4/setup-common.mk
+
+else
+
+ifneq ($(filter %armeabi-v7a,$(TARGET_ARCH_ABI)),)
+
+SYSROOT_LINK := $(NDK_PLATFORMS_ROOT)/$(TARGET_PLATFORM)/arch-arm
+TARGET_GDBSERVER := $(NDK_ROOT)/prebuilt/android-arm/gdbserver/gdbserver
+TARGET_ARCH_ABI := armeabi-v7a
+NDK_APP_DST_DIR := $(NDK_APP_PROJECT_PATH)/libs/$(TARGET_ARCH_ABI)
+TARGET_LDLIBS := $(NDK_ROOT)/sources/android/libportable/libs/armeabi-v7a/libportable.a $(TARGET_LDLIBS)
+TARGET_LDFLAGS += -Wl,@$(NDK_ROOT)/sources/android/libportable/libs/armeabi-v7a/libportable.wrap
+include $(NDK_ROOT)/toolchains/arm-linux-androideabi-clang3.4/setup.mk
+
+else
+ifneq ($(filter %armeabi-v7a-hard,$(TARGET_ARCH_ABI)),)
+
+SYSROOT_LINK := $(NDK_PLATFORMS_ROOT)/$(TARGET_PLATFORM)/arch-arm
+TARGET_GDBSERVER := $(NDK_ROOT)/prebuilt/android-arm/gdbserver/gdbserver
+TARGET_ARCH_ABI := armeabi-v7a-hard
+NDK_APP_DST_DIR := $(NDK_APP_PROJECT_PATH)/libs/$(TARGET_ARCH_ABI)
+TARGET_LDLIBS := $(NDK_ROOT)/sources/android/libportable/libs/armeabi-v7a-hard/libportable.a $(TARGET_LDLIBS)
+TARGET_LDFLAGS += -Wl,@$(NDK_ROOT)/sources/android/libportable/libs/armeabi-v7a-hard/libportable.wrap
+include $(NDK_ROOT)/toolchains/arm-linux-androideabi-clang3.4/setup.mk
+
+else
+ifneq ($(filter %armeabi,$(TARGET_ARCH_ABI)),)
+
+SYSROOT_LINK := $(NDK_PLATFORMS_ROOT)/$(TARGET_PLATFORM)/arch-arm
+TARGET_GDBSERVER := $(NDK_ROOT)/prebuilt/android-arm/gdbserver/gdbserver
+TARGET_ARCH_ABI := armeabi
+NDK_APP_DST_DIR := $(NDK_APP_PROJECT_PATH)/libs/$(TARGET_ARCH_ABI)
+TARGET_LDLIBS := $(NDK_ROOT)/sources/android/libportable/libs/armeabi/libportable.a $(TARGET_LDLIBS)
+TARGET_LDFLAGS += -Wl,@$(NDK_ROOT)/sources/android/libportable/libs/armeabi/libportable.wrap
+include $(NDK_ROOT)/toolchains/arm-linux-androideabi-clang3.4/setup.mk
+
+else
+ifneq ($(filter %x86,$(TARGET_ARCH_ABI)),)
+
+SYSROOT_LINK := $(NDK_PLATFORMS_ROOT)/$(TARGET_PLATFORM)/arch-x86
+TARGET_GDBSERVER := $(NDK_ROOT)/prebuilt/android-x86/gdbserver/gdbserver
+TARGET_ARCH_ABI := x86
+NDK_APP_DST_DIR := $(NDK_APP_PROJECT_PATH)/libs/$(TARGET_ARCH_ABI)
+TARGET_LDLIBS := $(NDK_ROOT)/sources/android/libportable/libs/x86/libportable.a $(TARGET_LDLIBS)
+TARGET_LDFLAGS += -Wl,@$(NDK_ROOT)/sources/android/libportable/libs/x86/libportable.wrap
+include $(NDK_ROOT)/toolchains/x86-clang3.4/setup.mk
+
+else
+ifneq ($(filter %mips,$(TARGET_ARCH_ABI)),)
+
+SYSROOT_LINK := $(NDK_PLATFORMS_ROOT)/$(TARGET_PLATFORM)/arch-mips
+TARGET_GDBSERVER := $(NDK_ROOT)/prebuilt/android-mips/gdbserver/gdbserver
+TARGET_ARCH_ABI := mips
+NDK_APP_DST_DIR := $(NDK_APP_PROJECT_PATH)/libs/$(TARGET_ARCH_ABI)
+TARGET_LDLIBS := $(NDK_ROOT)/sources/android/libportable/libs/mips/libportable.a $(TARGET_LDLIBS)
+TARGET_LDFLAGS += -Wl,@$(NDK_ROOT)/sources/android/libportable/libs/mips/libportable.wrap
+include $(NDK_ROOT)/toolchains/mipsel-linux-android-clang3.4/setup.mk
+
+else
+
+TARGET_OBJ_EXTENSION := .bc
+TARGET_LIB_EXTENSION := .a
+TARGET_SONAME_EXTENSION := .bc
+
+include $(NDK_ROOT)/toolchains/llvm-3.4/setup-common.mk
+
+endif
+endif
+endif
+endif
+endif
+endif
+endif
+endif
+endif
+endif
diff --git a/toolchains/mipsel-linux-android-clang3.4/config.mk b/toolchains/mipsel-linux-android-clang3.4/config.mk
new file mode 100644
index 0000000..f7b5bbb
--- /dev/null
+++ b/toolchains/mipsel-linux-android-clang3.4/config.mk
@@ -0,0 +1,20 @@
+# 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.
+#
+
+# config file for the mipsel llvm-3.4 toolchain for the Android NDK
+# the real meat is in the setup.mk file adjacent to this one
+#
+TOOLCHAIN_ARCH := mips
+TOOLCHAIN_ABIS := mips
diff --git a/toolchains/mipsel-linux-android-clang3.4/setup.mk b/toolchains/mipsel-linux-android-clang3.4/setup.mk
new file mode 100644
index 0000000..18d6d2f
--- /dev/null
+++ b/toolchains/mipsel-linux-android-clang3.4/setup.mk
@@ -0,0 +1,90 @@
+# 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.
+#
+
+# this file is used to prepare the NDK to build with the mipsel llvm-3.4
+# toolchain any number of source files
+#
+# its purpose is to define (or re-define) templates used to build
+# various sources into target object files, libraries or executables.
+#
+# Note that this file may end up being parsed several times in future
+# revisions of the NDK.
+#
+
+#
+# Override the toolchain prefix
+#
+
+LLVM_VERSION := 3.4
+LLVM_NAME := llvm-$(LLVM_VERSION)
+LLVM_TOOLCHAIN_ROOT := $(NDK_ROOT)/toolchains/$(LLVM_NAME)
+LLVM_TOOLCHAIN_PREBUILT_ROOT := $(call host-prebuilt-tag,$(LLVM_TOOLCHAIN_ROOT))
+LLVM_TOOLCHAIN_PREFIX := $(LLVM_TOOLCHAIN_PREBUILT_ROOT)/bin/
+
+TOOLCHAIN_VERSION := 4.8
+TOOLCHAIN_NAME := mipsel-linux-android-$(TOOLCHAIN_VERSION)
+TOOLCHAIN_ROOT := $(NDK_ROOT)/toolchains/$(TOOLCHAIN_NAME)
+TOOLCHAIN_PREBUILT_ROOT := $(call host-prebuilt-tag,$(TOOLCHAIN_ROOT))
+TOOLCHAIN_PREFIX := $(TOOLCHAIN_PREBUILT_ROOT)/bin/mipsel-linux-android-
+
+TARGET_CC := $(LLVM_TOOLCHAIN_PREFIX)clang$(HOST_EXEEXT)
+TARGET_CXX := $(LLVM_TOOLCHAIN_PREFIX)clang++$(HOST_EXEEXT)
+
+#
+# CFLAGS, C_INCLUDES, and LDFLAGS
+#
+
+LLVM_TRIPLE := mipsel-none-linux-android
+
+TARGET_CFLAGS := \
+ -gcc-toolchain $(call host-path,$(TOOLCHAIN_PREBUILT_ROOT)) \
+ -target $(LLVM_TRIPLE) \
+ -fpic \
+ -fno-strict-aliasing \
+ -finline-functions \
+ -ffunction-sections \
+ -funwind-tables \
+ -fmessage-length=0 \
+ -no-canonical-prefixes
+
+TARGET_LDFLAGS += \
+ -gcc-toolchain $(call host-path,$(TOOLCHAIN_PREBUILT_ROOT)) \
+ -target $(LLVM_TRIPLE) \
+ -no-canonical-prefixes
+
+TARGET_C_INCLUDES := \
+ $(SYSROOT_INC)/usr/include
+
+TARGET_mips_release_CFLAGS := -O2 \
+ -g \
+ -DNDEBUG \
+ -fomit-frame-pointer
+
+TARGET_mips_debug_CFLAGS := -O0 \
+ -g \
+ -fno-omit-frame-pointer
+
+
+# This function will be called to determine the target CFLAGS used to build
+# a C or Assembler source file, based on its tags.
+TARGET-process-src-files-tags = \
+$(eval __debug_sources := $(call get-src-files-with-tag,debug)) \
+$(eval __release_sources := $(call get-src-files-without-tag,debug)) \
+$(call set-src-files-target-cflags, \
+ $(__debug_sources),\
+ $(TARGET_mips_debug_CFLAGS)) \
+$(call set-src-files-target-cflags,\
+ $(__release_sources),\
+ $(TARGET_mips_release_CFLAGS)) \
diff --git a/toolchains/x86-clang3.4/config.mk b/toolchains/x86-clang3.4/config.mk
new file mode 100644
index 0000000..83e1cb3
--- /dev/null
+++ b/toolchains/x86-clang3.4/config.mk
@@ -0,0 +1,20 @@
+# 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.
+#
+
+# config file for the x86 clang-3.4 toolchain for the Android NDK
+# the real meat is in the setup.mk file adjacent to this one
+#
+TOOLCHAIN_ARCH := x86
+TOOLCHAIN_ABIS := x86
diff --git a/toolchains/x86-clang3.4/setup.mk b/toolchains/x86-clang3.4/setup.mk
new file mode 100644
index 0000000..97a5e24
--- /dev/null
+++ b/toolchains/x86-clang3.4/setup.mk
@@ -0,0 +1,89 @@
+# Copyright (C) 2009 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.
+#
+
+# this file is used to prepare the NDK to build with the x86 llvm-3.4
+# toolchain any number of source files
+#
+# its purpose is to define (or re-define) templates used to build
+# various sources into target object files, libraries or executables.
+#
+# Note that this file may end up being parsed several times in future
+# revisions of the NDK.
+#
+
+#
+# Override the toolchain prefix
+#
+
+LLVM_VERSION := 3.4
+LLVM_NAME := llvm-$(LLVM_VERSION)
+LLVM_TOOLCHAIN_ROOT := $(NDK_ROOT)/toolchains/$(LLVM_NAME)
+LLVM_TOOLCHAIN_PREBUILT_ROOT := $(call host-prebuilt-tag,$(LLVM_TOOLCHAIN_ROOT))
+LLVM_TOOLCHAIN_PREFIX := $(LLVM_TOOLCHAIN_PREBUILT_ROOT)/bin/
+
+TOOLCHAIN_VERSION := 4.8
+TOOLCHAIN_NAME := x86-$(TOOLCHAIN_VERSION)
+TOOLCHAIN_ROOT := $(NDK_ROOT)/toolchains/$(TOOLCHAIN_NAME)
+TOOLCHAIN_PREBUILT_ROOT := $(call host-prebuilt-tag,$(TOOLCHAIN_ROOT))
+TOOLCHAIN_PREFIX := $(TOOLCHAIN_PREBUILT_ROOT)/bin/i686-linux-android-
+
+TARGET_CC := $(LLVM_TOOLCHAIN_PREFIX)clang$(HOST_EXEEXT)
+TARGET_CXX := $(LLVM_TOOLCHAIN_PREFIX)clang++$(HOST_EXEEXT)
+
+LLVM_TRIPLE := i686-none-linux-android
+
+TARGET_CFLAGS := \
+ -gcc-toolchain $(call host-path,$(TOOLCHAIN_PREBUILT_ROOT)) \
+ -target $(LLVM_TRIPLE) \
+ -ffunction-sections \
+ -funwind-tables \
+ -fstack-protector \
+ -fPIC \
+ -no-canonical-prefixes
+
+TARGET_C_INCLUDES := \
+ $(SYSROOT_INC)/usr/include
+
+# Add and LDFLAGS for the target here
+TARGET_LDFLAGS += \
+ -gcc-toolchain $(call host-path,$(TOOLCHAIN_PREBUILT_ROOT)) \
+ -target $(LLVM_TRIPLE) \
+ -no-canonical-prefixes
+
+TARGET_x86_release_CFLAGS := -O2 \
+ -g \
+ -DNDEBUG \
+ -fomit-frame-pointer \
+ -fstrict-aliasing
+
+# When building for debug, compile everything as x86.
+TARGET_x86_debug_CFLAGS := $(TARGET_x86_release_CFLAGS) \
+ -O0 \
+ -UNDEBUG \
+ -fno-omit-frame-pointer \
+ -fno-strict-aliasing
+
+# This function will be called to determine the target CFLAGS used to build
+# a C or Assembler source file, based on its tags.
+#
+TARGET-process-src-files-tags = \
+$(eval __debug_sources := $(call get-src-files-with-tag,debug)) \
+$(eval __release_sources := $(call get-src-files-without-tag,debug)) \
+$(call set-src-files-target-cflags, $(__debug_sources), $(TARGET_x86_debug_CFLAGS)) \
+$(call set-src-files-target-cflags, $(__release_sources),$(TARGET_x86_release_CFLAGS)) \
+
+# The ABI-specific sub-directory that the SDK tools recognize for
+# this toolchain's generated binaries
+TARGET_ABI_SUBDIR := x86