Cherry-pick libc++ bug fixes.
This fixes the stack trace issue when compiling Android chromium with libc++.
BUG=490275
Change-Id: Ifc12b502535a2c53129f89f6bb5dde2c376ce7c7
Reviewed-on: https://chromium-review.googlesource.com/287200
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Tested-by: Ross McIlroy <rmcilroy@chromium.org>
diff --git a/README.chromium b/README.chromium
index 0028a85..680770f 100644
--- a/README.chromium
+++ b/README.chromium
@@ -24,6 +24,8 @@
- Cherry-picked
https://android-review.googlesource.com/#/c/150680/
to fix component build at -Oz.
+- Cherry-picked various upstream libc++ fixes, including stack trace fixes.
+ https://android-review.googlesource.com/#/c/152910
-In sdk/
- Included the Android support library and required extras packages
diff --git a/ndk/sources/cxx-stl/llvm-libc++/Android.mk b/ndk/sources/cxx-stl/llvm-libc++/Android.mk
index 2628914..afd0999 100644
--- a/ndk/sources/cxx-stl/llvm-libc++/Android.mk
+++ b/ndk/sources/cxx-stl/llvm-libc++/Android.mk
@@ -8,42 +8,12 @@
#
LIBCXX_FORCE_REBUILD := $(strip $(LIBCXX_FORCE_REBUILD))
-
-__libcxx_force_rebuild := $(LIBCXX_FORCE_REBUILD)
-
ifndef LIBCXX_FORCE_REBUILD
ifeq (,$(strip $(wildcard $(LOCAL_PATH)/libs/$(TARGET_ARCH_ABI)/libc++_static$(TARGET_LIB_EXTENSION))))
$(call __ndk_info,WARNING: Rebuilding libc++ libraries from sources!)
$(call __ndk_info,You might want to use $$NDK/build/tools/build-cxx-stl.sh --stl=libc++)
$(call __ndk_info,in order to build prebuilt versions to speed up your builds!)
- __libcxx_force_rebuild := true
- endif
-endif
-
-# Use gabi++ for x86* and mips* until libc++/libc++abi is ready for them
-ifneq (,$(filter x86% mips%,$(TARGET_ARCH_ABI)))
- __prebuilt_libcxx_compiled_with_gabixx := true
-else
- __prebuilt_libcxx_compiled_with_gabixx := false
-endif
-
-__libcxx_use_gabixx := $(__prebuilt_libcxx_compiled_with_gabixx)
-
-LIBCXX_USE_GABIXX := $(strip $(LIBCXX_USE_GABIXX))
-ifeq ($(LIBCXX_USE_GABIXX),true)
- __libcxx_use_gabixx := true
-endif
-
-ifneq ($(__libcxx_use_gabixx),$(__prebuilt_libcxx_compiled_with_gabixx))
- ifneq ($(__libcxx_force_rebuild),true)
- ifeq ($(__prebuilt_libcxx_compiled_with_gabixx),true)
- $(call __ndk_info,WARNING: Rebuilding libc++ libraries from sources since libc++ prebuilt libraries for $(TARGET_ARCH_ABI))
- $(call __ndk_info,are compiled with gabi++ but LIBCXX_USE_GABIXX is not set to true)
- else
- $(call __ndk_info,WARNING: Rebuilding libc++ libraries from sources since libc++ prebuilt libraries for $(TARGET_ARCH_ABI))
- $(call __ndk_info,are not compiled with gabi++ and LIBCXX_USE_GABIXX is set to true)
- endif
- __libcxx_force_rebuild := true
+ LIBCXX_FORCE_REBUILD := true
endif
endif
@@ -93,34 +63,6 @@
llvm_libc++_cxxflags := $(llvm_libc++_export_cxxflags)
llvm_libc++_cflags :=
-ifeq ($(__libcxx_use_gabixx),true)
-
-# Gabi++ emulates libcxxabi when building 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
-# tree. This can make it easier to experiment / update / debug it.
-#
-libgabi++_sources_dir := $(strip $(wildcard $(LOCAL_PATH)/../gabi++))
-ifdef libgabi++_sources_dir
- libgabi++_sources_prefix := ../gabi++
-else
- libgabi++_sources_dir := $(strip $(wildcard $(NDK_ROOT)/sources/cxx-stl/gabi++))
- ifndef libgabi++_sources_dir
- $(error Can't find GAbi++ sources directory!!)
- endif
- libgabi++_sources_prefix := $(libgabi++_sources_dir)
-endif
-
-include $(libgabi++_sources_dir)/sources.mk
-llvm_libc++_sources += $(addprefix $(libgabi++_sources_prefix:%/=%)/,$(libgabi++_src_files))
-llvm_libc++_includes += $(libgabi++_c_includes)
-llvm_libc++_export_includes += $(libgabi++_c_includes)
-
-else
-# libc++abi
-
libcxxabi_sources_dir := $(strip $(wildcard $(LOCAL_PATH)/../llvm-libc++abi))
ifdef libcxxabi_sources_dir
libcxxabi_sources_prefix := ../llvm-libc++abi
@@ -133,7 +75,16 @@
endif
include $(libcxxabi_sources_dir)/sources.mk
+
+ifneq (,$(filter armeabi%,$(TARGET_ARCH_ABI)))
+# for armeabi*, use llvm libunwind
llvm_libc++_sources += $(addprefix $(libcxxabi_sources_prefix:%/=%)/,$(libcxxabi_src_files))
+llvm_libc++_cxxflags += -DLIBCXXABI_USE_LLVM_UNWINDER=1 -D__STDC_FORMAT_MACROS
+else
+llvm_libc++_sources += $(addprefix $(libcxxabi_sources_prefix:%/=%)/,$(libcxxabi_src_base_files))
+llvm_libc++_cxxflags += -DLIBCXXABI_USE_LLVM_UNWINDER=0
+endif
+
llvm_libc++_includes += $(libcxxabi_c_includes)
llvm_libc++_export_includes += $(libcxxabi_c_includes)
@@ -143,9 +94,7 @@
llvm_libc++_cflags += -no-integrated-as
endif
-endif
-
-ifneq ($(__libcxx_force_rebuild),true)
+ifneq ($(LIBCXX_FORCE_REBUILD),true)
$(call ndk_log,Using prebuilt libc++ libraries)
@@ -182,7 +131,7 @@
include $(PREBUILT_SHARED_LIBRARY)
else
-# __libcxx_force_rebuild == true
+# LIBCXX_FORCE_REBUILD == true
$(call ndk_log,Rebuilding libc++ libraries from sources)
@@ -225,7 +174,7 @@
include $(BUILD_SHARED_LIBRARY)
-endif # __libcxx_force_rebuild == true
+endif # LIBCXX_FORCE_REBUILD == true
$(call import-module, android/support)
$(call import-module, android/compiler-rt)
diff --git a/ndk/sources/cxx-stl/llvm-libc++/libs/arm64-v8a/libc++_shared.so b/ndk/sources/cxx-stl/llvm-libc++/libs/arm64-v8a/libc++_shared.so
index d1387d7..c7149bd 100755
--- a/ndk/sources/cxx-stl/llvm-libc++/libs/arm64-v8a/libc++_shared.so
+++ b/ndk/sources/cxx-stl/llvm-libc++/libs/arm64-v8a/libc++_shared.so
Binary files differ
diff --git a/ndk/sources/cxx-stl/llvm-libc++/libs/arm64-v8a/libc++_static.a b/ndk/sources/cxx-stl/llvm-libc++/libs/arm64-v8a/libc++_static.a
index d246cd3..b91f63d 100644
--- a/ndk/sources/cxx-stl/llvm-libc++/libs/arm64-v8a/libc++_static.a
+++ b/ndk/sources/cxx-stl/llvm-libc++/libs/arm64-v8a/libc++_static.a
Binary files differ
diff --git a/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a-hard/libc++_shared.so b/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a-hard/libc++_shared.so
index 9d09360..f4c5dff 100755
--- a/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a-hard/libc++_shared.so
+++ b/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a-hard/libc++_shared.so
Binary files differ
diff --git a/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a-hard/libc++_static.a b/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a-hard/libc++_static.a
index 4dde0e2..26bf601 100644
--- a/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a-hard/libc++_static.a
+++ b/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a-hard/libc++_static.a
Binary files differ
diff --git a/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a-hard/thumb/libc++_shared.so b/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a-hard/thumb/libc++_shared.so
index 6c801b3..34bb13a 100755
--- a/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a-hard/thumb/libc++_shared.so
+++ b/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a-hard/thumb/libc++_shared.so
Binary files differ
diff --git a/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a-hard/thumb/libc++_static.a b/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a-hard/thumb/libc++_static.a
index dbcbf57..22dae7d 100644
--- a/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a-hard/thumb/libc++_static.a
+++ b/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a-hard/thumb/libc++_static.a
Binary files differ
diff --git a/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libc++_shared.so b/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libc++_shared.so
index 315ef5e..08b5ddb 100755
--- a/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libc++_shared.so
+++ b/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libc++_shared.so
Binary files differ
diff --git a/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libc++_static.a b/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libc++_static.a
index 98ea863..2033216 100644
--- a/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libc++_static.a
+++ b/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libc++_static.a
Binary files differ
diff --git a/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/thumb/libc++_shared.so b/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/thumb/libc++_shared.so
index 098c824..202df7b 100755
--- a/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/thumb/libc++_shared.so
+++ b/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/thumb/libc++_shared.so
Binary files differ
diff --git a/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/thumb/libc++_static.a b/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/thumb/libc++_static.a
index d78792e..d89173f 100644
--- a/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/thumb/libc++_static.a
+++ b/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/thumb/libc++_static.a
Binary files differ
diff --git a/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi/libc++_shared.so b/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi/libc++_shared.so
index e92625c..b79380f 100755
--- a/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi/libc++_shared.so
+++ b/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi/libc++_shared.so
Binary files differ
diff --git a/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi/libc++_static.a b/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi/libc++_static.a
index 12ef5c2..0ff951b 100644
--- a/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi/libc++_static.a
+++ b/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi/libc++_static.a
Binary files differ
diff --git a/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi/thumb/libc++_shared.so b/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi/thumb/libc++_shared.so
index 957534b..90e918e 100755
--- a/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi/thumb/libc++_shared.so
+++ b/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi/thumb/libc++_shared.so
Binary files differ
diff --git a/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi/thumb/libc++_static.a b/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi/thumb/libc++_static.a
index 05a9429..edbd89d 100644
--- a/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi/thumb/libc++_static.a
+++ b/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi/thumb/libc++_static.a
Binary files differ
diff --git a/ndk/sources/cxx-stl/llvm-libc++/libs/mips/libc++_shared.so b/ndk/sources/cxx-stl/llvm-libc++/libs/mips/libc++_shared.so
index 94b3867..f7f9684 100755
--- a/ndk/sources/cxx-stl/llvm-libc++/libs/mips/libc++_shared.so
+++ b/ndk/sources/cxx-stl/llvm-libc++/libs/mips/libc++_shared.so
Binary files differ
diff --git a/ndk/sources/cxx-stl/llvm-libc++/libs/mips/libc++_static.a b/ndk/sources/cxx-stl/llvm-libc++/libs/mips/libc++_static.a
index 56b3df4..8a6b403 100644
--- a/ndk/sources/cxx-stl/llvm-libc++/libs/mips/libc++_static.a
+++ b/ndk/sources/cxx-stl/llvm-libc++/libs/mips/libc++_static.a
Binary files differ
diff --git a/ndk/sources/cxx-stl/llvm-libc++/libs/mips64/libc++_shared.so b/ndk/sources/cxx-stl/llvm-libc++/libs/mips64/libc++_shared.so
index cbe3852..e61c8c9 100755
--- a/ndk/sources/cxx-stl/llvm-libc++/libs/mips64/libc++_shared.so
+++ b/ndk/sources/cxx-stl/llvm-libc++/libs/mips64/libc++_shared.so
Binary files differ
diff --git a/ndk/sources/cxx-stl/llvm-libc++/libs/mips64/libc++_static.a b/ndk/sources/cxx-stl/llvm-libc++/libs/mips64/libc++_static.a
index d6ca6cd..beddd57 100644
--- a/ndk/sources/cxx-stl/llvm-libc++/libs/mips64/libc++_static.a
+++ b/ndk/sources/cxx-stl/llvm-libc++/libs/mips64/libc++_static.a
Binary files differ
diff --git a/ndk/sources/cxx-stl/llvm-libc++/libs/x86/libc++_shared.so b/ndk/sources/cxx-stl/llvm-libc++/libs/x86/libc++_shared.so
index 040e2f8..862940f 100755
--- a/ndk/sources/cxx-stl/llvm-libc++/libs/x86/libc++_shared.so
+++ b/ndk/sources/cxx-stl/llvm-libc++/libs/x86/libc++_shared.so
Binary files differ
diff --git a/ndk/sources/cxx-stl/llvm-libc++/libs/x86/libc++_static.a b/ndk/sources/cxx-stl/llvm-libc++/libs/x86/libc++_static.a
index 311e998..455a678 100644
--- a/ndk/sources/cxx-stl/llvm-libc++/libs/x86/libc++_static.a
+++ b/ndk/sources/cxx-stl/llvm-libc++/libs/x86/libc++_static.a
Binary files differ
diff --git a/ndk/sources/cxx-stl/llvm-libc++/libs/x86_64/libc++_shared.so b/ndk/sources/cxx-stl/llvm-libc++/libs/x86_64/libc++_shared.so
index 19ee162..2fe5044 100755
--- a/ndk/sources/cxx-stl/llvm-libc++/libs/x86_64/libc++_shared.so
+++ b/ndk/sources/cxx-stl/llvm-libc++/libs/x86_64/libc++_shared.so
Binary files differ
diff --git a/ndk/sources/cxx-stl/llvm-libc++/libs/x86_64/libc++_static.a b/ndk/sources/cxx-stl/llvm-libc++/libs/x86_64/libc++_static.a
index d134480..4cc4fc3 100644
--- a/ndk/sources/cxx-stl/llvm-libc++/libs/x86_64/libc++_static.a
+++ b/ndk/sources/cxx-stl/llvm-libc++/libs/x86_64/libc++_static.a
Binary files differ
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/CREDITS.TXT b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/CREDITS.TXT
index bd54ba9..9c910fc 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/CREDITS.TXT
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/CREDITS.TXT
@@ -8,6 +8,14 @@
(W), PGP key ID and fingerprint (P), description (D), and snail-mail address
(S).
+N: Aaron Ballman
+E: aaron@aaronballman.com
+D: Minor patches
+
+N: Logan Chien
+E: logan.chien@mediatek.com
+D: ARM EHABI Unwind & Exception Handling
+
N: Marshall Clow
E: mclow.lists@gmail.com
E: marshall@idio.com
@@ -25,9 +33,17 @@
E: hhinnant@apple.com
D: Architect and primary coauthor of libc++abi
+N: Dana Jansens
+E: danakj@chromium.org
+D: ARM EHABI Unwind & Exception Handling
+
N: Nick Kledzik
E: kledzik@apple.com
+N: Antoine Labour
+E: piman@chromium.org
+D: ARM EHABI Unwind & Exception Handling
+
N: Bruce Mitchener, Jr.
E: bruce.mitchener@gmail.com
D: Minor typo fixes
@@ -40,3 +56,16 @@
E: erik.olofsson@hansoft.se
E: erik@olofsson.info
D: Minor patches and fixes
+
+N: Jon Roelofs
+E: jonathan@codesourcery.com
+D: ARM EHABI Unwind & Exception Handling, Bare-metal
+
+N: Nico Weber
+E: thakis@chromium.org
+D: ARM EHABI Unwind & Exception Handling
+
+N: Albert J. Wong
+E: ajwong@google.com
+D: ARM EHABI Unwind & Exception Handling
+
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/include/__cxxabi_config.h b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/include/__cxxabi_config.h
new file mode 100644
index 0000000..c040a06
--- /dev/null
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/include/__cxxabi_config.h
@@ -0,0 +1,20 @@
+//===-------------------------- __cxxabi_config.h -------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ____CXXABI_CONFIG_H
+#define ____CXXABI_CONFIG_H
+
+#if defined(__arm__) && !defined(__USING_SJLJ_EXCEPTIONS__) && \
+ !defined(__ARM_DWARF_EH__)
+#define LIBCXXABI_ARM_EHABI 1
+#else
+#define LIBCXXABI_ARM_EHABI 0
+#endif
+
+#endif // ____CXXABI_CONFIG_H
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/include/cxxabi.h b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/include/cxxabi.h
index 8fb079b..767acfe 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/include/cxxabi.h
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/include/cxxabi.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
#ifndef __CXXABI_H
-#define __CXXABI_H
+#define __CXXABI_H
/*
* This header provides the interface to the C++ ABI as defined at:
@@ -18,34 +18,28 @@
#include <stddef.h>
#include <stdint.h>
+#include <__cxxabi_config.h>
+
#define _LIBCPPABI_VERSION 1001
#define LIBCXXABI_NORETURN __attribute__((noreturn))
-// TODO(danakj): This is also in unwind.h and libunwind.h, can we consolidate?
-#if !defined(__USING_SJLJ_EXCEPTIONS__) && defined(__arm__) && \
- !defined(__ARM_DWARF_EH__) && !defined(__APPLE__)
-#define LIBCXXABI_ARM_EHABI 1
-#else
-#define LIBCXXABI_ARM_EHABI 0
-#endif
-
#ifdef __cplusplus
namespace std {
- class type_info; // forward declaration
+class type_info; // forward declaration
}
// runtime routines use C calling conventions, but are in __cxxabiv1 namespace
-namespace __cxxabiv1 {
- extern "C" {
+namespace __cxxabiv1 {
+extern "C" {
// 2.4.2 Allocating the Exception Object
extern void * __cxa_allocate_exception(size_t thrown_size) throw();
extern void __cxa_free_exception(void * thrown_exception) throw();
// 2.4.3 Throwing the Exception Object
-extern LIBCXXABI_NORETURN void __cxa_throw(void * thrown_exception,
+extern LIBCXXABI_NORETURN void __cxa_throw(void * thrown_exception,
std::type_info * tinfo, void (*dest)(void *));
// 2.5.3 Exception Handlers
@@ -66,6 +60,7 @@
// 2.6 Auxiliary Runtime APIs
extern LIBCXXABI_NORETURN void __cxa_bad_cast(void);
extern LIBCXXABI_NORETURN void __cxa_bad_typeid(void);
+extern LIBCXXABI_NORETURN void __cxa_throw_bad_array_new_length(void);
@@ -76,7 +71,7 @@
extern LIBCXXABI_NORETURN void __cxa_deleted_virtual(void);
// 3.3.2 One-time Construction API
-#if __arm__
+#ifdef __arm__
extern int __cxa_guard_acquire(uint32_t*);
extern void __cxa_guard_release(uint32_t*);
extern void __cxa_guard_abort(uint32_t*);
@@ -87,84 +82,76 @@
#endif
// 3.3.3 Array Construction and Destruction API
-extern void* __cxa_vec_new(size_t element_count,
- size_t element_size,
- size_t padding_size,
+extern void* __cxa_vec_new(size_t element_count,
+ size_t element_size,
+ size_t padding_size,
void (*constructor)(void*),
- void (*destructor)(void*) );
+ void (*destructor)(void*));
extern void* __cxa_vec_new2(size_t element_count,
- size_t element_size,
+ size_t element_size,
size_t padding_size,
void (*constructor)(void*),
void (*destructor)(void*),
- void* (*alloc)(size_t),
- void (*dealloc)(void*) );
+ void* (*alloc)(size_t),
+ void (*dealloc)(void*));
extern void* __cxa_vec_new3(size_t element_count,
- size_t element_size,
+ size_t element_size,
size_t padding_size,
void (*constructor)(void*),
void (*destructor)(void*),
- void* (*alloc)(size_t),
- void (*dealloc)(void*, size_t) );
-
-extern void __cxa_vec_ctor(void* array_address,
+ void* (*alloc)(size_t),
+ void (*dealloc)(void*, size_t));
+
+extern void __cxa_vec_ctor(void* array_address,
size_t element_count,
- size_t element_size,
+ size_t element_size,
void (*constructor)(void*),
- void (*destructor)(void*) );
+ void (*destructor)(void*));
-
-extern void __cxa_vec_dtor(void* array_address,
+extern void __cxa_vec_dtor(void* array_address,
size_t element_count,
- size_t element_size,
- void (*destructor)(void*) );
+ size_t element_size,
+ void (*destructor)(void*));
-
-extern void __cxa_vec_cleanup(void* array_address,
+extern void __cxa_vec_cleanup(void* array_address,
size_t element_count,
- size_t element_size,
- void (*destructor)(void*) );
+ size_t element_size,
+ void (*destructor)(void*));
+extern void __cxa_vec_delete(void* array_address,
+ size_t element_size,
+ size_t padding_size,
+ void (*destructor)(void*));
-extern void __cxa_vec_delete(void* array_address,
- size_t element_size,
- size_t padding_size,
- void (*destructor)(void*) );
-
-
-extern void __cxa_vec_delete2(void* array_address,
- size_t element_size,
- size_t padding_size,
+extern void __cxa_vec_delete2(void* array_address,
+ size_t element_size,
+ size_t padding_size,
void (*destructor)(void*),
- void (*dealloc)(void*) );
-
+ void (*dealloc)(void*));
-extern void __cxa_vec_delete3(void* __array_address,
- size_t element_size,
- size_t padding_size,
+extern void __cxa_vec_delete3(void* __array_address,
+ size_t element_size,
+ size_t padding_size,
void (*destructor)(void*),
- void (*dealloc) (void*, size_t));
+ void (*dealloc)(void*, size_t));
-
-extern void __cxa_vec_cctor(void* dest_array,
- void* src_array,
- size_t element_count,
- size_t element_size,
- void (*constructor) (void*, void*),
- void (*destructor)(void*) );
-
+extern void __cxa_vec_cctor(void* dest_array,
+ void* src_array,
+ size_t element_count,
+ size_t element_size,
+ void (*constructor)(void*, void*),
+ void (*destructor)(void*));
// 3.3.5.3 Runtime API
extern int __cxa_atexit(void (*f)(void*), void* p, void* d);
extern int __cxa_finalize(void*);
-
// 3.4 Demangler API
-extern char* __cxa_demangle(const char* mangled_name,
+extern char* __cxa_demangle(const char* mangled_name,
char* output_buffer,
- size_t* length,
+ size_t* length,
int* status);
// Apple additions to support C++ 0x exception_ptr class
@@ -177,6 +164,12 @@
// Apple addition to support std::uncaught_exception()
extern bool __cxa_uncaught_exception() throw();
+#ifdef __linux__
+// Linux TLS support. Not yet an official part of the Itanium ABI.
+// https://sourceware.org/glibc/wiki/Destructor%20support%20for%20thread_local%20variables
+extern int __cxa_thread_atexit(void (*)(void *), void *, void *) throw();
+#endif
+
} // extern "C"
} // namespace __cxxabiv1
@@ -184,4 +177,4 @@
#endif // __cplusplus
-#endif // __CXXABI_H
+#endif // __CXXABI_H
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/include/libunwind.h b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/include/libunwind.h
index ab97c41..e2396e4 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/include/libunwind.h
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/include/libunwind.h
@@ -17,17 +17,11 @@
#include <stdint.h>
#include <stddef.h>
-// TODO(danakj): This is also in unwind.h and cxxabi.h, can we consolidate?
-#if !defined(__USING_SJLJ_EXCEPTIONS__) && defined(__arm__) && \
- !defined(__ARM_DWARF_EH__) && !defined(__APPLE__)
-#define LIBCXXABI_ARM_EHABI 1
-#else
-#define LIBCXXABI_ARM_EHABI 0
-#endif
+#include <__cxxabi_config.h>
-#if __APPLE__
+#ifdef __APPLE__
#include <Availability.h>
- #if __arm__
+ #ifdef __arm__
#define LIBUNWIND_AVAIL __attribute__((unavailable))
#else
#define LIBUNWIND_AVAIL __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_5_0)
@@ -64,15 +58,11 @@
typedef struct unw_addr_space *unw_addr_space_t;
typedef int unw_regnum_t;
-#if __arm__
+#if LIBCXXABI_ARM_EHABI
typedef uint32_t unw_word_t;
-#else
-typedef uint64_t unw_word_t;
-#endif
-
-#if __arm__
typedef uint64_t unw_fpreg_t;
#else
+typedef uint64_t unw_word_t;
typedef double unw_fpreg_t;
#endif
@@ -104,7 +94,7 @@
extern int unw_set_fpreg(unw_cursor_t *, unw_regnum_t, unw_fpreg_t) LIBUNWIND_AVAIL;
extern int unw_resume(unw_cursor_t *) LIBUNWIND_AVAIL;
-#if __arm__
+#ifdef __arm__
/* Save VFP registers in FSTMX format (instead of FSTMD). */
extern void unw_save_vfp_as_X(unw_cursor_t *) LIBUNWIND_AVAIL;
#endif
@@ -117,16 +107,17 @@
extern int unw_get_proc_name(unw_cursor_t *, char *, size_t, unw_word_t *) LIBUNWIND_AVAIL;
//extern int unw_get_save_loc(unw_cursor_t*, int, unw_save_loc_t*);
-#if UNW_REMOTE
+extern unw_addr_space_t unw_local_addr_space;
+
+#ifdef UNW_REMOTE
/*
* Mac OS X "remote" API for unwinding other processes on same machine
*
*/
-extern unw_addr_space_t unw_local_addr_space;
extern unw_addr_space_t unw_create_addr_space_for_task(task_t);
extern void unw_destroy_addr_space(unw_addr_space_t);
extern int unw_init_remote_thread(unw_cursor_t *, unw_addr_space_t, thread_t *);
-#endif
+#endif /* UNW_REMOTE */
/*
* traditional libuwind "remote" API
@@ -456,12 +447,12 @@
UNW_ARM_WR15 = 127,
// 128-133 -- SPSR, SPSR_{FIQ|IRQ|ABT|UND|SVC}
// 134-143 -- Reserved
- // 144-150 -- R8_USR–R14_USR
- // 151-157 -- R8_FIQ–R14_FIQ
- // 158-159 -- R13_IRQ–R14_IRQ
- // 160-161 -- R13_ABT–R14_ABT
- // 162-163 -- R13_UND–R14_UND
- // 164-165 -- R13_SVC–R14_SVC
+ // 144-150 -- R8_USR-R14_USR
+ // 151-157 -- R8_FIQ-R14_FIQ
+ // 158-159 -- R13_IRQ-R14_IRQ
+ // 160-161 -- R13_ABT-R14_ABT
+ // 162-163 -- R13_UND-R14_UND
+ // 164-165 -- R13_SVC-R14_SVC
// 166-191 -- Reserved
UNW_ARM_WC0 = 192,
UNW_ARM_WC1 = 193,
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/include/mach-o/compact_unwind_encoding.h b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/include/mach-o/compact_unwind_encoding.h
index 3e9b054..b71c2c8 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/include/mach-o/compact_unwind_encoding.h
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/include/mach-o/compact_unwind_encoding.h
@@ -133,6 +133,10 @@
// linker in final linked images which have only dwarf unwind info for a
// function.
//
+// The permutation encoding is a Lehmer code sequence encoded into a
+// single variable-base number so we can encode the ordering of up to
+// six registers in a 10-bit space.
+//
// The following is the algorithm used to create the permutation encoding used
// with frameless stacks. It is passed the number of registers to be saved and
// an array of the register numbers saved.
@@ -234,7 +238,7 @@
// EPB value, then RBP is restored by popping off the stack, and the return
// is done by popping the stack once more into the pc.
// All non-volatile registers that need to be restored must have been saved
-// in a small range in the stack that starts RBP-8 to RBP-1020. The offset/4
+// in a small range in the stack that starts RBP-8 to RBP-2040. The offset/8
// is encoded in the UNWIND_X86_64_RBP_FRAME_OFFSET bits. The registers saved
// are encoded in the UNWIND_X86_64_RBP_FRAME_REGISTERS bits as five 3-bit entries.
// Each entry contains which register to restore.
@@ -244,8 +248,8 @@
// unwind encoding) is added to the RSP. Then the return is done by
// popping the stack into the pc.
// All non-volatile registers that need to be restored must have been saved
-// on the stack immediately after the return address. The stack_size/4 is
-// encoded in the UNWIND_X86_64_FRAMELESS_STACK_SIZE (max stack size is 1024).
+// on the stack immediately after the return address. The stack_size/8 is
+// encoded in the UNWIND_X86_64_FRAMELESS_STACK_SIZE (max stack size is 2048).
// The number of registers saved is encoded in UNWIND_X86_64_FRAMELESS_STACK_REG_COUNT.
// UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION constains which registers were
// saved and their order.
@@ -413,7 +417,7 @@
uint32_t indexSectionOffset;
uint32_t indexCount;
// compact_unwind_encoding_t[]
- // uintptr_t personalities[]
+ // uint32_t personalities[]
// unwind_info_section_header_index_entry[]
// unwind_info_section_header_lsda_index_entry[]
};
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/include/unwind.h b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/include/unwind.h
index 7d16f02..86001bb 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/include/unwind.h
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/include/unwind.h
@@ -23,13 +23,7 @@
#define LIBUNWIND_UNAVAIL
#endif
-// TODO(danakj): This is also in cxxabi.h and libunwind.h, can we consolidate?
-#if !defined(__USING_SJLJ_EXCEPTIONS__) && defined(__arm__) && \
- !defined(__ARM_DWARF_EH__) && !defined(__APPLE__)
-#define LIBCXXABI_ARM_EHABI 1
-#else
-#define LIBCXXABI_ARM_EHABI 0
-#endif
+#include <__cxxabi_config.h>
typedef enum {
_URC_NO_REASON = 0,
@@ -43,7 +37,7 @@
_URC_INSTALL_CONTEXT = 7,
_URC_CONTINUE_UNWIND = 8,
#if LIBCXXABI_ARM_EHABI
- _URC_FAILURE = 9,
+ _URC_FAILURE = 9
#endif
} _Unwind_Reason_Code;
@@ -63,6 +57,8 @@
static const _Unwind_State _US_VIRTUAL_UNWIND_FRAME = 0;
static const _Unwind_State _US_UNWIND_FRAME_STARTING = 1;
static const _Unwind_State _US_UNWIND_FRAME_RESUME = 2;
+/* Undocumented flag for force unwinding. */
+static const _Unwind_State _US_FORCE_UNWIND = 8;
typedef uint32_t _Unwind_EHT_Header;
@@ -73,6 +69,7 @@
struct _Unwind_Control_Block {
uint64_t exception_class;
void (*exception_cleanup)(_Unwind_Reason_Code, _Unwind_Control_Block*);
+
/* Unwinder cache, private fields for the unwinder's use */
struct {
uint32_t reserved1; /* init reserved1 to 0, then don't touch */
@@ -81,20 +78,23 @@
uint32_t reserved4;
uint32_t reserved5;
} unwinder_cache;
+
/* Propagation barrier cache (valid after phase 1): */
struct {
uint32_t sp;
uint32_t bitpattern[5];
} barrier_cache;
+
/* Cleanup cache (preserved over cleanup): */
struct {
uint32_t bitpattern[4];
} cleanup_cache;
+
/* Pr cache (for pr's benefit): */
struct {
uint32_t fnstart; /* function start address */
_Unwind_EHT_Header* ehtp; /* pointer to EHT entry header word */
- uint32_t additional; /* additional data */
+ uint32_t additional;
uint32_t reserved1;
} pr_cache;
@@ -121,30 +121,29 @@
_Unwind_Exception *exc);
uintptr_t private_1; // non-zero means forced unwind
uintptr_t private_2; // holds sp that phase1 found for phase2 to use
-#if !__LP64__
+#ifndef __LP64__
// The gcc implementation of _Unwind_Exception used attribute mode on the
- // above fields which had the side effect of causing this whole struct to
- // round up to 32 bytes in size. To be more explicit, we add pad fields
+ // above fields which had the side effect of causing this whole struct to
+ // round up to 32 bytes in size. To be more explicit, we add pad fields
// added for binary compatibility.
uint32_t reserved[3];
#endif
};
+typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn)
+ (int version,
+ _Unwind_Action actions,
+ uint64_t exceptionClass,
+ _Unwind_Exception* exceptionObject,
+ struct _Unwind_Context* context,
+ void* stop_parameter );
+
typedef _Unwind_Reason_Code (*__personality_routine)
(int version,
_Unwind_Action actions,
uint64_t exceptionClass,
_Unwind_Exception* exceptionObject,
struct _Unwind_Context* context);
-
-typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn)
- (int version,
- _Unwind_Action actions,
- uint64_t exceptionClass,
- struct _Unwind_Exception *exceptionObject,
- struct _Unwind_Context *context,
- void *stop_parameter );
-
#endif
#ifdef __cplusplus
@@ -154,7 +153,7 @@
//
// The following are the base functions documented by the C++ ABI
//
-#if __USING_SJLJ_EXCEPTIONS__
+#ifdef __USING_SJLJ_EXCEPTIONS__
extern _Unwind_Reason_Code
_Unwind_SjLj_RaiseException(_Unwind_Exception *exception_object);
extern void _Unwind_SjLj_Resume(_Unwind_Exception *exception_object);
@@ -189,76 +188,42 @@
extern void _Unwind_Complete(_Unwind_Exception* exception_object);
-extern _Unwind_VRS_Result _Unwind_VRS_Get(_Unwind_Context* context,
- _Unwind_VRS_RegClass regclass,
- uint32_t regno,
- _Unwind_VRS_DataRepresentation representation,
- void *valuep);
+extern _Unwind_VRS_Result
+_Unwind_VRS_Get(_Unwind_Context *context, _Unwind_VRS_RegClass regclass,
+ uint32_t regno, _Unwind_VRS_DataRepresentation representation,
+ void *valuep);
-extern _Unwind_VRS_Result _Unwind_VRS_Set(_Unwind_Context* context,
- _Unwind_VRS_RegClass regclass,
- uint32_t regno,
- _Unwind_VRS_DataRepresentation representation,
- void *valuep);
+extern _Unwind_VRS_Result
+_Unwind_VRS_Set(_Unwind_Context *context, _Unwind_VRS_RegClass regclass,
+ uint32_t regno, _Unwind_VRS_DataRepresentation representation,
+ void *valuep);
-extern _Unwind_VRS_Result _Unwind_VRS_Pop(_Unwind_Context *context,
- _Unwind_VRS_RegClass regclass,
- uint32_t discriminator,
- _Unwind_VRS_DataRepresentation representation);
+extern _Unwind_VRS_Result
+_Unwind_VRS_Pop(_Unwind_Context *context, _Unwind_VRS_RegClass regclass,
+ uint32_t discriminator,
+ _Unwind_VRS_DataRepresentation representation);
+#endif
-// TODO(ajwong): This is not part of the EHABI. Decide if the name is right.
-extern _Unwind_Reason_Code _Unwind_VRS_Interpret(_Unwind_Context* context,
- uint32_t* data,
- size_t offset,
- size_t len);
-
-// TODO(ajwong) Should these {Set,Get}/{GR,IP} be removed in favor of
-// VRS_Get/VRS_Set? Is the thumb bit inference in SetIP correct?
-static inline uintptr_t _Unwind_GetGR(struct _Unwind_Context* context,
- int index) {
- uintptr_t value = 0;
- _Unwind_VRS_Get(context, _UVRSC_CORE, (uint32_t)index, _UVRSD_UINT32, &value);
- return value;
-}
-
-static inline void _Unwind_SetGR(struct _Unwind_Context* context, int index,
- uintptr_t new_value) {
- _Unwind_VRS_Set(context, _UVRSC_CORE, (uint32_t)index,
- _UVRSD_UINT32, &new_value);
-}
-
-static inline uintptr_t _Unwind_GetIP(struct _Unwind_Context* context) {
- // remove the thumb-bit before returning
- return (_Unwind_GetGR(context, 15) & (~(uintptr_t)0x1));
-}
-
-static inline void _Unwind_SetIP(struct _Unwind_Context* context,
- uintptr_t new_value) {
- uintptr_t thumb_bit = _Unwind_GetGR(context, 15) & ((uintptr_t)0x1);
- _Unwind_SetGR(context, 15, new_value | thumb_bit);
-}
-#else // LIBCXXABI_ARM_EHABI
extern uintptr_t _Unwind_GetGR(struct _Unwind_Context *context, int index);
extern void _Unwind_SetGR(struct _Unwind_Context *context, int index,
uintptr_t new_value);
extern uintptr_t _Unwind_GetIP(struct _Unwind_Context *context);
extern void _Unwind_SetIP(struct _Unwind_Context *, uintptr_t new_value);
-#endif // LIBCXXABI_ARM_EHABI
extern uintptr_t _Unwind_GetRegionStart(struct _Unwind_Context *context);
extern uintptr_t
_Unwind_GetLanguageSpecificData(struct _Unwind_Context *context);
-#if __USING_SJLJ_EXCEPTIONS__
+#ifdef __USING_SJLJ_EXCEPTIONS__
extern _Unwind_Reason_Code
_Unwind_SjLj_ForcedUnwind(_Unwind_Exception *exception_object,
_Unwind_Stop_Fn stop, void *stop_parameter);
-#else // !__USING_SJLJ_EXCEPTIONS__
+#else
extern _Unwind_Reason_Code
_Unwind_ForcedUnwind(_Unwind_Exception *exception_object,
_Unwind_Stop_Fn stop, void *stop_parameter);
-#endif // !__USING_SJLJ_EXCEPTIONS__
+#endif
-#if __USING_SJLJ_EXCEPTIONS__
+#ifdef __USING_SJLJ_EXCEPTIONS__
typedef struct _Unwind_FunctionContext *_Unwind_FunctionContext_t;
extern void _Unwind_SjLj_Register(_Unwind_FunctionContext_t fc);
extern void _Unwind_SjLj_Unregister(_Unwind_FunctionContext_t fc);
@@ -271,7 +236,7 @@
//
// called by __cxa_rethrow().
//
-#if __USING_SJLJ_EXCEPTIONS__
+#ifdef __USING_SJLJ_EXCEPTIONS__
extern _Unwind_Reason_Code
_Unwind_SjLj_Resume_or_Rethrow(_Unwind_Exception *exception_object);
#else
@@ -287,15 +252,15 @@
extern _Unwind_Reason_Code _Unwind_Backtrace(_Unwind_Trace_Fn, void *);
// _Unwind_GetCFA is a gcc extension that can be called from within a
-// personality handler to get the CFA (stack pointer before call) of
+// personality handler to get the CFA (stack pointer before call) of
// current frame.
extern uintptr_t _Unwind_GetCFA(struct _Unwind_Context *);
// _Unwind_GetIPInfo is a gcc extension that can be called from within a
-// personality handler. Similar to _Unwind_GetIP() but also returns in
-// *ipBefore a non-zero value if the instruction pointer is at or before the
-// instruction causing the unwind. Normally, in a function call, the IP returned
+// personality handler. Similar to _Unwind_GetIP() but also returns in
+// *ipBefore a non-zero value if the instruction pointer is at or before the
+// instruction causing the unwind. Normally, in a function call, the IP returned
// is the return address which is after the call instruction and may be past the
// end of the function containing the call instruction.
extern uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context,
@@ -304,17 +269,17 @@
// __register_frame() is used with dynamically generated code to register the
// FDE for a generated (JIT) code. The FDE must use pc-rel addressing to point
-// to its function and optional LSDA.
-// __register_frame() has existed in all versions of Mac OS X, but in 10.4 and
-// 10.5 it was buggy and did not actually register the FDE with the unwinder.
+// to its function and optional LSDA.
+// __register_frame() has existed in all versions of Mac OS X, but in 10.4 and
+// 10.5 it was buggy and did not actually register the FDE with the unwinder.
// In 10.6 and later it does register properly.
extern void __register_frame(const void *fde);
extern void __deregister_frame(const void *fde);
// _Unwind_Find_FDE() will locate the FDE if the pc is in some function that has
// an associated FDE. Note, Mac OS X 10.6 and later, introduces "compact unwind
-// info" which the runtime uses in preference to dwarf unwind info. This
-// function will only work if the target function has an FDE but no compact
+// info" which the runtime uses in preference to dwarf unwind info. This
+// function will only work if the target function has an FDE but no compact
// unwind info.
struct dwarf_eh_bases {
uintptr_t tbase;
@@ -339,7 +304,7 @@
LIBUNWIND_UNAVAIL;
// Mac OS X 10.4 and 10.5 had implementations of these functions in
-// libgcc_s.dylib, but they never worked.
+// libgcc_s.dylib, but they never worked.
/// These functions are no longer available on Mac OS X.
extern void __register_frame_info_bases(const void *fde, void *ob, void *tb,
void *db) LIBUNWIND_UNAVAIL;
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/lib/buildit b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/lib/buildit
index ea4359d..5a4a710 100755
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/lib/buildit
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/lib/buildit
@@ -22,34 +22,12 @@
CC=clang
fi
-if [ -z "$AR" ]
-then
- AR=ar
-fi
-
-if [ -z "$RANLIB" ]
-then
- RANLIB=ranlib
-fi
-
-if [ -z "$AR" ]
-then
- AR=ar
-fi
-
-if [ -z "$RANLIB" ]
-then
- RANLIB=ranlib
-fi
-
if [ -z $RC_ProjectSourceVersion ]
then
RC_ProjectSourceVersion=1
fi
-EXTRA_CC_FLAGS="-std=c11"
-EXTRA_CXX_FLAGS="-std=c++11 -stdlib=libc++"
-EXTRA_FLAGS="-fstrict-aliasing -Wstrict-aliasing=2 \
+EXTRA_FLAGS="-std=c++11 -stdlib=libc++ -fstrict-aliasing -Wstrict-aliasing=2 \
-Wsign-conversion -Wshadow -Wconversion -Wunused-variable \
-Wmissing-field-initializers -Wchar-subscripts -Wmismatched-tags \
-Wmissing-braces -Wshorten-64-to-32 -Wsign-compare \
@@ -65,7 +43,7 @@
SOEXT=dylib
if [ -n "$SDKROOT" ]
then
- EXTRA_CXX_FLAGS+="-isysroot ${SDKROOT}"
+ EXTRA_FLAGS+="-isysroot ${SDKROOT}"
CXX=`xcrun -sdk "${SDKROOT}" -find clang++`
CC=`xcrun -sdk "${SDKROOT}" -find clang`
fi
@@ -87,11 +65,6 @@
-shared -nodefaultlibs -Wl,--export-all-symbols -Wl,--allow-multiple-definition -Wl,--out-implib,libc++abi.dll.a \
-lsupc++ -lpthread -lmingw32 -lgcc_s -lgcc -lmoldname -lmingwex -lmsvcr100 -ladvapi32 -lshell32 -luser32 -lkernel32 -lmingw32 -lgcc_s -lgcc -lmoldname -lmingwex -lmsvcrt"
;;
- *-none-eabi*)
- RC_CFLAGS="-fPIC"
- SOEXT=so
- EXTRA_FLAGS+=" -target $TRIPLE --sysroot=$SYSROOT -no-integrated-as -funwind-tables -DLIBCXXABI_BARE_METAL=1"
- ;;
*)
RC_CFLAGS="-fPIC"
SOEXT=so
@@ -108,50 +81,17 @@
set -x
-# Build the generic bits
for FILE in ../src/*.cpp; do
- $CXX -c -g -O0 $RC_CFLAGS $EXTRA_CXX_FLAGS $EXTRA_FLAGS -I../include $OPTIONS $FILE
+ $CXX -c -g -O3 $RC_CFLAGS $EXTRA_FLAGS -I../include $OPTIONS $FILE
done
case $TRIPLE in
*-*-mingw*)
- for FILE in ../src/support/win32/*.cpp; do
- $CXX -c -g -O0 $RC_CFLAGS $EXTRA_CXX_FLAGS $EXTRA_FLAGS -I../include $OPTIONS $FILE
- done
- ;;
- *-apple-*)
- for FILE in ../src/support/apple/*.cpp; do
- $CXX -c -g -O0 $RC_CFLAGS $EXTRA_CXX_FLAGS $EXTRA_FLAGS -I../include $OPTIONS $FILE
- done
- ;;
- *)
- ;;
-esac
-
-# Build the Unwinder
-case $TRIPLE in
- *-none-eabi*)
- for FILE in ../src/Unwind/*.S; do
- $CC -c -g -O0 $RC_CFLAGS $EXTRA_CC_FLAGS $EXTRA_FLAGS -I../include $OPTIONS $FILE
- done
- for FILE in ../src/Unwind/*.c; do
- $CC -c -g -O0 $RC_CFLAGS $EXTRA_CC_FLAGS $EXTRA_FLAGS -I../include $OPTIONS $FILE
- done
- for FILE in ../src/Unwind/*.cpp; do
- $CXX -c -g -O0 $RC_CFLAGS $EXTRA_CXX_FLAGS $EXTRA_FLAGS -I../include $OPTIONS $FILE
- done
+ for FILE in ../src/support/win32/*.cpp; do
+ $CXX -c -g -Os $RC_CFLAGS $EXTRA_FLAGS -I../include $OPTIONS $FILE
+ done
;;
esac
-
-# Package everything up in a library (shared or static)
-case $TRIPLE in
- *-none-eabi*)
- $AR rc libc++abi.a *.o
- $RANLIB libc++abi.a
- ;;
- *)
- $CC *.o $RC_CFLAGS $LDSHARED_FLAGS $EXTRA_CXX_FLAGS $EXTRA_FLAGS
- ;;
-esac
+$CC *.o $RC_CFLAGS $LDSHARED_FLAGS $EXTRA_FLAGS
if [ -z $RC_XBS ]
then
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/AddressSpace.hpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/AddressSpace.hpp
index 857dc16..649c614 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/AddressSpace.hpp
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/AddressSpace.hpp
@@ -18,7 +18,18 @@
#include <stdlib.h>
#include <string.h>
-#if !_LIBUNWIND_IS_BAREMETAL
+#ifdef __ANDROID__
+/* Older bionic header in NDK is broken wrt to elf.h, in that include <linux/elf.h> doesn't
+ * cause other fails. Hardcode PT_GNU_EH_FRAME as workaround.
+ */
+#if !defined(PT_GNU_EH_FRAME)
+#define PT_GNU_EH_FRAME 0x6474e550
+#elif PT_GNU_EH_FRAME != 0x6474e550
+#error PT_GNU_EH_FRAME != 0x6474e550
+#endif
+#endif
+
+#ifndef _LIBUNWIND_IS_BAREMETAL
#include <dlfcn.h>
#if defined(__ANDROID__) && !__LP64__
// dladdr only exits in API >= 8. Call to our my_dladdr in android/support for dynamic lookup
@@ -35,7 +46,7 @@
#endif
#endif
-#if __APPLE__
+#ifdef __APPLE__
#include <mach-o/getsect.h>
namespace libunwind {
bool checkKeyMgrRegisteredFDEs(uintptr_t targetAddr, void *&fde);
@@ -48,51 +59,57 @@
#include "Registers.hpp"
#if LIBCXXABI_ARM_EHABI
-#if __LINUX__
- // Emulate the BSD dl_unwind_find_exidx API when on a GNU libdl system.
- typedef long unsigned int *_Unwind_Ptr;
- extern "C" _Unwind_Ptr __gnu_Unwind_Find_exidx(_Unwind_Ptr targetAddr, int *length);
- _Unwind_Ptr (*dl_unwind_find_exidx)(_Unwind_Ptr targetAddr, int *length) =
- __gnu_Unwind_Find_exidx;
-#else
- #include <link.h>
-#endif
-#endif // LIBCXXABI_ARM_EHABI
+#ifdef __linux__
-#if LIBCXXABI_ARM_EHABI && _LIBUNWIND_IS_BAREMETAL
+typedef long unsigned int *_Unwind_Ptr;
+extern "C" _Unwind_Ptr __gnu_Unwind_Find_exidx(_Unwind_Ptr addr, int *len);
+
+// Emulate the BSD dl_unwind_find_exidx API when on a GNU libdl system.
+#define dl_unwind_find_exidx __gnu_Unwind_Find_exidx
+
+#elif !defined(_LIBUNWIND_IS_BAREMETAL)
+#include <link.h>
+#else // !defined(_LIBUNWIND_IS_BAREMETAL)
// When statically linked on bare-metal, the symbols for the EH table are looked
// up without going through the dynamic loader.
-// TODO(jroelofs): since Newlib on arm-none-eabi doesn't
-// have dl_unwind_find_exidx...
struct EHTEntry {
uint32_t functionOffset;
uint32_t unwindOpcodes;
};
extern EHTEntry __exidx_start;
extern EHTEntry __exidx_end;
+#endif // !defined(_LIBUNWIND_IS_BAREMETAL)
+#endif // LIBCXXABI_ARM_EHABI
+
+#if defined(__linux__)
+#if _LIBUNWIND_SUPPORT_DWARF_UNWIND && _LIBUNWIND_SUPPORT_DWARF_INDEX
+#include <link.h>
+#include "EHHeaderParser.hpp"
+#endif
#endif
namespace libunwind {
/// Used by findUnwindSections() to return info about needed sections.
struct UnwindInfoSections {
-#if _LIBUNWIND_SUPPORT_DWARF_UNWIND
+#if _LIBUNWIND_SUPPORT_DWARF_UNWIND || _LIBUNWIND_SUPPORT_DWARF_INDEX || \
+ _LIBUNWIND_SUPPORT_COMPACT_UNWIND
+ // No dso_base for ARM EHABI.
uintptr_t dso_base;
+#endif
+#if _LIBUNWIND_SUPPORT_DWARF_UNWIND
uintptr_t dwarf_section;
uintptr_t dwarf_section_length;
#endif
#if _LIBUNWIND_SUPPORT_DWARF_INDEX
- uintptr_t dso_base;
uintptr_t dwarf_index_section;
uintptr_t dwarf_index_section_length;
#endif
#if _LIBUNWIND_SUPPORT_COMPACT_UNWIND
- uintptr_t dso_base;
uintptr_t compact_unwind_section;
uintptr_t compact_unwind_section_length;
#endif
#if LIBCXXABI_ARM_EHABI
- // No dso_base for ARM EHABI.
uintptr_t arm_section;
uintptr_t arm_section_length;
#endif
@@ -104,7 +121,7 @@
/// making local unwinds fast.
class __attribute__((visibility("hidden"))) LocalAddressSpace {
public:
-#if __LP64__
+#ifdef __LP64__
typedef uint64_t pint_t;
typedef int64_t sint_t;
#else
@@ -145,7 +162,8 @@
static uint64_t getULEB128(pint_t &addr, pint_t end);
static int64_t getSLEB128(pint_t &addr, pint_t end);
- pint_t getEncodedP(pint_t &addr, pint_t end, uint8_t encoding);
+ pint_t getEncodedP(pint_t &addr, pint_t end, uint8_t encoding,
+ pint_t datarelBase = 0);
bool findFunctionName(pint_t addr, char *buf, size_t bufLen,
unw_word_t *offset);
bool findUnwindSections(pint_t targetAddr, UnwindInfoSections &info);
@@ -155,7 +173,7 @@
};
inline uintptr_t LocalAddressSpace::getP(pint_t addr) {
-#if __LP64__
+#ifdef __LP64__
return get64(addr);
#else
return get32(addr);
@@ -208,9 +226,9 @@
return result;
}
-inline LocalAddressSpace::pint_t LocalAddressSpace::getEncodedP(pint_t &addr,
- pint_t end,
- uint8_t encoding) {
+inline LocalAddressSpace::pint_t
+LocalAddressSpace::getEncodedP(pint_t &addr, pint_t end, uint8_t encoding,
+ pint_t datarelBase) {
pint_t startAddr = addr;
const uint8_t *p = (uint8_t *)addr;
pint_t result;
@@ -276,7 +294,12 @@
_LIBUNWIND_ABORT("DW_EH_PE_textrel pointer encoding not supported");
break;
case DW_EH_PE_datarel:
- _LIBUNWIND_ABORT("DW_EH_PE_datarel pointer encoding not supported");
+ // DW_EH_PE_datarel is only valid in a few places, so the parameter has a
+ // default value of 0, and we abort in the event that someone calls this
+ // function with a datarelBase of 0 and DW_EH_PE_datarel encoding.
+ if (datarelBase == 0)
+ _LIBUNWIND_ABORT("DW_EH_PE_datarel is invalid with a datarelBase of 0");
+ result += datarelBase;
break;
case DW_EH_PE_funcrel:
_LIBUNWIND_ABORT("DW_EH_PE_funcrel pointer encoding not supported");
@@ -295,7 +318,7 @@
return result;
}
-#if __APPLE__
+#ifdef __APPLE__
struct dyld_unwind_sections
{
const struct mach_header* mh;
@@ -339,7 +362,7 @@
inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
UnwindInfoSections &info) {
-#if __APPLE__
+#ifdef __APPLE__
dyld_unwind_sections dyldInfo;
if (_dyld_find_unwind_sections((void *)targetAddr, &dyldInfo)) {
info.dso_base = (uintptr_t)dyldInfo.mh;
@@ -352,20 +375,78 @@
return true;
}
#elif LIBCXXABI_ARM_EHABI
- #if !_LIBUNWIND_IS_BAREMETAL
+ #ifdef _LIBUNWIND_IS_BAREMETAL
+ // Bare metal is statically linked, so no need to ask the dynamic loader
+ info.arm_section = (uintptr_t)(&__exidx_start);
+ info.arm_section_length = (uintptr_t)(&__exidx_end - &__exidx_start);
+ #else
int length = 0;
info.arm_section = (uintptr_t) dl_unwind_find_exidx(
(_Unwind_Ptr) targetAddr, &length);
- info.arm_section_length = length;
- #else
- // Bare metal, statically linked
- info.arm_section = (uintptr_t)(&__exidx_start);
- info.arm_section_length = (uintptr_t)(&__exidx_end - &__exidx_start);
+ info.arm_section_length = (uintptr_t)length;
#endif
_LIBUNWIND_TRACE_UNWINDING("findUnwindSections: section %X length %x\n",
info.arm_section, info.arm_section_length);
if (info.arm_section && info.arm_section_length)
return true;
+#elif _LIBUNWIND_SUPPORT_DWARF_UNWIND
+#if _LIBUNWIND_SUPPORT_DWARF_INDEX
+ struct dl_iterate_cb_data {
+ LocalAddressSpace *addressSpace;
+ UnwindInfoSections *sects;
+ uintptr_t targetAddr;
+ };
+
+ dl_iterate_cb_data cb_data = {this, &info, targetAddr};
+ int found = dl_iterate_phdr(
+ [](struct dl_phdr_info *pinfo, size_t, void *data) -> int {
+ auto cbdata = static_cast<dl_iterate_cb_data *>(data);
+ size_t object_length;
+ bool found_obj = false;
+ bool found_hdr = false;
+
+ assert(cbdata);
+ assert(cbdata->sects);
+
+ if (cbdata->targetAddr < pinfo->dlpi_addr) {
+ return false;
+ }
+
+ for (ElfW(Half) i = 0; i < pinfo->dlpi_phnum; i++) {
+ const ElfW(Phdr) *phdr = &pinfo->dlpi_phdr[i];
+ if (phdr->p_type == PT_LOAD) {
+ uintptr_t begin = pinfo->dlpi_addr + phdr->p_vaddr;
+ uintptr_t end = begin + phdr->p_memsz;
+ if (cbdata->targetAddr >= begin && cbdata->targetAddr < end) {
+ cbdata->sects->dso_base = begin;
+ object_length = phdr->p_memsz;
+ found_obj = true;
+ }
+ } else if (phdr->p_type == PT_GNU_EH_FRAME) {
+ EHHeaderParser<LocalAddressSpace>::EHHeaderInfo hdrInfo;
+ uintptr_t eh_frame_hdr_start = pinfo->dlpi_addr + phdr->p_vaddr;
+ cbdata->sects->dwarf_index_section = eh_frame_hdr_start;
+ cbdata->sects->dwarf_index_section_length = phdr->p_memsz;
+ EHHeaderParser<LocalAddressSpace>::decodeEHHdr(
+ *cbdata->addressSpace, eh_frame_hdr_start, phdr->p_memsz,
+ hdrInfo);
+ cbdata->sects->dwarf_section = hdrInfo.eh_frame_ptr;
+ found_hdr = true;
+ }
+ }
+
+ if (found_obj && found_hdr) {
+ cbdata->sects->dwarf_section_length = object_length;
+ return true;
+ } else {
+ return false;
+ }
+ },
+ &cb_data);
+ return static_cast<bool>(found);
+#else
+#error "_LIBUNWIND_SUPPORT_DWARF_UNWIND requires _LIBUNWIND_SUPPORT_DWARF_INDEX on this platform."
+#endif
#endif
return false;
@@ -373,10 +454,12 @@
inline bool LocalAddressSpace::findOtherFDE(pint_t targetAddr, pint_t &fde) {
-#if __APPLE__
+#ifdef __APPLE__
return checkKeyMgrRegisteredFDEs(targetAddr, *((void**)&fde));
#else
// TO DO: if OS has way to dynamically register FDEs, check that.
+ (void)targetAddr;
+ (void)fde;
return false;
#endif
}
@@ -384,11 +467,11 @@
inline bool LocalAddressSpace::findFunctionName(pint_t addr, char *buf,
size_t bufLen,
unw_word_t *offset) {
-#if !_LIBUNWIND_IS_BAREMETAL
+#ifndef _LIBUNWIND_IS_BAREMETAL
Dl_info dyldInfo;
if (dladdr((void *)addr, &dyldInfo)) {
if (dyldInfo.dli_sname != NULL) {
- strlcpy(buf, dyldInfo.dli_sname, bufLen);
+ snprintf(buf, bufLen, "%s", dyldInfo.dli_sname);
*offset = (addr - (pint_t) dyldInfo.dli_saddr);
return true;
}
@@ -399,7 +482,7 @@
-#if UNW_REMOTE
+#ifdef UNW_REMOTE
/// OtherAddressSpace is used as a template parameter to UnwindCursor when
/// unwinding a thread in the another process. The other process can be a
@@ -419,7 +502,8 @@
pint_t getP(pint_t addr);
uint64_t getULEB128(pint_t &addr, pint_t end);
int64_t getSLEB128(pint_t &addr, pint_t end);
- pint_t getEncodedP(pint_t &addr, pint_t end, uint8_t encoding);
+ pint_t getEncodedP(pint_t &addr, pint_t end, uint8_t encoding,
+ pint_t datarelBase = 0);
bool findFunctionName(pint_t addr, char *buf, size_t bufLen,
unw_word_t *offset);
bool findUnwindSections(pint_t targetAddr, UnwindInfoSections &info);
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/CompactUnwinder.hpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/CompactUnwinder.hpp
index 0dc187f..cd9ce3e 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/CompactUnwinder.hpp
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/CompactUnwinder.hpp
@@ -688,6 +688,6 @@
}
-}; // namespace libunwind
+} // namespace libunwind
#endif // __COMPACT_UNWINDER_HPP__
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/DwarfInstructions.hpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/DwarfInstructions.hpp
index dbce2e8..99737e0 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/DwarfInstructions.hpp
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/DwarfInstructions.hpp
@@ -156,11 +156,11 @@
pint_t fdeStart, R ®isters) {
FDE_Info fdeInfo;
CIE_Info cieInfo;
- if (CFI_Parser<A>::decodeFDE(addressSpace, fdeStart,
- &fdeInfo, &cieInfo) == NULL) {
+ if (CFI_Parser<A>::decodeFDE(addressSpace, fdeStart, &fdeInfo,
+ &cieInfo) == NULL) {
PrologInfo prolog;
if (CFI_Parser<A>::parseFDEInstructions(addressSpace, fdeInfo, cieInfo, pc,
- &prolog)) {
+ &prolog)) {
// get pointer to cfa (architecture specific)
pint_t cfa = getCFA(addressSpace, prolog, registers);
@@ -168,10 +168,10 @@
R newRegisters = registers;
pint_t returnAddress = 0;
const int lastReg = R::lastDwarfRegNum();
- assert((int)CFI_Parser<A>::kMaxRegisterNumber > lastReg
- && "register range too large");
- assert(lastReg <= (int)cieInfo.returnAddressRegister
- && "register range does not contain return address register");
+ assert((int)CFI_Parser<A>::kMaxRegisterNumber > lastReg &&
+ "register range too large");
+ assert(lastReg <= (int)cieInfo.returnAddressRegister &&
+ "register range does not contain return address register");
for (int i = 0; i <= lastReg; ++i) {
if (prolog.savedRegisters[i].location !=
CFI_Parser<A>::kRegisterUnused) {
@@ -223,7 +223,8 @@
pint_t length = (pint_t)addressSpace.getULEB128(p, expressionEnd);
expressionEnd = p + length;
if (log)
- fprintf(stderr, "evaluateExpression(): length=%llu\n", (uint64_t)length);
+ fprintf(stderr, "evaluateExpression(): length=%" PRIu64 "\n",
+ (uint64_t)length);
pint_t stack[100];
pint_t *sp = stack;
*(++sp) = initialStackValue;
@@ -231,7 +232,7 @@
while (p < expressionEnd) {
if (log) {
for (pint_t *t = sp; t > stack; --t) {
- fprintf(stderr, "sp[] = 0x%llX\n", (uint64_t)(*t));
+ fprintf(stderr, "sp[] = 0x%" PRIx64 "\n", (uint64_t)(*t));
}
}
uint8_t opcode = addressSpace.get8(p++);
@@ -245,7 +246,7 @@
p += sizeof(pint_t);
*(++sp) = value;
if (log)
- fprintf(stderr, "push 0x%llX\n", (uint64_t) value);
+ fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value);
break;
case DW_OP_deref:
@@ -253,7 +254,7 @@
value = *sp--;
*(++sp) = addressSpace.getP(value);
if (log)
- fprintf(stderr, "dereference 0x%llX\n", (uint64_t) value);
+ fprintf(stderr, "dereference 0x%" PRIx64 "\n", (uint64_t)value);
break;
case DW_OP_const1u:
@@ -262,7 +263,7 @@
p += 1;
*(++sp) = value;
if (log)
- fprintf(stderr, "push 0x%llX\n", (uint64_t) value);
+ fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value);
break;
case DW_OP_const1s:
@@ -271,7 +272,7 @@
p += 1;
*(++sp) = (pint_t)svalue;
if (log)
- fprintf(stderr, "push 0x%llX\n", (uint64_t) svalue);
+ fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)svalue);
break;
case DW_OP_const2u:
@@ -280,7 +281,7 @@
p += 2;
*(++sp) = value;
if (log)
- fprintf(stderr, "push 0x%llX\n", (uint64_t) value);
+ fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value);
break;
case DW_OP_const2s:
@@ -289,7 +290,7 @@
p += 2;
*(++sp) = (pint_t)svalue;
if (log)
- fprintf(stderr, "push 0x%llX\n", (uint64_t) svalue);
+ fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)svalue);
break;
case DW_OP_const4u:
@@ -298,7 +299,7 @@
p += 4;
*(++sp) = value;
if (log)
- fprintf(stderr, "push 0x%llX\n", (uint64_t) value);
+ fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value);
break;
case DW_OP_const4s:
@@ -307,7 +308,7 @@
p += 4;
*(++sp) = (pint_t)svalue;
if (log)
- fprintf(stderr, "push 0x%llX\n", (uint64_t) svalue);
+ fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)svalue);
break;
case DW_OP_const8u:
@@ -316,7 +317,7 @@
p += 8;
*(++sp) = value;
if (log)
- fprintf(stderr, "push 0x%llX\n", (uint64_t) value);
+ fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value);
break;
case DW_OP_const8s:
@@ -325,7 +326,7 @@
p += 8;
*(++sp) = value;
if (log)
- fprintf(stderr, "push 0x%llX\n", (uint64_t) value);
+ fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value);
break;
case DW_OP_constu:
@@ -333,7 +334,7 @@
value = (pint_t)addressSpace.getULEB128(p, expressionEnd);
*(++sp) = value;
if (log)
- fprintf(stderr, "push 0x%llX\n", (uint64_t) value);
+ fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value);
break;
case DW_OP_consts:
@@ -341,7 +342,7 @@
svalue = (sint_t)addressSpace.getSLEB128(p, expressionEnd);
*(++sp) = (pint_t)svalue;
if (log)
- fprintf(stderr, "push 0x%llX\n", (uint64_t) svalue);
+ fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)svalue);
break;
case DW_OP_dup:
@@ -401,7 +402,7 @@
value = *sp--;
*sp = *((pint_t*)value);
if (log)
- fprintf(stderr, "x-dereference 0x%llX\n", (uint64_t) value);
+ fprintf(stderr, "x-dereference 0x%" PRIx64 "\n", (uint64_t)value);
break;
case DW_OP_abs:
@@ -518,7 +519,7 @@
p += 2;
p = (pint_t)((sint_t)p + svalue);
if (log)
- fprintf(stderr, "skip %lld\n", (uint64_t) svalue);
+ fprintf(stderr, "skip %" PRIu64 "\n", (uint64_t)svalue);
break;
case DW_OP_bra:
@@ -527,7 +528,7 @@
if (*sp--)
p = (pint_t)((sint_t)p + svalue);
if (log)
- fprintf(stderr, "bra %lld\n", (uint64_t) svalue);
+ fprintf(stderr, "bra %" PRIu64 "\n", (uint64_t)svalue);
break;
case DW_OP_eq:
@@ -604,10 +605,10 @@
case DW_OP_lit29:
case DW_OP_lit30:
case DW_OP_lit31:
- value = opcode - DW_OP_lit0;
+ value = static_cast<pint_t>(opcode - DW_OP_lit0);
*(++sp) = value;
if (log)
- fprintf(stderr, "push literal 0x%llX\n", (uint64_t) value);
+ fprintf(stderr, "push literal 0x%" PRIx64 "\n", (uint64_t)value);
break;
case DW_OP_reg0:
@@ -642,17 +643,17 @@
case DW_OP_reg29:
case DW_OP_reg30:
case DW_OP_reg31:
- reg = opcode - DW_OP_reg0;
+ reg = static_cast<uint32_t>(opcode - DW_OP_reg0);
*(++sp) = registers.getRegister((int)reg);
if (log)
fprintf(stderr, "push reg %d\n", reg);
break;
case DW_OP_regx:
- reg = (uint32_t)addressSpace.getULEB128(p, expressionEnd);
+ reg = static_cast<uint32_t>(addressSpace.getULEB128(p, expressionEnd));
*(++sp) = registers.getRegister((int)reg);
if (log)
- fprintf(stderr, "push reg %d + 0x%llX\n", reg, (uint64_t) svalue);
+ fprintf(stderr, "push reg %d + 0x%" PRIx64 "\n", reg, (uint64_t)svalue);
break;
case DW_OP_breg0:
@@ -687,21 +688,21 @@
case DW_OP_breg29:
case DW_OP_breg30:
case DW_OP_breg31:
- reg = opcode - DW_OP_breg0;
+ reg = static_cast<uint32_t>(opcode - DW_OP_breg0);
svalue = (sint_t)addressSpace.getSLEB128(p, expressionEnd);
- svalue += registers.getRegister((int)reg);
+ svalue += static_cast<sint_t>(registers.getRegister((int)reg));
*(++sp) = (pint_t)(svalue);
if (log)
- fprintf(stderr, "push reg %d + 0x%llX\n", reg, (uint64_t) svalue);
+ fprintf(stderr, "push reg %d + 0x%" PRIx64 "\n", reg, (uint64_t)svalue);
break;
case DW_OP_bregx:
- reg = (uint32_t)addressSpace.getULEB128(p, expressionEnd);
+ reg = static_cast<uint32_t>(addressSpace.getULEB128(p, expressionEnd));
svalue = (sint_t)addressSpace.getSLEB128(p, expressionEnd);
- svalue += registers.getRegister((int)reg);
+ svalue += static_cast<sint_t>(registers.getRegister((int)reg));
*(++sp) = (pint_t)(svalue);
if (log)
- fprintf(stderr, "push reg %d + 0x%llX\n", reg, (uint64_t) svalue);
+ fprintf(stderr, "push reg %d + 0x%" PRIx64 "\n", reg, (uint64_t)svalue);
break;
case DW_OP_fbreg:
@@ -733,7 +734,7 @@
}
*(++sp) = value;
if (log)
- fprintf(stderr, "sized dereference 0x%llX\n", (uint64_t) value);
+ fprintf(stderr, "sized dereference 0x%" PRIx64 "\n", (uint64_t)value);
break;
case DW_OP_xderef_size:
@@ -748,7 +749,7 @@
}
if (log)
- fprintf(stderr, "expression evaluates to 0x%llX\n", (uint64_t) * sp);
+ fprintf(stderr, "expression evaluates to 0x%" PRIx64 "\n", (uint64_t)*sp);
return *sp;
}
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/DwarfParser.hpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/DwarfParser.hpp
index 2ba0c9c..f6ef738 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/DwarfParser.hpp
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/DwarfParser.hpp
@@ -13,6 +13,7 @@
#ifndef __DWARF_PARSER_HPP__
#define __DWARF_PARSER_HPP__
+#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@@ -346,7 +347,7 @@
const CIE_Info &cieInfo, pint_t upToPC,
PrologInfo *results) {
// clear results
- bzero(results, sizeof(PrologInfo));
+ memset(results, '\0', sizeof(PrologInfo));
PrologInfoStackEntry *rememberStack = NULL;
// parse CIE then FDE instructions
@@ -370,8 +371,8 @@
pint_t codeOffset = 0;
PrologInfo initialState = *results;
if (logDwarf)
- fprintf(stderr, "parseInstructions(instructions=0x%0llX)\n",
- (uint64_t) instructionsEnd);
+ fprintf(stderr, "parseInstructions(instructions=0x%0" PRIx64 ")\n",
+ (uint64_t)instructionsEnd);
// see Dwarf Spec, section 6.4.2 for details on unwind opcodes
while ((p < instructionsEnd) && (codeOffset < pcoffset)) {
@@ -398,22 +399,22 @@
codeOffset += (addressSpace.get8(p) * cieInfo.codeAlignFactor);
p += 1;
if (logDwarf)
- fprintf(stderr, "DW_CFA_advance_loc1: new offset=%llu\n",
- (uint64_t)codeOffset);
+ fprintf(stderr, "DW_CFA_advance_loc1: new offset=%" PRIu64 "\n",
+ (uint64_t)codeOffset);
break;
case DW_CFA_advance_loc2:
codeOffset += (addressSpace.get16(p) * cieInfo.codeAlignFactor);
p += 2;
if (logDwarf)
- fprintf(stderr, "DW_CFA_advance_loc2: new offset=%llu\n",
- (uint64_t)codeOffset);
+ fprintf(stderr, "DW_CFA_advance_loc2: new offset=%" PRIu64 "\n",
+ (uint64_t)codeOffset);
break;
case DW_CFA_advance_loc4:
codeOffset += (addressSpace.get32(p) * cieInfo.codeAlignFactor);
p += 4;
if (logDwarf)
- fprintf(stderr, "DW_CFA_advance_loc4: new offset=%llu\n",
- (uint64_t)codeOffset);
+ fprintf(stderr, "DW_CFA_advance_loc4: new offset=%" PRIu64 "\n",
+ (uint64_t)codeOffset);
break;
case DW_CFA_offset_extended:
reg = addressSpace.getULEB128(p, instructionsEnd);
@@ -427,8 +428,9 @@
results->savedRegisters[reg].location = kRegisterInCFA;
results->savedRegisters[reg].value = offset;
if (logDwarf)
- fprintf(stderr, "DW_CFA_offset_extended(reg=%lld, offset=%lld)\n", reg,
- offset);
+ fprintf(stderr,
+ "DW_CFA_offset_extended(reg=%" PRIu64 ", offset=%" PRId64 ")\n",
+ reg, offset);
break;
case DW_CFA_restore_extended:
reg = addressSpace.getULEB128(p, instructionsEnd);
@@ -441,7 +443,7 @@
}
results->savedRegisters[reg] = initialState.savedRegisters[reg];
if (logDwarf)
- fprintf(stderr, "DW_CFA_restore_extended(reg=%lld)\n", reg);
+ fprintf(stderr, "DW_CFA_restore_extended(reg=%" PRIu64 ")\n", reg);
break;
case DW_CFA_undefined:
reg = addressSpace.getULEB128(p, instructionsEnd);
@@ -452,7 +454,7 @@
}
results->savedRegisters[reg].location = kRegisterUnused;
if (logDwarf)
- fprintf(stderr, "DW_CFA_undefined(reg=%lld)\n", reg);
+ fprintf(stderr, "DW_CFA_undefined(reg=%" PRIu64 ")\n", reg);
break;
case DW_CFA_same_value:
reg = addressSpace.getULEB128(p, instructionsEnd);
@@ -469,7 +471,7 @@
// set flag to disable conversion to compact unwind
results->sameValueUsed = true;
if (logDwarf)
- fprintf(stderr, "DW_CFA_same_value(reg=%lld)\n", reg);
+ fprintf(stderr, "DW_CFA_same_value(reg=%" PRIu64 ")\n", reg);
break;
case DW_CFA_register:
reg = addressSpace.getULEB128(p, instructionsEnd);
@@ -489,7 +491,8 @@
// set flag to disable conversion to compact unwind
results->registersInOtherRegisters = true;
if (logDwarf)
- fprintf(stderr, "DW_CFA_register(reg=%lld, reg2=%lld)\n", reg, reg2);
+ fprintf(stderr, "DW_CFA_register(reg=%" PRIu64 ", reg2=%" PRIu64 ")\n",
+ reg, reg2);
break;
case DW_CFA_remember_state:
// avoid operator new, because that would be an upward dependency
@@ -526,7 +529,8 @@
results->cfaRegister = (uint32_t)reg;
results->cfaRegisterOffset = (int32_t)offset;
if (logDwarf)
- fprintf(stderr, "DW_CFA_def_cfa(reg=%lld, offset=%lld)\n", reg, offset);
+ fprintf(stderr, "DW_CFA_def_cfa(reg=%" PRIu64 ", offset=%" PRIu64 ")\n",
+ reg, offset);
break;
case DW_CFA_def_cfa_register:
reg = addressSpace.getULEB128(p, instructionsEnd);
@@ -538,7 +542,7 @@
}
results->cfaRegister = (uint32_t)reg;
if (logDwarf)
- fprintf(stderr, "DW_CFA_def_cfa_register(%lld)\n", reg);
+ fprintf(stderr, "DW_CFA_def_cfa_register(%" PRIu64 ")\n", reg);
break;
case DW_CFA_def_cfa_offset:
results->cfaRegisterOffset = (int32_t)
@@ -554,8 +558,8 @@
length = addressSpace.getULEB128(p, instructionsEnd);
p += length;
if (logDwarf)
- fprintf(stderr,
- "DW_CFA_def_cfa_expression(expression=0x%llX, length=%llu)\n",
+ fprintf(stderr, "DW_CFA_def_cfa_expression(expression=0x%" PRIx64
+ ", length=%" PRIu64 ")\n",
results->cfaExpression, length);
break;
case DW_CFA_expression:
@@ -570,8 +574,8 @@
length = addressSpace.getULEB128(p, instructionsEnd);
p += length;
if (logDwarf)
- fprintf(stderr,
- "DW_CFA_expression(reg=%lld, expression=0x%llX, length=%llu)\n",
+ fprintf(stderr, "DW_CFA_expression(reg=%" PRIu64
+ ", expression=0x%" PRIx64 ", length=%" PRIu64 ")\n",
reg, results->savedRegisters[reg].value, length);
break;
case DW_CFA_offset_extended_sf:
@@ -587,7 +591,8 @@
results->savedRegisters[reg].location = kRegisterInCFA;
results->savedRegisters[reg].value = offset;
if (logDwarf)
- fprintf(stderr, "DW_CFA_offset_extended_sf(reg=%lld, offset=%lld)\n",
+ fprintf(stderr, "DW_CFA_offset_extended_sf(reg=%" PRIu64
+ ", offset=%" PRId64 ")\n",
reg, offset);
break;
case DW_CFA_def_cfa_sf:
@@ -602,7 +607,8 @@
results->cfaRegister = (uint32_t)reg;
results->cfaRegisterOffset = (int32_t)offset;
if (logDwarf)
- fprintf(stderr, "DW_CFA_def_cfa_sf(reg=%lld, offset=%lld)\n", reg,
+ fprintf(stderr,
+ "DW_CFA_def_cfa_sf(reg=%" PRIu64 ", offset=%" PRId64 ")\n", reg,
offset);
break;
case DW_CFA_def_cfa_offset_sf:
@@ -620,7 +626,8 @@
results->savedRegisters[reg].location = kRegisterOffsetFromCFA;
results->savedRegisters[reg].value = offset;
if (logDwarf)
- fprintf(stderr, "DW_CFA_val_offset(reg=%lld, offset=%lld\n", reg,
+ fprintf(stderr,
+ "DW_CFA_val_offset(reg=%" PRIu64 ", offset=%" PRId64 "\n", reg,
offset);
break;
case DW_CFA_val_offset_sf:
@@ -635,8 +642,9 @@
results->savedRegisters[reg].location = kRegisterOffsetFromCFA;
results->savedRegisters[reg].value = offset;
if (logDwarf)
- fprintf(stderr, "DW_CFA_val_offset_sf(reg=%lld, offset=%lld\n", reg,
- offset);
+ fprintf(stderr,
+ "DW_CFA_val_offset_sf(reg=%" PRIu64 ", offset=%" PRId64 "\n",
+ reg, offset);
break;
case DW_CFA_val_expression:
reg = addressSpace.getULEB128(p, instructionsEnd);
@@ -650,16 +658,15 @@
length = addressSpace.getULEB128(p, instructionsEnd);
p += length;
if (logDwarf)
- fprintf(
- stderr,
- "DW_CFA_val_expression(reg=%lld, expression=0x%llX, length=%lld)\n",
- reg, results->savedRegisters[reg].value, length);
+ fprintf(stderr, "DW_CFA_val_expression(reg=%" PRIu64
+ ", expression=0x%" PRIx64 ", length=%" PRIu64 ")\n",
+ reg, results->savedRegisters[reg].value, length);
break;
case DW_CFA_GNU_args_size:
length = addressSpace.getULEB128(p, instructionsEnd);
results->spExtraArgSize = (uint32_t)length;
if (logDwarf)
- fprintf(stderr, "DW_CFA_GNU_args_size(%lld)\n", length);
+ fprintf(stderr, "DW_CFA_GNU_args_size(%" PRIu64 ")\n", length);
break;
case DW_CFA_GNU_negative_offset_extended:
reg = addressSpace.getULEB128(p, instructionsEnd);
@@ -673,7 +680,8 @@
results->savedRegisters[reg].location = kRegisterInCFA;
results->savedRegisters[reg].value = -offset;
if (logDwarf)
- fprintf(stderr, "DW_CFA_GNU_negative_offset_extended(%lld)\n", offset);
+ fprintf(stderr, "DW_CFA_GNU_negative_offset_extended(%" PRId64 ")\n",
+ offset);
break;
default:
operand = opcode & 0x3F;
@@ -685,20 +693,20 @@
results->savedRegisters[reg].location = kRegisterInCFA;
results->savedRegisters[reg].value = offset;
if (logDwarf)
- fprintf(stderr, "DW_CFA_offset(reg=%d, offset=%lld)\n", operand,
- offset);
+ fprintf(stderr, "DW_CFA_offset(reg=%d, offset=%" PRId64 ")\n",
+ operand, offset);
break;
case DW_CFA_advance_loc:
codeOffset += operand * cieInfo.codeAlignFactor;
if (logDwarf)
- fprintf(stderr, "DW_CFA_advance_loc: new offset=%llu\n",
- (uint64_t)codeOffset);
+ fprintf(stderr, "DW_CFA_advance_loc: new offset=%" PRIu64 "\n",
+ (uint64_t)codeOffset);
break;
case DW_CFA_restore:
reg = operand;
results->savedRegisters[reg] = initialState.savedRegisters[reg];
if (logDwarf)
- fprintf(stderr, "DW_CFA_restore(reg=%lld)\n", reg);
+ fprintf(stderr, "DW_CFA_restore(reg=%" PRIu64 ")\n", reg);
break;
default:
if (logDwarf)
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/EHHeaderParser.hpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/EHHeaderParser.hpp
new file mode 100644
index 0000000..7945c7b
--- /dev/null
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/EHHeaderParser.hpp
@@ -0,0 +1,161 @@
+//===------------------------- EHHeaderParser.hpp -------------------------===//
+//
+// 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.
+//
+//
+// Parses ELF .eh_frame_hdr sections.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __EHHEADERPARSER_HPP__
+#define __EHHEADERPARSER_HPP__
+
+#include "libunwind.h"
+
+#include "AddressSpace.hpp"
+#include "DwarfParser.hpp"
+
+namespace libunwind {
+
+/// \brief EHHeaderParser does basic parsing of an ELF .eh_frame_hdr section.
+///
+/// See DWARF spec for details:
+/// http://refspecs.linuxbase.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html
+///
+template <typename A> class EHHeaderParser {
+public:
+ typedef typename A::pint_t pint_t;
+
+ /// Information encoded in the EH frame header.
+ struct EHHeaderInfo {
+ pint_t eh_frame_ptr;
+ size_t fde_count;
+ pint_t table;
+ uint8_t table_enc;
+ };
+
+ static void decodeEHHdr(A &addressSpace, pint_t ehHdrStart, pint_t ehHdrEnd,
+ EHHeaderInfo &ehHdrInfo);
+ static bool findFDE(A &addressSpace, pint_t pc, pint_t ehHdrStart,
+ uint32_t sectionLength,
+ typename CFI_Parser<A>::FDE_Info *fdeInfo,
+ typename CFI_Parser<A>::CIE_Info *cieInfo);
+
+private:
+ static bool decodeTableEntry(A &addressSpace, pint_t &tableEntry,
+ pint_t ehHdrStart, pint_t ehHdrEnd,
+ uint8_t tableEnc,
+ typename CFI_Parser<A>::FDE_Info *fdeInfo,
+ typename CFI_Parser<A>::CIE_Info *cieInfo);
+ static size_t getTableEntrySize(uint8_t tableEnc);
+};
+
+template <typename A>
+void EHHeaderParser<A>::decodeEHHdr(A &addressSpace, pint_t ehHdrStart,
+ pint_t ehHdrEnd, EHHeaderInfo &ehHdrInfo) {
+ pint_t p = ehHdrStart;
+ uint8_t version = addressSpace.get8(p++);
+ if (version != 1)
+ _LIBUNWIND_ABORT("Unsupported .eh_frame_hdr version");
+
+ uint8_t eh_frame_ptr_enc = addressSpace.get8(p++);
+ uint8_t fde_count_enc = addressSpace.get8(p++);
+ ehHdrInfo.table_enc = addressSpace.get8(p++);
+
+ ehHdrInfo.eh_frame_ptr =
+ addressSpace.getEncodedP(p, ehHdrEnd, eh_frame_ptr_enc, ehHdrStart);
+ ehHdrInfo.fde_count =
+ addressSpace.getEncodedP(p, ehHdrEnd, fde_count_enc, ehHdrStart);
+ ehHdrInfo.table = p;
+}
+
+template <typename A>
+bool EHHeaderParser<A>::decodeTableEntry(
+ A &addressSpace, pint_t &tableEntry, pint_t ehHdrStart, pint_t ehHdrEnd,
+ uint8_t tableEnc, typename CFI_Parser<A>::FDE_Info *fdeInfo,
+ typename CFI_Parser<A>::CIE_Info *cieInfo) {
+ // Have to decode the whole FDE for the PC range anyway, so just throw away
+ // the PC start.
+ addressSpace.getEncodedP(tableEntry, ehHdrEnd, tableEnc, ehHdrStart);
+ pint_t fde =
+ addressSpace.getEncodedP(tableEntry, ehHdrEnd, tableEnc, ehHdrStart);
+ const char *message =
+ CFI_Parser<A>::decodeFDE(addressSpace, fde, fdeInfo, cieInfo);
+ if (message != NULL) {
+ _LIBUNWIND_DEBUG_LOG("EHHeaderParser::decodeTableEntry: bad fde: %s\n",
+ message);
+ return false;
+ }
+
+ return true;
+}
+
+template <typename A>
+bool EHHeaderParser<A>::findFDE(A &addressSpace, pint_t pc, pint_t ehHdrStart,
+ uint32_t sectionLength,
+ typename CFI_Parser<A>::FDE_Info *fdeInfo,
+ typename CFI_Parser<A>::CIE_Info *cieInfo) {
+ pint_t ehHdrEnd = ehHdrStart + sectionLength;
+
+ EHHeaderParser<A>::EHHeaderInfo hdrInfo;
+ EHHeaderParser<A>::decodeEHHdr(addressSpace, ehHdrStart, ehHdrEnd, hdrInfo);
+
+ size_t tableEntrySize = getTableEntrySize(hdrInfo.table_enc);
+ pint_t tableEntry;
+
+ size_t low = 0;
+ for (size_t len = hdrInfo.fde_count; len > 1;) {
+ size_t mid = low + (len / 2);
+ tableEntry = hdrInfo.table + mid * tableEntrySize;
+ pint_t start = addressSpace.getEncodedP(tableEntry, ehHdrEnd,
+ hdrInfo.table_enc, ehHdrStart);
+
+ if (start == pc) {
+ low = mid;
+ break;
+ } else if (start < pc) {
+ low = mid;
+ len -= (len / 2);
+ } else {
+ len /= 2;
+ }
+ }
+
+ tableEntry = hdrInfo.table + low * tableEntrySize;
+ if (decodeTableEntry(addressSpace, tableEntry, ehHdrStart, ehHdrEnd,
+ hdrInfo.table_enc, fdeInfo, cieInfo)) {
+ if (pc >= fdeInfo->pcStart && pc < fdeInfo->pcEnd)
+ return true;
+ }
+
+ return false;
+}
+
+template <typename A>
+size_t EHHeaderParser<A>::getTableEntrySize(uint8_t tableEnc) {
+ switch (tableEnc & 0x0f) {
+ case DW_EH_PE_sdata2:
+ case DW_EH_PE_udata2:
+ return 4;
+ case DW_EH_PE_sdata4:
+ case DW_EH_PE_udata4:
+ return 8;
+ case DW_EH_PE_sdata8:
+ case DW_EH_PE_udata8:
+ return 16;
+ case DW_EH_PE_sleb128:
+ case DW_EH_PE_uleb128:
+ _LIBUNWIND_ABORT("Can't binary search on variable length encoded data.");
+ case DW_EH_PE_omit:
+ return 0;
+ default:
+ _LIBUNWIND_ABORT("Unknown DWARF encoding for search table.");
+ }
+}
+
+}
+
+#endif
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/Registers.hpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/Registers.hpp
index 8c1acfc..4a441b7 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/Registers.hpp
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/Registers.hpp
@@ -89,7 +89,7 @@
inline Registers_x86::Registers_x86(const void *registers) {
static_assert(sizeof(Registers_x86) < sizeof(unw_context_t),
"x86 registers do not fit into unw_context_t");
- _registers = *((GPRs *)registers);
+ memcpy(&_registers, registers, sizeof(_registers));
}
inline Registers_x86::Registers_x86() {
@@ -281,7 +281,7 @@
inline Registers_x86_64::Registers_x86_64(const void *registers) {
static_assert(sizeof(Registers_x86_64) < sizeof(unw_context_t),
"x86_64 registers do not fit into unw_context_t");
- _registers = *((GPRs *)registers);
+ memcpy(&_registers, registers, sizeof(_registers));
}
inline Registers_x86_64::Registers_x86_64() {
@@ -546,9 +546,19 @@
inline Registers_ppc::Registers_ppc(const void *registers) {
static_assert(sizeof(Registers_ppc) < sizeof(unw_context_t),
"ppc registers do not fit into unw_context_t");
- _registers = *((ppc_thread_state_t *)registers);
- _floatRegisters = *((ppc_float_state_t *)((char *)registers + 160));
- memcpy(_vectorRegisters, ((char *)registers + 424), sizeof(_vectorRegisters));
+ memcpy(&_registers, static_cast<const uint8_t *>(registers),
+ sizeof(_registers));
+ static_assert(sizeof(ppc_thread_state_t) == 160,
+ "expected float register offset to be 160");
+ memcpy(&_floatRegisters,
+ static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t),
+ sizeof(_floatRegisters));
+ static_assert(sizeof(ppc_thread_state_t) + sizeof(ppc_float_state_t) == 424,
+ "expected vector register offset to be 424 bytes");
+ memcpy(_vectorRegisters,
+ static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t) +
+ sizeof(ppc_float_state_t),
+ sizeof(_vectorRegisters));
}
inline Registers_ppc::Registers_ppc() {
@@ -1065,7 +1075,10 @@
static_assert(sizeof(Registers_arm64) < sizeof(unw_context_t),
"arm64 registers do not fit into unw_context_t");
memcpy(&_registers, registers, sizeof(_registers));
- memcpy(_vectorHalfRegisters, (((char *)registers) + 0x110),
+ static_assert(sizeof(GPRs) == 0x110,
+ "expected VFP registers to be at offset 272");
+ memcpy(_vectorHalfRegisters,
+ static_cast<const uint8_t *>(registers) + sizeof(GPRs),
sizeof(_vectorHalfRegisters));
}
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/Unwind-EHABI.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/Unwind-EHABI.cpp
index f4619f0..7ebba67 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/Unwind-EHABI.cpp
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/Unwind-EHABI.cpp
@@ -10,7 +10,9 @@
//
//===----------------------------------------------------------------------===//
-#include <unwind.h>
+#include "Unwind-EHABI.h"
+
+#if LIBCXXABI_ARM_EHABI
#include <stdbool.h>
#include <stdint.h>
@@ -18,19 +20,21 @@
#include <stdlib.h>
#include <string.h>
+#include <type_traits>
+
#include "config.h"
#include "libunwind.h"
+#include "libunwind_ext.h"
#include "unwind.h"
#include "../private_typeinfo.h"
-#if LIBCXXABI_ARM_EHABI
namespace {
// Strange order: take words in order, but inside word, take from most to least
// signinficant byte.
-uint8_t getByte(uint32_t* data, size_t offset) {
- uint8_t* byteData = reinterpret_cast<uint8_t*>(data);
- return byteData[(offset & ~0x03) + (3 - (offset&0x03))];
+uint8_t getByte(const uint32_t* data, size_t offset) {
+ const uint8_t* byteData = reinterpret_cast<const uint8_t*>(data);
+ return byteData[(offset & ~(size_t)0x03) + (3 - (offset & (size_t)0x03))];
}
const char* getNextWord(const char* data, uint32_t* out) {
@@ -43,28 +47,24 @@
return data + 2;
}
-static inline uint32_t signExtendPrel31(uint32_t data) {
- return data | ((data & 0x40000000u) << 1);
-}
-
struct Descriptor {
- // See # 9.2
- typedef enum {
- SU16 = 0, // Short descriptor, 16-bit entries
- LU16 = 1, // Long descriptor, 16-bit entries
- LU32 = 3, // Long descriptor, 32-bit entries
- RESERVED0 = 4, RESERVED1 = 5, RESERVED2 = 6, RESERVED3 = 7,
- RESERVED4 = 8, RESERVED5 = 9, RESERVED6 = 10, RESERVED7 = 11,
- RESERVED8 = 12, RESERVED9 = 13, RESERVED10 = 14, RESERVED11 = 15
- } Format;
+ // See # 9.2
+ typedef enum {
+ SU16 = 0, // Short descriptor, 16-bit entries
+ LU16 = 1, // Long descriptor, 16-bit entries
+ LU32 = 3, // Long descriptor, 32-bit entries
+ RESERVED0 = 4, RESERVED1 = 5, RESERVED2 = 6, RESERVED3 = 7,
+ RESERVED4 = 8, RESERVED5 = 9, RESERVED6 = 10, RESERVED7 = 11,
+ RESERVED8 = 12, RESERVED9 = 13, RESERVED10 = 14, RESERVED11 = 15
+ } Format;
- // See # 9.2
- typedef enum {
- CLEANUP = 0x0,
- FUNC = 0x1,
- CATCH = 0x2,
- INVALID = 0x4
- } Kind;
+ // See # 9.2
+ typedef enum {
+ CLEANUP = 0x0,
+ FUNC = 0x1,
+ CATCH = 0x2,
+ INVALID = 0x4
+ } Kind;
};
_Unwind_Reason_Code ProcessDescriptors(
@@ -73,11 +73,16 @@
struct _Unwind_Context* context,
Descriptor::Format format,
const char* descriptorStart,
- int flags) {
+ uint32_t flags) {
+
// EHT is inlined in the index using compact form. No descriptors. #5
if (flags & 0x1)
return _URC_CONTINUE_UNWIND;
+ // TODO: We should check the state here, and determine whether we need to
+ // perform phase1 or phase2 unwinding.
+ (void)state;
+
const char* descriptor = descriptorStart;
uint32_t descriptorWord;
getNextWord(descriptor, &descriptorWord);
@@ -102,8 +107,8 @@
static_cast<Descriptor::Kind>((length & 0x1) | ((offset & 0x1) << 1));
// Clear off flag from last bit.
- length &= ~1;
- offset &= ~1;
+ length &= ~1u;
+ offset &= ~1u;
uintptr_t scopeStart = ucbp->pr_cache.fnstart + offset;
uintptr_t scopeEnd = scopeStart + length;
uintptr_t pc = _Unwind_GetIP(context);
@@ -126,15 +131,15 @@
if (isInScope) {
// TODO(ajwong): This is only phase1 compatible logic. Implement
// phase2.
- bool is_reference_type = landing_pad & 0x80000000;
landing_pad = signExtendPrel31(landing_pad & ~0x80000000);
if (landing_pad == 0xffffffff) {
return _URC_HANDLER_FOUND;
- } else if (landing_pad == 0xfffffffe ) {
+ } else if (landing_pad == 0xfffffffe) {
return _URC_FAILURE;
} else {
- void* matched_object;
/*
+ bool is_reference_type = landing_pad & 0x80000000;
+ void* matched_object;
if (__cxxabiv1::__cxa_type_match(
ucbp, reinterpret_cast<const std::type_info *>(landing_pad),
is_reference_type,
@@ -148,7 +153,7 @@
}
default:
_LIBUNWIND_ABORT("Invalid descriptor kind found.");
- };
+ }
getNextWord(descriptor, &descriptorWord);
}
@@ -156,30 +161,19 @@
return _URC_CONTINUE_UNWIND;
}
-_Unwind_Reason_Code unwindOneFrame(
- _Unwind_State state,
- _Unwind_Control_Block* ucbp,
- struct _Unwind_Context* context) {
+static _Unwind_Reason_Code unwindOneFrame(_Unwind_State state,
+ _Unwind_Control_Block* ucbp,
+ struct _Unwind_Context* context) {
// Read the compact model EHT entry's header # 6.3
- uint32_t* unwindingData = ucbp->pr_cache.ehtp;
- uint32_t unwindInfo = *unwindingData;
- assert((unwindInfo & 0xf0000000) == 0x80000000 && "Must be a compact entry");
+ const uint32_t* unwindingData = ucbp->pr_cache.ehtp;
+ assert((*unwindingData & 0xf0000000) == 0x80000000 && "Must be a compact entry");
Descriptor::Format format =
- static_cast<Descriptor::Format>((unwindInfo & 0x0f000000) >> 24);
+ static_cast<Descriptor::Format>((*unwindingData & 0x0f000000) >> 24);
size_t len = 0;
- size_t startOffset = 0;
- switch (format) {
- case Descriptor::SU16:
- len = 4;
- startOffset = 1;
- break;
- case Descriptor::LU16:
- case Descriptor::LU32:
- len = 4 + 4 * ((unwindInfo & 0x00ff0000) >> 16);
- startOffset = 2;
- break;
- default:
- return _URC_FAILURE;
+ size_t off = 0;
+ unwindingData = decode_eht_entry(unwindingData, &off, &len);
+ if (unwindingData == nullptr) {
+ return _URC_FAILURE;
}
// Handle descriptors before unwinding so they are processed in the context
@@ -193,7 +187,7 @@
if (result != _URC_CONTINUE_UNWIND)
return result;
- return _Unwind_VRS_Interpret(context, unwindingData, startOffset, len);
+ return _Unwind_VRS_Interpret(context, unwindingData, off, len);
}
// Generates mask discriminator for _Unwind_VRS_Pop, e.g. for _UVRSC_CORE /
@@ -205,14 +199,48 @@
// Generates mask discriminator for _Unwind_VRS_Pop, e.g. for _UVRSC_VFP /
// _UVRSD_DOUBLE.
uint32_t RegisterRange(uint8_t start, uint8_t count_minus_one) {
- return (start << 16) | (count_minus_one + 1);
+ return ((uint32_t)start << 16) | ((uint32_t)count_minus_one + 1);
}
} // end anonymous namespace
+/**
+ * Decodes an EHT entry.
+ *
+ * @param data Pointer to EHT.
+ * @param[out] off Offset from return value (in bytes) to begin interpretation.
+ * @param[out] len Number of bytes in unwind code.
+ * @return Pointer to beginning of unwind code.
+ */
+extern "C" const uint32_t*
+decode_eht_entry(const uint32_t* data, size_t* off, size_t* len) {
+ assert((*data & 0x80000000) != 0 &&
+ "decode_eht_entry() does not support user-defined personality");
+
+ // 6.3: ARM Compact Model
+ // EHT entries here correspond to the __aeabi_unwind_cpp_pr[012] PRs indeded
+ // by format:
+ Descriptor::Format format =
+ static_cast<Descriptor::Format>((*data & 0x0f000000) >> 24);
+ switch (format) {
+ case Descriptor::SU16:
+ *len = 4;
+ *off = 1;
+ break;
+ case Descriptor::LU16:
+ case Descriptor::LU32:
+ *len = 4 + 4 * ((*data & 0x00ff0000) >> 16);
+ *off = 2;
+ break;
+ default:
+ return nullptr;
+ }
+ return data;
+}
+
_Unwind_Reason_Code _Unwind_VRS_Interpret(
_Unwind_Context* context,
- uint32_t* data,
+ const uint32_t* data,
size_t offset,
size_t len) {
bool wrotePC = false;
@@ -223,20 +251,21 @@
uint32_t sp;
_Unwind_VRS_Get(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32, &sp);
if (byte & 0x40)
- sp -= ((byte & 0x3f) << 2) + 4;
+ sp -= (((uint32_t)byte & 0x3f) << 2) + 4;
else
- sp += (byte << 2) + 4;
+ sp += ((uint32_t)byte << 2) + 4;
_Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32, &sp);
} else {
switch (byte & 0xf0) {
case 0x80: {
if (offset >= len)
return _URC_FAILURE;
- uint16_t registers =
- ((byte & 0x0f) << 12) | (getByte(data, offset++) << 4);
+ uint32_t registers =
+ (((uint32_t)byte & 0x0f) << 12) |
+ (((uint32_t)getByte(data, offset++)) << 4);
if (!registers)
return _URC_FAILURE;
- if (registers & (1<<15))
+ if (registers & (1 << 15))
wrotePC = true;
_Unwind_VRS_Pop(context, _UVRSC_CORE, registers, _UVRSD_UINT32);
break;
@@ -255,7 +284,7 @@
case 0xa0: {
uint32_t registers = RegisterMask(4, byte & 0x07);
if (byte & 0x08)
- registers |= 1<<14;
+ registers |= 1 << 14;
_Unwind_VRS_Pop(context, _UVRSC_CORE, registers, _UVRSD_UINT32);
break;
}
@@ -297,7 +326,8 @@
case 0xb3: {
uint8_t v = getByte(data, offset++);
_Unwind_VRS_Pop(context, _UVRSC_VFP,
- RegisterRange(v >> 4, v & 0x0f), _UVRSD_VFPX);
+ RegisterRange(static_cast<uint8_t>(v >> 4),
+ v & 0x0f), _UVRSD_VFPX);
break;
}
case 0xb4:
@@ -325,7 +355,7 @@
break;
case 0xc6: {
uint8_t v = getByte(data, offset++);
- uint8_t start = v >> 4;
+ uint8_t start = static_cast<uint8_t>(v >> 4);
uint8_t count_minus_one = v & 0xf;
if (start + count_minus_one >= 16)
return _URC_FAILURE;
@@ -344,7 +374,8 @@
case 0xc8:
case 0xc9: {
uint8_t v = getByte(data, offset++);
- uint8_t start = ((byte == 0xc8) ? 16 : 0) + (v >> 4);
+ uint8_t start =
+ static_cast<uint8_t>(((byte == 0xc8) ? 16 : 0) + (v >> 4));
uint8_t count_minus_one = v & 0xf;
if (start + count_minus_one >= 32)
return _URC_FAILURE;
@@ -418,41 +449,42 @@
int stepResult = unw_step(&cursor1);
if (stepResult == 0) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): unw_step() reached "
- "bottom => _URC_END_OF_STACK\n",
- exception_object);
+ "bottom => _URC_END_OF_STACK\n",
+ static_cast<void *>(exception_object));
return _URC_END_OF_STACK;
} else if (stepResult < 0) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): unw_step failed => "
- "_URC_FATAL_PHASE1_ERROR\n",
- exception_object);
+ "_URC_FATAL_PHASE1_ERROR\n",
+ static_cast<void *>(exception_object));
return _URC_FATAL_PHASE1_ERROR;
}
// See if frame has code to run (has personality routine).
unw_proc_info_t frameInfo;
- unw_word_t sp;
if (unw_get_proc_info(&cursor1, &frameInfo) != UNW_ESUCCESS) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): unw_get_proc_info "
- "failed => _URC_FATAL_PHASE1_ERROR\n",
- exception_object);
+ "failed => _URC_FATAL_PHASE1_ERROR\n",
+ static_cast<void *>(exception_object));
return _URC_FATAL_PHASE1_ERROR;
}
// When tracing, print state information.
if (_LIBUNWIND_TRACING_UNWINDING) {
- char functionName[512];
+ char functionBuf[512];
+ const char *functionName = functionBuf;
unw_word_t offset;
- if ((unw_get_proc_name(&cursor1, functionName, 512, &offset) !=
- UNW_ESUCCESS) || (frameInfo.start_ip + offset > frameInfo.end_ip))
- strcpy(functionName, ".anonymous.");
+ if ((unw_get_proc_name(&cursor1, functionBuf, sizeof(functionBuf),
+ &offset) != UNW_ESUCCESS) ||
+ (frameInfo.start_ip + offset > frameInfo.end_ip))
+ functionName = ".anonymous.";
unw_word_t pc;
unw_get_reg(&cursor1, UNW_REG_IP, &pc);
_LIBUNWIND_TRACE_UNWINDING(
"unwind_phase1(ex_ojb=%p): pc=0x%llX, start_ip=0x%llX, func=%s, "
"lsda=0x%llX, personality=0x%llX\n",
- exception_object, (long long)pc, (long long)frameInfo.start_ip,
- functionName, (long long)frameInfo.lsda,
- (long long)frameInfo.handler);
+ static_cast<void *>(exception_object), (long long)pc,
+ (long long)frameInfo.start_ip, functionName,
+ (long long)frameInfo.lsda, (long long)frameInfo.handler);
}
// If there is a personality routine, ask it if it will want to stop at
@@ -462,7 +494,8 @@
(__personality_routine)(long)(frameInfo.handler);
_LIBUNWIND_TRACE_UNWINDING(
"unwind_phase1(ex_ojb=%p): calling personality function %p\n",
- exception_object, p);
+ static_cast<void *>(exception_object),
+ reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(p)));
struct _Unwind_Context *context = (struct _Unwind_Context *)(&cursor1);
exception_object->pr_cache.fnstart = frameInfo.start_ip;
exception_object->pr_cache.ehtp =
@@ -471,10 +504,11 @@
_Unwind_Reason_Code personalityResult =
(*p)(_US_VIRTUAL_UNWIND_FRAME, exception_object, context);
_LIBUNWIND_TRACE_UNWINDING(
- "unwind_phase1(ex_ojb=%p): personality result %d "
- "start_ip %x ehtp %p additional %x\n",
- exception_object, personalityResult,
- exception_object->pr_cache.fnstart, exception_object->pr_cache.ehtp,
+ "unwind_phase1(ex_ojb=%p): personality result %d start_ip %x ehtp %p "
+ "additional %x\n",
+ static_cast<void *>(exception_object), personalityResult,
+ exception_object->pr_cache.fnstart,
+ static_cast<void *>(exception_object->pr_cache.ehtp),
exception_object->pr_cache.additional);
switch (personalityResult) {
case _URC_HANDLER_FOUND:
@@ -482,15 +516,15 @@
// stop search and remember stack pointer at the frame
handlerNotFound = false;
// p should have initialized barrier_cache. EHABI #7.3.5
- _LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): "
- "_URC_HANDLER_FOUND \n",
- exception_object);
+ _LIBUNWIND_TRACE_UNWINDING(
+ "unwind_phase1(ex_ojb=%p): _URC_HANDLER_FOUND \n",
+ static_cast<void *>(exception_object));
return _URC_NO_REASON;
case _URC_CONTINUE_UNWIND:
_LIBUNWIND_TRACE_UNWINDING(
"unwind_phase1(ex_ojb=%p): _URC_CONTINUE_UNWIND\n",
- exception_object);
+ static_cast<void *>(exception_object));
// continue unwinding
break;
@@ -502,7 +536,7 @@
// something went wrong
_LIBUNWIND_TRACE_UNWINDING(
"unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR\n",
- exception_object);
+ static_cast<void *>(exception_object));
return _URC_FATAL_PHASE1_ERROR;
}
}
@@ -517,7 +551,8 @@
unw_cursor_t cursor2;
unw_init_local(&cursor2, uc);
- _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)\n", exception_object);
+ _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)\n",
+ static_cast<void *>(exception_object));
int frame_count = 0;
// Walk each frame until we reach where search phase said to stop.
@@ -544,13 +579,13 @@
int stepResult = unw_step(&cursor2);
if (stepResult == 0) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_step() reached "
- "bottom => _URC_END_OF_STACK\n",
- exception_object);
+ "bottom => _URC_END_OF_STACK\n",
+ static_cast<void *>(exception_object));
return _URC_END_OF_STACK;
} else if (stepResult < 0) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_step failed => "
- "_URC_FATAL_PHASE1_ERROR\n",
- exception_object);
+ "_URC_FATAL_PHASE1_ERROR\n",
+ static_cast<void *>(exception_object));
return _URC_FATAL_PHASE2_ERROR;
}
@@ -560,23 +595,25 @@
unw_get_reg(&cursor2, UNW_REG_SP, &sp);
if (unw_get_proc_info(&cursor2, &frameInfo) != UNW_ESUCCESS) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_get_proc_info "
- "failed => _URC_FATAL_PHASE1_ERROR\n",
- exception_object);
+ "failed => _URC_FATAL_PHASE1_ERROR\n",
+ static_cast<void *>(exception_object));
return _URC_FATAL_PHASE2_ERROR;
}
// When tracing, print state information.
if (_LIBUNWIND_TRACING_UNWINDING) {
- char functionName[512];
+ char functionBuf[512];
+ const char *functionName = functionBuf;
unw_word_t offset;
- if ((unw_get_proc_name(&cursor2, functionName, 512, &offset) !=
- UNW_ESUCCESS) || (frameInfo.start_ip + offset > frameInfo.end_ip))
- strcpy(functionName, ".anonymous.");
+ if ((unw_get_proc_name(&cursor2, functionBuf, sizeof(functionBuf),
+ &offset) != UNW_ESUCCESS) ||
+ (frameInfo.start_ip + offset > frameInfo.end_ip))
+ functionName = ".anonymous.";
_LIBUNWIND_TRACE_UNWINDING(
"unwind_phase2(ex_ojb=%p): start_ip=0x%llX, func=%s, sp=0x%llX, "
"lsda=0x%llX, personality=0x%llX\n",
- exception_object, (long long)frameInfo.start_ip, functionName,
- (long long)sp, (long long)frameInfo.lsda,
+ static_cast<void *>(exception_object), (long long)frameInfo.start_ip,
+ functionName, (long long)sp, (long long)frameInfo.lsda,
(long long)frameInfo.handler);
}
@@ -597,7 +634,7 @@
// Continue unwinding
_LIBUNWIND_TRACE_UNWINDING(
"unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND\n",
- exception_object);
+ static_cast<void *>(exception_object));
// EHABI #7.2
if (sp == exception_object->barrier_cache.sp) {
// Phase 1 said we would stop at this frame, but we did not...
@@ -608,17 +645,17 @@
case _URC_INSTALL_CONTEXT:
_LIBUNWIND_TRACE_UNWINDING(
"unwind_phase2(ex_ojb=%p): _URC_INSTALL_CONTEXT\n",
- exception_object);
+ static_cast<void *>(exception_object));
// Personality routine says to transfer control to landing pad.
// We may get control back if landing pad calls _Unwind_Resume().
if (_LIBUNWIND_TRACING_UNWINDING) {
unw_word_t pc;
unw_get_reg(&cursor2, UNW_REG_IP, &pc);
unw_get_reg(&cursor2, UNW_REG_SP, &sp);
- _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): re-entering "
+ _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): re-entering "
"user code with ip=0x%llX, sp=0x%llX\n",
- exception_object, (long long)pc,
- (long long)sp);
+ static_cast<void *>(exception_object),
+ (long long)pc, (long long)sp);
}
{
@@ -655,7 +692,7 @@
_LIBUNWIND_EXPORT _Unwind_Reason_Code
_Unwind_RaiseException(_Unwind_Exception *exception_object) {
_LIBUNWIND_TRACE_API("_Unwind_RaiseException(ex_obj=%p)\n",
- exception_object);
+ static_cast<void *>(exception_object));
unw_context_t uc;
unw_getcontext(&uc);
@@ -675,6 +712,7 @@
_LIBUNWIND_EXPORT void _Unwind_Complete(_Unwind_Exception* exception_object) {
// This is to be called when exception handling completes to give us a chance
// to perform any housekeeping. EHABI #7.2. But we have nothing to do here.
+ (void)exception_object;
}
/// When _Unwind_RaiseException() is in phase2, it hands control
@@ -690,7 +728,8 @@
/// in turn calls _Unwind_Resume_or_Rethrow().
_LIBUNWIND_EXPORT void
_Unwind_Resume(_Unwind_Exception *exception_object) {
- _LIBUNWIND_TRACE_API("_Unwind_Resume(ex_obj=%p)\n", exception_object);
+ _LIBUNWIND_TRACE_API("_Unwind_Resume(ex_obj=%p)\n",
+ static_cast<void *>(exception_object));
unw_context_t uc;
unw_getcontext(&uc);
@@ -711,8 +750,9 @@
uintptr_t result = 0;
if (unw_get_proc_info(cursor, &frameInfo) == UNW_ESUCCESS)
result = (uintptr_t)frameInfo.lsda;
- _LIBUNWIND_TRACE_API("_Unwind_GetLanguageSpecificData(context=%p)"
- "=> 0x%llx\n", context, (long long)result);
+ _LIBUNWIND_TRACE_API(
+ "_Unwind_GetLanguageSpecificData(context=%p) => 0x%llx\n",
+ static_cast<void *>(context), (long long)result);
if (result != 0) {
if (*((uint8_t *)result) != 0xFF)
_LIBUNWIND_DEBUG_LOG("lsda at 0x%llx does not start with 0xFF\n",
@@ -739,30 +779,29 @@
return value;
}
-_Unwind_VRS_Result _Unwind_VRS_Set(
- _Unwind_Context *context,
- _Unwind_VRS_RegClass regclass,
- uint32_t regno,
- _Unwind_VRS_DataRepresentation representation,
- void *valuep) {
+_Unwind_VRS_Result
+_Unwind_VRS_Set(_Unwind_Context *context, _Unwind_VRS_RegClass regclass,
+ uint32_t regno, _Unwind_VRS_DataRepresentation representation,
+ void *valuep) {
_LIBUNWIND_TRACE_API("_Unwind_VRS_Set(context=%p, regclass=%d, reg=%d, "
- "rep=%d, value=0x%llX)\n", context, regclass,
- regno, representation,
+ "rep=%d, value=0x%llX)\n",
+ static_cast<void *>(context), regclass, regno,
+ representation,
ValueAsBitPattern(representation, valuep));
unw_cursor_t *cursor = (unw_cursor_t *)context;
switch (regclass) {
case _UVRSC_CORE:
if (representation != _UVRSD_UINT32 || regno > 15)
return _UVRSR_FAILED;
- return unw_set_reg(cursor, UNW_ARM_R0 + regno, *(unw_word_t *)valuep) ==
- UNW_ESUCCESS
+ return unw_set_reg(cursor, (unw_regnum_t)(UNW_ARM_R0 + regno),
+ *(unw_word_t *)valuep) == UNW_ESUCCESS
? _UVRSR_OK
: _UVRSR_FAILED;
case _UVRSC_WMMXC:
if (representation != _UVRSD_UINT32 || regno > 3)
return _UVRSR_FAILED;
- return unw_set_reg(cursor, UNW_ARM_WC0 + regno, *(unw_word_t *)valuep) ==
- UNW_ESUCCESS
+ return unw_set_reg(cursor, (unw_regnum_t)(UNW_ARM_WC0 + regno),
+ *(unw_word_t *)valuep) == UNW_ESUCCESS
? _UVRSR_OK
: _UVRSR_FAILED;
case _UVRSC_VFP:
@@ -777,40 +816,40 @@
if (regno > 31)
return _UVRSR_FAILED;
}
- return unw_set_fpreg(cursor, UNW_ARM_D0 + regno,
+ return unw_set_fpreg(cursor, (unw_regnum_t)(UNW_ARM_D0 + regno),
*(unw_fpreg_t *)valuep) == UNW_ESUCCESS
? _UVRSR_OK
: _UVRSR_FAILED;
case _UVRSC_WMMXD:
if (representation != _UVRSD_DOUBLE || regno > 31)
return _UVRSR_FAILED;
- return unw_set_fpreg(cursor, UNW_ARM_WR0 + regno,
+ return unw_set_fpreg(cursor, (unw_regnum_t)(UNW_ARM_WR0 + regno),
*(unw_fpreg_t *)valuep) == UNW_ESUCCESS
? _UVRSR_OK
: _UVRSR_FAILED;
}
+ _LIBUNWIND_ABORT("unsupported register class");
}
-static _Unwind_VRS_Result _Unwind_VRS_Get_Internal(
- _Unwind_Context *context,
- _Unwind_VRS_RegClass regclass,
- uint32_t regno,
- _Unwind_VRS_DataRepresentation representation,
- void *valuep) {
+static _Unwind_VRS_Result
+_Unwind_VRS_Get_Internal(_Unwind_Context *context,
+ _Unwind_VRS_RegClass regclass, uint32_t regno,
+ _Unwind_VRS_DataRepresentation representation,
+ void *valuep) {
unw_cursor_t *cursor = (unw_cursor_t *)context;
switch (regclass) {
case _UVRSC_CORE:
if (representation != _UVRSD_UINT32 || regno > 15)
return _UVRSR_FAILED;
- return unw_get_reg(cursor, UNW_ARM_R0 + regno, (unw_word_t *)valuep) ==
- UNW_ESUCCESS
+ return unw_get_reg(cursor, (unw_regnum_t)(UNW_ARM_R0 + regno),
+ (unw_word_t *)valuep) == UNW_ESUCCESS
? _UVRSR_OK
: _UVRSR_FAILED;
case _UVRSC_WMMXC:
if (representation != _UVRSD_UINT32 || regno > 3)
return _UVRSR_FAILED;
- return unw_get_reg(cursor, UNW_ARM_WC0 + regno, (unw_word_t *)valuep) ==
- UNW_ESUCCESS
+ return unw_get_reg(cursor, (unw_regnum_t)(UNW_ARM_WC0 + regno),
+ (unw_word_t *)valuep) == UNW_ESUCCESS
? _UVRSR_OK
: _UVRSR_FAILED;
case _UVRSC_VFP:
@@ -825,18 +864,19 @@
if (regno > 31)
return _UVRSR_FAILED;
}
- return unw_get_fpreg(cursor, UNW_ARM_D0 + regno, (unw_fpreg_t *)valuep) ==
- UNW_ESUCCESS
+ return unw_get_fpreg(cursor, (unw_regnum_t)(UNW_ARM_D0 + regno),
+ (unw_fpreg_t *)valuep) == UNW_ESUCCESS
? _UVRSR_OK
: _UVRSR_FAILED;
case _UVRSC_WMMXD:
if (representation != _UVRSD_DOUBLE || regno > 31)
return _UVRSR_FAILED;
- return unw_get_fpreg(cursor, UNW_ARM_WR0 + regno,
+ return unw_get_fpreg(cursor, (unw_regnum_t)(UNW_ARM_WR0 + regno),
(unw_fpreg_t *)valuep) == UNW_ESUCCESS
? _UVRSR_OK
: _UVRSR_FAILED;
}
+ _LIBUNWIND_ABORT("unsupported register class");
}
_Unwind_VRS_Result _Unwind_VRS_Get(
@@ -850,19 +890,20 @@
valuep);
_LIBUNWIND_TRACE_API("_Unwind_VRS_Get(context=%p, regclass=%d, reg=%d, "
"rep=%d, value=0x%llX, result = %d)\n",
- context, regclass, regno, representation,
+ static_cast<void *>(context), regclass, regno,
+ representation,
ValueAsBitPattern(representation, valuep), result);
return result;
}
-_Unwind_VRS_Result _Unwind_VRS_Pop(
- _Unwind_Context *context,
- _Unwind_VRS_RegClass regclass,
- uint32_t discriminator,
- _Unwind_VRS_DataRepresentation representation) {
+_Unwind_VRS_Result
+_Unwind_VRS_Pop(_Unwind_Context *context, _Unwind_VRS_RegClass regclass,
+ uint32_t discriminator,
+ _Unwind_VRS_DataRepresentation representation) {
_LIBUNWIND_TRACE_API("_Unwind_VRS_Pop(context=%p, regclass=%d, "
"discriminator=%d, representation=%d)\n",
- context, regclass, discriminator, representation);
+ static_cast<void *>(context), regclass, discriminator,
+ representation);
switch (regclass) {
case _UVRSC_CORE:
case _UVRSC_WMMXC: {
@@ -876,8 +917,8 @@
_UVRSD_UINT32, &sp) != _UVRSR_OK) {
return _UVRSR_FAILED;
}
- for (int i = 0; i < 16; ++i) {
- if (!(discriminator & (1<<i)))
+ for (uint32_t i = 0; i < 16; ++i) {
+ if (!(discriminator & static_cast<uint32_t>(1 << i)))
continue;
uint32_t value = *sp++;
if (regclass == _UVRSC_CORE && i == 13)
@@ -920,7 +961,8 @@
return _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32,
&sp);
}
- };
+ }
+ _LIBUNWIND_ABORT("unsupported register class");
}
/// Called by personality handler during phase 2 to find the start of the
@@ -933,7 +975,7 @@
if (unw_get_proc_info(cursor, &frameInfo) == UNW_ESUCCESS)
result = (uintptr_t)frameInfo.start_ip;
_LIBUNWIND_TRACE_API("_Unwind_GetRegionStart(context=%p) => 0x%llX\n",
- context, (long long)result);
+ static_cast<void *>(context), (long long)result);
return result;
}
@@ -943,7 +985,7 @@
_LIBUNWIND_EXPORT void
_Unwind_DeleteException(_Unwind_Exception *exception_object) {
_LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)\n",
- exception_object);
+ static_cast<void *>(exception_object));
if (exception_object->exception_cleanup != NULL)
(*exception_object->exception_cleanup)(_URC_FOREIGN_EXCEPTION_CAUGHT,
exception_object);
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/Unwind-EHABI.h b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/Unwind-EHABI.h
new file mode 100644
index 0000000..ebd56a1
--- /dev/null
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/Unwind-EHABI.h
@@ -0,0 +1,51 @@
+//===------------------------- Unwind-EHABI.hpp ---------------------------===//
+//
+// 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.
+//
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __UNWIND_EHABI_H__
+#define __UNWIND_EHABI_H__
+
+#include <__cxxabi_config.h>
+
+#if LIBCXXABI_ARM_EHABI
+
+#include <stdint.h>
+#include <unwind.h>
+
+// Unable to unwind in the ARM index table (section 5 EHABI).
+#define UNW_EXIDX_CANTUNWIND 0x1
+
+static inline uint32_t signExtendPrel31(uint32_t data) {
+ return data | ((data & 0x40000000u) << 1);
+}
+
+static inline uint32_t readPrel31(const uint32_t *data) {
+ return (((uint32_t)(uintptr_t)data) + signExtendPrel31(*data));
+}
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+extern _Unwind_Reason_Code __aeabi_unwind_cpp_pr0(
+ _Unwind_State state, _Unwind_Control_Block *ucbp, _Unwind_Context *context);
+
+extern _Unwind_Reason_Code __aeabi_unwind_cpp_pr1(
+ _Unwind_State state, _Unwind_Control_Block *ucbp, _Unwind_Context *context);
+
+extern _Unwind_Reason_Code __aeabi_unwind_cpp_pr2(
+ _Unwind_State state, _Unwind_Control_Block *ucbp, _Unwind_Context *context);
+
+#if defined(__cplusplus)
+} // extern "C"
+#endif
+
+#endif // LIBCXXABI_ARM_EHABI
+
+#endif // __UNWIND_EHABI_H__
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/UnwindCursor.hpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/UnwindCursor.hpp
index d348b78..b4d413f 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/UnwindCursor.hpp
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/UnwindCursor.hpp
@@ -19,17 +19,20 @@
#include <pthread.h>
#include <unwind.h>
-#if __APPLE__
+#ifdef __APPLE__
#include <mach-o/dyld.h>
#endif
-#include "libunwind.h"
+#include "config.h"
#include "AddressSpace.hpp"
-#include "Registers.hpp"
-#include "DwarfInstructions.hpp"
#include "CompactUnwinder.hpp"
#include "config.h"
+#include "DwarfInstructions.hpp"
+#include "EHHeaderParser.hpp"
+#include "libunwind.h"
+#include "Registers.hpp"
+#include "Unwind-EHABI.h"
namespace libunwind {
@@ -58,7 +61,7 @@
// These fields are all static to avoid needing an initializer.
// There is only one instance of this class per process.
static pthread_rwlock_t _lock;
-#if __APPLE__
+#ifdef __APPLE__
static void dyldUnloadHook(const struct mach_header *mh, intptr_t slide);
static bool _registeredForDyldUnloads;
#endif
@@ -87,7 +90,7 @@
template <typename A>
pthread_rwlock_t DwarfFDECache<A>::_lock = PTHREAD_RWLOCK_INITIALIZER;
-#if __APPLE__
+#ifdef __APPLE__
template <typename A>
bool DwarfFDECache<A>::_registeredForDyldUnloads = false;
#endif
@@ -129,7 +132,7 @@
_bufferUsed->ip_end = ip_end;
_bufferUsed->fde = fde;
++_bufferUsed;
-#if __APPLE__
+#ifdef __APPLE__
if (!_registeredForDyldUnloads) {
_dyld_register_func_for_remove_image(&dyldUnloadHook);
_registeredForDyldUnloads = true;
@@ -153,7 +156,7 @@
_LIBUNWIND_LOG_NON_ZERO(::pthread_rwlock_unlock(&_lock));
}
-#if __APPLE__
+#ifdef __APPLE__
template <typename A>
void DwarfFDECache<A>::dyldUnloadHook(const struct mach_header *mh, intptr_t ) {
removeAllIn((pint_t) mh);
@@ -364,29 +367,49 @@
};
#endif // _LIBUNWIND_SUPPORT_COMPACT_UNWIND
-
class _LIBUNWIND_HIDDEN AbstractUnwindCursor {
public:
- virtual ~AbstractUnwindCursor() {}
- virtual bool validReg(int) = 0;
- virtual unw_word_t getReg(int) = 0;
- virtual void setReg(int, unw_word_t) = 0;
- virtual bool validFloatReg(int) = 0;
- virtual unw_fpreg_t getFloatReg(int) = 0;
- virtual void setFloatReg(int, unw_fpreg_t) = 0;
- virtual int step() = 0;
- virtual void getInfo(unw_proc_info_t *) = 0;
- virtual void jumpto() = 0;
- virtual bool isSignalFrame() = 0;
- virtual bool getFunctionName(char *bf, size_t ln, unw_word_t *off) = 0;
- virtual void setInfoBasedOnIPRegister(bool isReturnAddr = false) = 0;
- virtual const char *getRegisterName(int num) = 0;
-#if __arm__
- virtual void saveVFPAsX() = 0;
+ // NOTE: provide a class specific placement deallocation function (S5.3.4 p20)
+ // This avoids an unnecessary dependency to libc++abi.
+ void operator delete(void *, size_t) {}
+
+ virtual ~AbstractUnwindCursor() {}
+ virtual bool validReg(int) { _LIBUNWIND_ABORT("validReg not implemented"); }
+ virtual unw_word_t getReg(int) { _LIBUNWIND_ABORT("getReg not implemented"); }
+ virtual void setReg(int, unw_word_t) {
+ _LIBUNWIND_ABORT("setReg not implemented");
+ }
+ virtual bool validFloatReg(int) {
+ _LIBUNWIND_ABORT("validFloatReg not implemented");
+ }
+ virtual unw_fpreg_t getFloatReg(int) {
+ _LIBUNWIND_ABORT("getFloatReg not implemented");
+ }
+ virtual void setFloatReg(int, unw_fpreg_t) {
+ _LIBUNWIND_ABORT("setFloatReg not implemented");
+ }
+ virtual int step() { _LIBUNWIND_ABORT("step not implemented"); }
+ virtual void getInfo(unw_proc_info_t *) {
+ _LIBUNWIND_ABORT("getInfo not implemented");
+ }
+ virtual void jumpto() { _LIBUNWIND_ABORT("jumpto not implemented"); }
+ virtual bool isSignalFrame() {
+ _LIBUNWIND_ABORT("isSignalFrame not implemented");
+ }
+ virtual bool getFunctionName(char *, size_t, unw_word_t *) {
+ _LIBUNWIND_ABORT("getFunctionName not implemented");
+ }
+ virtual void setInfoBasedOnIPRegister(bool = false) {
+ _LIBUNWIND_ABORT("setInfoBasedOnIPRegister not implemented");
+ }
+ virtual const char *getRegisterName(int) {
+ _LIBUNWIND_ABORT("getRegisterName not implemented");
+ }
+#ifdef __arm__
+ virtual void saveVFPAsX() { _LIBUNWIND_ABORT("saveVFPAsX not implemented"); }
#endif
};
-
/// UnwindCursor contains all state (including all register values) during
/// an unwind. This is normally stack allocated inside a unw_cursor_t.
template <typename A, typename R>
@@ -409,12 +432,10 @@
virtual bool getFunctionName(char *buf, size_t len, unw_word_t *off);
virtual void setInfoBasedOnIPRegister(bool isReturnAddress = false);
virtual const char *getRegisterName(int num);
-#if __arm__
+#ifdef __arm__
virtual void saveVFPAsX();
#endif
- void operator delete(void *, size_t) {}
-
private:
#if LIBCXXABI_ARM_EHABI
@@ -584,7 +605,7 @@
_registers.jumpto();
}
-#if __arm__
+#ifdef __arm__
template <typename A, typename R> void UnwindCursor<A, R>::saveVFPAsX() {
_registers.saveVFPAsX();
}
@@ -605,20 +626,6 @@
uint32_t data;
};
-// Unable to unwind in the ARM index table (section 5 EHABI).
-#define UNW_EXIDX_CANTUNWIND 0x1
-
-static inline uint32_t signExtendPrel31(uint32_t data) {
- return data | ((data & 0x40000000u) << 1);
-}
-
-extern "C" _Unwind_Reason_Code __aeabi_unwind_cpp_pr0(
- _Unwind_State state, _Unwind_Control_Block *ucbp, _Unwind_Context *context);
-extern "C" _Unwind_Reason_Code __aeabi_unwind_cpp_pr1(
- _Unwind_State state, _Unwind_Control_Block *ucbp, _Unwind_Context *context);
-extern "C" _Unwind_Reason_Code __aeabi_unwind_cpp_pr2(
- _Unwind_State state, _Unwind_Control_Block *ucbp, _Unwind_Context *context);
-
template<typename A>
struct EHABISectionIterator {
typedef EHABISectionIterator _Self;
@@ -638,7 +645,7 @@
}
EHABISectionIterator(A& addressSpace, const UnwindInfoSections& sects, size_t i)
- : _addressSpace(&addressSpace), _sects(§s), _i(i) {}
+ : _i(i), _addressSpace(&addressSpace), _sects(§s) {}
_Self& operator++() { ++_i; return *this; }
_Self& operator+=(size_t a) { _i += a; return *this; }
@@ -730,8 +737,8 @@
// in compact form (section 6.3 EHABI).
if (exceptionTableData & 0x80000000) {
// Grab the index of the personality routine from the compact form.
- int choice = (exceptionTableData & 0x0f000000) >> 24;
- int extraWords = 0;
+ uint32_t choice = (exceptionTableData & 0x0f000000) >> 24;
+ uint32_t extraWords = 0;
switch (choice) {
case 0:
personalityRoutine = (unw_word_t) &__aeabi_unwind_cpp_pr0;
@@ -823,8 +830,9 @@
}
#if _LIBUNWIND_SUPPORT_DWARF_INDEX
if (!foundFDE && (sects.dwarf_index_section != 0)) {
- // Have eh_frame_hdr section which is index into dwarf section.
- // TO DO: implement index search
+ foundFDE = EHHeaderParser<A>::findFDE(
+ _addressSpace, pc, sects.dwarf_index_section,
+ (uint32_t)sects.dwarf_index_section_length, &fdeInfo, &cieInfo);
}
#endif
if (!foundFDE) {
@@ -1274,9 +1282,6 @@
result = this->stepWithDwarfFDE();
#elif LIBCXXABI_ARM_EHABI
result = UNW_STEP_SUCCESS;
-#elif defined(__i386__) || defined(__x86_64__) || defined(__mips__) || defined(__mips64)
- // ToDo: really?
- result = UNW_STEP_SUCCESS;
#else
#error Need _LIBUNWIND_SUPPORT_COMPACT_UNWIND or \
_LIBUNWIND_SUPPORT_DWARF_UNWIND or \
@@ -1307,6 +1312,6 @@
buf, bufLen, offset);
}
-}; // namespace libunwind
+} // namespace libunwind
#endif // __UNWINDCURSOR_HPP__
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/UnwindLevel1-gcc-ext.c b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/UnwindLevel1-gcc-ext.c
index 745c309..b1e3f77 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/UnwindLevel1-gcc-ext.c
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/UnwindLevel1-gcc-ext.c
@@ -10,27 +10,30 @@
//
//===----------------------------------------------------------------------===//
-#include <stdint.h>
+#include <inttypes.h>
#include <stdbool.h>
-#include <stdlib.h>
+#include <stdint.h>
#include <stdio.h>
+#include <stdlib.h>
-#include "libunwind.h"
-#include "unwind.h"
-#include "libunwind_ext.h"
#include "config.h"
+#include "libunwind_ext.h"
+#include "libunwind.h"
+#include "Unwind-EHABI.h"
+#include "unwind.h"
#if _LIBUNWIND_BUILD_ZERO_COST_APIS
/// Called by __cxa_rethrow().
_LIBUNWIND_EXPORT _Unwind_Reason_Code
_Unwind_Resume_or_Rethrow(_Unwind_Exception *exception_object) {
- _LIBUNWIND_TRACE_API("_Unwind_Resume_or_Rethrow(ex_obj=%p), "
- "private_1=%ld\n",
- exception_object,
#if LIBCXXABI_ARM_EHABI
+ _LIBUNWIND_TRACE_API("_Unwind_Resume_or_Rethrow(ex_obj=%p), private_1=%ld\n",
+ (void *)exception_object,
(long)exception_object->unwinder_cache.reserved1);
#else
+ _LIBUNWIND_TRACE_API("_Unwind_Resume_or_Rethrow(ex_obj=%p), private_1=%ld\n",
+ (void *)exception_object,
(long)exception_object->private_1);
#endif
@@ -62,7 +65,7 @@
_LIBUNWIND_EXPORT uintptr_t
_Unwind_GetDataRelBase(struct _Unwind_Context *context) {
(void)context;
- _LIBUNWIND_TRACE_API("_Unwind_GetDataRelBase(context=%p)\n", context);
+ _LIBUNWIND_TRACE_API("_Unwind_GetDataRelBase(context=%p)\n", (void *)context);
_LIBUNWIND_ABORT("_Unwind_GetDataRelBase() not implemented");
}
@@ -72,7 +75,7 @@
_LIBUNWIND_EXPORT uintptr_t
_Unwind_GetTextRelBase(struct _Unwind_Context *context) {
(void)context;
- _LIBUNWIND_TRACE_API("_Unwind_GetTextRelBase(context=%p)\n", context);
+ _LIBUNWIND_TRACE_API("_Unwind_GetTextRelBase(context=%p)\n", (void *)context);
_LIBUNWIND_ABORT("_Unwind_GetTextRelBase() not implemented");
}
@@ -95,7 +98,6 @@
return NULL;
}
-
/// Walk every frame and call trace function at each one. If trace function
/// returns anything other than _URC_NO_REASON, then walk is terminated.
_LIBUNWIND_EXPORT _Unwind_Reason_Code
@@ -105,10 +107,12 @@
unw_getcontext(&uc);
unw_init_local(&cursor, &uc);
- _LIBUNWIND_TRACE_API("_Unwind_Backtrace(callback=%p)\n", callback);
+ _LIBUNWIND_TRACE_API("_Unwind_Backtrace(callback=%p)\n",
+ (void *)(uintptr_t)callback);
// walk each frame
while (true) {
+ _Unwind_Reason_Code result;
// ask libuwind to get next frame (skip over first frame which is
// _Unwind_Backtrace())
@@ -119,26 +123,68 @@
return _URC_END_OF_STACK;
}
+#if LIBCXXABI_ARM_EHABI
+ // Get the information for this frame.
+ unw_proc_info_t frameInfo;
+ if (unw_get_proc_info(&cursor, &frameInfo) != UNW_ESUCCESS) {
+ return _URC_END_OF_STACK;
+ }
+
+ struct _Unwind_Context *context = (struct _Unwind_Context *)&cursor;
+ const uint32_t* unwindInfo = (uint32_t *) frameInfo.unwind_info;
+ if ((*unwindInfo & 0x80000000) == 0) {
+ // 6.2: Generic Model
+ // EHT entry is a prel31 pointing to the PR, followed by data understood
+ // only by the personality routine. Since EHABI doesn't guarantee the
+ // location or availability of the unwind opcodes in the generic model,
+ // we have to call personality functions with (_US_VIRTUAL_UNWIND_FRAME |
+ // _US_FORCE_UNWIND) state.
+
+ // Create a mock exception object for force unwinding.
+ _Unwind_Exception ex;
+ ex.exception_class = 0x434C4E47554E5700; // CLNGUNW\0
+ ex.pr_cache.fnstart = frameInfo.start_ip;
+ ex.pr_cache.ehtp = (_Unwind_EHT_Header *) unwindInfo;
+ ex.pr_cache.additional= frameInfo.flags;
+
+ // Get and call the personality function to unwind the frame.
+ __personality_routine pr = (__personality_routine) readPrel31(unwindInfo);
+ if (pr(_US_VIRTUAL_UNWIND_FRAME | _US_FORCE_UNWIND, &ex, context) !=
+ _URC_CONTINUE_UNWIND) {
+ return _URC_END_OF_STACK;
+ }
+ } else {
+ size_t off, len;
+ unwindInfo = decode_eht_entry(unwindInfo, &off, &len);
+ if (unwindInfo == NULL) {
+ return _URC_FAILURE;
+ }
+
+ result = _Unwind_VRS_Interpret(context, unwindInfo, off, len);
+ if (result != _URC_CONTINUE_UNWIND) {
+ return _URC_END_OF_STACK;
+ }
+ }
+#endif // LIBCXXABI_ARM_EHABI
+
// debugging
if (_LIBUNWIND_TRACING_UNWINDING) {
char functionName[512];
- unw_proc_info_t frameInfo;
+ unw_proc_info_t frame;
unw_word_t offset;
unw_get_proc_name(&cursor, functionName, 512, &offset);
- unw_get_proc_info(&cursor, &frameInfo);
+ unw_get_proc_info(&cursor, &frame);
_LIBUNWIND_TRACE_UNWINDING(
" _backtrace: start_ip=0x%llX, func=%s, lsda=0x%llX, context=%p\n",
- (long long)frameInfo.start_ip, functionName, (long long)frameInfo.lsda,
- &cursor);
+ (long long)frame.start_ip, functionName, (long long)frame.lsda,
+ (void *)&cursor);
}
// call trace function with this frame
- _Unwind_Reason_Code result =
- (*callback)((struct _Unwind_Context *)(&cursor), ref);
+ result = (*callback)((struct _Unwind_Context *)(&cursor), ref);
if (result != _URC_NO_REASON) {
- _LIBUNWIND_TRACE_UNWINDING(" _backtrace: ended because callback "
- "returned %d\n",
- result);
+ _LIBUNWIND_TRACE_UNWINDING(
+ " _backtrace: ended because callback returned %d\n", result);
return result;
}
}
@@ -171,8 +217,8 @@
unw_cursor_t *cursor = (unw_cursor_t *)context;
unw_word_t result;
unw_get_reg(cursor, UNW_REG_SP, &result);
- _LIBUNWIND_TRACE_API("_Unwind_GetCFA(context=%p) => 0x%llX\n", context,
- (uint64_t) result);
+ _LIBUNWIND_TRACE_API("_Unwind_GetCFA(context=%p) => 0x%" PRIx64 "\n",
+ (void *)context, (uint64_t)result);
return (uintptr_t)result;
}
@@ -182,7 +228,7 @@
/// site address. Normally IP is the return address.
_LIBUNWIND_EXPORT uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context,
int *ipBefore) {
- _LIBUNWIND_TRACE_API("_Unwind_GetIPInfo(context=%p)\n", context);
+ _LIBUNWIND_TRACE_API("_Unwind_GetIPInfo(context=%p)\n", (void *)context);
*ipBefore = 0;
return _Unwind_GetIP(context);
}
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/UnwindLevel1.c b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/UnwindLevel1.c
index 410ac74..5b911de 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/UnwindLevel1.c
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/UnwindLevel1.c
@@ -12,6 +12,7 @@
//
//===----------------------------------------------------------------------===//
+#include <inttypes.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
@@ -28,23 +29,22 @@
unwind_phase1(unw_context_t *uc, _Unwind_Exception *exception_object) {
unw_cursor_t cursor1;
unw_init_local(&cursor1, uc);
- bool handlerNotFound;
// Walk each frame looking for a place to stop.
- for (handlerNotFound = true; handlerNotFound;) {
+ for (bool handlerNotFound = true; handlerNotFound;) {
// Ask libuwind to get next frame (skip over first which is
// _Unwind_RaiseException).
int stepResult = unw_step(&cursor1);
if (stepResult == 0) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): unw_step() reached "
- "bottom => _URC_END_OF_STACK\n",
- exception_object);
+ "bottom => _URC_END_OF_STACK\n",
+ (void *)exception_object);
return _URC_END_OF_STACK;
} else if (stepResult < 0) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): unw_step failed => "
- "_URC_FATAL_PHASE1_ERROR\n",
- exception_object);
+ "_URC_FATAL_PHASE1_ERROR\n",
+ (void *)exception_object);
return _URC_FATAL_PHASE1_ERROR;
}
@@ -53,25 +53,27 @@
unw_word_t sp;
if (unw_get_proc_info(&cursor1, &frameInfo) != UNW_ESUCCESS) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): unw_get_proc_info "
- "failed => _URC_FATAL_PHASE1_ERROR\n",
- exception_object);
+ "failed => _URC_FATAL_PHASE1_ERROR\n",
+ (void *)exception_object);
return _URC_FATAL_PHASE1_ERROR;
}
// When tracing, print state information.
if (_LIBUNWIND_TRACING_UNWINDING) {
- char functionName[512];
+ char functionBuf[512];
+ const char *functionName = functionBuf;
unw_word_t offset;
- if ((unw_get_proc_name(&cursor1, functionName, 512, &offset) !=
- UNW_ESUCCESS) || (frameInfo.start_ip + offset > frameInfo.end_ip))
- strcpy(functionName, ".anonymous.");
+ if ((unw_get_proc_name(&cursor1, functionBuf, sizeof(functionBuf),
+ &offset) != UNW_ESUCCESS) ||
+ (frameInfo.start_ip + offset > frameInfo.end_ip))
+ functionName = ".anonymous.";
unw_word_t pc;
unw_get_reg(&cursor1, UNW_REG_IP, &pc);
_LIBUNWIND_TRACE_UNWINDING(
- "unwind_phase1(ex_ojb=%p): pc=0x%llX, start_ip=0x%llX, func=%s, "
- "lsda=0x%llX, personality=0x%llX\n",
- exception_object, (long long)pc, (long long)frameInfo.start_ip, functionName,
- (long long)frameInfo.lsda, (long long)frameInfo.handler);
+ "unwind_phase1(ex_ojb=%p): pc=0x%" PRIx64 ", start_ip=0x%" PRIx64
+ ", func=%s, lsda=0x%" PRIx64 ", personality=0x%" PRIx64 "\n",
+ (void *)exception_object, pc, frameInfo.start_ip, functionName,
+ frameInfo.lsda, frameInfo.handler);
}
// If there is a personality routine, ask it if it will want to stop at
@@ -81,7 +83,7 @@
(__personality_routine)(long)(frameInfo.handler);
_LIBUNWIND_TRACE_UNWINDING(
"unwind_phase1(ex_ojb=%p): calling personality function %p\n",
- exception_object, p);
+ (void *)exception_object, (void *)(uintptr_t)p);
_Unwind_Reason_Code personalityResult =
(*p)(1, _UA_SEARCH_PHASE, exception_object->exception_class,
exception_object, (struct _Unwind_Context *)(&cursor1));
@@ -92,15 +94,15 @@
handlerNotFound = false;
unw_get_reg(&cursor1, UNW_REG_SP, &sp);
exception_object->private_2 = (uintptr_t)sp;
- _LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): "
- "_URC_HANDLER_FOUND \n",
- exception_object);
+ _LIBUNWIND_TRACE_UNWINDING(
+ "unwind_phase1(ex_ojb=%p): _URC_HANDLER_FOUND \n",
+ (void *)exception_object);
return _URC_NO_REASON;
case _URC_CONTINUE_UNWIND:
_LIBUNWIND_TRACE_UNWINDING(
"unwind_phase1(ex_ojb=%p): _URC_CONTINUE_UNWIND\n",
- exception_object);
+ (void *)exception_object);
// continue unwinding
break;
@@ -108,7 +110,7 @@
// something went wrong
_LIBUNWIND_TRACE_UNWINDING(
"unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR\n",
- exception_object);
+ (void *)exception_object);
return _URC_FATAL_PHASE1_ERROR;
}
}
@@ -122,22 +124,24 @@
unw_cursor_t cursor2;
unw_init_local(&cursor2, uc);
- _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)\n", exception_object);
+ _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)\n",
+ (void *)exception_object);
// Walk each frame until we reach where search phase said to stop.
while (true) {
+
// Ask libuwind to get next frame (skip over first which is
// _Unwind_RaiseException).
int stepResult = unw_step(&cursor2);
if (stepResult == 0) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_step() reached "
- "bottom => _URC_END_OF_STACK\n",
- exception_object);
+ "bottom => _URC_END_OF_STACK\n",
+ (void *)exception_object);
return _URC_END_OF_STACK;
} else if (stepResult < 0) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_step failed => "
- "_URC_FATAL_PHASE1_ERROR\n",
- exception_object);
+ "_URC_FATAL_PHASE1_ERROR\n",
+ (void *)exception_object);
return _URC_FATAL_PHASE2_ERROR;
}
@@ -147,24 +151,26 @@
unw_get_reg(&cursor2, UNW_REG_SP, &sp);
if (unw_get_proc_info(&cursor2, &frameInfo) != UNW_ESUCCESS) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_get_proc_info "
- "failed => _URC_FATAL_PHASE1_ERROR\n",
- exception_object);
+ "failed => _URC_FATAL_PHASE1_ERROR\n",
+ (void *)exception_object);
return _URC_FATAL_PHASE2_ERROR;
}
// When tracing, print state information.
if (_LIBUNWIND_TRACING_UNWINDING) {
- char functionName[512];
+ char functionBuf[512];
+ const char *functionName = functionBuf;
unw_word_t offset;
- if ((unw_get_proc_name(&cursor2, functionName, 512, &offset) !=
- UNW_ESUCCESS) || (frameInfo.start_ip + offset > frameInfo.end_ip))
- strcpy(functionName, ".anonymous.");
- _LIBUNWIND_TRACE_UNWINDING(
- "unwind_phase2(ex_ojb=%p): start_ip=0x%llX, func=%s, sp=0x%llX, "
- "lsda=0x%llX, personality=0x%llX\n",
- exception_object, (long long)frameInfo.start_ip, functionName,
- (long long)sp, (long long)frameInfo.lsda,
- (long long)frameInfo.handler);
+ if ((unw_get_proc_name(&cursor2, functionBuf, sizeof(functionBuf),
+ &offset) != UNW_ESUCCESS) ||
+ (frameInfo.start_ip + offset > frameInfo.end_ip))
+ functionName = ".anonymous.";
+ _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): start_ip=0x%" PRIx64
+ ", func=%s, sp=0x%" PRIx64 ", lsda=0x%" PRIx64
+ ", personality=0x%" PRIx64 "\n",
+ (void *)exception_object, frameInfo.start_ip,
+ functionName, sp, frameInfo.lsda,
+ frameInfo.handler);
}
// If there is a personality routine, tell it we are unwinding.
@@ -184,7 +190,7 @@
// Continue unwinding
_LIBUNWIND_TRACE_UNWINDING(
"unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND\n",
- exception_object);
+ (void *)exception_object);
if (sp == exception_object->private_2) {
// Phase 1 said we would stop at this frame, but we did not...
_LIBUNWIND_ABORT("during phase1 personality function said it would "
@@ -194,26 +200,25 @@
case _URC_INSTALL_CONTEXT:
_LIBUNWIND_TRACE_UNWINDING(
"unwind_phase2(ex_ojb=%p): _URC_INSTALL_CONTEXT\n",
- exception_object);
+ (void *)exception_object);
// Personality routine says to transfer control to landing pad.
// We may get control back if landing pad calls _Unwind_Resume().
if (_LIBUNWIND_TRACING_UNWINDING) {
unw_word_t pc;
unw_get_reg(&cursor2, UNW_REG_IP, &pc);
unw_get_reg(&cursor2, UNW_REG_SP, &sp);
- _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): re-entering "
- "user code with ip=0x%llX, sp=0x%llX\n",
- exception_object, (long long)pc,
- (long long)sp);
+ _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): re-entering "
+ "user code with ip=0x%" PRIx64
+ ", sp=0x%" PRIx64 "\n",
+ (void *)exception_object, pc, sp);
}
-
unw_resume(&cursor2);
// unw_resume() only returns if there was an error.
return _URC_FATAL_PHASE2_ERROR;
default:
// Personality routine returned an unknown result code.
_LIBUNWIND_DEBUG_LOG("personality function returned unknown result %d",
- personalityResult);
+ personalityResult);
return _URC_FATAL_PHASE2_ERROR;
}
}
@@ -239,23 +244,24 @@
if (unw_get_proc_info(&cursor2, &frameInfo) != UNW_ESUCCESS) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): unw_step "
"failed => _URC_END_OF_STACK\n",
- exception_object);
+ (void *)exception_object);
return _URC_FATAL_PHASE2_ERROR;
}
// When tracing, print state information.
if (_LIBUNWIND_TRACING_UNWINDING) {
- char functionName[512];
+ char functionBuf[512];
+ const char *functionName = functionBuf;
unw_word_t offset;
- if ((unw_get_proc_name(&cursor2, functionName, 512, &offset) !=
- UNW_ESUCCESS) || (frameInfo.start_ip + offset > frameInfo.end_ip))
- strcpy(functionName, ".anonymous.");
- _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
- "start_ip=0x%llX, func=%s, lsda=0x%llX, "
- " personality=0x%llX\n",
- exception_object, frameInfo.start_ip,
- functionName, frameInfo.lsda,
- frameInfo.handler);
+ if ((unw_get_proc_name(&cursor2, functionBuf, sizeof(functionBuf),
+ &offset) != UNW_ESUCCESS) ||
+ (frameInfo.start_ip + offset > frameInfo.end_ip))
+ functionName = ".anonymous.";
+ _LIBUNWIND_TRACE_UNWINDING(
+ "unwind_phase2_forced(ex_ojb=%p): start_ip=0x%" PRIx64
+ ", func=%s, lsda=0x%" PRIx64 ", personality=0x%" PRIx64 "\n",
+ (void *)exception_object, frameInfo.start_ip, functionName,
+ frameInfo.lsda, frameInfo.handler);
}
// Call stop function at each frame.
@@ -266,11 +272,11 @@
(struct _Unwind_Context *)(&cursor2), stop_parameter);
_LIBUNWIND_TRACE_UNWINDING(
"unwind_phase2_forced(ex_ojb=%p): stop function returned %d\n",
- exception_object, stopResult);
+ (void *)exception_object, stopResult);
if (stopResult != _URC_NO_REASON) {
_LIBUNWIND_TRACE_UNWINDING(
"unwind_phase2_forced(ex_ojb=%p): stopped by stop function\n",
- exception_object);
+ (void *)exception_object);
return _URC_FATAL_PHASE2_ERROR;
}
@@ -280,21 +286,23 @@
(__personality_routine)(long)(frameInfo.handler);
_LIBUNWIND_TRACE_UNWINDING(
"unwind_phase2_forced(ex_ojb=%p): calling personality function %p\n",
- exception_object, p);
+ (void *)exception_object, (void *)(uintptr_t)p);
_Unwind_Reason_Code personalityResult =
(*p)(1, action, exception_object->exception_class, exception_object,
(struct _Unwind_Context *)(&cursor2));
switch (personalityResult) {
case _URC_CONTINUE_UNWIND:
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
- "personality returned _URC_CONTINUE_UNWIND\n",
- exception_object);
+ "personality returned "
+ "_URC_CONTINUE_UNWIND\n",
+ (void *)exception_object);
// Destructors called, continue unwinding
break;
case _URC_INSTALL_CONTEXT:
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
- "personality returned _URC_INSTALL_CONTEXT\n",
- exception_object);
+ "personality returned "
+ "_URC_INSTALL_CONTEXT\n",
+ (void *)exception_object);
// We may get control back if landing pad calls _Unwind_Resume().
unw_resume(&cursor2);
break;
@@ -303,7 +311,7 @@
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
"personality returned %d, "
"_URC_FATAL_PHASE2_ERROR\n",
- exception_object, personalityResult);
+ (void *)exception_object, personalityResult);
return _URC_FATAL_PHASE2_ERROR;
}
}
@@ -312,8 +320,8 @@
// Call stop function one last time and tell it we've reached the end
// of the stack.
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): calling stop "
- "function with _UA_END_OF_STACK\n",
- exception_object);
+ "function with _UA_END_OF_STACK\n",
+ (void *)exception_object);
_Unwind_Action lastAction =
(_Unwind_Action)(_UA_FORCE_UNWIND | _UA_CLEANUP_PHASE | _UA_END_OF_STACK);
(*stop)(1, lastAction, exception_object->exception_class, exception_object,
@@ -329,7 +337,7 @@
_LIBUNWIND_EXPORT _Unwind_Reason_Code
_Unwind_RaiseException(_Unwind_Exception *exception_object) {
_LIBUNWIND_TRACE_API("_Unwind_RaiseException(ex_obj=%p)\n",
- exception_object);
+ (void *)exception_object);
unw_context_t uc;
unw_getcontext(&uc);
@@ -362,7 +370,7 @@
/// in turn calls _Unwind_Resume_or_Rethrow().
_LIBUNWIND_EXPORT void
_Unwind_Resume(_Unwind_Exception *exception_object) {
- _LIBUNWIND_TRACE_API("_Unwind_Resume(ex_obj=%p)\n", exception_object);
+ _LIBUNWIND_TRACE_API("_Unwind_Resume(ex_obj=%p)\n", (void *)exception_object);
unw_context_t uc;
unw_getcontext(&uc);
@@ -386,7 +394,7 @@
_Unwind_ForcedUnwind(_Unwind_Exception *exception_object,
_Unwind_Stop_Fn stop, void *stop_parameter) {
_LIBUNWIND_TRACE_API("_Unwind_ForcedUnwind(ex_obj=%p, stop=%p)\n",
- exception_object, stop);
+ (void *)exception_object, (void *)(uintptr_t)stop);
unw_context_t uc;
unw_getcontext(&uc);
@@ -408,68 +416,18 @@
uintptr_t result = 0;
if (unw_get_proc_info(cursor, &frameInfo) == UNW_ESUCCESS)
result = (uintptr_t)frameInfo.lsda;
- _LIBUNWIND_TRACE_API("_Unwind_GetLanguageSpecificData(context=%p)"
- "=> 0x%llx\n", context, (long long)result);
+ _LIBUNWIND_TRACE_API(
+ "_Unwind_GetLanguageSpecificData(context=%p) => 0x%" PRIxPTR "\n",
+ (void *)context, result);
if (result != 0) {
if (*((uint8_t *)result) != 0xFF)
- _LIBUNWIND_DEBUG_LOG("lsda at 0x%llx does not start with 0xFF\n",
- (long long)result);
+ _LIBUNWIND_DEBUG_LOG("lsda at 0x%" PRIxPTR " does not start with 0xFF\n",
+ result);
}
return result;
}
-
-/// Called by personality handler during phase 2 to get register values.
-_LIBUNWIND_EXPORT uintptr_t _Unwind_GetGR(struct _Unwind_Context *context,
- int index) {
- unw_cursor_t *cursor = (unw_cursor_t *)context;
- unw_word_t result;
- unw_get_reg(cursor, index, &result);
- _LIBUNWIND_TRACE_API("_Unwind_GetGR(context=%p, reg=%d) => 0x%llX\n",
- context,
- index, (uint64_t) result);
- return (uintptr_t)result;
-}
-
-
-
-/// Called by personality handler during phase 2 to alter register values.
-_LIBUNWIND_EXPORT void _Unwind_SetGR(struct _Unwind_Context *context, int index,
- uintptr_t new_value) {
- _LIBUNWIND_TRACE_API("_Unwind_SetGR(context=%p, reg=%d, "
- "value=0x%0llX)\n", context,
- index, (uint64_t) new_value);
- unw_cursor_t *cursor = (unw_cursor_t *)context;
- unw_set_reg(cursor, index, new_value);
-}
-
-
-
-/// Called by personality handler during phase 2 to get instruction pointer.
-_LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) {
- unw_cursor_t *cursor = (unw_cursor_t *)context;
- unw_word_t result;
- unw_get_reg(cursor, UNW_REG_IP, &result);
- _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%llX\n", context,
- (uint64_t) result);
- return (uintptr_t)result;
-}
-
-
-
-/// Called by personality handler during phase 2 to alter instruction pointer,
-/// such as setting where the landing pad is, so _Unwind_Resume() will
-/// start executing in the landing pad.
-_LIBUNWIND_EXPORT void _Unwind_SetIP(struct _Unwind_Context *context,
- uintptr_t new_value) {
- _LIBUNWIND_TRACE_API("_Unwind_SetIP(context=%p, value=0x%0llX)\n",
- context, (uint64_t) new_value);
- unw_cursor_t *cursor = (unw_cursor_t *)context;
- unw_set_reg(cursor, UNW_REG_IP, new_value);
-}
-
-
/// Called by personality handler during phase 2 to find the start of the
/// function.
_LIBUNWIND_EXPORT uintptr_t
@@ -479,8 +437,8 @@
uintptr_t result = 0;
if (unw_get_proc_info(cursor, &frameInfo) == UNW_ESUCCESS)
result = (uintptr_t)frameInfo.start_ip;
- _LIBUNWIND_TRACE_API("_Unwind_GetRegionStart(context=%p) => 0x%llX\n",
- context, (long long)result);
+ _LIBUNWIND_TRACE_API("_Unwind_GetRegionStart(context=%p) => 0x%" PRIxPTR "\n",
+ (void *)context, result);
return result;
}
@@ -490,10 +448,91 @@
_LIBUNWIND_EXPORT void
_Unwind_DeleteException(_Unwind_Exception *exception_object) {
_LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)\n",
- exception_object);
+ (void *)exception_object);
if (exception_object->exception_cleanup != NULL)
(*exception_object->exception_cleanup)(_URC_FOREIGN_EXCEPTION_CAUGHT,
exception_object);
}
#endif // _LIBUNWIND_BUILD_ZERO_COST_APIS && !LIBCXXABI_ARM_EHABI
+
+#if LIBCXXABI_ARM_EHABI
+
+_LIBUNWIND_EXPORT uintptr_t
+_Unwind_GetGR(struct _Unwind_Context *context, int index) {
+ uintptr_t value = 0;
+ _Unwind_VRS_Get(context, _UVRSC_CORE, (uint32_t)index, _UVRSD_UINT32, &value);
+ _LIBUNWIND_TRACE_API("_Unwind_GetGR(context=%p, reg=%d) => 0x%" PRIx64 "\n",
+ (void *)context, index, (uint64_t)value);
+ return value;
+}
+
+_LIBUNWIND_EXPORT void _Unwind_SetGR(struct _Unwind_Context *context, int index,
+ uintptr_t value) {
+ _LIBUNWIND_TRACE_API("_Unwind_SetGR(context=%p, reg=%d, value=0x%0"PRIx64")\n",
+ (void *)context, index, (uint64_t)value);
+ _Unwind_VRS_Set(context, _UVRSC_CORE, (uint32_t)index, _UVRSD_UINT32, &value);
+}
+
+_LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) {
+ // remove the thumb-bit before returning
+ uintptr_t value = _Unwind_GetGR(context, 15) & (~(uintptr_t)0x1);
+ _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%" PRIx64 "\n",
+ (void *)context, (uint64_t)value);
+ return value;
+}
+
+_LIBUNWIND_EXPORT void _Unwind_SetIP(struct _Unwind_Context *context,
+ uintptr_t value) {
+ _LIBUNWIND_TRACE_API("_Unwind_SetIP(context=%p, value=0x%0" PRIx64 ")\n",
+ (void *)context, (uint64_t)value);
+ uintptr_t thumb_bit = _Unwind_GetGR(context, 15) & ((uintptr_t)0x1);
+ _Unwind_SetGR(context, 15, value | thumb_bit);
+}
+
+#else
+
+/// Called by personality handler during phase 2 to get register values.
+_LIBUNWIND_EXPORT uintptr_t
+_Unwind_GetGR(struct _Unwind_Context *context, int index) {
+ unw_cursor_t *cursor = (unw_cursor_t *)context;
+ unw_word_t result;
+ unw_get_reg(cursor, index, &result);
+ _LIBUNWIND_TRACE_API("_Unwind_GetGR(context=%p, reg=%d) => 0x%" PRIx64 "\n",
+ (void *)context, index, (uint64_t)result);
+ return (uintptr_t)result;
+}
+
+/// Called by personality handler during phase 2 to alter register values.
+_LIBUNWIND_EXPORT void _Unwind_SetGR(struct _Unwind_Context *context, int index,
+ uintptr_t value) {
+ _LIBUNWIND_TRACE_API("_Unwind_SetGR(context=%p, reg=%d, value=0x%0" PRIx64
+ ")\n",
+ (void *)context, index, (uint64_t)value);
+ unw_cursor_t *cursor = (unw_cursor_t *)context;
+ unw_set_reg(cursor, index, value);
+}
+
+/// Called by personality handler during phase 2 to get instruction pointer.
+_LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) {
+ unw_cursor_t *cursor = (unw_cursor_t *)context;
+ unw_word_t result;
+ unw_get_reg(cursor, UNW_REG_IP, &result);
+ _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%" PRIx64 "\n",
+ (void *)context, (uint64_t)result);
+ return (uintptr_t)result;
+}
+
+/// Called by personality handler during phase 2 to alter instruction pointer,
+/// such as setting where the landing pad is, so _Unwind_Resume() will
+/// start executing in the landing pad.
+_LIBUNWIND_EXPORT void _Unwind_SetIP(struct _Unwind_Context *context,
+ uintptr_t value) {
+ _LIBUNWIND_TRACE_API("_Unwind_SetIP(context=%p, value=0x%0" PRIx64 ")\n",
+ (void *)context, (uint64_t)value);
+ unw_cursor_t *cursor = (unw_cursor_t *)context;
+ unw_set_reg(cursor, UNW_REG_IP, value);
+}
+
+#endif
+
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/UnwindRegistersRestore.S b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/UnwindRegistersRestore.S
index 17c68ca..00f2aeb 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/UnwindRegistersRestore.S
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/UnwindRegistersRestore.S
@@ -11,7 +11,7 @@
.text
-#if __i386__
+#if defined(__i386__)
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_x866jumptoEv)
#
# void libunwind::Registers_x86::jumpto()
@@ -52,7 +52,7 @@
# skip fs
# skip gs
-#elif __x86_64__
+#elif defined(__x86_64__)
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind16Registers_x86_646jumptoEv)
#
@@ -93,7 +93,7 @@
ret # rip was saved here
-#elif __ppc__
+#elif defined(__ppc__)
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_ppc6jumptoEv)
;
@@ -258,7 +258,7 @@
lwz r3,20(r3) ; do r3 last
bctr
-#elif __arm64__
+#elif defined(__arm64__)
;
; void libunwind::Registers_arm64::jumpto()
@@ -308,7 +308,11 @@
ldp x0, x1, [x0, #0x000] ; restore x0,x1
ret lr ; jump to pc
-#elif __arm__
+#elif defined(__arm__) && !defined(__APPLE__)
+
+#if !defined(__ARM_ARCH_ISA_ARM)
+ .thumb
+#endif
@
@ void libunwind::Registers_arm::restoreCoreAndJumpTo()
@@ -318,6 +322,13 @@
@
.p2align 2
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm20restoreCoreAndJumpToEv)
+#if !defined(__ARM_ARCH_ISA_ARM)
+ ldr r2, [r0, #52]
+ ldr r3, [r0, #60]
+ mov sp, r2
+ mov lr, r3 @ restore pc into lr
+ ldm r0, {r0-r7}
+#else
@ Use lr as base so that r0 can be restored.
mov lr, r0
@ 32bit thumb-2 restrictions for ldm:
@@ -326,11 +337,8 @@
ldm lr, {r0-r12}
ldr sp, [lr, #52]
ldr lr, [lr, #60] @ restore pc into lr
-#if _ARM_ARCH > 4
- bx lr
-#else
- mov pc, lr
#endif
+ JMP(lr)
@
@ static void libunwind::Registers_arm::restoreVFPWithFLDMD(unw_fpreg_t* values)
@@ -339,16 +347,17 @@
@ values pointer is in r0
@
.p2align 2
+ .fpu vfpv3-d16
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm19restoreVFPWithFLDMDEPy)
@ VFP and iwMMX instructions are only available when compiling with the flags
- @ that enable them. We don't want to do that in the library (because we don't
+ @ that enable them. We do not want to do that in the library (because we do not
@ want the compiler to generate instructions that access those) but this is
@ only accessed if the personality routine needs these registers. Use of
@ these registers implies they are, actually, available on the target, so
@ it's ok to execute.
@ So, generate the instruction using the corresponding coprocessor mnemonic.
- ldc p11, cr0, [r0], {0x20} @ fldmiad r0, {d0-d15}
- mov pc, lr
+ vldmia r0, {d0-d15}
+ JMP(lr)
@
@ static void libunwind::Registers_arm::restoreVFPWithFLDMX(unw_fpreg_t* values)
@@ -357,9 +366,10 @@
@ values pointer is in r0
@
.p2align 2
+ .fpu vfpv3-d16
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm19restoreVFPWithFLDMXEPy)
- ldc p11, cr0, [r0], {0x21} @ fldmiax r0, {d0-d15}
- mov pc, lr
+ vldmia r0, {d0-d15} @ fldmiax is deprecated in ARMv7+ and now behaves like vldmia
+ JMP(lr)
@
@ static void libunwind::Registers_arm::restoreVFPv3(unw_fpreg_t* values)
@@ -368,9 +378,10 @@
@ values pointer is in r0
@
.p2align 2
+ .fpu vfpv3
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm12restoreVFPv3EPy)
- ldcl p11, cr0, [r0], {0x20} @ vldm r0, {d16-d31}
- mov pc, lr
+ vldmia r0, {d16-d31}
+ JMP(lr)
@
@ static void libunwind::Registers_arm::restoreiWMMX(unw_fpreg_t* values)
@@ -380,6 +391,7 @@
@
.p2align 2
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm12restoreiWMMXEPy)
+#if (!defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_6SM__)) || defined(__ARM_WMMX)
ldcl p1, cr0, [r0], #8 @ wldrd wR0, [r0], #8
ldcl p1, cr1, [r0], #8 @ wldrd wR1, [r0], #8
ldcl p1, cr2, [r0], #8 @ wldrd wR2, [r0], #8
@@ -396,7 +408,8 @@
ldcl p1, cr13, [r0], #8 @ wldrd wR13, [r0], #8
ldcl p1, cr14, [r0], #8 @ wldrd wR14, [r0], #8
ldcl p1, cr15, [r0], #8 @ wldrd wR15, [r0], #8
- mov pc, lr
+#endif
+ JMP(lr)
@
@ static void libunwind::Registers_arm::restoreiWMMXControl(unw_uint32_t* values)
@@ -406,10 +419,12 @@
@
.p2align 2
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm19restoreiWMMXControlEPj)
+#if (!defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_6SM__)) || defined(__ARM_WMMX)
ldc2 p1, cr8, [r0], #4 @ wldrw wCGR0, [r0], #4
ldc2 p1, cr9, [r0], #4 @ wldrw wCGR1, [r0], #4
ldc2 p1, cr10, [r0], #4 @ wldrw wCGR2, [r0], #4
ldc2 p1, cr11, [r0], #4 @ wldrw wCGR3, [r0], #4
- mov pc, lr
+#endif
+ JMP(lr)
#endif
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/UnwindRegistersSave.S b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/UnwindRegistersSave.S
index 48c45b0..8c886a8 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/UnwindRegistersSave.S
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/UnwindRegistersSave.S
@@ -11,7 +11,7 @@
.text
-#if __i386__
+#if defined(__i386__)
#
# extern int unw_getcontext(unw_context_t* thread_state)
@@ -52,7 +52,7 @@
xorl %eax, %eax # return UNW_ESUCCESS
ret
-#elif __x86_64__
+#elif defined(__x86_64__)
#
# extern int unw_getcontext(unw_context_t* thread_state)
@@ -87,7 +87,7 @@
xorl %eax, %eax # return UNW_ESUCCESS
ret
-#elif __ppc__
+#elif defined(__ppc__)
;
; extern int unw_getcontext(unw_context_t* thread_state)
@@ -230,7 +230,7 @@
blr
-#elif __arm64__
+#elif defined(__arm64__)
;
; extern int unw_getcontext(unw_context_t* thread_state)
@@ -280,7 +280,11 @@
ldr x0, #0 ; return UNW_ESUCCESS
ret
-#elif __arm__ && !__APPLE__
+#elif defined(__arm__) && !defined(__APPLE__)
+
+#if !defined(__ARM_ARCH_ISA_ARM)
+ .thumb
+#endif
@
@ extern int unw_getcontext(unw_context_t* thread_state)
@@ -291,11 +295,19 @@
@ Per EHABI #4.7 this only saves the core integer registers.
@ EHABI #7.4.5 notes that in general all VRS registers should be restored
@ however this is very hard to do for VFP registers because it is unknown
-@ to the lbirary how many registers are implemented by the architecture.
+@ to the library how many registers are implemented by the architecture.
@ Instead, VFP registers are demand saved by logic external to unw_getcontext.
@
.p2align 2
DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
+#if !defined(__ARM_ARCH_ISA_ARM)
+ stm r0!, {r0-r7}
+ mov r2, sp
+ mov r3, lr
+ str r2, [r0, #52]
+ str r3, [r0, #56]
+ str r3, [r0, #60] @ store return address as pc
+#else
@ 32bit thumb-2 restrictions for stm:
@ . the sp (r13) cannot be in the list
@ . the pc (r15) cannot be in the list in an STM instruction
@@ -303,12 +315,16 @@
str sp, [r0, #52]
str lr, [r0, #56]
str lr, [r0, #60] @ store return address as pc
- mov r0, #0 @ return UNW_ESUCCESS
-#if _ARM_ARCH > 4
- bx lr
-#else
- mov pc, lr
#endif
+#if __ARM_ARCH_ISA_THUMB == 1
+ @ T1 does not have a non-cpsr-clobbering register-zeroing instruction.
+ @ It is safe to use here though because we are about to return, and cpsr is
+ @ not expected to be preserved.
+ movs r0, #0 @ return UNW_ESUCCESS
+#else
+ mov r0, #0 @ return UNW_ESUCCESS
+#endif
+ JMP(lr)
@
@ static void libunwind::Registers_arm::saveVFPWithFSTMD(unw_fpreg_t* values)
@@ -317,9 +333,10 @@
@ values pointer is in r0
@
.p2align 2
+ .fpu vfpv3-d16
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMDEPy)
- stc p11, cr0, [r0], {#0x20} @ fstmiad r0, {d0-d15}
- mov pc, lr
+ vstmia r0, {d0-d15}
+ JMP(lr)
@
@ static void libunwind::Registers_arm::saveVFPWithFSTMX(unw_fpreg_t* values)
@@ -328,9 +345,10 @@
@ values pointer is in r0
@
.p2align 2
+ .fpu vfpv3-d16
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMXEPy)
- stc p11, cr0, [r0], {#0x21} @ fstmiax r0, {d0-d15}
- mov pc, lr
+ vstmia r0, {d0-d15} @ fstmiax is deprecated in ARMv7+ and now behaves like vstmia
+ JMP(lr)
@
@ static void libunwind::Registers_arm::saveVFPv3(unw_fpreg_t* values)
@@ -339,16 +357,17 @@
@ values pointer is in r0
@
.p2align 2
+ .fpu vfpv3
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm9saveVFPv3EPy)
@ VFP and iwMMX instructions are only available when compiling with the flags
- @ that enable them. We don't want to do that in the library (because we don't
+ @ that enable them. We do not want to do that in the library (because we do not
@ want the compiler to generate instructions that access those) but this is
@ only accessed if the personality routine needs these registers. Use of
@ these registers implies they are, actually, available on the target, so
@ it's ok to execute.
@ So, generate the instructions using the corresponding coprocessor mnemonic.
- stcl p11, cr0, [r0], {#0x20} @ vldm r0, {d16-d31}
- mov pc, lr
+ vstmia r0, {d16-d31}
+ JMP(lr)
@
@ static void libunwind::Registers_arm::saveiWMMX(unw_fpreg_t* values)
@@ -358,6 +377,7 @@
@
.p2align 2
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm9saveiWMMXEPy)
+#if (!defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_6SM__)) || defined(__ARM_WMMX)
stcl p1, cr0, [r0], #8 @ wstrd wR0, [r0], #8
stcl p1, cr1, [r0], #8 @ wstrd wR1, [r0], #8
stcl p1, cr2, [r0], #8 @ wstrd wR2, [r0], #8
@@ -374,7 +394,8 @@
stcl p1, cr13, [r0], #8 @ wstrd wR13, [r0], #8
stcl p1, cr14, [r0], #8 @ wstrd wR14, [r0], #8
stcl p1, cr15, [r0], #8 @ wstrd wR15, [r0], #8
- mov pc, lr
+#endif
+ JMP(lr)
@
@ static void libunwind::Registers_arm::saveiWMMXControl(unw_uint32_t* values)
@@ -384,26 +405,12 @@
@
.p2align 2
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveiWMMXControlEPj)
+#if (!defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_6SM__)) || defined(__ARM_WMMX)
stc2 p1, cr8, [r0], #4 @ wstrw wCGR0, [r0], #4
stc2 p1, cr9, [r0], #4 @ wstrw wCGR1, [r0], #4
stc2 p1, cr10, [r0], #4 @ wstrw wCGR2, [r0], #4
stc2 p1, cr11, [r0], #4 @ wstrw wCGR3, [r0], #4
- mov pc, lr
-
-#elif __mips64
-#
-# extern int unw_getcontext(unw_context_t* thread_state)
-# ToDo:
-#
-DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
- j $31
-
-#elif __mips__
-#
-# extern int unw_getcontext(unw_context_t* thread_state)
-# ToDo:
-#
-DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
- j $31
+#endif
+ JMP(lr)
#endif
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/Unwind_AppleExtras.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/Unwind_AppleExtras.cpp
index 6d02a66..b8baef5 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/Unwind_AppleExtras.cpp
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/Unwind_AppleExtras.cpp
@@ -41,7 +41,7 @@
// static linker symbols to prevent wrong two level namespace for _Unwind symbols
-#if __arm__
+#if defined(__arm__)
#define NOT_HERE_BEFORE_5_0(sym) \
extern const char sym##_tmp30 __asm("$ld$hide$os3.0$_" #sym ); \
__attribute__((visibility("default"))) const char sym##_tmp30 = 0; \
@@ -57,7 +57,7 @@
__attribute__((visibility("default"))) const char sym##_tmp42 = 0; \
extern const char sym##_tmp43 __asm("$ld$hide$os4.3$_" #sym ); \
__attribute__((visibility("default"))) const char sym##_tmp43 = 0;
-#elif __arm64__
+#elif defined(__arm64__)
#define NOT_HERE_BEFORE_10_6(sym)
#define NEVER_HERE(sym)
#else
@@ -183,7 +183,7 @@
}
-#if !FOR_DYLD && _LIBUNWIND_BUILD_SJLJ_APIS
+#if !defined(FOR_DYLD) && _LIBUNWIND_BUILD_SJLJ_APIS
#include <System/pthread_machdep.h>
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/assembly.h b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/assembly.h
index 210d350..f46a24d 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/assembly.h
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/assembly.h
@@ -34,13 +34,47 @@
#define GLUE(a, b) GLUE2(a, b)
#define SYMBOL_NAME(name) GLUE(__USER_LABEL_PREFIX__, name)
+#if defined(__APPLE__)
+#define SYMBOL_IS_FUNC(name)
+#elif defined(__ELF__)
+#if defined(__arm__)
+#define SYMBOL_IS_FUNC(name) .type name,%function
+#else
+#define SYMBOL_IS_FUNC(name) .type name,@function
+#endif
+#else
+#define SYMBOL_IS_FUNC(name) \
+ .def name SEPARATOR \
+ .scl 2 SEPARATOR \
+ .type 32 SEPARATOR \
+ .endef
+#endif
+
#define DEFINE_LIBUNWIND_FUNCTION(name) \
.globl SYMBOL_NAME(name) SEPARATOR \
+ SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \
SYMBOL_NAME(name):
#define DEFINE_LIBUNWIND_PRIVATE_FUNCTION(name) \
.globl SYMBOL_NAME(name) SEPARATOR \
HIDDEN_DIRECTIVE SYMBOL_NAME(name) SEPARATOR \
+ SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \
SYMBOL_NAME(name):
+#if defined(__arm__)
+#if !defined(__ARM_ARCH)
+#define __ARM_ARCH 4
+#endif
+
+#if defined(__ARM_ARCH_4T__) || __ARM_ARCH >= 5
+#define ARM_HAS_BX
+#endif
+
+#ifdef ARM_HAS_BX
+#define JMP(r) bx r
+#else
+#define JMP(r) mov pc, r
+#endif
+#endif /* __arm__ */
+
#endif /* UNWIND_ASSEMBLY_H */
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/config.h b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/config.h
index ebd600f..828b68e 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/config.h
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/config.h
@@ -14,27 +14,21 @@
#ifndef LIBUNWIND_CONFIG_H
#define LIBUNWIND_CONFIG_H
-#ifndef NDEBUG
-#include <stdio.h> // for logging
-#endif
-
#include <assert.h>
#include <stdio.h>
-#include <stdlib.h>
// Define static_assert() unless already defined by compiler.
#ifndef __has_feature
#define __has_feature(__x) 0
#endif
#if !(__has_feature(cxx_static_assert)) && !defined(static_assert)
-// TODO(ajwong): This caused some compile failures on gcc.
-// #define static_assert(__b, __m) \
-// extern int compile_time_assert_failed[ ( __b ) ? 1 : -1 ] \
-// __attribute__( ( unused ) );
+ #define static_assert(__b, __m) \
+ extern int compile_time_assert_failed[ ( __b ) ? 1 : -1 ] \
+ __attribute__( ( unused ) );
#endif
// Platform specific configuration defines.
-#if __APPLE__
+#ifdef __APPLE__
#include <Availability.h>
#ifdef __cplusplus
extern "C" {
@@ -45,45 +39,53 @@
}
#endif
- #define _LIBUNWIND_BUILD_ZERO_COST_APIS (__i386__ || __x86_64__ || __arm64__)
- #define _LIBUNWIND_BUILD_SJLJ_APIS (__arm__)
- #define _LIBUNWIND_SUPPORT_FRAME_APIS (__i386__ || __x86_64__)
+ #define _LIBUNWIND_BUILD_ZERO_COST_APIS (defined(__i386__) || \
+ defined(__x86_64__) || \
+ defined(__arm64__))
+ #define _LIBUNWIND_BUILD_SJLJ_APIS defined(__arm__)
+ #define _LIBUNWIND_SUPPORT_FRAME_APIS (defined(__i386__) || \
+ defined(__x86_64__))
#define _LIBUNWIND_EXPORT __attribute__((visibility("default")))
#define _LIBUNWIND_HIDDEN __attribute__((visibility("hidden")))
- #define _LIBUNWIND_LOG(msg, ...) fprintf(stderr, "libuwind: " msg, __VA_ARGS__)
+ #define _LIBUNWIND_LOG(msg, ...) fprintf(stderr, "libunwind: " msg, __VA_ARGS__)
#define _LIBUNWIND_ABORT(msg) __assert_rtn(__func__, __FILE__, __LINE__, msg)
- #if FOR_DYLD
- #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND 1
- #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 0
- #define _LIBUNWIND_SUPPORT_DWARF_INDEX 0
- #define _LIBUNWIND_IS_BAREMETAL 0
+ #if defined(FOR_DYLD)
+ #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND 1
+ #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 0
+ #define _LIBUNWIND_SUPPORT_DWARF_INDEX 0
#else
- #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND 1
- #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
- #define _LIBUNWIND_SUPPORT_DWARF_INDEX 0
- #define _LIBUNWIND_IS_BAREMETAL 0
+ #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND 1
+ #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
+ #define _LIBUNWIND_SUPPORT_DWARF_INDEX 0
#endif
#else
+ #include <stdlib.h>
+
static inline void assert_rtn(const char* func, const char* file, int line, const char* msg) __attribute__ ((noreturn));
static inline void assert_rtn(const char* func, const char* file, int line, const char* msg) {
fprintf(stderr, "libunwind: %s %s:%d - %s\n", func, file, line, msg);
assert(false);
abort();
}
- #define _LIBUNWIND_BUILD_ZERO_COST_APIS (__i386__ || __x86_64__ || __arm64__ || __arm__ || __mips__)
+
+ #define _LIBUNWIND_BUILD_ZERO_COST_APIS (defined(__i386__) || \
+ defined(__x86_64__) || \
+ defined(__arm64__) || \
+ defined(__arm__))
#define _LIBUNWIND_BUILD_SJLJ_APIS 0
- #define _LIBUNWIND_SUPPORT_FRAME_APIS (__i386__ || __x86_64__)
+ #define _LIBUNWIND_SUPPORT_FRAME_APIS (defined(__i386__) || \
+ defined(__x86_64__))
#define _LIBUNWIND_EXPORT __attribute__((visibility("default")))
#define _LIBUNWIND_HIDDEN __attribute__((visibility("hidden")))
#define _LIBUNWIND_LOG(msg, ...) fprintf(stderr, "libuwind: " msg, __VA_ARGS__)
#define _LIBUNWIND_ABORT(msg) assert_rtn(__func__, __FILE__, __LINE__, msg)
- #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND 0
- #define _LIBUNWIND_SUPPORT_DWARF_UNWIND defined(__mips__)
- #define _LIBUNWIND_SUPPORT_DWARF_INDEX 0
- #define _LIBUNWIND_IS_BAREMETAL 0
+ #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND 0
+ #define _LIBUNWIND_SUPPORT_DWARF_UNWIND !defined(__arm__) || \
+ defined(__ARM_DWARF_EH__)
+ #define _LIBUNWIND_SUPPORT_DWARF_INDEX _LIBUNWIND_SUPPORT_DWARF_UNWIND
#endif
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/libunwind.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/libunwind.cpp
index 0c07c15..49f06cc 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/libunwind.cpp
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/libunwind.cpp
@@ -16,6 +16,9 @@
#include <cstdlib> // getenv
#endif
#include <new>
+#include <tuple>
+#include <memory>
+#include <vector>
#include "libunwind_ext.h"
#include "config.h"
@@ -32,6 +35,9 @@
/// internal object to represent this processes address space
LocalAddressSpace LocalAddressSpace::sThisAddressSpace;
+_LIBUNWIND_EXPORT unw_addr_space_t unw_local_addr_space =
+ (unw_addr_space_t)&LocalAddressSpace::sThisAddressSpace;
+
/// record the registers and stack position of the caller
extern int unw_getcontext(unw_context_t *);
// note: unw_getcontext() implemented in assembly
@@ -41,21 +47,22 @@
_LIBUNWIND_EXPORT int unw_init_local(unw_cursor_t *cursor,
unw_context_t *context) {
_LIBUNWIND_TRACE_API("unw_init_local(cursor=%p, context=%p)\n",
- cursor, context);
+ static_cast<void *>(cursor),
+ static_cast<void *>(context));
// Use "placement new" to allocate UnwindCursor in the cursor buffer.
-#if __i386__
+#if defined(__i386__)
new ((void *)cursor) UnwindCursor<LocalAddressSpace, Registers_x86>(
context, LocalAddressSpace::sThisAddressSpace);
-#elif __x86_64__
+#elif defined(__x86_64__)
new ((void *)cursor) UnwindCursor<LocalAddressSpace, Registers_x86_64>(
context, LocalAddressSpace::sThisAddressSpace);
-#elif __ppc__
+#elif defined(__ppc__)
new ((void *)cursor) UnwindCursor<LocalAddressSpace, Registers_ppc>(
context, LocalAddressSpace::sThisAddressSpace);
-#elif __arm64__
+#elif defined(__arm64__)
new ((void *)cursor) UnwindCursor<LocalAddressSpace, Registers_arm64>(
context, LocalAddressSpace::sThisAddressSpace);
-#elif __arm__
+#elif LIBCXXABI_ARM_EHABI
new ((void *)cursor) UnwindCursor<LocalAddressSpace, Registers_arm>(
context, LocalAddressSpace::sThisAddressSpace);
#endif
@@ -65,17 +72,13 @@
return UNW_ESUCCESS;
}
-#if UNW_REMOTE
-
-_LIBUNWIND_EXPORT unw_addr_space_t unw_local_addr_space =
- (unw_addr_space_t) & sThisAddressSpace;
-
+#ifdef UNW_REMOTE
/// Create a cursor into a thread in another process.
_LIBUNWIND_EXPORT int unw_init_remote_thread(unw_cursor_t *cursor,
unw_addr_space_t as,
void *arg) {
// special case: unw_init_remote(xx, unw_local_addr_space, xx)
- if (as == (unw_addr_space_t) & sThisAddressSpace)
+ if (as == (unw_addr_space_t)&LocalAddressSpace::sThisAddressSpace)
return unw_init_local(cursor, NULL); //FIXME
// use "placement new" to allocate UnwindCursor in the cursor buffer
@@ -155,7 +158,8 @@
_LIBUNWIND_EXPORT int unw_get_reg(unw_cursor_t *cursor, unw_regnum_t regNum,
unw_word_t *value) {
_LIBUNWIND_TRACE_API("unw_get_reg(cursor=%p, regNum=%d, &value=%p)\n",
- cursor, regNum, value);
+ static_cast<void *>(cursor), regNum,
+ static_cast<void *>(value));
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
if (co->validReg(regNum)) {
*value = co->getReg(regNum);
@@ -168,8 +172,8 @@
/// Set value of specified register at cursor position in stack frame.
_LIBUNWIND_EXPORT int unw_set_reg(unw_cursor_t *cursor, unw_regnum_t regNum,
unw_word_t value) {
- _LIBUNWIND_TRACE_API("unw_set_reg(cursor=%p, regNum=%d, value=0x%lX)\n",
- cursor, regNum, (long)value);
+ _LIBUNWIND_TRACE_API("unw_set_reg(cursor=%p, regNum=%d, value=0x%llX)\n",
+ static_cast<void *>(cursor), regNum, (long long)value);
typedef LocalAddressSpace::pint_t pint_t;
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
if (co->validReg(regNum)) {
@@ -188,7 +192,8 @@
_LIBUNWIND_EXPORT int unw_get_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum,
unw_fpreg_t *value) {
_LIBUNWIND_TRACE_API("unw_get_fpreg(cursor=%p, regNum=%d, &value=%p)\n",
- cursor, regNum, value);
+ static_cast<void *>(cursor), regNum,
+ static_cast<void *>(value));
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
if (co->validFloatReg(regNum)) {
*value = co->getFloatReg(regNum);
@@ -201,10 +206,12 @@
/// Set value of specified float register at cursor position in stack frame.
_LIBUNWIND_EXPORT int unw_set_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum,
unw_fpreg_t value) {
-#if __arm__
- _LIBUNWIND_TRACE_API("unw_set_fpreg(cursor=%p, regNum=%d, value=%llx)\n", cursor, regNum, value);
+#if LIBCXXABI_ARM_EHABI
+ _LIBUNWIND_TRACE_API("unw_set_fpreg(cursor=%p, regNum=%d, value=%llX)\n",
+ static_cast<void *>(cursor), regNum, value);
#else
- _LIBUNWIND_TRACE_API("unw_set_fpreg(cursor=%p, regNum=%d, value=%g)\n", cursor, regNum, value);
+ _LIBUNWIND_TRACE_API("unw_set_fpreg(cursor=%p, regNum=%d, value=%g)\n",
+ static_cast<void *>(cursor), regNum, value);
#endif
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
if (co->validFloatReg(regNum)) {
@@ -217,7 +224,7 @@
/// Move cursor to next frame.
_LIBUNWIND_EXPORT int unw_step(unw_cursor_t *cursor) {
- _LIBUNWIND_TRACE_API("unw_step(cursor=%p)\n", cursor);
+ _LIBUNWIND_TRACE_API("unw_step(cursor=%p)\n", static_cast<void *>(cursor));
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
return co->step();
}
@@ -227,7 +234,7 @@
_LIBUNWIND_EXPORT int unw_get_proc_info(unw_cursor_t *cursor,
unw_proc_info_t *info) {
_LIBUNWIND_TRACE_API("unw_get_proc_info(cursor=%p, &info=%p)\n",
- cursor, info);
+ static_cast<void *>(cursor), static_cast<void *>(info));
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
co->getInfo(info);
if (info->end_ip == 0)
@@ -239,7 +246,7 @@
/// Resume execution at cursor position (aka longjump).
_LIBUNWIND_EXPORT int unw_resume(unw_cursor_t *cursor) {
- _LIBUNWIND_TRACE_API("unw_resume(cursor=%p)\n", cursor);
+ _LIBUNWIND_TRACE_API("unw_resume(cursor=%p)\n", static_cast<void *>(cursor));
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
co->jumpto();
return UNW_EUNSPEC;
@@ -249,8 +256,9 @@
/// Get name of function at cursor position in stack frame.
_LIBUNWIND_EXPORT int unw_get_proc_name(unw_cursor_t *cursor, char *buf,
size_t bufLen, unw_word_t *offset) {
- _LIBUNWIND_TRACE_API("unw_get_proc_name(cursor=%p, &buf=%p,"
- "bufLen=%zu)\n", cursor, buf, bufLen);
+ _LIBUNWIND_TRACE_API("unw_get_proc_name(cursor=%p, &buf=%p, bufLen=%lu)\n",
+ static_cast<void *>(cursor), static_cast<void *>(buf),
+ static_cast<unsigned long>(bufLen));
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
if (co->getFunctionName(buf, bufLen, offset))
return UNW_ESUCCESS;
@@ -262,7 +270,7 @@
/// Checks if a register is a floating-point register.
_LIBUNWIND_EXPORT int unw_is_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum) {
_LIBUNWIND_TRACE_API("unw_is_fpreg(cursor=%p, regNum=%d)\n",
- cursor, regNum);
+ static_cast<void *>(cursor), regNum);
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
return co->validFloatReg(regNum);
}
@@ -272,7 +280,7 @@
_LIBUNWIND_EXPORT const char *unw_regname(unw_cursor_t *cursor,
unw_regnum_t regNum) {
_LIBUNWIND_TRACE_API("unw_regname(cursor=%p, regNum=%d)\n",
- cursor, regNum);
+ static_cast<void *>(cursor), regNum);
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
return co->getRegisterName(regNum);
}
@@ -280,15 +288,17 @@
/// Checks if current frame is signal trampoline.
_LIBUNWIND_EXPORT int unw_is_signal_frame(unw_cursor_t *cursor) {
- _LIBUNWIND_TRACE_API("unw_is_signal_frame(cursor=%p)\n", cursor);
+ _LIBUNWIND_TRACE_API("unw_is_signal_frame(cursor=%p)\n",
+ static_cast<void *>(cursor));
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
return co->isSignalFrame();
}
-#if __arm__
+#ifdef __arm__
// Save VFP registers d0-d15 using FSTMIADX instead of FSTMIADD
_LIBUNWIND_EXPORT void unw_save_vfp_as_X(unw_cursor_t *cursor) {
- _LIBUNWIND_TRACE_API("unw_fpreg_save_vfp_as_X(cursor=%p)\n", cursor);
+ _LIBUNWIND_TRACE_API("unw_fpreg_save_vfp_as_X(cursor=%p)\n",
+ static_cast<void *>(cursor));
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
return co->saveVFPAsX();
}
@@ -299,7 +309,8 @@
/// SPI: walks cached dwarf entries
_LIBUNWIND_EXPORT void unw_iterate_dwarf_unwind_cache(void (*func)(
unw_word_t ip_start, unw_word_t ip_end, unw_word_t fde, unw_word_t mh)) {
- _LIBUNWIND_TRACE_API("unw_iterate_dwarf_unwind_cache(func=%p)\n", func);
+ _LIBUNWIND_TRACE_API("unw_iterate_dwarf_unwind_cache(func=%p)\n",
+ reinterpret_cast<void *>(func));
DwarfFDECache<LocalAddressSpace>::iterateCacheEntries(func);
}
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/libunwind_ext.h b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/libunwind_ext.h
index 38d71cc..5eb0e87 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/libunwind_ext.h
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/Unwind/libunwind_ext.h
@@ -13,7 +13,9 @@
#ifndef __LIBUNWIND_EXT__
#define __LIBUNWIND_EXT__
+#include "config.h"
#include <libunwind.h>
+#include <unwind.h>
#define UNW_STEP_SUCCESS 1
#define UNW_STEP_END 0
@@ -31,6 +33,13 @@
extern void _unw_add_dynamic_fde(unw_word_t fde);
extern void _unw_remove_dynamic_fde(unw_word_t fde);
+#if LIBCXXABI_ARM_EHABI
+extern const uint32_t* decode_eht_entry(const uint32_t*, size_t*, size_t*);
+extern _Unwind_Reason_Code _Unwind_VRS_Interpret(_Unwind_Context *context,
+ const uint32_t *data,
+ size_t offset, size_t len);
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/abort_message.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/abort_message.cpp
index 3da4ef6..5e25c0f 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/abort_message.cpp
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/abort_message.cpp
@@ -12,11 +12,21 @@
#include <stdarg.h>
#include "abort_message.h"
+#ifdef __BIONIC__
+#include <android/api-level.h>
+#if __ANDROID_API__ >= 21
+#include <syslog.h>
+extern "C" void android_set_abort_message(const char* msg);
+#else
+#include <assert.h>
+#endif // __ANDROID_API__ >= 21
+#endif // __BIONIC__
+
#pragma GCC visibility push(hidden)
-#if __APPLE__
+#ifdef __APPLE__
# if defined(__has_include) && __has_include(<CrashReporterClient.h>)
-# define HAVE_CRASHREPORTERCLIENT_H 1
+# define HAVE_CRASHREPORTERCLIENT_H
# include <CrashReporterClient.h>
# endif
#endif
@@ -25,7 +35,7 @@
void abort_message(const char* format, ...)
{
// write message to stderr
-#if __APPLE__
+#ifdef __APPLE__
fprintf(stderr, "libc++abi.dylib: ");
#endif
va_list list;
@@ -33,8 +43,8 @@
vfprintf(stderr, format, list);
va_end(list);
fprintf(stderr, "\n");
-
-#if __APPLE__ && HAVE_CRASHREPORTERCLIENT_H
+
+#if defined(__APPLE__) && defined(HAVE_CRASHREPORTERCLIENT_H)
// record message in crash report
char* buffer;
va_list list2;
@@ -42,7 +52,28 @@
vasprintf(&buffer, format, list2);
va_end(list2);
CRSetCrashLogMessage(buffer);
-#endif
+#elif defined(__BIONIC__)
+ char* buffer;
+ va_list list2;
+ va_start(list2, format);
+ vasprintf(&buffer, format, list2);
+ va_end(list2);
+
+#if __ANDROID_API__ >= 21
+ // Show error in tombstone.
+ android_set_abort_message(buffer);
+
+ // Show error in logcat.
+ openlog("libc++abi", 0, 0);
+ syslog(LOG_CRIT, "%s", buffer);
+ closelog();
+#else
+ // The good error reporting wasn't available in Android until L. Since we're
+ // about to abort anyway, just call __assert2, which will log _somewhere_
+ // (tombstone and/or logcat) in older releases.
+ __assert2(__FILE__, __LINE__, __func__, buffer);
+#endif // __ANDROID_API__ >= 21
+#endif // __BIONIC__
abort();
}
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/config.h b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/config.h
index 0ca9791..c0122ed 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/config.h
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/config.h
@@ -16,17 +16,16 @@
#include <unistd.h>
-#if defined(_POSIX_THREADS) && _POSIX_THREADS > 0
-# define LIBCXXABI_SINGLE_THREADED 0
-#else
-# define LIBCXXABI_SINGLE_THREADED 1
+// Set this in the CXXFLAGS when you need it
+#if !defined(LIBCXXABI_HAS_NO_THREADS)
+# define LIBCXXABI_HAS_NO_THREADS 0
#endif
// Set this in the CXXFLAGS when you need it, because otherwise we'd have to
// #if !defined(__linux__) && !defined(__APPLE__) && ...
// and so-on for *every* platform.
-#ifndef LIBCXXABI_BARE_METAL
-# define LIBCXXABI_BARE_METAL 0
+#ifndef LIBCXXABI_BAREMETAL
+# define LIBCXXABI_BAREMETAL 0
#endif
// -- BEGIN Taken from gabixx_config.h for gcc compat
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_aux_runtime.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_aux_runtime.cpp
index 15fede0..7fec810 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_aux_runtime.cpp
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_aux_runtime.cpp
@@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//
#include "cxxabi.h"
+#include <new>
#include <typeinfo>
namespace __cxxabiv1
@@ -29,6 +30,10 @@
throw std::bad_typeid();
}
+LIBCXXABI_NORETURN
+void __cxa_throw_bad_array_new_length(void) {
+ throw std::bad_array_new_length();
+}
} // extern "C"
} // abi
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_default_handlers.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_default_handlers.cpp
index 583edb4..a26ea2a 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_default_handlers.cpp
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_default_handlers.cpp
@@ -92,9 +92,6 @@
std::unexpected_handler __cxa_unexpected_handler = default_unexpected_handler;
// In the future these will become:
-// TODO(ajwong): Can this actually be true? Is std::atomic part of libc++? If so, do we have a
-// layering violation?
-//
// std::atomic<std::terminate_handler> __cxa_terminate_handler(default_terminate_handler);
// std::atomic<std::unexpected_handler> __cxa_unexpected_handler(default_unexpected_handler);
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_demangle.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_demangle.cpp
index 1344f43..2d07686 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_demangle.cpp
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_demangle.cpp
@@ -4711,7 +4711,7 @@
std::size_t
align_up(std::size_t n) noexcept
- {return (n + (alignment-1)) & ~(alignment-1);}
+ {return n + (alignment-1) & ~(alignment-1);}
bool
pointer_in_buffer(char* p) noexcept
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_exception.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_exception.cpp
index 31ddc51..b7a33d7 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_exception.cpp
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_exception.cpp
@@ -17,7 +17,7 @@
#include <exception> // for std::terminate
#include <cstdlib> // for malloc, free
#include <cstring> // for memset
-#if !LIBCXXABI_SINGLE_THREADED
+#if !LIBCXXABI_HAS_NO_THREADS
# include <pthread.h> // for fallback_malloc.ipp's mutexes
#endif
#include "cxa_exception.hpp"
@@ -234,7 +234,7 @@
globals->uncaughtExceptions += 1; // Not atomically, since globals are thread-local
exception_header->unwindHeader.exception_cleanup = exception_cleanup_func;
-#if __USING_SJLJ_EXCEPTIONS__
+#ifdef __USING_SJLJ_EXCEPTIONS__
_Unwind_SjLj_RaiseException(&exception_header->unwindHeader);
#else
_Unwind_RaiseException(&exception_header->unwindHeader);
@@ -258,12 +258,10 @@
{
#if LIBCXXABI_ARM_EHABI
return reinterpret_cast<void*>(
- static_cast<_Unwind_Control_Block*>(unwind_exception)->barrier_cache.bitpattern[0]);
+ static_cast<_Unwind_Control_Block*>(unwind_exception)->barrier_cache.bitpattern[0]);
#else
- return cxa_exception_from_exception_unwind_exception
- (
- static_cast<_Unwind_Exception*>(unwind_exception)
- )->adjustedPtr;
+ return cxa_exception_from_exception_unwind_exception(
+ static_cast<_Unwind_Exception*>(unwind_exception))->adjustedPtr;
#endif
}
@@ -447,12 +445,17 @@
*/
void __cxa_end_catch()
{
- static_assert(sizeof(__cxa_exception) == sizeof(__cxa_dependent_exception),
- "sizeof(__cxa_exception) must be equal to sizeof(__cxa_dependent_exception)");
- static_assert(offsetof(__cxa_exception, referenceCount) == offsetof(__cxa_dependent_exception, primaryException),
- "the layout of __cxa_exception must match the layout of __cxa_dependent_exception");
- static_assert(offsetof(__cxa_exception, handlerCount) == offsetof(__cxa_dependent_exception, handlerCount),
- "the layout of __cxa_exception must match the layout of __cxa_dependent_exception");
+ static_assert(sizeof(__cxa_exception) == sizeof(__cxa_dependent_exception),
+ "sizeof(__cxa_exception) must be equal to "
+ "sizeof(__cxa_dependent_exception)");
+ static_assert(offsetof(__cxa_exception, referenceCount) ==
+ offsetof(__cxa_dependent_exception, primaryException),
+ "the layout of __cxa_exception must match the layout of "
+ "__cxa_dependent_exception");
+ static_assert(offsetof(__cxa_exception, handlerCount) ==
+ offsetof(__cxa_dependent_exception, handlerCount),
+ "the layout of __cxa_exception must match the layout of "
+ "__cxa_dependent_exception");
__cxa_eh_globals* globals = __cxa_get_globals_fast(); // __cxa_get_globals called in __cxa_begin_catch
__cxa_exception* exception_header = globals->caughtExceptions;
// If we've rethrown a foreign exception, then globals->caughtExceptions
@@ -566,7 +569,7 @@
// nothing
globals->caughtExceptions = 0;
}
-#if __USING_SJLJ_EXCEPTIONS__
+#ifdef __USING_SJLJ_EXCEPTIONS__
_Unwind_SjLj_RaiseException(&exception_header->unwindHeader);
#else
_Unwind_RaiseException(&exception_header->unwindHeader);
@@ -695,7 +698,7 @@
setDependentExceptionClass(&dep_exception_header->unwindHeader);
__cxa_get_globals()->uncaughtExceptions += 1;
dep_exception_header->unwindHeader.exception_cleanup = dependent_exception_cleanup;
-#if __USING_SJLJ_EXCEPTIONS__
+#ifdef __USING_SJLJ_EXCEPTIONS__
_Unwind_SjLj_RaiseException(&dep_exception_header->unwindHeader);
#else
_Unwind_RaiseException(&dep_exception_header->unwindHeader);
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_exception.hpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_exception.hpp
index 9b22ce3..6e68f98 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_exception.hpp
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_exception.hpp
@@ -24,20 +24,20 @@
static const uint64_t kOurExceptionClass = 0x434C4E47432B2B00; // CLNGC++\0
static const uint64_t kOurDependentExceptionClass = 0x434C4E47432B2B01; // CLNGC++\1
-static const uint64_t get_vendor_and_language = 0xFFFFFFFFFFFFFF00; // mask for CLNGC++
-
-struct __cxa_exception {
-#if __LP64__ || LIBCXXABI_ARM_EHABI
+static const uint64_t get_vendor_and_language = 0xFFFFFFFFFFFFFF00; // mask for CLNGC++
+
+struct __cxa_exception {
+#if defined(__LP64__) || LIBCXXABI_ARM_EHABI
// This is a new field to support C++ 0x exception_ptr.
// For binary compatibility it is at the start of this
// struct which is prepended to the object thrown in
// __cxa_allocate_exception.
size_t referenceCount;
#endif
-
+
// Manage the exception object itself.
std::type_info *exceptionType;
- void (*exceptionDestructor)(void *);
+ void (*exceptionDestructor)(void *);
std::unexpected_handler unexpectedHandler;
std::terminate_handler terminateHandler;
@@ -56,7 +56,7 @@
void *adjustedPtr;
#endif
-#if !__LP64__ && !LIBCXXABI_ARM_EHABI
+#if !defined(__LP64__) && !LIBCXXABI_ARM_EHABI
// This is a new field to support C++ 0x exception_ptr.
// For binary compatibility it is placed where the compiler
// previously adding padded to 64-bit align unwindHeader.
@@ -70,19 +70,19 @@
// The layout of this structure MUST match the layout of __cxa_exception, with
// primaryException instead of referenceCount.
struct __cxa_dependent_exception {
-#if __LP64__ || LIBCXXABI_ARM_EHABI
+#if defined(__LP64__) || LIBCXXABI_ARM_EHABI
void* primaryException;
#endif
-
+
std::type_info *exceptionType;
- void (*exceptionDestructor)(void *);
+ void (*exceptionDestructor)(void *);
std::unexpected_handler unexpectedHandler;
std::terminate_handler terminateHandler;
__cxa_exception *nextException;
int handlerCount;
-
+
#if LIBCXXABI_ARM_EHABI
__cxa_exception* nextPropagatingException;
int propagationCount;
@@ -93,8 +93,8 @@
void * catchTemp;
void *adjustedPtr;
#endif
-
-#if !__LP64__ && !LIBCXXABI_ARM_EHABI
+
+#if !defined(__LP64__) && !LIBCXXABI_ARM_EHABI
void* primaryException;
#endif
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_exception_storage.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_exception_storage.cpp
index 6f902c6..a39b6db 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_exception_storage.cpp
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_exception_storage.cpp
@@ -15,7 +15,7 @@
#include "config.h"
-#if LIBCXXABI_SINGLE_THREADED
+#if LIBCXXABI_HAS_NO_THREADS
namespace __cxxabiv1 {
extern "C" {
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_guard.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_guard.cpp
index c6ac89f..1b41917 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_guard.cpp
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_guard.cpp
@@ -10,7 +10,7 @@
#include "abort_message.h"
#include "config.h"
-#if !LIBCXXABI_SINGLE_THREADED
+#if !LIBCXXABI_HAS_NO_THREADS
# include <pthread.h>
#endif
#include <stdint.h>
@@ -31,7 +31,7 @@
namespace
{
-#if __arm__
+#ifdef __arm__
// A 32-bit, 4-byte-aligned static data value. The least significant 2 bits must
// be statically initialized to 0.
@@ -62,7 +62,7 @@
#endif
-#if !LIBCXXABI_SINGLE_THREADED
+#if !LIBCXXABI_HAS_NO_THREADS
pthread_mutex_t guard_mut = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t guard_cv = PTHREAD_COND_INITIALIZER;
#endif
@@ -166,7 +166,7 @@
extern "C"
{
-#if LIBCXXABI_SINGLE_THREADED
+#if LIBCXXABI_HAS_NO_THREADS
int __cxa_guard_acquire(guard_type* guard_object)
{
return !is_initialized(guard_object);
@@ -183,7 +183,7 @@
*guard_object = 0;
}
-#else // !LIBCXXABI_SINGLE_THREADED
+#else // !LIBCXXABI_HAS_NO_THREADS
int __cxa_guard_acquire(guard_type* guard_object)
{
@@ -250,7 +250,7 @@
abort_message("__cxa_guard_abort failed to broadcast condition variable");
}
-#endif // !LIBCXXABI_SINGLE_THREADED
+#endif // !LIBCXXABI_HAS_NO_THREADS
} // extern "C"
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_handlers.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_handlers.cpp
index 674933b..59895a6 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_handlers.cpp
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_handlers.cpp
@@ -102,7 +102,7 @@
__terminate(get_terminate());
}
-extern "C" new_handler __cxa_new_handler = 0;
+new_handler __cxa_new_handler = 0;
// In the future these will become:
// std::atomic<std::new_handler> __cxa_new_handler(0);
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_new_delete.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_new_delete.cpp
index c2258e2..25a5454 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_new_delete.cpp
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_new_delete.cpp
@@ -230,8 +230,6 @@
return "bad_array_new_length";
}
-#if 0 // WE DONT WANT NO C++14 FIXME can remove this if 0 now?
-
// bad_array_length
#ifndef _LIBCPP_BAD_ARRAY_LENGTH_DEFINED
@@ -261,6 +259,4 @@
return "bad_array_length";
}
-#endif // WE DONT WANT NO C++14
-
} // std
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_personality.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_personality.cpp
index 486591f..b68d12a 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_personality.cpp
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_personality.cpp
@@ -12,14 +12,19 @@
//
//===----------------------------------------------------------------------===//
+#include <assert.h>
+#include <stdlib.h>
+#include <typeinfo>
+
#include "config.h"
-#include "unwind.h"
#include "cxa_exception.hpp"
#include "cxa_handlers.hpp"
#include "private_typeinfo.h"
-#include <typeinfo>
-#include <stdlib.h>
-#include <assert.h>
+#include "unwind.h"
+
+#if LIBCXXABI_ARM_EHABI
+#include "Unwind/libunwind_ext.h"
+#endif
/*
Exception Header Layout:
@@ -50,7 +55,7 @@
+------------------+--+-----+-----+------------------------+--------------------------+
| callSiteTableLength | (ULEB128) | Call Site Table length, used to find Action table |
+---------------------+-----------+---------------------------------------------------+
-#if !__USING_SJLJ_EXCEPTIONS__
+#ifndef __USING_SJLJ_EXCEPTIONS__
+---------------------+-----------+------------------------------------------------+
| Beginning of Call Site Table The current ip lies within the |
| ... (start, length) range of one of these |
@@ -319,10 +324,12 @@
// deferred to the linker. For bare-metal they turn into absolute
// relocations. For linux they turn into GOT-REL relocations."
// https://gcc.gnu.org/ml/gcc-patches/2009-08/msg00264.html
-#if LIBCXXABI_BARE_METAL
- return reinterpret_cast<const void*>(reinterpret_cast<uintptr_t>(ptr) + offset);
+#if LIBCXXABI_BAREMETAL
+ return reinterpret_cast<const void*>(reinterpret_cast<uintptr_t>(ptr) +
+ offset);
#else
- return *reinterpret_cast<const void**>(reinterpret_cast<uintptr_t>(ptr) + offset);
+ return *reinterpret_cast<const void **>(reinterpret_cast<uintptr_t>(ptr) +
+ offset);
#endif
}
@@ -338,11 +345,12 @@
}
assert((ttypeEncoding == DW_EH_PE_absptr) || (ttypeEncoding == (DW_EH_PE_pcrel | DW_EH_PE_indirect))
- && "Unexpected TTypeEncoding");
+ && "Unexpected TTypeEncoding");
(void)ttypeEncoding;
const uint8_t* ttypePtr = classInfo - ttypeIndex * sizeof(uintptr_t);
- return reinterpret_cast<const __shim_type_info*>(read_target2_value(ttypePtr));
+ return reinterpret_cast<const __shim_type_info *>(
+ read_target2_value(ttypePtr));
}
#else // !LIBCXXABI_ARM_EHABI
static
@@ -405,7 +413,7 @@
}
assert((ttypeEncoding == DW_EH_PE_absptr) || (ttypeEncoding == (DW_EH_PE_pcrel | DW_EH_PE_indirect))
- && "Unexpected TTypeEncoding");
+ && "Unexpected TTypeEncoding");
(void)ttypeEncoding;
// specIndex is negative of 1-based byte offset into classInfo;
@@ -533,12 +541,10 @@
_UA_CLEANUP_PHASE && !_UA_HANDLER_FRAME
*/
-static
-void
-scan_eh_tab(scan_results& results, _Unwind_Action actions, bool native_exception,
- _Unwind_Exception* unwind_exception, _Unwind_Context* context,
- const uint8_t* lsda)
-{
+static void scan_eh_tab(scan_results &results, _Unwind_Action actions,
+ bool native_exception,
+ _Unwind_Exception *unwind_exception,
+ _Unwind_Context *context) {
// Initialize results to found nothing but an error
results.ttypeIndex = 0;
results.actionRecord = 0;
@@ -577,6 +583,7 @@
return;
}
// Start scan by getting exception table address
+ const uint8_t *lsda = (const uint8_t *)_Unwind_GetLanguageSpecificData(context);
if (lsda == 0)
{
// There is no exception table
@@ -590,7 +597,7 @@
// Get beginning current frame's code (as defined by the
// emitted dwarf code)
uintptr_t funcStart = _Unwind_GetRegionStart(context);
-#if __USING_SJLJ_EXCEPTIONS__
+#ifdef __USING_SJLJ_EXCEPTIONS__
if (ip == uintptr_t(-1))
{
// no action
@@ -623,7 +630,7 @@
// Walk call-site table looking for range that
// includes current PC.
uint8_t callSiteEncoding = *lsda++;
-#if __USING_SJLJ_EXCEPTIONS__
+#ifdef __USING_SJLJ_EXCEPTIONS__
(void)callSiteEncoding; // When using SjLj exceptions, callSiteEncoding is never used
#endif
uint32_t callSiteTableLength = static_cast<uint32_t>(readULEB128(&lsda));
@@ -634,7 +641,7 @@
while (callSitePtr < callSiteTableEnd)
{
// There is one entry per call site.
-#if !__USING_SJLJ_EXCEPTIONS__
+#ifndef __USING_SJLJ_EXCEPTIONS__
// The call sites are non-overlapping in [start, start+length)
// The call sites are ordered in increasing value of start
uintptr_t start = readEncodedPointer(&callSitePtr, callSiteEncoding);
@@ -650,7 +657,7 @@
#endif // __USING_SJLJ_EXCEPTIONS__
{
// Found the call site containing ip.
-#if !__USING_SJLJ_EXCEPTIONS__
+#ifndef __USING_SJLJ_EXCEPTIONS__
if (landingPad == 0)
{
// No handler here
@@ -852,7 +859,7 @@
action += actionOffset;
} // there is no break out of this loop, only return
}
-#if !__USING_SJLJ_EXCEPTIONS__
+#ifndef __USING_SJLJ_EXCEPTIONS__
else if (ipOffset < start)
{
// There is no call site for this ip
@@ -918,7 +925,7 @@
#if !LIBCXXABI_ARM_EHABI
_Unwind_Reason_Code
-#if __USING_SJLJ_EXCEPTIONS__
+#ifdef __USING_SJLJ_EXCEPTIONS__
__gxx_personality_sj0
#else
__gxx_personality_v0
@@ -936,8 +943,7 @@
{
// Phase 1 search: All we're looking for in phase 1 is a handler that
// halts unwinding
- scan_eh_tab(results, actions, native_exception, unwind_exception, context,
- (const uint8_t*)_Unwind_GetLanguageSpecificData(context));
+ scan_eh_tab(results, actions, native_exception, unwind_exception, context);
if (results.reason == _URC_HANDLER_FOUND)
{
// Found one. Can we cache the results somewhere to optimize phase 2?
@@ -978,8 +984,7 @@
else
{
// No, do the scan again to reload the results.
- scan_eh_tab(results, actions, native_exception, unwind_exception, context,
- (const uint8_t*)_Unwind_GetLanguageSpecificData(context));
+ scan_eh_tab(results, actions, native_exception, unwind_exception, context);
// Phase 1 told us we would find a handler. Now in Phase 2 we
// didn't find a handler. The eh table should not be changing!
if (results.reason != _URC_HANDLER_FOUND)
@@ -992,8 +997,7 @@
// Either we didn't do a phase 1 search (due to forced unwinding), or
// phase 1 reported no catching-handlers.
// Search for a (non-catching) cleanup
- scan_eh_tab(results, actions, native_exception, unwind_exception, context,
- (const uint8_t*)_Unwind_GetLanguageSpecificData(context));
+ scan_eh_tab(results, actions, native_exception, unwind_exception, context);
if (results.reason == _URC_HANDLER_FOUND)
{
// Found a non-catching handler. Jump to it:
@@ -1010,22 +1014,55 @@
}
#else
+#if !LIBCXXABI_USE_LLVM_UNWINDER
+extern "C" _Unwind_Reason_Code __gnu_unwind_frame(_Unwind_Exception*, _Unwind_Context*);
+#endif
+
// Helper function to unwind one frame.
// ARM EHABI 7.3 and 7.4: If the personality function returns _URC_CONTINUE_UNWIND, the
// personality routine should update the virtual register set (VRS) according to the
// corresponding frame unwinding instructions (ARM EHABI 9.3.)
-static _Unwind_Reason_Code continue_unwind(_Unwind_Context* context,
- uint32_t* unwind_opcodes,
- size_t opcode_words)
+static _Unwind_Reason_Code continue_unwind(_Unwind_Exception* unwind_exception,
+ _Unwind_Context* context)
{
+#if LIBCXXABI_USE_LLVM_UNWINDER
+ // ARM EHABI # 6.2, # 9.2
+ //
+ // +---- ehtp
+ // v
+ // +--------------------------------------+
+ // | +--------+--------+--------+-------+ |
+ // | |0| prel31 to __gxx_personality_v0 | |
+ // | +--------+--------+--------+-------+ |
+ // | | N | unwind opcodes | | <-- unwind_opcodes
+ // | +--------+--------+--------+-------+ |
+ // | | Word 2 unwind opcodes | |
+ // | +--------+--------+--------+-------+ |
+ // | ... |
+ // | +--------+--------+--------+-------+ |
+ // | | Word N unwind opcodes | |
+ // | +--------+--------+--------+-------+ |
+ // | | LSDA | | <-- lsda
+ // | | ... | |
+ // | +--------+--------+--------+-------+ |
+ // +--------------------------------------+
+
+ uint32_t *unwind_opcodes = unwind_exception->pr_cache.ehtp + 1;
+ size_t opcode_words = ((*unwind_opcodes >> 24) & 0xff) + 1;
if (_Unwind_VRS_Interpret(context, unwind_opcodes, 1, opcode_words * 4) !=
_URC_CONTINUE_UNWIND)
return _URC_FAILURE;
+#else
+ if (__gnu_unwind_frame(unwind_exception, context) != _URC_OK)
+ return _URC_FAILURE;
+#endif
return _URC_CONTINUE_UNWIND;
}
// ARM register names
+#if !LIBCXXABI_USE_LLVM_UNWINDER
static const uint32_t REG_UCB = 12; // Register to save _Unwind_Control_Block
+#endif
static const uint32_t REG_SP = 13;
static void save_results_to_barrier_cache(_Unwind_Exception* unwind_exception,
@@ -1059,50 +1096,25 @@
bool native_exception = (unwind_exception->exception_class & get_vendor_and_language) ==
(kOurExceptionClass & get_vendor_and_language);
-#if LIBCXXABI_ARM_EHABI
- // ARM EHABI # 6.2, # 9.2
- //
- // +---- ehtp
- // v
- // +--------------------------------------+
- // | +--------+--------+--------+-------+ |
- // | |0| prel31 to __gxx_personality_v0 | |
- // | +--------+--------+--------+-------+ |
- // | | N | unwind opcodes | | <-- UnwindData
- // | +--------+--------+--------+-------+ |
- // | | Word 2 unwind opcodes | |
- // | +--------+--------+--------+-------+ |
- // | ... |
- // | +--------+--------+--------+-------+ |
- // | | Word N unwind opcodes | |
- // | +--------+--------+--------+-------+ |
- // | | LSDA | | <-- lsda
- // | | ... | |
- // | +--------+--------+--------+-------+ |
- // +--------------------------------------+
-
- uint32_t *UnwindData = unwind_exception->pr_cache.ehtp + 1;
- uint32_t FirstDataWord = *UnwindData;
- size_t N = ((FirstDataWord >> 24) & 0xff);
- size_t NDataWords = N + 1;
+#if !LIBCXXABI_USE_LLVM_UNWINDER
+ // Copy the address of _Unwind_Control_Block to r12 so that
+ // _Unwind_GetLanguageSpecificData() and _Unwind_GetRegionStart() can
+ // return correct address.
+ _Unwind_SetGR(context, REG_UCB, reinterpret_cast<uint32_t>(unwind_exception));
#endif
- // TODO(ajwong): The "Copy the address" comment was in upstream...do we actually need this in arm?
- // Copy the address of _Unwind_Control_Block to r12 so that _Unwind_GetLanguageSpecificData()
-
- const uint8_t *lsda = (const uint8_t*)_Unwind_GetLanguageSpecificData(context);
-
-
- // TODO(ajwong): _Unwind_GetLanguageSpecificData() doesn't work.
- // Copy the address of _Unwind_Control_Block to r12 so that _Unwind_GetLanguageSpecificData()
- // and _Unwind_GetRegionStart() can return correct address.
- _Unwind_SetGR(context, REG_UCB, reinterpret_cast<uint32_t>(unwind_exception));
+ // Check the undocumented force unwinding behavior
+ bool is_force_unwinding = state & _US_FORCE_UNWIND;
+ state &= ~_US_FORCE_UNWIND;
scan_results results;
switch (state) {
case _US_VIRTUAL_UNWIND_FRAME:
+ if (is_force_unwinding)
+ return continue_unwind(unwind_exception, context);
+
// Phase 1 search: All we're looking for in phase 1 is a handler that halts unwinding
- scan_eh_tab(results, _UA_SEARCH_PHASE, native_exception, unwind_exception, context, lsda);
+ scan_eh_tab(results, _UA_SEARCH_PHASE, native_exception, unwind_exception, context);
if (results.reason == _URC_HANDLER_FOUND)
{
unwind_exception->barrier_cache.sp = _Unwind_GetGR(context, REG_SP);
@@ -1112,10 +1124,15 @@
}
// Did not find the catch handler
if (results.reason == _URC_CONTINUE_UNWIND)
- return continue_unwind(context, UnwindData, NDataWords);
+ return continue_unwind(unwind_exception, context);
return results.reason;
case _US_UNWIND_FRAME_STARTING:
+ // TODO: Support force unwinding in the phase 2 search.
+ // NOTE: In order to call the cleanup functions, _Unwind_ForcedUnwind()
+ // will call this personality function with (_US_FORCE_UNWIND |
+ // _US_UNWIND_FRAME_STARTING).
+
// Phase 2 search
if (unwind_exception->barrier_cache.sp == _Unwind_GetGR(context, REG_SP))
{
@@ -1130,7 +1147,7 @@
{
// Search for the catching handler again for the foreign exception.
scan_eh_tab(results, static_cast<_Unwind_Action>(_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME),
- native_exception, unwind_exception, context, lsda);
+ native_exception, unwind_exception, context);
if (results.reason != _URC_HANDLER_FOUND) // phase1 search should guarantee to find one
call_terminate(native_exception, unwind_exception);
}
@@ -1143,7 +1160,7 @@
// Either we didn't do a phase 1 search (due to forced unwinding), or
// phase 1 reported no catching-handlers.
// Search for a (non-catching) cleanup
- scan_eh_tab(results, _UA_CLEANUP_PHASE, native_exception, unwind_exception, context, lsda);
+ scan_eh_tab(results, _UA_CLEANUP_PHASE, native_exception, unwind_exception, context);
if (results.reason == _URC_HANDLER_FOUND)
{
// Found a non-catching handler
@@ -1160,11 +1177,11 @@
// Did not find any handler
if (results.reason == _URC_CONTINUE_UNWIND)
- return continue_unwind(context, UnwindData, NDataWords);
+ return continue_unwind(unwind_exception, context);
return results.reason;
case _US_UNWIND_FRAME_RESUME:
- return continue_unwind(context, UnwindData, NDataWords);
+ return continue_unwind(unwind_exception, context);
}
// We were called improperly: neither a phase 1 or phase 2 search
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_thread_atexit.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_thread_atexit.cpp
new file mode 100644
index 0000000..2b4b9fa
--- /dev/null
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/cxa_thread_atexit.cpp
@@ -0,0 +1,28 @@
+//===----------------------- cxa_thread_atexit.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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "cxxabi.h"
+
+namespace __cxxabiv1 {
+
+extern "C" {
+
+#ifdef HAVE___CXA_THREAD_ATEXIT_IMPL
+
+int __cxa_thread_atexit(void (*dtor)(void *), void *obj,
+ void *dso_symbol) throw() {
+ extern int __cxa_thread_atexit_impl(void (*)(void *), void *, void *);
+ return __cxa_thread_atexit_impl(dtor, obj, dso_symbol);
+}
+
+#endif // HAVE__CXA_THREAD_ATEXIT_IMPL
+
+} // extern "C"
+
+} // namespace __cxxabiv1
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/fallback_malloc.ipp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/fallback_malloc.ipp
index a97f3fd..135d489 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/fallback_malloc.ipp
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/fallback_malloc.ipp
@@ -26,7 +26,7 @@
namespace {
// When POSIX threads are not available, make the mutex operations a nop
-#if LIBCXXABI_SINGLE_THREADED
+#if LIBCXXABI_HAS_NO_THREADS
static void * heap_mutex = 0;
#else
static pthread_mutex_t heap_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -34,7 +34,7 @@
class mutexor {
public:
-#if LIBCXXABI_SINGLE_THREADED
+#if LIBCXXABI_HAS_NO_THREADS
mutexor ( void * ) {}
~mutexor () {}
#else
@@ -44,7 +44,7 @@
private:
mutexor ( const mutexor &rhs );
mutexor & operator = ( const mutexor &rhs );
-#if !LIBCXXABI_SINGLE_THREADED
+#if !LIBCXXABI_HAS_NO_THREADS
pthread_mutex_t *mtx_;
#endif
};
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/private_typeinfo.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/private_typeinfo.cpp
index c65dcab..821796f 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/private_typeinfo.cpp
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/src/private_typeinfo.cpp
@@ -34,7 +34,7 @@
//
// _LIBCXX_DYNAMIC_FALLBACK is currently off by default.
-#if _LIBCXX_DYNAMIC_FALLBACK
+#ifdef _LIBCXX_DYNAMIC_FALLBACK
#include "abort_message.h"
#include <string.h>
#include <sys/syslog.h>
@@ -57,7 +57,7 @@
#pragma GCC visibility push(hidden)
-#if _LIBCXX_DYNAMIC_FALLBACK
+#ifdef _LIBCXX_DYNAMIC_FALLBACK
inline
bool
@@ -347,30 +347,34 @@
__pbase_type_info::can_catch(const __shim_type_info* thrown_type,
void*&) const
{
- if (is_equal(this, thrown_type, false))
- return true;
- return is_equal(thrown_type, &typeid(std::nullptr_t), false);
+ return is_equal(this, thrown_type, false) ||
+ is_equal(thrown_type, &typeid(std::nullptr_t), false);
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wmissing-field-initializers"
// Handles bullets 1, 3 and 4
+// NOTE: It might not be safe to adjust the pointer if it is not not a pointer
+// type. Only adjust the pointer after we know it is safe to do so.
bool
__pointer_type_info::can_catch(const __shim_type_info* thrown_type,
void*& adjustedPtr) const
{
- // Do the dereference adjustment
- if (adjustedPtr != NULL)
- adjustedPtr = *static_cast<void**>(adjustedPtr);
// bullets 1 and 4
- if (__pbase_type_info::can_catch(thrown_type, adjustedPtr))
+ if (__pbase_type_info::can_catch(thrown_type, adjustedPtr)) {
+ if (adjustedPtr != NULL)
+ adjustedPtr = *static_cast<void**>(adjustedPtr);
return true;
+ }
// bullet 3
const __pointer_type_info* thrown_pointer_type =
dynamic_cast<const __pointer_type_info*>(thrown_type);
if (thrown_pointer_type == 0)
return false;
+ // Do the dereference adjustment
+ if (adjustedPtr != NULL)
+ adjustedPtr = *static_cast<void**>(adjustedPtr);
// bullet 3B
if (thrown_pointer_type->__flags & ~__flags)
return false;
@@ -511,7 +515,7 @@
info.number_of_dst_type = 1;
// Do the search
dynamic_type->search_above_dst(&info, dynamic_ptr, dynamic_ptr, public_path, false);
-#if _LIBCXX_DYNAMIC_FALLBACK
+#ifdef _LIBCXX_DYNAMIC_FALLBACK
// The following if should always be false because we should definitely
// find (static_ptr, static_type), either on a public or private path
if (info.path_dst_ptr_to_static_ptr == unknown)
@@ -535,7 +539,7 @@
{
// Not using giant short cut. Do the search
dynamic_type->search_below_dst(&info, dynamic_ptr, public_path, false);
- #if _LIBCXX_DYNAMIC_FALLBACK
+ #ifdef _LIBCXX_DYNAMIC_FALLBACK
// The following if should always be false because we should definitely
// find (static_ptr, static_type), either on a public or private path
if (info.path_dst_ptr_to_static_ptr == unknown &&
@@ -957,7 +961,6 @@
int path_below,
bool use_strcmp) const
{
- typedef const __base_class_type_info* Iter;
if (is_equal(this, info->static_type, use_strcmp))
process_static_type_below_dst(info, current_ptr, path_below);
else if (is_equal(this, info->dst_type, use_strcmp))
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/backtrace_test.pass.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/backtrace_test.pass.cpp
new file mode 100644
index 0000000..df291c9
--- /dev/null
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/backtrace_test.pass.cpp
@@ -0,0 +1,62 @@
+//===---------------------- backtrace_test.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.
+//
+//===----------------------------------------------------------------------===//
+#include <assert.h>
+#include <stddef.h>
+#include <unwind.h>
+
+extern "C" _Unwind_Reason_Code
+trace_function(struct _Unwind_Context* context, void* ntraced) {
+ (*reinterpret_cast<size_t*>(ntraced))++;
+ // We should never have a call stack this deep...
+ assert(*reinterpret_cast<size_t*>(ntraced) < 20);
+ return _URC_NO_REASON;
+}
+
+void call3_throw(size_t* ntraced) {
+ try {
+ _Unwind_Backtrace(trace_function, ntraced);
+ } catch (...) {
+ assert(false);
+ }
+}
+
+void call3_nothrow(size_t* ntraced) {
+ _Unwind_Backtrace(trace_function, ntraced);
+}
+
+void call2(size_t* ntraced, bool do_throw) {
+ if (do_throw) {
+ call3_throw(ntraced);
+ } else {
+ call3_nothrow(ntraced);
+ }
+}
+
+void call1(size_t* ntraced, bool do_throw) {
+ call2(ntraced, do_throw);
+}
+
+int main() {
+ size_t throw_ntraced = 0;
+ size_t nothrow_ntraced = 0;
+
+ call1(¬hrow_ntraced, false);
+
+ try {
+ call1(&throw_ntraced, true);
+ } catch (...) {
+ assert(false);
+ }
+
+ // Different platforms (and different runtimes) will unwind a different number
+ // of times, so we can't make any better assumptions than this.
+ assert(nothrow_ntraced > 1);
+ assert(throw_ntraced == nothrow_ntraced); // Make sure we unwind through catch
+ return 0;
+}
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_array_01.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_array_01.pass.cpp
similarity index 100%
rename from ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_array_01.cpp
rename to ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_array_01.pass.cpp
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_array_02.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_array_02.pass.cpp
similarity index 100%
rename from ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_array_02.cpp
rename to ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_array_02.pass.cpp
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_class_01.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_class_01.pass.cpp
similarity index 100%
rename from ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_class_01.cpp
rename to ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_class_01.pass.cpp
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_class_02.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_class_02.pass.cpp
similarity index 100%
rename from ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_class_02.cpp
rename to ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_class_02.pass.cpp
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_class_03.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_class_03.pass.cpp
similarity index 100%
rename from ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_class_03.cpp
rename to ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_class_03.pass.cpp
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_class_04.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_class_04.pass.cpp
similarity index 100%
rename from ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_class_04.cpp
rename to ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_class_04.pass.cpp
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_const_pointer_nullptr.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_const_pointer_nullptr.pass.cpp
similarity index 100%
rename from ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_const_pointer_nullptr.cpp
rename to ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_const_pointer_nullptr.pass.cpp
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_function_01.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_function_01.pass.cpp
similarity index 100%
rename from ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_function_01.cpp
rename to ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_function_01.pass.cpp
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_function_02.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_function_02.pass.cpp
similarity index 100%
rename from ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_function_02.cpp
rename to ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_function_02.pass.cpp
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_in_noexcept.pass.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_in_noexcept.pass.cpp
new file mode 100644
index 0000000..02fecda
--- /dev/null
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_in_noexcept.pass.cpp
@@ -0,0 +1,34 @@
+//===---------------------- catch_in_noexcept.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.
+//
+//===----------------------------------------------------------------------===//
+
+#include <exception>
+#include <stdlib.h>
+#include <assert.h>
+
+struct A {};
+
+// Despite being marked as noexcept, this function must have an EHT entry that
+// is not 'cantunwind', so that the unwinder can correctly deal with the throw.
+void f1() noexcept
+{
+ try {
+ A a;
+ throw a;
+ assert(false);
+ } catch (...) {
+ assert(true);
+ return;
+ }
+ assert(false);
+}
+
+int main()
+{
+ f1();
+}
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_member_data_pointer_01.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_member_data_pointer_01.pass.cpp
similarity index 100%
rename from ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_member_data_pointer_01.cpp
rename to ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_member_data_pointer_01.pass.cpp
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_member_function_pointer_01.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_member_function_pointer_01.pass.cpp
similarity index 100%
rename from ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_member_function_pointer_01.cpp
rename to ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_member_function_pointer_01.pass.cpp
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_member_pointer_nullptr.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_member_pointer_nullptr.pass.cpp
similarity index 100%
rename from ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_member_pointer_nullptr.cpp
rename to ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_member_pointer_nullptr.pass.cpp
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_pointer_nullptr.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_pointer_nullptr.pass.cpp
similarity index 100%
rename from ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_pointer_nullptr.cpp
rename to ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_pointer_nullptr.pass.cpp
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_pointer_reference.pass.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_pointer_reference.pass.cpp
new file mode 100644
index 0000000..88d2140
--- /dev/null
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_pointer_reference.pass.cpp
@@ -0,0 +1,444 @@
+//===---------------------- catch_pointer_referece.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.
+//
+//===----------------------------------------------------------------------===//
+//
+// This test case checks specifically the cases under bullet 3.1 & 3.2:
+//
+// C++ ABI 15.3:
+// A handler is a match for an exception object of type E if
+// * The handler is of type cv T or cv T& and E and T are the same type
+// (ignoring the top-level cv-qualifiers), or
+// * the handler is of type cv T or cv T& and T is an unambiguous base
+// class of E, or
+// / * the handler is of type cv1 T* cv2 and E is a pointer type that can \
+// | be converted to the type of the handler by either or both of |
+// | o a standard pointer conversion (4.10 [conv.ptr]) not involving |
+// | conversions to private or protected or ambiguous classes |
+// \ o a qualification conversion /
+// * the handler is a pointer or pointer to member type and E is
+// std::nullptr_t
+//
+//===----------------------------------------------------------------------===//
+
+#include <exception>
+#include <stdlib.h>
+#include <assert.h>
+#include <stdio.h>
+
+struct Base {};
+struct Derived : Base {};
+struct Derived2 : Base {};
+struct Ambiguous : Derived, Derived2 {};
+struct Private : private Base {};
+struct Protected : protected Base {};
+
+template <typename T // Handler type
+ ,typename E // Thrown exception type
+ ,typename O // Object type
+ >
+void assert_catches()
+{
+ try
+ {
+ O o;
+ throw static_cast<E>(&o);
+ printf("%s\n", __PRETTY_FUNCTION__);
+ assert(false && "Statements after throw must be unreachable");
+ }
+ catch (T t)
+ {
+ assert(true);
+ return;
+ }
+ catch (...)
+ {
+ printf("%s\n", __PRETTY_FUNCTION__);
+ assert(false && "Should not have entered catch-all");
+ }
+
+ printf("%s\n", __PRETTY_FUNCTION__);
+ assert(false && "The catch should have returned");
+}
+
+template <typename T // Handler type
+ ,typename E // Thrown exception type
+ ,typename O // Object type
+ >
+void assert_cannot_catch()
+{
+ try
+ {
+ O o;
+ throw static_cast<E>(&o);
+ printf("%s\n", __PRETTY_FUNCTION__);
+ assert(false && "Statements after throw must be unreachable");
+ }
+ catch (T t)
+ {
+ printf("%s\n", __PRETTY_FUNCTION__);
+ assert(false && "Should not have entered the catch");
+ }
+ catch (...)
+ {
+ assert(true);
+ return;
+ }
+
+ printf("%s\n", __PRETTY_FUNCTION__);
+ assert(false && "The catch-all should have returned");
+}
+
+void f1()
+{
+ // Test that every combination of handler of type:
+ // cv1 Base * cv2
+ // catches an exception of type:
+ // Derived *
+ assert_catches< Base * , Derived *, Derived>();
+ assert_catches<const Base * , Derived *, Derived>();
+ assert_catches< volatile Base * , Derived *, Derived>();
+ assert_catches<const volatile Base * , Derived *, Derived>();
+ assert_catches< Base * const , Derived *, Derived>();
+ assert_catches<const Base * const , Derived *, Derived>();
+ assert_catches< volatile Base * const , Derived *, Derived>();
+ assert_catches<const volatile Base * const , Derived *, Derived>();
+ assert_catches< Base * volatile, Derived *, Derived>();
+ assert_catches<const Base * volatile, Derived *, Derived>();
+ assert_catches< volatile Base * volatile, Derived *, Derived>();
+ assert_catches<const volatile Base * volatile, Derived *, Derived>();
+ assert_catches< Base * const volatile, Derived *, Derived>();
+ assert_catches<const Base * const volatile, Derived *, Derived>();
+ assert_catches< volatile Base * const volatile, Derived *, Derived>();
+ assert_catches<const volatile Base * const volatile, Derived *, Derived>();
+}
+
+void f2()
+{
+ // Test that every combination of handler of type:
+ // cv1 Base * cv2
+ // catches an exception of type:
+ // Base *
+ assert_catches< Base * , Base *, Derived>();
+ assert_catches<const Base * , Base *, Derived>();
+ assert_catches< volatile Base * , Base *, Derived>();
+ assert_catches<const volatile Base * , Base *, Derived>();
+ assert_catches< Base * const , Base *, Derived>();
+ assert_catches<const Base * const , Base *, Derived>();
+ assert_catches< volatile Base * const , Base *, Derived>();
+ assert_catches<const volatile Base * const , Base *, Derived>();
+ assert_catches< Base * volatile, Base *, Derived>();
+ assert_catches<const Base * volatile, Base *, Derived>();
+ assert_catches< volatile Base * volatile, Base *, Derived>();
+ assert_catches<const volatile Base * volatile, Base *, Derived>();
+ assert_catches< Base * const volatile, Base *, Derived>();
+ assert_catches<const Base * const volatile, Base *, Derived>();
+ assert_catches< volatile Base * const volatile, Base *, Derived>();
+ assert_catches<const volatile Base * const volatile, Base *, Derived>();
+}
+
+void f3()
+{
+ // Test that every combination of handler of type:
+ // cv1 Derived * cv2
+ // catches an exception of type:
+ // Derived *
+ assert_catches< Derived * , Derived *, Derived>();
+ assert_catches<const Derived * , Derived *, Derived>();
+ assert_catches< volatile Derived * , Derived *, Derived>();
+ assert_catches<const volatile Derived * , Derived *, Derived>();
+ assert_catches< Derived * const , Derived *, Derived>();
+ assert_catches<const Derived * const , Derived *, Derived>();
+ assert_catches< volatile Derived * const , Derived *, Derived>();
+ assert_catches<const volatile Derived * const , Derived *, Derived>();
+ assert_catches< Derived * volatile, Derived *, Derived>();
+ assert_catches<const Derived * volatile, Derived *, Derived>();
+ assert_catches< volatile Derived * volatile, Derived *, Derived>();
+ assert_catches<const volatile Derived * volatile, Derived *, Derived>();
+ assert_catches< Derived * const volatile, Derived *, Derived>();
+ assert_catches<const Derived * const volatile, Derived *, Derived>();
+ assert_catches< volatile Derived * const volatile, Derived *, Derived>();
+ assert_catches<const volatile Derived * const volatile, Derived *, Derived>();
+}
+
+void f4()
+{
+ // Test that every combination of handler of type:
+ // cv1 Derived * cv2
+ // cannot catch an exception of type:
+ // Base *
+ assert_cannot_catch< Derived * , Base *, Derived>();
+ assert_cannot_catch<const Derived * , Base *, Derived>();
+ assert_cannot_catch< volatile Derived * , Base *, Derived>();
+ assert_cannot_catch<const volatile Derived * , Base *, Derived>();
+ assert_cannot_catch< Derived * const , Base *, Derived>();
+ assert_cannot_catch<const Derived * const , Base *, Derived>();
+ assert_cannot_catch< volatile Derived * const , Base *, Derived>();
+ assert_cannot_catch<const volatile Derived * const , Base *, Derived>();
+ assert_cannot_catch< Derived * volatile, Base *, Derived>();
+ assert_cannot_catch<const Derived * volatile, Base *, Derived>();
+ assert_cannot_catch< volatile Derived * volatile, Base *, Derived>();
+ assert_cannot_catch<const volatile Derived * volatile, Base *, Derived>();
+ assert_cannot_catch< Derived * const volatile, Base *, Derived>();
+ assert_cannot_catch<const Derived * const volatile, Base *, Derived>();
+ assert_cannot_catch< volatile Derived * const volatile, Base *, Derived>();
+ assert_cannot_catch<const volatile Derived * const volatile, Base *, Derived>();
+}
+
+void f5()
+{
+ // Test that every combination of handler of type:
+ // cv1 Derived * cv2 &
+ // catches an exception of type:
+ // Derived *
+ assert_catches< Derived * &, Derived *, Derived>();
+ assert_catches<const Derived * &, Derived *, Derived>();
+ assert_catches< volatile Derived * &, Derived *, Derived>();
+ assert_catches<const volatile Derived * &, Derived *, Derived>();
+ assert_catches< Derived * const &, Derived *, Derived>();
+ assert_catches<const Derived * const &, Derived *, Derived>();
+ assert_catches< volatile Derived * const &, Derived *, Derived>();
+ assert_catches<const volatile Derived * const &, Derived *, Derived>();
+ assert_catches< Derived * volatile &, Derived *, Derived>();
+ assert_catches<const Derived * volatile &, Derived *, Derived>();
+ assert_catches< volatile Derived * volatile &, Derived *, Derived>();
+ assert_catches<const volatile Derived * volatile &, Derived *, Derived>();
+ assert_catches< Derived * const volatile &, Derived *, Derived>();
+ assert_catches<const Derived * const volatile &, Derived *, Derived>();
+ assert_catches< volatile Derived * const volatile &, Derived *, Derived>();
+ assert_catches<const volatile Derived * const volatile &, Derived *, Derived>();
+}
+
+void f6()
+{
+ // Test that every combination of handler of type:
+ // cv1 Base * cv2 &
+ // catches an exception of type:
+ // Base *
+ assert_catches< Base * &, Base *, Derived>();
+ assert_catches<const Base * &, Base *, Derived>();
+ assert_catches< volatile Base * &, Base *, Derived>();
+ assert_catches<const volatile Base * &, Base *, Derived>();
+ assert_catches< Base * const &, Base *, Derived>();
+ assert_catches<const Base * const &, Base *, Derived>();
+ assert_catches< volatile Base * const &, Base *, Derived>();
+ assert_catches<const volatile Base * const &, Base *, Derived>();
+ assert_catches< Base * volatile &, Base *, Derived>();
+ assert_catches<const Base * volatile &, Base *, Derived>();
+ assert_catches< volatile Base * volatile &, Base *, Derived>();
+ assert_catches<const volatile Base * volatile &, Base *, Derived>();
+ assert_catches< Base * const volatile &, Base *, Derived>();
+ assert_catches<const Base * const volatile &, Base *, Derived>();
+ assert_catches< volatile Base * const volatile &, Base *, Derived>();
+ assert_catches<const volatile Base * const volatile &, Base *, Derived>();
+
+}
+
+void f7()
+{
+ // Test that every combination of handler of type:
+ // cv1 Derived * cv2 &
+ // cannot catch an exception of type:
+ // Base *
+ assert_cannot_catch< Derived * &, Base *, Derived>();
+ assert_cannot_catch<const Derived * &, Base *, Derived>();
+ assert_cannot_catch< volatile Derived * &, Base *, Derived>();
+ assert_cannot_catch<const volatile Derived * &, Base *, Derived>();
+ assert_cannot_catch< Derived * const &, Base *, Derived>();
+ assert_cannot_catch<const Derived * const &, Base *, Derived>();
+ assert_cannot_catch< volatile Derived * const &, Base *, Derived>();
+ assert_cannot_catch<const volatile Derived * const &, Base *, Derived>();
+ assert_cannot_catch< Derived * volatile &, Base *, Derived>();
+ assert_cannot_catch<const Derived * volatile &, Base *, Derived>();
+ assert_cannot_catch< volatile Derived * volatile &, Base *, Derived>();
+ assert_cannot_catch<const volatile Derived * volatile &, Base *, Derived>();
+ assert_cannot_catch< Derived * const volatile &, Base *, Derived>();
+ assert_cannot_catch<const Derived * const volatile &, Base *, Derived>();
+ assert_cannot_catch< volatile Derived * const volatile &, Base *, Derived>();
+ assert_cannot_catch<const volatile Derived * const volatile &, Base *, Derived>();
+}
+
+void f8()
+{
+ // This test case has a caveat noted in the discussion here:
+ // https://gcc.gnu.org/ml/gcc-patches/2009-08/msg00264.html
+ // Specifically:
+ // This [test exposes a] corner case of the ARM C++ ABI. The generic C++
+ // ABI also gets this wrong, because I failed to notice the subtlety here.
+ // The issue is that 15.3/3 3rd bullet says:
+ // The handler is of type cv1 T* cv2 and E is a pointer type that
+ // can be converted to the type of the handler by either or both of:
+ // * a standard pointer conversion (4.10) not involving conversions
+ // to pointers to private or protected or ambiguous classes
+ // Notice that the handlers of type "cv1 T*cv2&" are not allowed such
+ // freedom to find a base class. The ABI error is that we treat handlers
+ // of reference type exactly the same as the corresponding hander of
+ // non-reference type. Elsewhere in the exception handling this makes no
+ // difference (for instance bullet 1 explicitly says 'cv T or cv T&').
+ //
+ // See also: http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#388
+ //
+ // TL;DR: it is an unresolved C++ ABI defect that these do catch
+
+ // Test that every combination of handler of type:
+ // cv1 Base * cv2 &
+ // catches an exception of type:
+ // Derived *
+ assert_catches< Base * &, Derived *, Derived>();
+ assert_catches<const Base * &, Derived *, Derived>();
+ assert_catches< volatile Base * &, Derived *, Derived>();
+ assert_catches<const volatile Base * &, Derived *, Derived>();
+ assert_catches< Base * const &, Derived *, Derived>();
+ assert_catches<const Base * const &, Derived *, Derived>();
+ assert_catches< volatile Base * const &, Derived *, Derived>();
+ assert_catches<const volatile Base * const &, Derived *, Derived>();
+ assert_catches< Base * volatile &, Derived *, Derived>();
+ assert_catches<const Base * volatile &, Derived *, Derived>();
+ assert_catches< volatile Base * volatile &, Derived *, Derived>();
+ assert_catches<const volatile Base * volatile &, Derived *, Derived>();
+ assert_catches< Base * const volatile &, Derived *, Derived>();
+ assert_catches<const Base * const volatile &, Derived *, Derived>();
+ assert_catches< volatile Base * const volatile &, Derived *, Derived>();
+ assert_catches<const volatile Base * const volatile &, Derived *, Derived>();
+}
+
+void f9()
+{
+ // Test that every combination of handler of type:
+ // cv1 Base * cv2
+ // cannot catch an exception of type:
+ // Ambiguous *
+ assert_cannot_catch< Base * , Ambiguous *, Ambiguous>();
+ assert_cannot_catch<const Base * , Ambiguous *, Ambiguous>();
+ assert_cannot_catch< volatile Base * , Ambiguous *, Ambiguous>();
+ assert_cannot_catch<const volatile Base * , Ambiguous *, Ambiguous>();
+ assert_cannot_catch< Base * const , Ambiguous *, Ambiguous>();
+ assert_cannot_catch<const Base * const , Ambiguous *, Ambiguous>();
+ assert_cannot_catch< volatile Base * const , Ambiguous *, Ambiguous>();
+ assert_cannot_catch<const volatile Base * const , Ambiguous *, Ambiguous>();
+ assert_cannot_catch< Base * volatile, Ambiguous *, Ambiguous>();
+ assert_cannot_catch<const Base * volatile, Ambiguous *, Ambiguous>();
+ assert_cannot_catch< volatile Base * volatile, Ambiguous *, Ambiguous>();
+ assert_cannot_catch<const volatile Base * volatile, Ambiguous *, Ambiguous>();
+ assert_cannot_catch< Base * const volatile, Ambiguous *, Ambiguous>();
+ assert_cannot_catch<const Base * const volatile, Ambiguous *, Ambiguous>();
+ assert_cannot_catch< volatile Base * const volatile, Ambiguous *, Ambiguous>();
+ assert_cannot_catch<const volatile Base * const volatile, Ambiguous *, Ambiguous>();
+}
+
+void f10()
+{
+ // Test that every combination of handler of type:
+ // cv1 Base * cv2
+ // cannot catch an exception of type:
+ // Private *
+ assert_cannot_catch< Base * , Private *, Private>();
+ assert_cannot_catch<const Base * , Private *, Private>();
+ assert_cannot_catch< volatile Base * , Private *, Private>();
+ assert_cannot_catch<const volatile Base * , Private *, Private>();
+ assert_cannot_catch< Base * const , Private *, Private>();
+ assert_cannot_catch<const Base * const , Private *, Private>();
+ assert_cannot_catch< volatile Base * const , Private *, Private>();
+ assert_cannot_catch<const volatile Base * const , Private *, Private>();
+ assert_cannot_catch< Base * volatile, Private *, Private>();
+ assert_cannot_catch<const Base * volatile, Private *, Private>();
+ assert_cannot_catch< volatile Base * volatile, Private *, Private>();
+ assert_cannot_catch<const volatile Base * volatile, Private *, Private>();
+ assert_cannot_catch< Base * const volatile, Private *, Private>();
+ assert_cannot_catch<const Base * const volatile, Private *, Private>();
+ assert_cannot_catch< volatile Base * const volatile, Private *, Private>();
+ assert_cannot_catch<const volatile Base * const volatile, Private *, Private>();
+}
+
+void f11()
+{
+ // Test that every combination of handler of type:
+ // cv1 Base * cv2
+ // cannot catch an exception of type:
+ // Protected *
+ assert_cannot_catch< Base * , Protected *, Protected>();
+ assert_cannot_catch<const Base * , Protected *, Protected>();
+ assert_cannot_catch< volatile Base * , Protected *, Protected>();
+ assert_cannot_catch<const volatile Base * , Protected *, Protected>();
+ assert_cannot_catch< Base * const , Protected *, Protected>();
+ assert_cannot_catch<const Base * const , Protected *, Protected>();
+ assert_cannot_catch< volatile Base * const , Protected *, Protected>();
+ assert_cannot_catch<const volatile Base * const , Protected *, Protected>();
+ assert_cannot_catch< Base * volatile, Protected *, Protected>();
+ assert_cannot_catch<const Base * volatile, Protected *, Protected>();
+ assert_cannot_catch< volatile Base * volatile, Protected *, Protected>();
+ assert_cannot_catch<const volatile Base * volatile, Protected *, Protected>();
+ assert_cannot_catch< Base * const volatile, Protected *, Protected>();
+ assert_cannot_catch<const Base * const volatile, Protected *, Protected>();
+ assert_cannot_catch< volatile Base * const volatile, Protected *, Protected>();
+ assert_cannot_catch<const volatile Base * const volatile, Protected *, Protected>();
+}
+
+void f12()
+{
+ // Test that every combination of handler of type:
+ // cv1 Base * cv2 &
+ // cannot catch an exception of type:
+ // Private *
+ assert_cannot_catch< Base * &, Private *, Private>();
+ assert_cannot_catch<const Base * &, Private *, Private>();
+ assert_cannot_catch< volatile Base * &, Private *, Private>();
+ assert_cannot_catch<const volatile Base * &, Private *, Private>();
+ assert_cannot_catch< Base * const &, Private *, Private>();
+ assert_cannot_catch<const Base * const &, Private *, Private>();
+ assert_cannot_catch< volatile Base * const &, Private *, Private>();
+ assert_cannot_catch<const volatile Base * const &, Private *, Private>();
+ assert_cannot_catch< Base * volatile &, Private *, Private>();
+ assert_cannot_catch<const Base * volatile &, Private *, Private>();
+ assert_cannot_catch< volatile Base * volatile &, Private *, Private>();
+ assert_cannot_catch<const volatile Base * volatile &, Private *, Private>();
+ assert_cannot_catch< Base * const volatile &, Private *, Private>();
+ assert_cannot_catch<const Base * const volatile &, Private *, Private>();
+ assert_cannot_catch< volatile Base * const volatile &, Private *, Private>();
+ assert_cannot_catch<const volatile Base * const volatile &, Private *, Private>();
+}
+
+void f13()
+{
+ // Test that every combination of handler of type:
+ // cv1 Base * cv2 &
+ // cannot catch an exception of type:
+ // Protected *
+ assert_cannot_catch< Base * &, Protected *, Protected>();
+ assert_cannot_catch<const Base * &, Protected *, Protected>();
+ assert_cannot_catch< volatile Base * &, Protected *, Protected>();
+ assert_cannot_catch<const volatile Base * &, Protected *, Protected>();
+ assert_cannot_catch< Base * const &, Protected *, Protected>();
+ assert_cannot_catch<const Base * const &, Protected *, Protected>();
+ assert_cannot_catch< volatile Base * const &, Protected *, Protected>();
+ assert_cannot_catch<const volatile Base * const &, Protected *, Protected>();
+ assert_cannot_catch< Base * volatile &, Protected *, Protected>();
+ assert_cannot_catch<const Base * volatile &, Protected *, Protected>();
+ assert_cannot_catch< volatile Base * volatile &, Protected *, Protected>();
+ assert_cannot_catch<const volatile Base * volatile &, Protected *, Protected>();
+ assert_cannot_catch< Base * const volatile &, Protected *, Protected>();
+ assert_cannot_catch<const Base * const volatile &, Protected *, Protected>();
+ assert_cannot_catch< volatile Base * const volatile &, Protected *, Protected>();
+ assert_cannot_catch<const volatile Base * const volatile &, Protected *, Protected>();
+}
+
+int main()
+{
+ f1();
+ f2();
+ f3();
+ f4();
+ f5();
+ f6();
+ f7();
+ f8();
+ f9();
+ f10();
+ f11();
+ f12();
+ f13();
+}
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_ptr.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_ptr.pass.cpp
similarity index 100%
rename from ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_ptr.cpp
rename to ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_ptr.pass.cpp
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_ptr_02.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_ptr_02.pass.cpp
similarity index 97%
rename from ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_ptr_02.cpp
rename to ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_ptr_02.pass.cpp
index 9421782..34af3c8 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_ptr_02.cpp
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/catch_ptr_02.pass.cpp
@@ -135,9 +135,10 @@
void test8 ()
{
+ vDerived derived;
try
{
- throw new vDerived;
+ throw &derived;
assert(false);
}
catch (vBase *p) {
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/cxa_thread_atexit_test.pass.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/cxa_thread_atexit_test.pass.cpp
new file mode 100644
index 0000000..e3b0797
--- /dev/null
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/cxa_thread_atexit_test.pass.cpp
@@ -0,0 +1,33 @@
+//===--------------------- cxa_thread_atexit_test.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.
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: linux
+
+#include <assert.h>
+#include <cxxabi.h>
+
+static bool AtexitImplCalled = false;
+
+extern "C" int __cxa_thread_atexit_impl(void (*dtor)(void *), void *obj,
+ void *dso_symbol) {
+ assert(dtor == reinterpret_cast<void (*)(void *)>(1));
+ assert(obj == reinterpret_cast<void *>(2));
+ assert(dso_symbol == reinterpret_cast<void *>(3));
+ AtexitImplCalled = true;
+ return 4;
+}
+
+int main() {
+ int RV = __cxxabiv1::__cxa_thread_atexit(
+ reinterpret_cast<void (*)(void *)>(1), reinterpret_cast<void *>(2),
+ reinterpret_cast<void *>(3));
+ assert(RV = 4);
+ assert(AtexitImplCalled);
+ return 0;
+}
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/dynamic_cast14.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/dynamic_cast14.pass.cpp
similarity index 99%
rename from ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/dynamic_cast14.cpp
rename to ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/dynamic_cast14.pass.cpp
index 2145fb4..c929e38 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/dynamic_cast14.cpp
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/dynamic_cast14.pass.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include <cassert>
+#include "support/timer.hpp"
namespace t1
{
@@ -2172,18 +2173,10 @@
} // t3
-#include <chrono>
-#include <iostream>
-
int main()
{
- typedef std::chrono::high_resolution_clock Clock;
- typedef Clock::time_point time_point;
- typedef std::chrono::duration<double, std::micro> NS;
- time_point t0 = Clock::now();
+ timer t;
t1::test();
t2::test();
t3::test();
- time_point t1 = Clock::now();
- std::cout << NS(t1-t0).count() << " microseconds\n";
}
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/dynamic_cast3.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/dynamic_cast3.pass.cpp
similarity index 98%
rename from ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/dynamic_cast3.cpp
rename to ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/dynamic_cast3.pass.cpp
index 2ce77f3..afd4ad8 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/dynamic_cast3.cpp
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/dynamic_cast3.pass.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include <cassert>
+#include "support/timer.hpp"
/*
@@ -2406,15 +2407,9 @@
} // t41
-#include <chrono>
-#include <iostream>
-
int main()
{
- typedef std::chrono::high_resolution_clock Clock;
- typedef Clock::time_point time_point;
- typedef std::chrono::duration<double, std::micro> NS;
- time_point t0 = Clock::now();
+ timer t;
t1::test();
t2::test();
t3::test();
@@ -2456,6 +2451,4 @@
t39::test();
t40::test();
t41::test();
- time_point t1 = Clock::now();
- std::cout << NS(t1-t0).count() << " microseconds\n";
}
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/dynamic_cast5.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/dynamic_cast5.pass.cpp
similarity index 98%
rename from ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/dynamic_cast5.cpp
rename to ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/dynamic_cast5.pass.cpp
index 8986969..d7064f4 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/dynamic_cast5.cpp
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/dynamic_cast5.pass.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include <cassert>
+#include "support/timer.hpp"
namespace t1
{
@@ -1298,15 +1299,10 @@
} // t9
-#include <chrono>
-#include <iostream>
int main()
{
- typedef std::chrono::high_resolution_clock Clock;
- typedef Clock::time_point time_point;
- typedef std::chrono::duration<double, std::micro> NS;
- time_point t0 = Clock::now();
+ timer t;
t1::test();
t2::test();
t3::test();
@@ -1316,6 +1312,4 @@
t7::test();
t8::test();
t9::test();
- time_point t1 = Clock::now();
- std::cout << NS(t1-t0).count() << " microseconds\n";
}
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/dynamic_cast_stress.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/dynamic_cast_stress.pass.cpp
similarity index 84%
rename from ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/dynamic_cast_stress.cpp
rename to ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/dynamic_cast_stress.pass.cpp
index c3e5d0a..95276b2 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/dynamic_cast_stress.cpp
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/dynamic_cast_stress.pass.cpp
@@ -9,8 +9,7 @@
#include <cassert>
#include <tuple>
-#include <chrono>
-#include <iostream>
+#include "support/timer.hpp"
template <std::size_t Indx, std::size_t Depth>
struct C
@@ -50,17 +49,16 @@
void test()
{
- typedef std::chrono::high_resolution_clock Clock;
- typedef std::chrono::duration<double, std::micro> US;
const std::size_t Width = 10;
const std::size_t Depth = 5;
A<Width, Depth> a;
typedef B<Width/2, Depth> Destination;
// typedef A<Width, Depth> Destination;
- auto t0 = Clock::now();
- Destination* b = dynamic_cast<Destination*>((C<Width/2, 0>*)&a);
- auto t1 = Clock::now();
- std::cout << US(t1-t0).count() << " microseconds\n";
+ Destination *b = nullptr;
+ {
+ timer t;
+ b = dynamic_cast<Destination*>((C<Width/2, 0>*)&a);
+ }
assert(b != 0);
}
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/inherited_exception.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/inherited_exception.pass.cpp
similarity index 64%
rename from ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/inherited_exception.cpp
rename to ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/inherited_exception.pass.cpp
index e9a7e95..7c106c1 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/inherited_exception.cpp
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/inherited_exception.pass.cpp
@@ -6,6 +6,24 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
+// This test case checks specifically the cases under C++ ABI 15.3.1, and 15.3.2
+//
+// C++ ABI 15.3:
+// A handler is a match for an exception object of type E if
+// / * The handler is of type cv T or cv T& and E and T are the same type \
+// | (ignoring the top-level cv-qualifiers), or |
+// | * the handler is of type cv T or cv T& and T is an unambiguous base |
+// \ class of E, or /
+// * the handler is of type cv1 T* cv2 and E is a pointer type that can
+// be converted to the type of the handler by either or both of
+// o a standard pointer conversion (4.10 [conv.ptr]) not involving
+// conversions to private or protected or ambiguous classes
+// o a qualification conversion
+// * the handler is a pointer or pointer to member type and E is
+// std::nullptr_t
+//
+//===----------------------------------------------------------------------===//
#include <assert.h>
@@ -38,11 +56,11 @@
}
void f3() {
- Child* child = new Child;
- child->b1 = 10;
- child->b2 = 11;
- child->c = 12;
- throw static_cast<Base2*>(child);
+ static Child child;
+ child.b1 = 10;
+ child.b2 = 11;
+ child.c = 12;
+ throw static_cast<Base2*>(&child);
}
int main()
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/libcxxabi/__init__.py b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/libcxxabi/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/libcxxabi/__init__.py
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/libcxxabi/test/__init__.py b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/libcxxabi/test/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/libcxxabi/test/__init__.py
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/libcxxabi/test/config.py b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/libcxxabi/test/config.py
new file mode 100644
index 0000000..d08aff8
--- /dev/null
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/libcxxabi/test/config.py
@@ -0,0 +1,80 @@
+import os
+import sys
+
+from libcxx.test.config import Configuration as LibcxxConfiguration
+
+
+class Configuration(LibcxxConfiguration):
+ # pylint: disable=redefined-outer-name
+ def __init__(self, lit_config, config):
+ super(Configuration, self).__init__(lit_config, config)
+ self.libcxxabi_src_root = None
+ self.libcxxabi_obj_root = None
+ self.libcxxabi_lib_root = None
+ self.libcxx_src_root = None
+
+ def configure_src_root(self):
+ self.libcxxabi_src_root = self.get_lit_conf(
+ 'libcxxabi_src_root',
+ os.path.dirname(self.config.test_source_root))
+ self.libcxx_src_root = self.get_lit_conf(
+ 'libcxx_src_root',
+ os.path.join(self.libcxxabi_src_root, '/../libcxx'))
+
+ def configure_obj_root(self):
+ self.libcxxabi_obj_root = self.get_lit_conf('libcxxabi_obj_root')
+ self.libcxxabi_lib_root = self.get_lit_conf('libcxxabi_lib_root',
+ self.libcxxabi_obj_root)
+ super(Configuration, self).configure_obj_root()
+
+ def configure_compile_flags(self):
+ self.cxx.compile_flags += ['-DLIBCXXABI_NO_TIMER']
+ super(Configuration, self).configure_compile_flags()
+
+ def configure_compile_flags_header_includes(self):
+ cxx_headers = self.get_lit_conf(
+ 'cxx_headers',
+ os.path.join(self.libcxx_src_root, '/include'))
+ if not os.path.isdir(cxx_headers):
+ self.lit_config.fatal("cxx_headers='%s' is not a directory."
+ % cxx_headers)
+ self.cxx.compile_flags += ['-I' + cxx_headers]
+
+ libcxxabi_headers = self.get_lit_conf(
+ 'libcxxabi_headers',
+ os.path.join(self.libcxxabi_src_root, 'include'))
+ if not os.path.isdir(libcxxabi_headers):
+ self.lit_config.fatal("libcxxabi_headers='%s' is not a directory."
+ % libcxxabi_headers)
+ self.cxx.compile_flags += ['-I' + libcxxabi_headers]
+
+ def configure_compile_flags_exceptions(self):
+ pass
+
+ def configure_compile_flags_rtti(self):
+ pass
+
+ def configure_compile_flags_no_threads(self):
+ self.cxx.compile_flags += ['-DLIBCXXABI_HAS_NO_THREADS=1']
+
+ def configure_compile_flags_no_monotonic_clock(self):
+ pass
+
+ def configure_link_flags_abi_library_path(self):
+ # Configure ABI library paths.
+ if self.libcxxabi_lib_root:
+ self.cxx.link_flags += ['-L' + self.libcxxabi_lib_root,
+ '-Wl,-rpath,' + self.libcxxabi_lib_root]
+
+ # TODO(ericwf): Remove this. This is a hack for OS X.
+ # libc++ *should* export all of the symbols found in libc++abi on OS X.
+ # For this reason LibcxxConfiguration will not link libc++abi in OS X.
+ # However __cxa_throw_bad_new_array_length doesn't get exported into libc++
+ # yet so we still need to explicitly link libc++abi.
+ # See PR22654.
+ def configure_link_flags_abi_library(self):
+ self.cxx.link_flags += ['-lc++abi']
+
+ def configure_env(self):
+ if sys.platform == 'darwin' and self.libcxxabi_lib_root:
+ self.env['DYLD_LIBRARY_PATH'] = self.libcxxabi_lib_root
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/lit.cfg b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/lit.cfg
new file mode 100644
index 0000000..ae46288
--- /dev/null
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/lit.cfg
@@ -0,0 +1,67 @@
+# -*- Python -*- vim: set ft=python ts=4 sw=4 expandtab tw=79:
+
+# Configuration file for the 'lit' test runner.
+
+
+import os
+import site
+
+site.addsitedir(os.path.dirname(__file__))
+
+
+# Tell pylint that we know config and lit_config exist somewhere.
+if 'PYLINT_IMPORT' in os.environ:
+ config = object()
+ lit_config = object()
+
+# name: The name of this test suite.
+config.name = 'libc++abi'
+
+# suffixes: A list of file extensions to treat as test files.
+config.suffixes = ['.cpp']
+
+# test_source_root: The root path where tests are located.
+config.test_source_root = os.path.dirname(__file__)
+
+# Infer the libcxx_test_source_root for configuration import.
+# If libcxx_source_root isn't specified in the config, assume that the libcxx
+# and libcxxabi source directories are sibling directories.
+libcxx_src_root = getattr(config, 'libcxx_src_root', None)
+if not libcxx_src_root:
+ libcxx_src_root = os.path.join(config.test_source_root, '../../libcxx')
+libcxx_test_src_root = os.path.join(libcxx_src_root, 'test')
+if os.path.isfile(os.path.join(libcxx_test_src_root, 'libcxx', '__init__.py')):
+ site.addsitedir(libcxx_test_src_root)
+else:
+ lit_config.fatal('Could not find libcxx test directory for test imports'
+ ' in: %s' % libcxx_test_src_root)
+
+# Infer the test_exec_root from the libcxx_object root.
+obj_root = getattr(config, 'libcxxabi_obj_root', None)
+
+# Check that the test exec root is known.
+if obj_root is None:
+ import libcxx.test.config
+ libcxx.test.config.loadSiteConfig(
+ lit_config, config, 'libcxxabi_site_config', 'LIBCXXABI_SITE_CONFIG')
+ obj_root = getattr(config, 'libcxxabi_obj_root', None)
+ if obj_root is None:
+ import tempfile
+ obj_root = tempfile.mkdtemp(prefix='libcxxabi-testsuite-')
+ lit_config.warning('Creating temporary directory for object root: %s' %
+ obj_root)
+
+config.test_exec_root = os.path.join(obj_root, 'test')
+
+cfg_variant = getattr(config, 'configuration_variant', 'libcxxabi')
+if cfg_variant:
+ print 'Using configuration variant: %s' % cfg_variant
+
+# Load the Configuration class from the module name <cfg_variant>.test.config.
+config_module_name = '.'.join([cfg_variant, 'test', 'config'])
+config_module = __import__(config_module_name, fromlist=['Configuration'])
+
+configuration = config_module.Configuration(lit_config, config)
+configuration.configure()
+configuration.print_config_info()
+config.test_format = configuration.get_test_format()
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/lit.site.cfg.in b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/lit.site.cfg.in
new file mode 100644
index 0000000..c033dbb
--- /dev/null
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/lit.site.cfg.in
@@ -0,0 +1,16 @@
+@AUTO_GEN_COMMENT@
+config.cxx_under_test = "@LIBCXXABI_COMPILER@"
+config.libcxxabi_src_root = "@LIBCXXABI_SOURCE_DIR@"
+config.libcxxabi_obj_root = "@LIBCXXABI_BINARY_DIR@"
+config.libcxxabi_lib_root = "@LIBCXXABI_LIBRARY_DIR@"
+config.libcxx_src_root = "@LIBCXXABI_LIBCXX_PATH@"
+config.cxx_headers = "@LIBCXXABI_LIBCXX_INCLUDES@"
+config.llvm_unwinder = "@LIBCXXABI_USE_LLVM_UNWINDER@"
+config.enable_threads = "@LIBCXXABI_ENABLE_THREADS@"
+config.use_sanitizer = "@LLVM_USE_SANITIZER@"
+config.enable_32bit = "@LIBCXXABI_BUILD_32_BITS@"
+config.target_info = "@LIBCXXABI_TARGET_INFO@"
+config.executor = "@LIBCXXABI_EXECUTOR@"
+
+# Let the main config do the real work.
+lit_config.load_config(config, "@LIBCXXABI_SOURCE_DIR@/test/lit.cfg")
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/support/timer.hpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/support/timer.hpp
new file mode 100644
index 0000000..5d6ad30
--- /dev/null
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/support/timer.hpp
@@ -0,0 +1,46 @@
+#ifndef TIMER_HPP
+#define TIMER_HPP
+
+// Define LIBCXXABI_NO_TIMER to disable testing with a timer.
+#ifndef LIBCXXABI_NO_TIMER
+
+#include <chrono>
+#include <iostream>
+
+class timer
+{
+ typedef std::chrono::high_resolution_clock Clock;
+ typedef Clock::time_point TimePoint;
+ typedef std::chrono::microseconds MicroSeconds;
+public:
+ timer() : m_start(Clock::now()) {}
+
+ timer(timer const &) = delete;
+ timer & operator=(timer const &) = delete;
+
+ ~timer()
+ {
+ using std::chrono::duration_cast;
+ TimePoint end = Clock::now();
+ MicroSeconds us = duration_cast<MicroSeconds>(end - m_start);
+ std::cout << us.count() << " microseconds\n";
+ }
+
+private:
+ TimePoint m_start;
+};
+
+#else /* LIBCXXABI_NO_TIMER */
+
+class timer
+{
+public:
+ timer() {}
+ timer(timer const &) = delete;
+ timer & operator=(timer const &) = delete;
+ ~timer() {}
+};
+
+#endif /* LIBCXXABI_NO_TIMER */
+
+#endif /* TIMER_HPP */
\ No newline at end of file
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_aux_runtime.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_aux_runtime.pass.cpp
similarity index 100%
rename from ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_aux_runtime.cpp
rename to ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_aux_runtime.pass.cpp
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_aux_runtime_op_array_new.pass.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_aux_runtime_op_array_new.pass.cpp
new file mode 100644
index 0000000..8d9f547
--- /dev/null
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_aux_runtime_op_array_new.pass.cpp
@@ -0,0 +1,38 @@
+//===-------------------------- test_aux_runtime_op_array_new.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.
+//
+//===----------------------------------------------------------------------===//
+
+#include <iostream>
+#include <cxxabi.h>
+
+// If the expression passed to operator new[] would result in an overflow, the
+// allocation function is not called, and a std::bad_array_new_length exception
+// is thrown instead (5.3.4p7).
+bool bad_array_new_length_test() {
+ try {
+ // We test this directly because Clang does not currently codegen the
+ // correct call to __cxa_bad_array_new_length, so this test would result
+ // in passing -1 to ::operator new[], which would then throw a
+ // std::bad_alloc, causing the test to fail.
+ __cxxabiv1::__cxa_throw_bad_array_new_length();
+ } catch ( const std::bad_array_new_length &banl ) {
+ return true;
+ }
+ return false;
+}
+
+int main(int argc, char *argv []) {
+ int ret_val = 0;
+
+ if ( !bad_array_new_length_test ()) {
+ std::cerr << "Bad array new length test failed!" << std::endl;
+ ret_val = 1;
+ }
+
+ return ret_val;
+}
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_demangle.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_demangle.pass.cpp
similarity index 99%
rename from ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_demangle.cpp
rename to ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_demangle.pass.cpp
index 15cb3a1..8a4685a 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_demangle.cpp
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_demangle.pass.cpp
@@ -7,12 +7,12 @@
//
//===----------------------------------------------------------------------===//
+#include "support/timer.hpp"
#include <iostream>
#include <string>
#include <cstdlib>
#include <cxxabi.h>
#include <cassert>
-#include <chrono>
// Is long double fp80? (Only x87 extended double has 64-bit mantissa)
#define LDBL_FP80 (__LDBL_MANT_DIG__ == 64)
@@ -29664,14 +29664,12 @@
int main()
{
- typedef std::chrono::high_resolution_clock Clock;
- typedef std::chrono::duration<double> sec;
- Clock::time_point t0 = Clock::now();
- test();
- test2();
- Clock::time_point t1 = Clock::now();
- std::cout << sec(t1-t0).count() << " seconds for test\n";
- std::cout << N / sec(t1-t0).count() / 1000000. << " million symbols per second\n";
+ std::cout << "Testing " << N << " symbols." << std::endl;
+ {
+ timer t;
+ test();
+ test2();
+ }
#if 0
std::string input;
while (std::cin)
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_exception_storage.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_exception_storage.pass.cpp
similarity index 88%
rename from ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_exception_storage.cpp
rename to ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_exception_storage.pass.cpp
index 9a01236..0d5deaa 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_exception_storage.cpp
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_exception_storage.pass.cpp
@@ -12,7 +12,7 @@
#include <cstdlib>
#include <algorithm>
#include <iostream>
-#if !LIBCXXABI_SINGLE_THREADED
+#if !LIBCXXABI_HAS_NO_THREADS
# include <pthread.h>
#endif
#include <unistd.h>
@@ -26,25 +26,19 @@
globals_t *glob1, *glob2;
glob1 = __cxxabiv1::__cxa_get_globals ();
- if ( NULL == glob1 ) {
+ if ( NULL == glob1 )
std::cerr << "Got null result from __cxa_get_globals" << std::endl;
- return 0;
- }
glob2 = __cxxabiv1::__cxa_get_globals_fast ();
- if ( glob1 != glob2 ) {
+ if ( glob1 != glob2 )
std::cerr << "Got different globals!" << std::endl;
- return 0;
- }
-
+
*result = (size_t) glob1;
-#if !LIBCXXABI_SINGLE_THREADED
sleep ( 1 );
-#endif
return parm;
}
-#if !LIBCXXABI_SINGLE_THREADED
+#if !LIBCXXABI_HAS_NO_THREADS
#define NUMTHREADS 10
size_t thread_globals [ NUMTHREADS ] = { 0 };
pthread_t threads [ NUMTHREADS ];
@@ -60,9 +54,12 @@
int main ( int argc, char *argv [] ) {
int retVal = 0;
-#if LIBCXXABI_SINGLE_THREADED
+#if LIBCXXABI_HAS_NO_THREADS
size_t thread_globals;
- retVal = thread_code(&thread_globals) != &thread_globals;
+ // Check that __cxa_get_globals() is not NULL.
+ if (thread_code(&thread_globals) == 0) {
+ retVal = 1;
+ }
#else
// Make the threads, let them run, and wait for them to finish
for ( int i = 0; i < NUMTHREADS; ++i )
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_fallback_malloc.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_fallback_malloc.pass.cpp
similarity index 100%
rename from ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_fallback_malloc.cpp
rename to ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_fallback_malloc.pass.cpp
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_guard.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_guard.pass.cpp
similarity index 94%
rename from ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_guard.cpp
rename to ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_guard.pass.cpp
index 805ec81..41ff794 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_guard.cpp
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_guard.pass.cpp
@@ -11,8 +11,9 @@
#include "cxxabi.h"
#include <cassert>
-#if !LIBCXXABI_SINGLE_THREADED
-# include <thread>
+
+#if !LIBCXXABI_HAS_NO_THREADS
+#include <thread>
#endif
// Ensure that we initialize each variable once and only once.
@@ -75,7 +76,7 @@
}
}
-#if !LIBCXXABI_SINGLE_THREADED
+#if !LIBCXXABI_HAS_NO_THREADS
// A simple thread test of two threads racing to initialize a variable. This
// isn't guaranteed to catch any particular threading problems.
namespace test4 {
@@ -127,14 +128,14 @@
assert(run_count == 1);
}
}
-#endif
+#endif /* LIBCXXABI_HAS_NO_THREADS */
int main()
{
test1::test();
test2::test();
test3::test();
-#if !LIBCXXABI_SINGLE_THREADED
+#if !LIBCXXABI_HAS_NO_THREADS
test4::test();
test5::test();
#endif
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_vector1.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_vector1.pass.cpp
similarity index 95%
rename from ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_vector1.cpp
rename to ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_vector1.pass.cpp
index b8bf45c..6790cb5 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_vector1.cpp
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_vector1.pass.cpp
@@ -11,6 +11,7 @@
#include <iostream>
#include <cstdlib>
+#include <cassert>
// Wrapper routines
void *my_alloc2 ( size_t sz ) {
@@ -206,31 +207,32 @@
int test_exception_in_destructor ( ) {
int retVal = 0;
void *one, *two, *three;
+ one = two = three = NULL;
// Throw from within a destructor
gConstructorCounter = gDestructorCounter = 0;
gConstructorThrowTarget = -1;
gDestructorThrowTarget = 15;
try {
- one = two = three = NULL;
+ one = two = NULL;
one = __cxxabiv1::__cxa_vec_new ( 10, 40, 8, throw_construct, throw_destruct );
two = __cxxabiv1::__cxa_vec_new2( 10, 40, 8, throw_construct, throw_destruct, my_alloc2, my_dealloc2 );
- three = __cxxabiv1::__cxa_vec_new3( 10, 40, 8, throw_construct, throw_destruct, my_alloc2, my_dealloc3 );
}
catch ( int i ) {}
try {
__cxxabiv1::__cxa_vec_delete ( one, 40, 8, throw_destruct );
__cxxabiv1::__cxa_vec_delete2( two, 40, 8, throw_destruct, my_dealloc2 );
- __cxxabiv1::__cxa_vec_delete3( three, 40, 8, throw_destruct, my_dealloc3 );
+ assert(false);
}
catch ( int i ) {}
// We should have thrown in the middle of cleaning up "two", which means that
-// there should be 20 calls to the destructor, and "three" was not cleaned up.
- if ( gConstructorCounter != 30 || gDestructorCounter != 20 ) {
+// there should be 20 calls to the destructor and the try block should exit
+// before the assertion.
+ if ( gConstructorCounter != 20 || gDestructorCounter != 20 ) {
std::cerr << "Unexpected Constructor/Destructor calls (1D)" << std::endl;
- std::cerr << "Expected (30, 20), but got (" << gConstructorCounter << ", " <<
+ std::cerr << "Expected (20, 20), but got (" << gConstructorCounter << ", " <<
gDestructorCounter << ")" << std::endl;
retVal = 1;
}
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_vector2.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_vector2.pass.cpp
similarity index 100%
rename from ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_vector2.cpp
rename to ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_vector2.pass.cpp
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_vector3.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_vector3.pass.cpp
similarity index 100%
rename from ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_vector3.cpp
rename to ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/test_vector3.pass.cpp
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/testit b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/testit
index 99a6c71..ac52f05 100755
--- a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/testit
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/testit
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
# //===--------------------------- testit ---------------------------------===//
# //
# // The LLVM Compiler Infrastructure
@@ -8,9 +8,9 @@
# //
# //===--------------------------------------------------------------------===//
-if [ -z $CXX ]
+if [ -z "$CC" ]
then
- CXX=clang++
+ CC=clang++
fi
if [ -z "$OPTIONS" ]
@@ -18,17 +18,12 @@
OPTIONS="-std=c++0x -stdlib=libc++"
fi
-if [ -z "$QEMU" ]
-then
- QEMU=qemu-system-arm
-fi
-
case $TRIPLE in
*-*-mingw* | *-*-cygwin* | *-*-win*)
- TEST_EXE_SUFFIX=.exe
+ TEST_EXE=test.exe
;;
*)
- TEST_EXE_SUFFIX=.out
+ TEST_EXE=a.out
;;
esac
@@ -38,72 +33,41 @@
IMPLEMENTED_FAIL=0
IMPLEMENTED_PASS=0
-function compile
-{
- echo " [COMPILE] $1"
- echo $CXX $OPTIONS $HEADER_INCLUDE $SOURCE_LIB $LIBS -o $1$TEST_EXE_SUFFIX $1 test_wrapper.cc
- $CXX $OPTIONS $HEADER_INCLUDE $SOURCE_LIB $LIBS -o $1$TEST_EXE_SUFFIX $1 test_wrapper.cc
-}
-
-function run
-{
- echo " [RUN ] $1"
- case $TRIPLE in
- armv4-none-eabi)
- echo $QEMU -semihosting -M integratorcp -cpu arm1026 -kernel $1
- $QEMU -semihosting -M integratorcp -cpu arm1026 -kernel $1 | awk 'BEGIN { f=0; } /PASS/ { next } /FAIL/ { f=1; print; next } { print } END { exit f }'
- ;;
- thumbv4t-none-eabi)
- echo $QEMU -semihosting -M integratorcp -cpu arm926 -kernel $1
- $QEMU -semihosting -M integratorcp -cpu arm1026 -kernel $1 | awk 'BEGIN { f=0; } /PASS/ { next } /FAIL/ { f=1; print; next } { print } END { exit f }'
- ;;
- thumbv6m-none-eabi)
- echo $QEMU -semihosting -M integratorcp -cpu cortex-m3 -kernel $1
- $QEMU -semihosting -M integratorcp -cpu cortex-m3 -kernel $1 | awk 'BEGIN { f=0; } /PASS/ { next } /FAIL/ { f=1; print; next } { print } END { exit f }'
- ;;
- thumbv7t-none-eabi)
- echo $QEMU -semihosting -M integratorcp -cpu cortex-a8 -kernel $1
- $QEMU -semihosting -M integratorcp -cpu cortex-a8 -kernel $1 | awk 'BEGIN { f=0; } /PASS/ { next } /FAIL/ { f=1; print; next } { print } END { exit f }'
- ;;
- *)
- $1
- ;;
- esac
-}
-
-function afunc
+afunc()
{
fail=0
pass=0
- if (ls *.fail.cpp &> /dev/null)
+ if (ls *.fail.cpp > /dev/null 2>&1)
then
for FILE in $(ls *.fail.cpp); do
- if compile $FILE &> /dev/null
+ if $CC $OPTIONS $HEADER_INCLUDE $SOURCE_LIB $FILE $LIBS -o ./$TEST_EXE > /dev/null 2>&1
then
- rm $FILE$TEST_EXE_SUFFIX
- echo " [FAIL ] $FILE should not compile"
- let "fail+=1"
+ rm ./$TEST_EXE
+ echo "$FILE should not compile"
+ fail=$(($fail + 1))
else
- let "pass+=1"
+ pass=$(($pass + 1))
fi
done
fi
- if (ls *.cpp &> /dev/null)
+ if (ls *.cpp > /dev/null 2>&1)
then
- for FILE in $(ls *.cpp); do
- if compile $FILE
+ for FILE in $(ls *.pass.cpp); do
+ if $CC $OPTIONS $HEADER_INCLUDE $SOURCE_LIB $FILE $LIBS -o ./$TEST_EXE
then
- if run $FILE$TEST_EXE_SUFFIX
+ if ./$TEST_EXE
then
- let "pass+=1"
+ rm ./$TEST_EXE
+ pass=$(($pass + 1))
else
- echo " [FAIL ] $FILE failed at run time"
- let "fail+=1"
+ echo "$FILE failed at run time"
+ fail=$(($fail + 1))
+ rm ./$TEST_EXE
fi
else
- echo " [FAIL ] $FILE failed to compile"
- let "fail+=1"
+ echo "$FILE failed to compile"
+ fail=$(($fail + 1))
fi
done
fi
@@ -111,24 +75,24 @@
if [ $fail -gt 0 ]
then
echo "failed $fail tests in `pwd`"
- let "IMPLEMENTED_FAIL+=1"
+ IMPLEMENTED_FAIL=$(($IMPLEMENTED_FAIL + 1))
fi
if [ $pass -gt 0 ]
then
echo "passed $pass tests in `pwd`"
if [ $fail -eq 0 ]
then
- let "IMPLEMENTED_PASS+=1"
+ IMPLEMENTED_PASS=$(($IMPLEMENTED_PASS + 1))
fi
fi
if [ $fail -eq 0 -a $pass -eq 0 ]
then
echo "not implemented: `pwd`"
- let "UNIMPLEMENTED+=1"
+ UNIMPLEMENTED=$(($UNIMPLEMENTED + 1))
fi
- let "FAIL+=$fail"
- let "PASS+=$pass"
+ FAIL=$(($FAIL + $fail))
+ PASS=$(($PASS + $pass))
for FILE in *
do
@@ -145,7 +109,7 @@
echo "****************************************************"
echo "Results for `pwd`:"
-echo "using `$CXX --version`"
+echo "using `$CC --version`"
echo "with $OPTIONS $HEADER_INCLUDE $SOURCE_LIB"
echo "----------------------------------------------------"
echo "sections without tests : $UNIMPLEMENTED"
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/unwind_01.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/unwind_01.pass.cpp
similarity index 100%
rename from ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/unwind_01.cpp
rename to ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/unwind_01.pass.cpp
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/unwind_02.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/unwind_02.pass.cpp
similarity index 100%
rename from ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/unwind_02.cpp
rename to ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/unwind_02.pass.cpp
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/unwind_03.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/unwind_03.pass.cpp
similarity index 100%
rename from ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/unwind_03.cpp
rename to ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/unwind_03.pass.cpp
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/unwind_04.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/unwind_04.pass.cpp
similarity index 100%
rename from ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/unwind_04.cpp
rename to ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/unwind_04.pass.cpp
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/unwind_05.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/unwind_05.pass.cpp
similarity index 100%
rename from ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/unwind_05.cpp
rename to ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/unwind_05.pass.cpp
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/unwind_06.cpp b/ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/unwind_06.pass.cpp
similarity index 100%
rename from ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/unwind_06.cpp
rename to ndk/sources/cxx-stl/llvm-libc++abi/libcxxabi/test/unwind_06.pass.cpp
diff --git a/ndk/sources/cxx-stl/llvm-libc++abi/sources.mk b/ndk/sources/cxx-stl/llvm-libc++abi/sources.mk
index 5a460f0..40ef4ea 100644
--- a/ndk/sources/cxx-stl/llvm-libc++abi/sources.mk
+++ b/ndk/sources/cxx-stl/llvm-libc++abi/sources.mk
@@ -1,6 +1,6 @@
libcxxabi_path := $(call my-dir)
-libcxxabi_src_files := \
+libcxxabi_src_base_files := \
libcxxabi/src/abort_message.cpp \
libcxxabi/src/cxa_aux_runtime.cpp \
libcxxabi/src/cxa_default_handlers.cpp \
@@ -11,20 +11,25 @@
libcxxabi/src/cxa_handlers.cpp \
libcxxabi/src/cxa_new_delete.cpp \
libcxxabi/src/cxa_personality.cpp \
+ libcxxabi/src/cxa_thread_atexit.cpp \
libcxxabi/src/cxa_unexpected.cpp \
libcxxabi/src/cxa_vector.cpp \
libcxxabi/src/cxa_virtual.cpp \
libcxxabi/src/exception.cpp \
libcxxabi/src/private_typeinfo.cpp \
libcxxabi/src/stdexcept.cpp \
- libcxxabi/src/typeinfo.cpp \
+ libcxxabi/src/typeinfo.cpp
+
+libcxxabi_src_unwind_files := \
libcxxabi/src/Unwind/libunwind.cpp \
libcxxabi/src/Unwind/Unwind-EHABI.cpp \
+ libcxxabi/src/Unwind/Unwind-sjlj.c \
libcxxabi/src/Unwind/UnwindLevel1.c \
libcxxabi/src/Unwind/UnwindLevel1-gcc-ext.c \
libcxxabi/src/Unwind/UnwindRegistersRestore.S \
- libcxxabi/src/Unwind/UnwindRegistersSave.S \
- libcxxabi/src/Unwind/Unwind-sjlj.c
+ libcxxabi/src/Unwind/UnwindRegistersSave.S
+
+libcxxabi_src_files := $(libcxxabi_src_base_files) $(libcxxabi_src_unwind_files)
libcxxabi_c_includes := $(libcxxabi_path)/libcxxabi/include