aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmit Pundir <amit.pundir@linaro.org>2014-05-06 22:15:58 +0530
committerAmit Pundir <amit.pundir@linaro.org>2014-05-06 22:15:58 +0530
commit1fcaeb31651c3a864526532f4cf64601f45a0a27 (patch)
tree74b010612d6319c361796f63c74c031217153632
parent963b5903b6056e17d95652e2c2f4e2c230a45dd2 (diff)
parent7c04242d6fcd486d16c7848fed599cbda658f6d7 (diff)
downloadlibunwind-linaro-juice-master.tar.gz
* aosp/master: Fix x86/x86_64 getcontext overflow problem.
-rw-r--r--Android.build.mk5
-rw-r--r--Android.mk50
-rw-r--r--android/tests/local_test.cpp41
-rw-r--r--src/x86/getcontext-linux.S3
-rw-r--r--src/x86_64/getcontext.S4
5 files changed, 102 insertions, 1 deletions
diff --git a/Android.build.mk b/Android.build.mk
index e5ee80a0..1a77ee83 100644
--- a/Android.build.mk
+++ b/Android.build.mk
@@ -18,6 +18,11 @@ include $(CLEAR_VARS)
LOCAL_MODULE := $(module)
LOCAL_MODULE_TAGS := $(module_tag)
+LOCAL_MULTILIB := $($(module)_multilib)
+ifeq ($(LOCAL_MULTILIB),both)
+ LOCAL_MODULE_STEM_32 := $(module)32
+ LOCAL_MODULE_STEM_64 := $(module)64
+endif
LOCAL_ADDITIONAL_DEPENDENCIES := \
$(LOCAL_PATH)/Android.mk \
diff --git a/Android.mk b/Android.mk
index e120f912..764eca0e 100644
--- a/Android.mk
+++ b/Android.mk
@@ -249,3 +249,53 @@ build_target := SHARED_LIBRARY
include $(LOCAL_PATH)/Android.build.mk
build_type := host
include $(LOCAL_PATH)/Android.build.mk
+
+#-----------------------------------------------------------------------
+# libunwind testing
+#-----------------------------------------------------------------------
+libunwind-unit-tests_cflags := \
+ -fno-builtin \
+ -O0 \
+ -g \
+
+libunwind-unit-tests_c_includes := \
+ $(LOCAL_PATH)/include \
+
+libunwind-unit-tests_src_files := \
+ android/tests/local_test.cpp \
+
+libunwind-unit-tests_shared_libraries := \
+ libunwind \
+
+libunwind-unit-tests_multilib := both
+module := libunwind-unit-tests
+module_tag := optional
+build_type := target
+build_target := NATIVE_TEST
+include $(LOCAL_PATH)/Android.build.mk
+build_type := host
+include $(LOCAL_PATH)/Android.build.mk
+
+# Run the unit tests built for x86 or x86_64.
+ifeq ($(TARGET_ARCH),$(filter $(TARGET_ARCH),x86 x86_64))
+ifneq ($(TARGET_ARCH),$(filter $(TARGET_ARCH),x86))
+LINKER = linker64
+TEST_SUFFIX = 64
+else
+LINKER = linker
+TEST_SUFFIX = 32
+endif
+
+libunwind-unit-tests-run-on-host: libunwind-unit-tests $(TARGET_OUT_EXECUTABLES)/$(LINKER) $(TARGET_OUT_EXECUTABLES)/sh
+ if [ ! -d /system -o ! -d /system/bin ]; then \
+ echo "Attempting to create /system/bin"; \
+ sudo mkdir -p -m 0777 /system/bin; \
+ fi
+ mkdir -p $(TARGET_OUT_DATA)/local/tmp
+ cp $(TARGET_OUT_EXECUTABLES)/$(LINKER) /system/bin
+ cp $(TARGET_OUT_EXECUTABLES)/sh /system/bin
+ ANDROID_DATA=$(TARGET_OUT_DATA) \
+ ANDROID_ROOT=$(TARGET_OUT) \
+ LD_LIBRARY_PATH=$(TARGET_OUT_SHARED_LIBRARIES) \
+ $(TARGET_OUT_DATA_NATIVE_TESTS)/libunwind-unit-tests/libunwind-unit-tests$(TEST_SUFFIX) $(LIBUNWIND_TEST_FLAGS)
+endif
diff --git a/android/tests/local_test.cpp b/android/tests/local_test.cpp
new file mode 100644
index 00000000..d1f3436d
--- /dev/null
+++ b/android/tests/local_test.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdint.h>
+
+#include <gtest/gtest.h>
+
+#define UNW_LOCAL_ONLY
+#include <libunwind.h>
+
+#define EXTRA_CONTEXT_BYTES 1024
+
+TEST(libbacktrace, getcontext_size) {
+ unw_context_t* context;
+ context = reinterpret_cast<unw_context_t*>(malloc(sizeof(unw_context_t) + EXTRA_CONTEXT_BYTES));
+ ASSERT_TRUE(context != NULL);
+ uint8_t* extra = reinterpret_cast<uint8_t*>(reinterpret_cast<uintptr_t>(context) + sizeof(unw_context_t));
+ for (size_t i = 0; i < EXTRA_CONTEXT_BYTES; i++) {
+ extra[i] = (i % 255) + 1;
+ }
+ ASSERT_TRUE(unw_getcontext(context) == 0);
+ /* Check that nothing was written past the end of the structure. */
+ for (size_t i = 0; i < EXTRA_CONTEXT_BYTES; i++) {
+ ASSERT_EQ((i % 255) + 1, extra[i]);
+ }
+
+ free(context);
+}
diff --git a/src/x86/getcontext-linux.S b/src/x86/getcontext-linux.S
index c469dadb..01da3d10 100644
--- a/src/x86/getcontext-linux.S
+++ b/src/x86/getcontext-linux.S
@@ -60,10 +60,13 @@ _Ux86_getcontext:
movw %fs, %cx
movl %ecx, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_FS_OFF)(%eax)
+ /* The ANDROID ucontext_t structure does not include fpregs_mem. */
+#if !defined(__ANDROID__)
leal LINUX_UC_FPREGS_MEM_OFF(%eax), %ecx
movl %ecx, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_FPSTATE_OFF)(%eax)
fnstenv (%ecx)
fldenv (%ecx)
+#endif
xor %eax, %eax
ret
diff --git a/src/x86_64/getcontext.S b/src/x86_64/getcontext.S
index 7a8b5664..e365df2c 100644
--- a/src/x86_64/getcontext.S
+++ b/src/x86_64/getcontext.S
@@ -57,7 +57,9 @@ _Ux86_64_getcontext:
movq %rax, UC_MCONTEXT_GREGS_RAX(%rdi)
movq %rcx, UC_MCONTEXT_GREGS_RCX(%rdi)
-#if defined __linux__
+#if defined __ANDROID__
+ /* The ANDROID ucontext_t structure does not include fpregs_mem. */
+#elif defined __linux__
/* Save fp state (not needed, except for setcontext not
restoring garbage). */
leaq UC_MCONTEXT_FPREGS_MEM(%rdi),%r8