Merge pull request #2841 from lambdageek/dev/bug-40060
authormonojenkins <jo.shields+jenkins@xamarin.com>
Thu, 7 Apr 2016 00:34:46 +0000 (01:34 +0100)
committermonojenkins <jo.shields+jenkins@xamarin.com>
Thu, 7 Apr 2016 00:34:46 +0000 (01:34 +0100)
[corlib] Type.GetType parser and resolver improvements

We have two type parsers the one invoked by `Type.GetType(string)` (and some others) which is implemented in C in `reflection.c`, and the one invoked by `Type.GetType(string, Func<...>, Func<...>)` implemented in managed code as `System.TypeSpec`.

In both cases `string→Type` conversion goes in two stages: parsing and resolution.  Parsing just changes the string into an AST.  And resolution crawls the AST and constructs the appropriate types.

This fixes [Bugzilla #40060](https://bugzilla.xamarin.com/show_bug.cgi?id=40060)

1. Fix the resolver on the native side for types like `"System.Generic.Collections.Dictionary[System.Int32,MyType]"` where the generic type is from corlib and a type argument is from the current assembly.
2. Fix `get_caller_no_reflection` to work correctly when the call stack has a System.Reflection method as the immediate caller of the icall.
3. Fix the resolver on the native side to work when it's called from corlib's System namespace, not just System.Reflection.
4. Fix the managed parser to work with types like `"MyGeneric[MyType]"` where the generic argument is not an assembly qualified name or there's a mixture of aqn and non-aqn type arguments.  Also rationalize how the code handles assembly qualification in general.
5. Test cases

47 files changed:
external/android-libunwind/README [new file with mode: 0644]
external/android-libunwind/include/libunwind-aarch64.h [new file with mode: 0644]
external/android-libunwind/include/libunwind-arm.h [new file with mode: 0644]
external/android-libunwind/include/libunwind-common.h [new file with mode: 0644]
external/android-libunwind/include/libunwind-coredump.h [new file with mode: 0644]
external/android-libunwind/include/libunwind-dynamic.h [new file with mode: 0644]
external/android-libunwind/include/libunwind-hppa.h [new file with mode: 0644]
external/android-libunwind/include/libunwind-ia64.h [new file with mode: 0644]
external/android-libunwind/include/libunwind-mips.h [new file with mode: 0644]
external/android-libunwind/include/libunwind-ppc32.h [new file with mode: 0644]
external/android-libunwind/include/libunwind-ppc64.h [new file with mode: 0644]
external/android-libunwind/include/libunwind-ptrace.h [new file with mode: 0644]
external/android-libunwind/include/libunwind-sh.h [new file with mode: 0644]
external/android-libunwind/include/libunwind-x86.h [new file with mode: 0644]
external/android-libunwind/include/libunwind-x86_64.h [new file with mode: 0644]
external/android-libunwind/include/libunwind.h [new file with mode: 0644]
external/android-libunwind/include/unwind.h [new file with mode: 0644]
mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/AssignProjectConfiguration.cs
mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/AssignProjectConfigurationTest.cs
mcs/tools/xbuild/SolutionParser.cs
mono/metadata/appdomain.c
mono/metadata/attach.c
mono/metadata/gc.c
mono/metadata/marshal.c
mono/metadata/metadata.h
mono/metadata/reflection.h
mono/metadata/sgen-mono.c
mono/metadata/threadpool-ms.c
mono/metadata/threads.c
mono/mini/aot-compiler.c
mono/mini/debugger-agent.c
mono/mini/driver.c
mono/mini/mini-arm-tls.S
mono/mini/mini-arm64-gsharedvt.c
mono/mini/mini-exceptions-native-unwinder.c
mono/mini/mini-posix.c
mono/mini/mini-runtime.c
mono/mini/tramp-arm64-gsharedvt.c
mono/profiler/decode.c
mono/profiler/proflog.c
mono/sgen/sgen-gc.c
mono/tests/sgen-toggleref.cs
mono/utils/mono-compiler.h
mono/utils/mono-threads-posix.c
mono/utils/mono-threads.h
mono/utils/monobitset.h
scripts/ci/run-jenkins.sh

diff --git a/external/android-libunwind/README b/external/android-libunwind/README
new file mode 100644 (file)
index 0000000..b226141
--- /dev/null
@@ -0,0 +1,9 @@
+This is a copy of a few libunwind headers from https://android.googlesource.com/platform/external/libunwind
+
+We can't make the repo a git submodule because it contains a folder called 'aux' which
+is reserved on Windows and would break on checkout there.
+
+These files are unmodified from the originals and should preferably stay that
+way to avoid merge hell.
+
+Commit: 338c9755cfe3d009c3dfff7d108e2c3ddaa6f3bb (android-6.0.1_r24)
\ No newline at end of file
diff --git a/external/android-libunwind/include/libunwind-aarch64.h b/external/android-libunwind/include/libunwind-aarch64.h
new file mode 100644 (file)
index 0000000..700ed17
--- /dev/null
@@ -0,0 +1,219 @@
+/* libunwind - a platform-independent unwind library
+   Copyright (C) 2001-2004 Hewlett-Packard Co
+       Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+   Copyright (C) 2013 Linaro Limited
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
+
+#ifndef LIBUNWIND_H
+#define LIBUNWIND_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#include <inttypes.h>
+#include <stddef.h>
+#include <ucontext.h>
+
+#define UNW_TARGET     aarch64
+#define UNW_TARGET_AARCH64     1
+
+#define _U_TDEP_QP_TRUE        0       /* see libunwind-dynamic.h  */
+
+/* This needs to be big enough to accommodate "struct cursor", while
+   leaving some slack for future expansion.  Changing this value will
+   require recompiling all users of this library.  Stack allocation is
+   relatively cheap and unwind-state copying is relatively rare, so we
+   want to err on making it rather too big than too small.  */
+
+#define UNW_TDEP_CURSOR_LEN    4096
+
+typedef uint64_t unw_word_t;
+typedef int64_t unw_sword_t;
+
+typedef long double unw_tdep_fpreg_t;
+
+typedef struct
+  {
+    /* no aarch64-specific auxiliary proc-info */
+    /* ANDROID support update. */
+    char __reserved;
+    /* End of ANDROID update. */
+  }
+unw_tdep_proc_info_t;
+
+typedef enum
+  {
+    /* 64-bit general registers.  */
+    UNW_AARCH64_X0,
+    UNW_AARCH64_X1,
+    UNW_AARCH64_X2,
+    UNW_AARCH64_X3,
+    UNW_AARCH64_X4,
+    UNW_AARCH64_X5,
+    UNW_AARCH64_X6,
+    UNW_AARCH64_X7,
+    UNW_AARCH64_X8,
+
+    /* Temporary registers.  */
+    UNW_AARCH64_X9,
+    UNW_AARCH64_X10,
+    UNW_AARCH64_X11,
+    UNW_AARCH64_X12,
+    UNW_AARCH64_X13,
+    UNW_AARCH64_X14,
+    UNW_AARCH64_X15,
+
+    /* Intra-procedure-call temporary registers.  */
+    UNW_AARCH64_X16,
+    UNW_AARCH64_X17,
+
+    /* Callee-saved registers.  */
+    UNW_AARCH64_X18,
+    UNW_AARCH64_X19,
+    UNW_AARCH64_X20,
+    UNW_AARCH64_X21,
+    UNW_AARCH64_X22,
+    UNW_AARCH64_X23,
+    UNW_AARCH64_X24,
+    UNW_AARCH64_X25,
+    UNW_AARCH64_X26,
+    UNW_AARCH64_X27,
+    UNW_AARCH64_X28,
+
+    /* 64-bit frame pointer.  */
+    UNW_AARCH64_X29,
+
+    /* 64-bit link register.  */
+    UNW_AARCH64_X30,
+
+    /* 64-bit stack pointer.  */
+    UNW_AARCH64_SP =  31,
+    UNW_AARCH64_PC,
+    UNW_AARCH64_PSTATE,
+
+    /* 128-bit FP/Advanced SIMD registers.  */
+    UNW_AARCH64_V0 = 64,
+    UNW_AARCH64_V1,
+    UNW_AARCH64_V2,
+    UNW_AARCH64_V3,
+    UNW_AARCH64_V4,
+    UNW_AARCH64_V5,
+    UNW_AARCH64_V6,
+    UNW_AARCH64_V7,
+    UNW_AARCH64_V8,
+    UNW_AARCH64_V9,
+    UNW_AARCH64_V10,
+    UNW_AARCH64_V11,
+    UNW_AARCH64_V12,
+    UNW_AARCH64_V13,
+    UNW_AARCH64_V14,
+    UNW_AARCH64_V15,
+    UNW_AARCH64_V16,
+    UNW_AARCH64_V17,
+    UNW_AARCH64_V18,
+    UNW_AARCH64_V19,
+    UNW_AARCH64_V20,
+    UNW_AARCH64_V21,
+    UNW_AARCH64_V22,
+    UNW_AARCH64_V23,
+    UNW_AARCH64_V24,
+    UNW_AARCH64_V25,
+    UNW_AARCH64_V26,
+    UNW_AARCH64_V27,
+    UNW_AARCH64_V28,
+    UNW_AARCH64_V29,
+    UNW_AARCH64_V30,
+    UNW_AARCH64_V31,
+
+    UNW_AARCH64_FPSR,
+    UNW_AARCH64_FPCR,
+
+    /* For AArch64, the CFA is the value of SP (x31) at the call site of the
+       previous frame.  */
+    UNW_AARCH64_CFA = UNW_AARCH64_SP,
+
+    UNW_TDEP_LAST_REG = UNW_AARCH64_FPCR,
+
+    UNW_TDEP_IP = UNW_AARCH64_X30,
+    UNW_TDEP_SP = UNW_AARCH64_SP,
+    UNW_TDEP_EH = UNW_AARCH64_X0,
+
+  }
+aarch64_regnum_t;
+
+/* Use R0 through R3 to pass exception handling information.  */
+#define UNW_TDEP_NUM_EH_REGS   4
+
+typedef struct unw_tdep_save_loc
+  {
+    /* Additional target-dependent info on a save location.  */
+    /* ANDROID support update. */
+    char __reserved;
+    /* End of ANDROID update. */
+  }
+unw_tdep_save_loc_t;
+
+
+/* On AArch64, we can directly use ucontext_t as the unwind context.  */
+typedef ucontext_t unw_tdep_context_t;
+
+#include "libunwind-common.h"
+#include "libunwind-dynamic.h"
+
+/* ANDROID support update. */
+/* There is no getcontext in Android. */
+#define unw_tdep_getcontext(uc) (({                                    \
+  unw_tdep_context_t *unw_ctx = (uc);                                  \
+  register uint64_t *unw_base asm ("x0") = (uint64_t*) unw_ctx->uc_mcontext.regs;              \
+  __asm__ __volatile__ (                                               \
+     "stp x0, x1, [%[base], #0]\n" \
+     "stp x2, x3, [%[base], #16]\n" \
+     "stp x4, x5, [%[base], #32]\n" \
+     "stp x6, x7, [%[base], #48]\n" \
+     "stp x8, x9, [%[base], #64]\n" \
+     "stp x10, x11, [%[base], #80]\n" \
+     "stp x12, x13, [%[base], #96]\n" \
+     "stp x14, x13, [%[base], #112]\n" \
+     "stp x16, x17, [%[base], #128]\n" \
+     "stp x18, x19, [%[base], #144]\n" \
+     "stp x20, x21, [%[base], #160]\n" \
+     "stp x22, x23, [%[base], #176]\n" \
+     "stp x24, x25, [%[base], #192]\n" \
+     "stp x26, x27, [%[base], #208]\n" \
+     "stp x28, x29, [%[base], #224]\n" \
+     "str x30, [%[base], #240]\n" \
+     "mov x1, sp\n" \
+     "stp x1, x30, [%[base], #248]\n" \
+     : [base] "+r" (unw_base) : : "x1", "memory"); \
+  }), 0)
+/* End of ANDROID update. */
+#define unw_tdep_is_fpreg              UNW_ARCH_OBJ(is_fpreg)
+
+extern int unw_tdep_is_fpreg (int);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* LIBUNWIND_H */
diff --git a/external/android-libunwind/include/libunwind-arm.h b/external/android-libunwind/include/libunwind-arm.h
new file mode 100644 (file)
index 0000000..495948e
--- /dev/null
@@ -0,0 +1,308 @@
+/* libunwind - a platform-independent unwind library
+   Copyright (C) 2008 CodeSourcery
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
+
+#ifndef LIBUNWIND_H
+#define LIBUNWIND_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#include <inttypes.h>
+#include <stddef.h>
+
+#define UNW_TARGET     arm
+#define UNW_TARGET_ARM 1
+
+#define _U_TDEP_QP_TRUE        0       /* see libunwind-dynamic.h  */
+
+/* This needs to be big enough to accommodate "struct cursor", while
+   leaving some slack for future expansion.  Changing this value will
+   require recompiling all users of this library.  Stack allocation is
+   relatively cheap and unwind-state copying is relatively rare, so we
+   want to err on making it rather too big than too small.  */
+   
+/* FIXME for ARM. Too big?  What do other things use for similar tasks?  */
+#define UNW_TDEP_CURSOR_LEN    4096
+
+typedef uint32_t unw_word_t;
+typedef int32_t unw_sword_t;
+
+typedef long double unw_tdep_fpreg_t;
+
+typedef enum
+  {
+    UNW_ARM_R0,
+    UNW_ARM_R1,
+    UNW_ARM_R2,
+    UNW_ARM_R3,
+    UNW_ARM_R4,
+    UNW_ARM_R5,
+    UNW_ARM_R6,
+    UNW_ARM_R7,
+    UNW_ARM_R8,
+    UNW_ARM_R9,
+    UNW_ARM_R10,
+    UNW_ARM_R11,
+    UNW_ARM_R12,
+    UNW_ARM_R13,
+    UNW_ARM_R14,
+    UNW_ARM_R15,
+    
+    /* VFPv2 s0-s31 (obsolescent numberings).  */
+    UNW_ARM_S0 = 64,
+    UNW_ARM_S1,
+    UNW_ARM_S2,
+    UNW_ARM_S3,
+    UNW_ARM_S4,
+    UNW_ARM_S5,
+    UNW_ARM_S6,
+    UNW_ARM_S7,
+    UNW_ARM_S8,
+    UNW_ARM_S9,
+    UNW_ARM_S10,
+    UNW_ARM_S11,
+    UNW_ARM_S12,
+    UNW_ARM_S13,
+    UNW_ARM_S14,
+    UNW_ARM_S15,
+    UNW_ARM_S16,
+    UNW_ARM_S17,
+    UNW_ARM_S18,
+    UNW_ARM_S19,
+    UNW_ARM_S20,
+    UNW_ARM_S21,
+    UNW_ARM_S22,
+    UNW_ARM_S23,
+    UNW_ARM_S24,
+    UNW_ARM_S25,
+    UNW_ARM_S26,
+    UNW_ARM_S27,
+    UNW_ARM_S28,
+    UNW_ARM_S29,
+    UNW_ARM_S30,
+    UNW_ARM_S31,
+    
+    /* FPA register numberings.  */
+    UNW_ARM_F0 = 96,
+    UNW_ARM_F1,
+    UNW_ARM_F2,
+    UNW_ARM_F3,
+    UNW_ARM_F4,
+    UNW_ARM_F5,
+    UNW_ARM_F6,
+    UNW_ARM_F7,
+    
+    /* iWMMXt GR register numberings.  */
+    UNW_ARM_wCGR0 = 104,
+    UNW_ARM_wCGR1,
+    UNW_ARM_wCGR2,
+    UNW_ARM_wCGR3,
+    UNW_ARM_wCGR4,
+    UNW_ARM_wCGR5,
+    UNW_ARM_wCGR6,
+    UNW_ARM_wCGR7,
+    
+    /* iWMMXt register numberings.  */
+    UNW_ARM_wR0 = 112,
+    UNW_ARM_wR1,
+    UNW_ARM_wR2,
+    UNW_ARM_wR3,
+    UNW_ARM_wR4,
+    UNW_ARM_wR5,
+    UNW_ARM_wR6,
+    UNW_ARM_wR7,
+    UNW_ARM_wR8,
+    UNW_ARM_wR9,
+    UNW_ARM_wR10,
+    UNW_ARM_wR11,
+    UNW_ARM_wR12,
+    UNW_ARM_wR13,
+    UNW_ARM_wR14,
+    UNW_ARM_wR15,
+    
+    /* Two-byte encodings from here on.  */
+    
+    /* SPSR.  */
+    UNW_ARM_SPSR = 128,
+    UNW_ARM_SPSR_FIQ,
+    UNW_ARM_SPSR_IRQ,
+    UNW_ARM_SPSR_ABT,
+    UNW_ARM_SPSR_UND,
+    UNW_ARM_SPSR_SVC,
+    
+    /* User mode registers.  */
+    UNW_ARM_R8_USR = 144,
+    UNW_ARM_R9_USR,
+    UNW_ARM_R10_USR,
+    UNW_ARM_R11_USR,
+    UNW_ARM_R12_USR,
+    UNW_ARM_R13_USR,
+    UNW_ARM_R14_USR,
+    
+    /* FIQ registers.  */
+    UNW_ARM_R8_FIQ = 151,
+    UNW_ARM_R9_FIQ,
+    UNW_ARM_R10_FIQ,
+    UNW_ARM_R11_FIQ,
+    UNW_ARM_R12_FIQ,
+    UNW_ARM_R13_FIQ,
+    UNW_ARM_R14_FIQ,
+    
+    /* IRQ registers.  */
+    UNW_ARM_R13_IRQ = 158,
+    UNW_ARM_R14_IRQ,
+    
+    /* ABT registers.  */
+    UNW_ARM_R13_ABT = 160,
+    UNW_ARM_R14_ABT,
+    
+    /* UND registers.  */
+    UNW_ARM_R13_UND = 162,
+    UNW_ARM_R14_UND,
+    
+    /* SVC registers.  */
+    UNW_ARM_R13_SVC = 164,
+    UNW_ARM_R14_SVC,
+    
+    /* iWMMXt control registers.  */
+    UNW_ARM_wC0 = 192,
+    UNW_ARM_wC1,
+    UNW_ARM_wC2,
+    UNW_ARM_wC3,
+    UNW_ARM_wC4,
+    UNW_ARM_wC5,
+    UNW_ARM_wC6,
+    UNW_ARM_wC7,
+
+    /* VFPv3/Neon 64-bit registers.  */
+    UNW_ARM_D0 = 256,
+    UNW_ARM_D1,
+    UNW_ARM_D2,
+    UNW_ARM_D3,
+    UNW_ARM_D4,
+    UNW_ARM_D5,
+    UNW_ARM_D6,
+    UNW_ARM_D7,
+    UNW_ARM_D8,
+    UNW_ARM_D9,
+    UNW_ARM_D10,
+    UNW_ARM_D11,
+    UNW_ARM_D12,
+    UNW_ARM_D13,
+    UNW_ARM_D14,
+    UNW_ARM_D15,
+    UNW_ARM_D16,
+    UNW_ARM_D17,
+    UNW_ARM_D18,
+    UNW_ARM_D19,
+    UNW_ARM_D20,
+    UNW_ARM_D21,
+    UNW_ARM_D22,
+    UNW_ARM_D23,
+    UNW_ARM_D24,
+    UNW_ARM_D25,
+    UNW_ARM_D26,
+    UNW_ARM_D27,
+    UNW_ARM_D28,
+    UNW_ARM_D29,
+    UNW_ARM_D30,
+    UNW_ARM_D31,
+
+    /* For ARM, the CFA is the value of SP (r13) at the call site in the
+       previous frame.  */
+    UNW_ARM_CFA,
+
+    UNW_TDEP_LAST_REG = UNW_ARM_D31,
+
+    UNW_TDEP_IP = UNW_ARM_R14,  /* A little white lie.  */
+    UNW_TDEP_SP = UNW_ARM_R13,
+    UNW_TDEP_EH = UNW_ARM_R0   /* FIXME.  */
+  }
+arm_regnum_t;
+
+#define UNW_TDEP_NUM_EH_REGS   2       /* FIXME for ARM.  */
+
+typedef struct unw_tdep_save_loc
+  {
+    /* Additional target-dependent info on a save location.  */
+    /* ANDROID support update. */
+    char __reserved;
+    /* End of ANDROID update. */
+  }
+unw_tdep_save_loc_t;
+
+/* On ARM, we define our own unw_tdep_context instead of using ucontext_t.
+   This allows us to support systems that don't support getcontext and
+   therefore do not define ucontext_t.  */
+typedef struct unw_tdep_context
+  {
+    unsigned long regs[16];
+  }
+unw_tdep_context_t;
+
+/* There is no getcontext() on ARM.  Use a stub version which only saves GP
+   registers.  FIXME: Not ideal, may not be sufficient for all libunwind
+   use cases.  Stores pc+8, which is only approximately correct, really.  */
+#ifndef __thumb__
+#define unw_tdep_getcontext(uc) (({                                    \
+  unw_tdep_context_t *unw_ctx = (uc);                                  \
+  register unsigned long *unw_base asm ("r0") = unw_ctx->regs;         \
+  __asm__ __volatile__ (                                               \
+    "stmia %[base], {r0-r15}"                                          \
+    : : [base] "r" (unw_base) : "memory");                             \
+  }), 0)
+#else /* __thumb__ */
+#define unw_tdep_getcontext(uc) (({                                    \
+  unw_tdep_context_t *unw_ctx = (uc);                                  \
+  register unsigned long *unw_base asm ("r0") = unw_ctx->regs;         \
+  __asm__ __volatile__ (                                               \
+    ".align 2\nbx pc\nnop\n.code 32\n"                                 \
+    "stmia %[base], {r0-r15}\n"                                                \
+    "orr %[base], pc, #1\nbx %[base]"                                  \
+    : [base] "+r" (unw_base) : : "memory", "cc");                      \
+  }), 0)
+#endif
+
+#include "libunwind-dynamic.h"
+
+typedef struct
+  {
+    /* no arm-specific auxiliary proc-info */
+    /* ANDROID support update. */
+    char __reserved;
+    /* End of ANDROID update. */
+  }
+unw_tdep_proc_info_t;
+
+#include "libunwind-common.h"
+
+#define unw_tdep_is_fpreg              UNW_ARCH_OBJ(is_fpreg)
+extern int unw_tdep_is_fpreg (int);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* LIBUNWIND_H */
diff --git a/external/android-libunwind/include/libunwind-common.h b/external/android-libunwind/include/libunwind-common.h
new file mode 100644 (file)
index 0000000..f4cbc88
--- /dev/null
@@ -0,0 +1,308 @@
+/* libunwind - a platform-independent unwind library
+   Copyright (C) 2001-2004 Hewlett-Packard Co
+       Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
+
+/* ANDROID support update. */
+#include <sys/types.h>
+/* End of ANDROID update. */
+
+#define UNW_VERSION_MAJOR      1
+#define UNW_VERSION_MINOR      1
+#define UNW_VERSION_EXTRA      
+
+#define UNW_VERSION_CODE(maj,min)      (((maj) << 16) | (min))
+#define UNW_VERSION    UNW_VERSION_CODE(UNW_VERSION_MAJOR, UNW_VERSION_MINOR)
+
+#define UNW_PASTE2(x,y)        x##y
+#define UNW_PASTE(x,y) UNW_PASTE2(x,y)
+#define UNW_OBJ(fn)    UNW_PASTE(UNW_PREFIX, fn)
+#define UNW_ARCH_OBJ(fn) UNW_PASTE(UNW_PASTE(UNW_PASTE(_U,UNW_TARGET),_), fn)
+
+#ifdef UNW_LOCAL_ONLY
+# ifdef UNW_ADDITIONAL_PREFIX
+#  define UNW_PREFIX   UNW_PASTE(UNW_PASTE(_UUL,UNW_TARGET),_)
+# else
+#  define UNW_PREFIX   UNW_PASTE(UNW_PASTE(_UL,UNW_TARGET),_)
+# endif
+#else /* !UNW_LOCAL_ONLY */
+# ifdef UNW_ADDITIONAL_PREFIX
+#  define UNW_PREFIX   UNW_PASTE(UNW_PASTE(_UU,UNW_TARGET),_)
+# else
+#  define UNW_PREFIX   UNW_PASTE(UNW_PASTE(_U,UNW_TARGET),_)
+# endif
+#endif /* !UNW_LOCAL_ONLY */
+
+/* Error codes.  The unwind routines return the *negated* values of
+   these error codes on error and a non-negative value on success.  */
+typedef enum
+  {
+    UNW_ESUCCESS = 0,          /* no error */
+    UNW_EUNSPEC,               /* unspecified (general) error */
+    UNW_ENOMEM,                        /* out of memory */
+    UNW_EBADREG,               /* bad register number */
+    UNW_EREADONLYREG,          /* attempt to write read-only register */
+    UNW_ESTOPUNWIND,           /* stop unwinding */
+    UNW_EINVALIDIP,            /* invalid IP */
+    UNW_EBADFRAME,             /* bad frame */
+    UNW_EINVAL,                        /* unsupported operation or bad value */
+    UNW_EBADVERSION,           /* unwind info has unsupported version */
+    UNW_ENOINFO                        /* no unwind info found */
+  }
+unw_error_t;
+
+/* The following enum defines the indices for a couple of
+   (pseudo-)registers which have the same meaning across all
+   platforms.  (RO) means read-only.  (RW) means read-write.  General
+   registers (aka "integer registers") are expected to start with
+   index 0.  The number of such registers is architecture-dependent.
+   The remaining indices can be used as an architecture sees fit.  The
+   last valid register index is given by UNW_REG_LAST.  */
+typedef enum
+  {
+    UNW_REG_IP = UNW_TDEP_IP,          /* (rw) instruction pointer (pc) */
+    UNW_REG_SP = UNW_TDEP_SP,          /* (ro) stack pointer */
+    UNW_REG_EH = UNW_TDEP_EH,          /* (rw) exception-handling reg base */
+    UNW_REG_LAST = UNW_TDEP_LAST_REG
+  }
+unw_frame_regnum_t;
+
+/* Number of exception-handler argument registers: */
+#define UNW_NUM_EH_REGS                UNW_TDEP_NUM_EH_REGS
+
+typedef enum
+  {
+    UNW_CACHE_NONE,                    /* no caching */
+    UNW_CACHE_GLOBAL,                  /* shared global cache */
+    UNW_CACHE_PER_THREAD               /* per-thread caching */
+  }
+unw_caching_policy_t;
+
+typedef int unw_regnum_t;
+
+/* The unwind cursor starts at the youngest (most deeply nested) frame
+   and is used to track the frame state as the unwinder steps from
+   frame to frame.  It is safe to make (shallow) copies of variables
+   of this type.  */
+typedef struct unw_cursor
+  {
+    unw_word_t opaque[UNW_TDEP_CURSOR_LEN];
+  }
+unw_cursor_t;
+
+/* This type encapsulates the entire (preserved) machine-state.  */
+typedef unw_tdep_context_t unw_context_t;
+
+/* unw_getcontext() fills the unw_context_t pointed to by UC with the
+   machine state as it exists at the call-site.  For implementation
+   reasons, this needs to be a target-dependent macro.  It's easiest
+   to think of unw_getcontext() as being identical to getcontext(). */
+#define unw_getcontext(uc)             unw_tdep_getcontext(uc)
+
+/* Return 1 if register number R is a floating-point register, zero
+   otherwise.
+   This routine is signal-safe.  */
+#define unw_is_fpreg(r)                        unw_tdep_is_fpreg(r)
+
+typedef unw_tdep_fpreg_t unw_fpreg_t;
+
+typedef struct unw_addr_space *unw_addr_space_t;
+
+/* Each target may define it's own set of flags, but bits 0-15 are
+   reserved for general libunwind-use.  */
+#define UNW_PI_FLAG_FIRST_TDEP_BIT     16
+/* The information comes from a .debug_frame section.  */
+#define UNW_PI_FLAG_DEBUG_FRAME        32
+
+typedef struct unw_proc_info
+  {
+    unw_word_t start_ip;       /* first IP covered by this procedure */
+    unw_word_t end_ip;         /* first IP NOT covered by this procedure */
+    unw_word_t lsda;           /* address of lang.-spec. data area (if any) */
+    unw_word_t handler;                /* optional personality routine */
+    unw_word_t gp;             /* global-pointer value for this procedure */
+    unw_word_t flags;          /* misc. flags */
+
+    int format;                        /* unwind-info format (arch-specific) */
+    int unwind_info_size;      /* size of the information (if applicable) */
+    void *unwind_info;         /* unwind-info (arch-specific) */
+    unw_tdep_proc_info_t extra;        /* target-dependent auxiliary proc-info */
+  }
+unw_proc_info_t;
+
+/* These are backend callback routines that provide access to the
+   state of a "remote" process.  This can be used, for example, to
+   unwind another process through the ptrace() interface.  */
+typedef struct unw_accessors
+  {
+    /* Look up the unwind info associated with instruction-pointer IP.
+       On success, the routine fills in the PROC_INFO structure.  */
+    int (*find_proc_info) (unw_addr_space_t, unw_word_t, unw_proc_info_t *,
+                          int, void *);
+
+    /* Release any resources (e.g., memory) that were allocated for
+       the unwind info returned in by a previous call to
+       find_proc_info() with NEED_UNWIND_INFO set to 1.  */
+    void (*put_unwind_info) (unw_addr_space_t, unw_proc_info_t *, void *);
+
+    /* Return the list-head of the dynamically registered unwind
+       info.  */
+    int (*get_dyn_info_list_addr) (unw_addr_space_t, unw_word_t *, void *);
+
+    /* Access aligned word at address ADDR.  The value is returned
+       according to the endianness of the host (e.g., if the host is
+       little-endian and the target is big-endian, access_mem() needs
+       to byte-swap the value before returning it).  */
+    int (*access_mem) (unw_addr_space_t, unw_word_t, unw_word_t *, int,
+                      void *);
+
+    /* Access register number REG at address ADDR.  */
+    int (*access_reg) (unw_addr_space_t, unw_regnum_t, unw_word_t *, int,
+                      void *);
+
+    /* Access register number REG at address ADDR.  */
+    int (*access_fpreg) (unw_addr_space_t, unw_regnum_t,
+                        unw_fpreg_t *, int, void *);
+
+    int (*resume) (unw_addr_space_t, unw_cursor_t *, void *);
+
+    /* Optional call back to obtain the name of a (static) procedure.
+       Dynamically generated procedures are handled automatically by
+       libunwind.  This callback is optional and may be set to
+       NULL.  */
+    int (*get_proc_name) (unw_addr_space_t, unw_word_t, char *, size_t,
+                         unw_word_t *, void *);
+  }
+unw_accessors_t;
+
+typedef enum unw_save_loc_type
+  {
+    UNW_SLT_NONE,      /* register is not saved ("not an l-value") */
+    UNW_SLT_MEMORY,    /* register has been saved in memory */
+    UNW_SLT_REG                /* register has been saved in (another) register */
+  }
+unw_save_loc_type_t;
+
+typedef struct unw_save_loc
+  {
+    unw_save_loc_type_t type;
+    union
+      {
+       unw_word_t addr;        /* valid if type==UNW_SLT_MEMORY */
+       unw_regnum_t regnum;    /* valid if type==UNW_SLT_REG */
+      }
+    u;
+    unw_tdep_save_loc_t extra; /* target-dependent additional information */
+  }
+unw_save_loc_t;
+
+/* ANDROID support update. */
+typedef struct unw_map_cursor
+  {
+    void *map_list;
+    void *cur_map;
+  }
+unw_map_cursor_t;
+
+typedef struct unw_map
+  {
+    unw_word_t start;
+    unw_word_t end;
+    unw_word_t offset;
+    unw_word_t load_base;
+    char *path;
+    int flags;
+  }
+unw_map_t;
+/* End of ANDROID update. */
+
+/* These routines work both for local and remote unwinding.  */
+
+#define unw_local_access_addr_space_init UNW_OBJ(local_access_addr_space_init)
+#define unw_local_addr_space   UNW_OBJ(local_addr_space)
+#define unw_create_addr_space  UNW_OBJ(create_addr_space)
+#define unw_destroy_addr_space UNW_OBJ(destroy_addr_space)
+#define unw_get_accessors      UNW_ARCH_OBJ(get_accessors)
+#define unw_init_local         UNW_OBJ(init_local)
+#define unw_init_remote                UNW_OBJ(init_remote)
+#define unw_step               UNW_OBJ(step)
+#define unw_resume             UNW_OBJ(resume)
+#define unw_get_proc_info      UNW_OBJ(get_proc_info)
+#define unw_get_proc_info_by_ip        UNW_OBJ(get_proc_info_by_ip)
+#define unw_get_reg            UNW_OBJ(get_reg)
+#define unw_set_reg            UNW_OBJ(set_reg)
+#define unw_get_fpreg          UNW_OBJ(get_fpreg)
+#define unw_set_fpreg          UNW_OBJ(set_fpreg)
+#define unw_get_save_loc       UNW_OBJ(get_save_loc)
+#define unw_is_signal_frame    UNW_OBJ(is_signal_frame)
+#define unw_handle_signal_frame        UNW_OBJ(handle_signal_frame)
+#define unw_get_proc_name      UNW_OBJ(get_proc_name)
+#define unw_get_proc_name_by_ip        UNW_OBJ(get_proc_name_by_ip)
+#define unw_set_caching_policy UNW_OBJ(set_caching_policy)
+#define unw_regname            UNW_ARCH_OBJ(regname)
+#define unw_flush_cache                UNW_ARCH_OBJ(flush_cache)
+#define unw_strerror           UNW_ARCH_OBJ(strerror)
+
+extern void unw_local_access_addr_space_init (unw_addr_space_t);
+extern unw_addr_space_t unw_create_addr_space (unw_accessors_t *, int);
+extern void unw_destroy_addr_space (unw_addr_space_t);
+extern unw_accessors_t *unw_get_accessors (unw_addr_space_t);
+extern void unw_flush_cache (unw_addr_space_t, unw_word_t, unw_word_t);
+extern int unw_set_caching_policy (unw_addr_space_t, unw_caching_policy_t);
+extern const char *unw_regname (unw_regnum_t);
+
+extern int unw_init_local (unw_cursor_t *, unw_context_t *);
+extern int unw_init_remote (unw_cursor_t *, unw_addr_space_t, void *);
+extern int unw_step (unw_cursor_t *);
+extern int unw_resume (unw_cursor_t *);
+extern int unw_get_proc_info (unw_cursor_t *, unw_proc_info_t *);
+extern int unw_get_proc_info_by_ip (unw_addr_space_t, unw_word_t,
+                                   unw_proc_info_t *, void *);
+extern int unw_get_reg (unw_cursor_t *, int, unw_word_t *);
+extern int unw_set_reg (unw_cursor_t *, int, unw_word_t);
+extern int unw_get_fpreg (unw_cursor_t *, int, unw_fpreg_t *);
+extern int unw_set_fpreg (unw_cursor_t *, int, unw_fpreg_t);
+extern int unw_get_save_loc (unw_cursor_t *, int, unw_save_loc_t *);
+extern int unw_is_signal_frame (unw_cursor_t *);
+extern int unw_handle_signal_frame (unw_cursor_t *);
+extern int unw_get_proc_name (unw_cursor_t *, char *, size_t, unw_word_t *);
+extern int unw_get_proc_name_by_ip (unw_addr_space_t, unw_word_t, char *,
+                                   size_t, unw_word_t *, void *);
+extern const char *unw_strerror (int);
+extern int unw_backtrace (void **, int);
+
+/* ANDROID support update. */
+extern int unw_map_local_cursor_valid (unw_map_cursor_t *);
+extern void unw_map_local_cursor_get (unw_map_cursor_t *);
+extern int unw_map_local_cursor_get_next (unw_map_cursor_t *, unw_map_t *);
+extern int unw_map_local_create (void);
+extern void unw_map_local_destroy (void);
+extern void unw_map_set (unw_addr_space_t, unw_map_cursor_t *);
+extern void unw_map_cursor_reset (unw_map_cursor_t *);
+extern void unw_map_cursor_clear (unw_map_cursor_t *);
+extern int unw_map_cursor_create (unw_map_cursor_t *, pid_t);
+extern void unw_map_cursor_destroy (unw_map_cursor_t *);
+extern int unw_map_cursor_get_next (unw_map_cursor_t *, unw_map_t *);
+/* End of ANDROID update. */
+
+extern unw_addr_space_t unw_local_addr_space;
diff --git a/external/android-libunwind/include/libunwind-coredump.h b/external/android-libunwind/include/libunwind-coredump.h
new file mode 100644 (file)
index 0000000..d2b05e7
--- /dev/null
@@ -0,0 +1,73 @@
+/* libunwind - a platform-independent unwind library
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
+
+#ifndef libunwind_coredump_h
+#define libunwind_coredump_h
+
+#include <libunwind.h>
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/* Helper routines which make it easy to use libunwind on a coredump.
+   They're available only if UNW_REMOTE_ONLY is _not_ defined and they
+   aren't really part of the libunwind API.  They are implemented in a
+   archive library called libunwind-coredump.a.  */
+
+struct UCD_info;
+
+extern struct UCD_info *_UCD_create(const char *filename);
+extern void _UCD_destroy(struct UCD_info *);
+
+extern int _UCD_get_num_threads(struct UCD_info *);
+extern void _UCD_select_thread(struct UCD_info *, int);
+extern pid_t _UCD_get_pid(struct UCD_info *);
+extern int _UCD_get_cursig(struct UCD_info *);
+extern int _UCD_add_backing_file_at_segment(struct UCD_info *, int phdr_no, const char *filename);
+extern int _UCD_add_backing_file_at_vaddr(struct UCD_info *,
+                                         unsigned long vaddr,
+                                         const char *filename);
+
+extern int _UCD_find_proc_info (unw_addr_space_t, unw_word_t,
+                               unw_proc_info_t *, int, void *);
+extern void _UCD_put_unwind_info (unw_addr_space_t, unw_proc_info_t *, void *);
+extern int _UCD_get_dyn_info_list_addr (unw_addr_space_t, unw_word_t *,
+                                       void *);
+extern int _UCD_access_mem (unw_addr_space_t, unw_word_t, unw_word_t *, int,
+                           void *);
+extern int _UCD_access_reg (unw_addr_space_t, unw_regnum_t, unw_word_t *,
+                           int, void *);
+extern int _UCD_access_fpreg (unw_addr_space_t, unw_regnum_t, unw_fpreg_t *,
+                             int, void *);
+extern int _UCD_get_proc_name (unw_addr_space_t, unw_word_t, char *, size_t,
+                              unw_word_t *, void *);
+extern int _UCD_resume (unw_addr_space_t, unw_cursor_t *, void *);
+extern unw_accessors_t _UCD_accessors;
+
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* libunwind_coredump_h */
diff --git a/external/android-libunwind/include/libunwind-dynamic.h b/external/android-libunwind/include/libunwind-dynamic.h
new file mode 100644 (file)
index 0000000..584f392
--- /dev/null
@@ -0,0 +1,210 @@
+/* libunwind - a platform-independent unwind library
+   Copyright (C) 2002-2004 Hewlett-Packard Co
+       Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
+
+/* This file defines the runtime-support routines for dynamically
+generated code.  Even though it is implemented as part of libunwind,
+it is logically separate from the interface to perform the actual
+unwinding.  In particular, this interface is always used in the
+context of the unwind target, whereas the rest of the unwind API is
+used in context of the process that is doing the unwind (which may be
+a debugger running on another machine, for example).
+
+Note that the data-structures declared here server a dual purpose:
+when a program registers a dynamically generated procedure, it uses
+these structures directly.  On the other hand, with remote-unwinding,
+the data-structures are read from the remote process's memory and
+translated into internalized versions.  To facilitate remote-access,
+the following rules should be followed in declaring these structures:
+
+ (1) Declare a member as a pointer only if the the information the
+     member points to needs to be internalized as well (e.g., a
+     string representing a procedure name should be declared as
+     "const char *", but the instruction pointer should be declared
+     as unw_word_t).
+
+ (2) Provide sufficient padding to ensure that no implicit padding
+     will be needed on any of the supported target architectures.  For
+     the time being, padding data structures with the assumption that
+     sizeof (unw_word_t) == 8 should be sufficient.  (Note: it's not
+     impossible to internalize structures with internal padding, but
+     it does make the process a bit harder).
+
+ (3) Don't declare members that contain bitfields or floating-point
+     values.
+
+ (4) Don't declare members with enumeration types.  Declare them as
+     int32_t instead.  */
+
+typedef enum
+  {
+    UNW_DYN_STOP = 0,          /* end-of-unwind-info marker */
+    UNW_DYN_SAVE_REG,          /* save register to another register */
+    UNW_DYN_SPILL_FP_REL,      /* frame-pointer-relative register spill */
+    UNW_DYN_SPILL_SP_REL,      /* stack-pointer-relative register spill */
+    UNW_DYN_ADD,               /* add constant value to a register */
+    UNW_DYN_POP_FRAMES,                /* drop one or more stack frames */
+    UNW_DYN_LABEL_STATE,       /* name the current state */
+    UNW_DYN_COPY_STATE,                /* set the region's entry-state */
+    UNW_DYN_ALIAS              /* get unwind info from an alias */
+  }
+unw_dyn_operation_t;
+
+typedef enum
+  {
+    UNW_INFO_FORMAT_DYNAMIC,           /* unw_dyn_proc_info_t */
+    UNW_INFO_FORMAT_TABLE,             /* unw_dyn_table_t */
+    UNW_INFO_FORMAT_REMOTE_TABLE,      /* unw_dyn_remote_table_t */
+    UNW_INFO_FORMAT_ARM_EXIDX          /* ARM specific unwind info */
+  }
+unw_dyn_info_format_t;
+
+typedef struct unw_dyn_op
+  {
+    int8_t tag;                                /* what operation? */
+    int8_t qp;                         /* qualifying predicate register */
+    int16_t reg;                       /* what register */
+    int32_t when;                      /* when does it take effect? */
+    unw_word_t val;                    /* auxiliary value */
+  }
+unw_dyn_op_t;
+
+typedef struct unw_dyn_region_info
+  {
+    struct unw_dyn_region_info *next;  /* linked list of regions */
+    int32_t insn_count;                        /* region length (# of instructions) */
+    uint32_t op_count;                 /* length of op-array */
+    unw_dyn_op_t op[1];                        /* variable-length op-array */
+  }
+unw_dyn_region_info_t;
+
+typedef struct unw_dyn_proc_info
+  {
+    unw_word_t name_ptr;       /* address of human-readable procedure name */
+    unw_word_t handler;                /* address of personality routine */
+    uint32_t flags;
+    int32_t pad0;
+    unw_dyn_region_info_t *regions;
+  }
+unw_dyn_proc_info_t;
+
+typedef struct unw_dyn_table_info
+  {
+    unw_word_t name_ptr;       /* addr. of table name (e.g., library name) */
+    unw_word_t segbase;                /* segment base */
+    unw_word_t table_len;      /* must be a multiple of sizeof(unw_word_t)! */
+    unw_word_t *table_data;
+  }
+unw_dyn_table_info_t;
+
+typedef struct unw_dyn_remote_table_info
+  {
+    unw_word_t name_ptr;       /* addr. of table name (e.g., library name) */
+    unw_word_t segbase;                /* segment base */
+    unw_word_t table_len;      /* must be a multiple of sizeof(unw_word_t)! */
+    unw_word_t table_data;
+  }
+unw_dyn_remote_table_info_t;
+
+typedef struct unw_dyn_info
+  {
+    /* doubly-linked list of dyn-info structures: */
+    struct unw_dyn_info *next;
+    struct unw_dyn_info *prev;
+    unw_word_t start_ip;       /* first IP covered by this entry */
+    unw_word_t end_ip;         /* first IP NOT covered by this entry */
+    unw_word_t gp;             /* global-pointer in effect for this entry */
+    int32_t format;            /* real type: unw_dyn_info_format_t */
+    int32_t pad;
+    union
+      {
+       unw_dyn_proc_info_t pi;
+       unw_dyn_table_info_t ti;
+       unw_dyn_remote_table_info_t rti;
+      }
+    u;
+  }
+unw_dyn_info_t;
+
+typedef struct unw_dyn_info_list
+  {
+    uint32_t version;
+    uint32_t generation;
+    unw_dyn_info_t *first;
+  }
+unw_dyn_info_list_t;
+
+/* Return the size (in bytes) of an unw_dyn_region_info_t structure that can
+   hold OP_COUNT ops.  */
+#define _U_dyn_region_info_size(op_count)                              \
+       ((char *) (((unw_dyn_region_info_t *) NULL)->op + (op_count))   \
+        - (char *) NULL)
+
+/* Register the unwind info for a single procedure.
+   This routine is NOT signal-safe.  */
+extern void _U_dyn_register (unw_dyn_info_t *);
+
+/* Cancel the unwind info for a single procedure.
+   This routine is NOT signal-safe.  */
+extern void _U_dyn_cancel (unw_dyn_info_t *);
+
+\f
+/* Convenience routines.  */
+
+#define _U_dyn_op(_tag, _qp, _when, _reg, _val)                                \
+       ((unw_dyn_op_t) { (_tag), (_qp), (_reg), (_when), (_val) })
+
+#define _U_dyn_op_save_reg(op, qp, when, reg, dst)                     \
+       (*(op) = _U_dyn_op (UNW_DYN_SAVE_REG, (qp), (when), (reg), (dst)))
+
+#define _U_dyn_op_spill_fp_rel(op, qp, when, reg, offset)              \
+       (*(op) = _U_dyn_op (UNW_DYN_SPILL_FP_REL, (qp), (when), (reg),  \
+                           (offset)))
+
+#define _U_dyn_op_spill_sp_rel(op, qp, when, reg, offset)              \
+       (*(op) = _U_dyn_op (UNW_DYN_SPILL_SP_REL, (qp), (when), (reg),  \
+                           (offset)))
+
+#define _U_dyn_op_add(op, qp, when, reg, value)                                \
+       (*(op) = _U_dyn_op (UNW_DYN_ADD, (qp), (when), (reg), (value)))
+
+#define _U_dyn_op_pop_frames(op, qp, when, num_frames)                 \
+       (*(op) = _U_dyn_op (UNW_DYN_POP_FRAMES, (qp), (when), 0, (num_frames)))
+
+#define _U_dyn_op_label_state(op, label)                               \
+       (*(op) = _U_dyn_op (UNW_DYN_LABEL_STATE, _U_QP_TRUE, -1, 0, (label)))
+
+#define _U_dyn_op_copy_state(op, label)                                        \
+       (*(op) = _U_dyn_op (UNW_DYN_COPY_STATE, _U_QP_TRUE, -1, 0, (label)))
+
+#define _U_dyn_op_alias(op, qp, when, addr)                            \
+       (*(op) = _U_dyn_op (UNW_DYN_ALIAS, (qp), (when), 0, (addr)))
+
+#define _U_dyn_op_stop(op)                                             \
+       (*(op) = _U_dyn_op (UNW_DYN_STOP, _U_QP_TRUE, -1, 0, 0))
+
+/* The target-dependent qualifying predicate which is always TRUE.  On
+   IA-64, that's p0 (0), on non-predicated architectures, the value is
+   ignored.  */
+#define _U_QP_TRUE     _U_TDEP_QP_TRUE
diff --git a/external/android-libunwind/include/libunwind-hppa.h b/external/android-libunwind/include/libunwind-hppa.h
new file mode 100644 (file)
index 0000000..b5fba56
--- /dev/null
@@ -0,0 +1,131 @@
+/* libunwind - a platform-independent unwind library
+   Copyright (C) 2003-2004 Hewlett-Packard Co
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
+
+#ifndef LIBUNWIND_H
+#define LIBUNWIND_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#include <inttypes.h>
+#include <ucontext.h>
+
+#define UNW_TARGET     hppa
+#define UNW_TARGET_HPPA        1
+
+#define _U_TDEP_QP_TRUE        0       /* see libunwind-dynamic.h  */
+
+/* This needs to be big enough to accommodate "struct cursor", while
+   leaving some slack for future expansion.  Changing this value will
+   require recompiling all users of this library.  Stack allocation is
+   relatively cheap and unwind-state copying is relatively rare, so we
+   want to err on making it rather too big than too small.  */
+#define UNW_TDEP_CURSOR_LEN    511
+
+typedef uint32_t unw_word_t;
+typedef int32_t unw_sword_t;
+
+typedef union
+  {
+    struct { unw_word_t bits[2]; } raw;
+    double val;
+  }
+unw_tdep_fpreg_t;
+
+typedef enum
+  {
+    /* Note: general registers are expected to start with index 0.
+       This convention facilitates architecture-independent
+       implementation of the C++ exception handling ABI.  See
+       _Unwind_SetGR() and _Unwind_GetGR() for details.  */
+    UNW_HPPA_GR = 0,
+     UNW_HPPA_RP = 2,                  /* return pointer */
+     UNW_HPPA_FP = 3,                  /* frame pointer */
+     UNW_HPPA_SP = UNW_HPPA_GR + 30,
+
+    UNW_HPPA_FR = UNW_HPPA_GR + 32,
+
+    UNW_HPPA_IP = UNW_HPPA_FR + 32,    /* instruction pointer */
+
+    /* other "preserved" registers (fpsr etc.)... */
+
+    /* PA-RISC has 4 exception-argument registers but they're not
+       contiguous.  To deal with this, we define 4 pseudo
+       exception-handling registers which we then alias to the actual
+       physical register.  */
+
+    UNW_HPPA_EH0 = UNW_HPPA_IP + 1,    /* alias for UNW_HPPA_GR + 20 */
+    UNW_HPPA_EH1 = UNW_HPPA_EH0 + 1,   /* alias for UNW_HPPA_GR + 21 */
+    UNW_HPPA_EH2 = UNW_HPPA_EH1 + 1,   /* alias for UNW_HPPA_GR + 22 */
+    UNW_HPPA_EH3 = UNW_HPPA_EH2 + 1,   /* alias for UNW_HPPA_GR + 31 */
+
+    /* frame info (read-only) */
+    UNW_HPPA_CFA,
+
+    UNW_TDEP_LAST_REG = UNW_HPPA_IP,
+
+    UNW_TDEP_IP = UNW_HPPA_IP,
+    UNW_TDEP_SP = UNW_HPPA_SP,
+    UNW_TDEP_EH = UNW_HPPA_EH0
+  }
+hppa_regnum_t;
+
+#define UNW_TDEP_NUM_EH_REGS   4
+
+typedef struct unw_tdep_save_loc
+  {
+    /* Additional target-dependent info on a save location.  */
+    /* ANDROID support update. */
+    char __reserved;
+    /* End of ANDROID update. */
+  }
+unw_tdep_save_loc_t;
+
+/* On PA-RISC, we can directly use ucontext_t as the unwind context.  */
+typedef ucontext_t unw_tdep_context_t;
+
+#define unw_tdep_is_fpreg(r)           ((unsigned) ((r) - UNW_HPPA_FR) < 32)
+
+#include "libunwind-dynamic.h"
+
+typedef struct
+  {
+    /* no PA-RISC-specific auxiliary proc-info */
+    /* ANDROID support update. */
+    char __reserved;
+    /* End of ANDROID update. */
+  }
+unw_tdep_proc_info_t;
+
+#include "libunwind-common.h"
+
+#define unw_tdep_getcontext            UNW_ARCH_OBJ (getcontext)
+extern int unw_tdep_getcontext (unw_tdep_context_t *);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* LIBUNWIND_H */
diff --git a/external/android-libunwind/include/libunwind-ia64.h b/external/android-libunwind/include/libunwind-ia64.h
new file mode 100644 (file)
index 0000000..4dcc4f9
--- /dev/null
@@ -0,0 +1,197 @@
+/* libunwind - a platform-independent unwind library
+   Copyright (C) 2001-2004 Hewlett-Packard Co
+       Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
+
+#ifndef LIBUNWIND_H
+#define LIBUNWIND_H
+
+#include <inttypes.h>
+#include <ucontext.h>
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#ifdef ia64
+  /* This works around a bug in Intel's ECC v7.0 which defines "ia64"
+     as "1".  */
+# undef ia64
+#endif
+
+#ifdef __hpux
+  /* On HP-UX, there is no hope of supporting UNW_LOCAL_ONLY, because
+     it's impossible to obtain the address of the members in the
+     sigcontext structure.  */
+# undef UNW_LOCAL_ONLY
+# define UNW_GENERIC_ONLY
+#endif
+
+#define UNW_TARGET     ia64
+#define UNW_TARGET_IA64        1
+
+#define _U_TDEP_QP_TRUE        0       /* see libunwind-dynamic.h  */
+
+/* This needs to be big enough to accommodate "struct cursor", while
+   leaving some slack for future expansion.  Changing this value will
+   require recompiling all users of this library.  Stack allocation is
+   relatively cheap and unwind-state copying is relatively rare, so we
+   want to err on making it rather too big than too small.  */
+#define UNW_TDEP_CURSOR_LEN    511
+
+/* If this bit is it indicates that the procedure saved all of ar.bsp,
+   ar.bspstore, and ar.rnat.  If, additionally, ar.bsp != saved ar.bsp,
+   then this procedure has performed a register-backing-store switch.  */
+#define UNW_PI_FLAG_IA64_RBS_SWITCH_BIT        (UNW_PI_FLAG_FIRST_TDEP_BIT + 0)
+
+#define UNW_PI_FLAG_IA64_RBS_SWITCH    (1 << UNW_PI_FLAG_IA64_RBS_SWITCH_BIT)
+
+typedef uint64_t unw_word_t;
+typedef int64_t unw_sword_t;
+
+/* On IA-64, we want to access the contents of floating-point
+   registers as a pair of "words", but to ensure 16-byte alignment, we
+   make it a union that contains a "long double".  This will do the
+   Right Thing on all known IA-64 platforms, including HP-UX.  */
+typedef union
+  {
+    struct { unw_word_t bits[2]; } raw;
+    long double dummy; /* dummy to force 16-byte alignment */
+  }
+unw_tdep_fpreg_t;
+
+typedef struct
+  {
+    /* no ia64-specific auxiliary proc-info */
+    /* ANDROID support update. */
+    char __reserved;
+    /* End of ANDROID update. */
+  }
+unw_tdep_proc_info_t;
+
+typedef enum
+  {
+    /* Note: general registers are excepted to start with index 0.
+       This convention facilitates architecture-independent
+       implementation of the C++ exception handling ABI.  See
+       _Unwind_SetGR() and _Unwind_GetGR() for details.  */
+    UNW_IA64_GR = 0,                   /* general registers (r0..r127) */
+     UNW_IA64_GP = UNW_IA64_GR + 1,
+     UNW_IA64_TP = UNW_IA64_GR + 13,
+
+    UNW_IA64_NAT = UNW_IA64_GR + 128,  /* NaT registers (nat0..nat127) */
+
+    UNW_IA64_FR = UNW_IA64_NAT + 128,  /* fp registers (f0..f127) */
+
+    UNW_IA64_AR = UNW_IA64_FR + 128,   /* application registers (ar0..r127) */
+     UNW_IA64_AR_RSC = UNW_IA64_AR + 16,
+     UNW_IA64_AR_BSP = UNW_IA64_AR + 17,
+     UNW_IA64_AR_BSPSTORE = UNW_IA64_AR + 18,
+     UNW_IA64_AR_RNAT = UNW_IA64_AR + 19,
+     UNW_IA64_AR_CSD = UNW_IA64_AR + 25,
+     UNW_IA64_AR_26 = UNW_IA64_AR + 26,
+     UNW_IA64_AR_SSD = UNW_IA64_AR_26,
+     UNW_IA64_AR_CCV = UNW_IA64_AR + 32,
+     UNW_IA64_AR_UNAT = UNW_IA64_AR + 36,
+     UNW_IA64_AR_FPSR = UNW_IA64_AR + 40,
+     UNW_IA64_AR_PFS = UNW_IA64_AR + 64,
+     UNW_IA64_AR_LC = UNW_IA64_AR + 65,
+     UNW_IA64_AR_EC = UNW_IA64_AR + 66,
+
+    UNW_IA64_BR = UNW_IA64_AR + 128,   /* branch registers (b0..p7) */
+      UNW_IA64_RP = UNW_IA64_BR + 0,   /* return pointer (rp) */
+    UNW_IA64_PR = UNW_IA64_BR + 8,     /* predicate registers (p0..p63) */
+    UNW_IA64_CFM,
+
+    /* frame info: */
+    UNW_IA64_BSP,
+    UNW_IA64_IP,
+    UNW_IA64_SP,
+
+    UNW_TDEP_LAST_REG = UNW_IA64_SP,
+
+    UNW_TDEP_IP = UNW_IA64_IP,
+    UNW_TDEP_SP = UNW_IA64_SP,
+    UNW_TDEP_EH = UNW_IA64_GR + 15
+  }
+ia64_regnum_t;
+
+#define UNW_TDEP_NUM_EH_REGS   4       /* r15-r18 are exception args */
+
+typedef struct unw_tdep_save_loc
+  {
+    /* Additional target-dependent info on a save location.  On IA-64,
+       we use this to provide the bit number in which a NaT bit gets
+       saved.  */
+    uint8_t nat_bitnr;
+
+    /* Padding reserved for future use.  */
+    uint8_t reserved[7];
+  }
+unw_tdep_save_loc_t;
+
+/* On IA-64, we can directly use ucontext_t as the unwind context.  */
+typedef ucontext_t unw_tdep_context_t;
+
+#define unw_tdep_is_fpreg(r)           ((unsigned) ((r) - UNW_IA64_FR) < 128)
+
+#include "libunwind-dynamic.h"
+#include "libunwind-common.h"
+
+#ifdef __hpux
+  /* In theory, we could use _Uia64_getcontext() on HP-UX as well, but
+     the benefit of doing so would be marginal given that it can't
+     support UNW_LOCAL_ONLY.  */
+# define unw_tdep_getcontext           getcontext
+#else
+# define unw_tdep_getcontext           UNW_ARCH_OBJ (getcontext)
+  extern int unw_tdep_getcontext (unw_tdep_context_t *);
+#endif
+
+/* This is a helper routine to search an ia64 unwind table.  If the
+   address-space argument AS points to something other than the local
+   address-space, the memory for the unwind-info will be allocated
+   with malloc(), and should be free()d during the put_unwind_info()
+   callback.  This routine is signal-safe for the local-address-space
+   case ONLY.  */
+#define unw_search_ia64_unwind_table   UNW_OBJ(search_unwind_table)
+extern int unw_search_ia64_unwind_table (unw_addr_space_t, unw_word_t,
+                                        unw_dyn_info_t *, unw_proc_info_t *,
+                                        int, void *);
+
+/* This is a helper routine which the get_dyn_info_list_addr()
+   callback can use to locate the special dynamic-info list entry in
+   an IA-64 unwind table.  If the entry exists in the table, the
+   list-address is returned.  In all other cases, 0 is returned.  */
+extern unw_word_t _Uia64_find_dyn_list (unw_addr_space_t, unw_dyn_info_t *,
+                                       void *);
+
+/* This is a helper routine to obtain the kernel-unwind info.  It is
+   signal-safe.  */
+extern int _Uia64_get_kernel_table (unw_dyn_info_t *);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* LIBUNWIND_H */
diff --git a/external/android-libunwind/include/libunwind-mips.h b/external/android-libunwind/include/libunwind-mips.h
new file mode 100644 (file)
index 0000000..83e44de
--- /dev/null
@@ -0,0 +1,163 @@
+/* libunwind - a platform-independent unwind library
+   Copyright (C) 2008 CodeSourcery
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
+
+#ifndef LIBUNWIND_H
+#define LIBUNWIND_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#include <inttypes.h>
+#include <ucontext.h>
+
+#ifdef mips
+# undef mips
+#endif
+
+#define UNW_TARGET     mips
+#define UNW_TARGET_MIPS        1
+
+#define _U_TDEP_QP_TRUE        0       /* see libunwind-dynamic.h  */
+
+/* This needs to be big enough to accommodate "struct cursor", while
+   leaving some slack for future expansion.  Changing this value will
+   require recompiling all users of this library.  Stack allocation is
+   relatively cheap and unwind-state copying is relatively rare, so we
+   want to err on making it rather too big than too small.  */
+   
+/* FIXME for MIPS. Too big?  What do other things use for similar tasks?  */
+#define UNW_TDEP_CURSOR_LEN    4096
+
+/* The size of a "word" varies on MIPS.  This type is used for memory
+   addresses and register values.  To allow a single library to support
+   multiple ABIs, and to support N32 at all, we must use a 64-bit type
+   even when addresses are only 32 bits.  */
+typedef uint64_t unw_word_t;
+typedef int32_t unw_sword_t;
+
+/* FIXME: MIPS ABIs.  */
+typedef long double unw_tdep_fpreg_t;
+
+typedef enum
+  {
+    UNW_MIPS_R0,
+    UNW_MIPS_R1,
+    UNW_MIPS_R2,
+    UNW_MIPS_R3,
+    UNW_MIPS_R4,
+    UNW_MIPS_R5,
+    UNW_MIPS_R6,
+    UNW_MIPS_R7,
+    UNW_MIPS_R8,
+    UNW_MIPS_R9,
+    UNW_MIPS_R10,
+    UNW_MIPS_R11,
+    UNW_MIPS_R12,
+    UNW_MIPS_R13,
+    UNW_MIPS_R14,
+    UNW_MIPS_R15,
+    UNW_MIPS_R16,
+    UNW_MIPS_R17,
+    UNW_MIPS_R18,
+    UNW_MIPS_R19,
+    UNW_MIPS_R20,
+    UNW_MIPS_R21,
+    UNW_MIPS_R22,
+    UNW_MIPS_R23,
+    UNW_MIPS_R24,
+    UNW_MIPS_R25,
+    UNW_MIPS_R26,
+    UNW_MIPS_R27,
+    UNW_MIPS_R28,
+    UNW_MIPS_R29,
+    UNW_MIPS_R30,
+    UNW_MIPS_R31,
+
+    UNW_MIPS_PC = 34,
+
+    /* FIXME: Other registers!  */
+
+    /* For MIPS, the CFA is the value of SP (r29) at the call site in the
+       previous frame.  */
+    UNW_MIPS_CFA,
+
+    UNW_TDEP_LAST_REG = UNW_MIPS_R31,
+
+    UNW_TDEP_IP = UNW_MIPS_R31,
+    UNW_TDEP_SP = UNW_MIPS_R29,
+    UNW_TDEP_EH = UNW_MIPS_R0   /* FIXME.  */
+  }
+mips_regnum_t;
+
+typedef enum
+  {
+    UNW_MIPS_ABI_O32,
+    UNW_MIPS_ABI_N32,
+    UNW_MIPS_ABI_N64
+  }
+mips_abi_t;
+
+#define UNW_TDEP_NUM_EH_REGS   2       /* FIXME for MIPS.  */
+
+typedef struct unw_tdep_save_loc
+  {
+    /* Additional target-dependent info on a save location.  */
+    /* ANDROID support update. */
+    char __reserved;
+    /* End of ANDROID update. */
+  }
+unw_tdep_save_loc_t;
+
+/* On x86, we can directly use ucontext_t as the unwind context.  FIXME for
+   MIPS.  */
+typedef ucontext_t unw_tdep_context_t;
+
+#include "libunwind-dynamic.h"
+
+typedef struct
+  {
+    /* no mips-specific auxiliary proc-info */
+    /* ANDROID support update. */
+    char __reserved;
+    /* End of ANDROID update. */
+  }
+unw_tdep_proc_info_t;
+
+#include "libunwind-common.h"
+
+/* There is no getcontext() on MIPS.  Use a stub version which only saves GP
+   registers.  FIXME: Not ideal, may not be sufficient for all libunwind
+   use cases.  */
+#define unw_tdep_getcontext UNW_ARCH_OBJ(getcontext)
+extern int unw_tdep_getcontext (ucontext_t *uc);
+
+#define unw_tdep_is_fpreg              UNW_ARCH_OBJ(is_fpreg)
+extern int unw_tdep_is_fpreg (int);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* LIBUNWIND_H */
diff --git a/external/android-libunwind/include/libunwind-ppc32.h b/external/android-libunwind/include/libunwind-ppc32.h
new file mode 100644 (file)
index 0000000..51852e8
--- /dev/null
@@ -0,0 +1,213 @@
+/* libunwind - a platform-independent unwind library
+   Copyright (C) 2006-2007 IBM
+   Contributed by
+     Corey Ashford <cjashfor@us.ibm.com>
+     Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
+
+   Copied from libunwind-x86_64.h, modified slightly for building
+   frysk successfully on ppc64, by Wu Zhou <woodzltc@cn.ibm.com>
+   Will be replaced when libunwind is ready on ppc64 platform.
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
+
+#ifndef LIBUNWIND_H
+#define LIBUNWIND_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#include <inttypes.h>
+#include <ucontext.h>
+
+#define UNW_TARGET             ppc32
+#define UNW_TARGET_PPC32       1
+
+#define _U_TDEP_QP_TRUE        0       /* see libunwind-dynamic.h  */
+
+/*
+ * This needs to be big enough to accommodate "struct cursor", while
+ * leaving some slack for future expansion.  Changing this value will
+ * require recompiling all users of this library.  Stack allocation is
+ * relatively cheap and unwind-state copying is relatively rare, so we want
+ * to err on making it rather too big than too small.
+ *
+ * To simplify this whole process, we are at least initially taking the
+ * tack that UNW_PPC32_* map straight across to the .eh_frame column register
+ * numbers.  These register numbers come from gcc's source in
+ * gcc/config/rs6000/rs6000.h
+ *
+ * UNW_TDEP_CURSOR_LEN is in terms of unw_word_t size.  Since we have 115
+ * elements in the loc array, each sized 2 * unw_word_t, plus the rest of
+ * the cursor struct, this puts us at about 2 * 115 + 40 = 270.  Let's
+ * round that up to 280.
+ */
+
+#define UNW_TDEP_CURSOR_LEN 280
+
+#if __WORDSIZE==32
+typedef uint32_t unw_word_t;
+typedef int32_t unw_sword_t;
+#else
+typedef uint64_t unw_word_t;
+typedef int64_t unw_sword_t;
+#endif
+
+typedef long double unw_tdep_fpreg_t;
+
+typedef enum
+  {
+    UNW_PPC32_R0,
+    UNW_PPC32_R1, /* called STACK_POINTER in gcc */
+    UNW_PPC32_R2,
+    UNW_PPC32_R3,
+    UNW_PPC32_R4,
+    UNW_PPC32_R5,
+    UNW_PPC32_R6,
+    UNW_PPC32_R7,
+    UNW_PPC32_R8,
+    UNW_PPC32_R9,
+    UNW_PPC32_R10,
+    UNW_PPC32_R11, /* called STATIC_CHAIN in gcc */
+    UNW_PPC32_R12,
+    UNW_PPC32_R13,
+    UNW_PPC32_R14,
+    UNW_PPC32_R15,
+    UNW_PPC32_R16,
+    UNW_PPC32_R17,
+    UNW_PPC32_R18,
+    UNW_PPC32_R19,
+    UNW_PPC32_R20,
+    UNW_PPC32_R21,
+    UNW_PPC32_R22,
+    UNW_PPC32_R23,
+    UNW_PPC32_R24,
+    UNW_PPC32_R25,
+    UNW_PPC32_R26,
+    UNW_PPC32_R27,
+    UNW_PPC32_R28,
+    UNW_PPC32_R29,
+    UNW_PPC32_R30,
+    UNW_PPC32_R31, /* called HARD_FRAME_POINTER in gcc */
+
+    /* Count Register */
+    UNW_PPC32_CTR = 32,
+    /* Fixed-Point Status and Control Register */
+    UNW_PPC32_XER = 33,
+    /* Condition Register */
+    UNW_PPC32_CCR = 34,
+    /* Machine State Register */
+    //UNW_PPC32_MSR = 35,
+    /* MQ or SPR0, not part of generic Power, part of MPC601 */
+    //UNW_PPC32_MQ = 36,
+    /* Link Register */
+    UNW_PPC32_LR = 36,
+    /* Floating Pointer Status and Control Register */
+    UNW_PPC32_FPSCR = 37,
+
+    UNW_PPC32_F0 = 48,
+    UNW_PPC32_F1,
+    UNW_PPC32_F2,
+    UNW_PPC32_F3,
+    UNW_PPC32_F4,
+    UNW_PPC32_F5,
+    UNW_PPC32_F6,
+    UNW_PPC32_F7,
+    UNW_PPC32_F8,
+    UNW_PPC32_F9,
+    UNW_PPC32_F10,
+    UNW_PPC32_F11,
+    UNW_PPC32_F12,
+    UNW_PPC32_F13,
+    UNW_PPC32_F14,
+    UNW_PPC32_F15,
+    UNW_PPC32_F16,
+    UNW_PPC32_F17,
+    UNW_PPC32_F18,
+    UNW_PPC32_F19,
+    UNW_PPC32_F20,
+    UNW_PPC32_F21,
+    UNW_PPC32_F22,
+    UNW_PPC32_F23,
+    UNW_PPC32_F24,
+    UNW_PPC32_F25,
+    UNW_PPC32_F26,
+    UNW_PPC32_F27,
+    UNW_PPC32_F28,
+    UNW_PPC32_F29,
+    UNW_PPC32_F30,
+    UNW_PPC32_F31,
+
+    UNW_TDEP_LAST_REG = UNW_PPC32_F31,
+
+    UNW_TDEP_IP = UNW_PPC32_LR,
+    UNW_TDEP_SP = UNW_PPC32_R1,
+    UNW_TDEP_EH = UNW_PPC32_R12
+  }
+ppc32_regnum_t;
+
+/*
+ * According to David Edelsohn, GNU gcc uses R3, R4, R5, and maybe R6 for
+ * passing parameters to exception handlers.
+ */
+
+#define UNW_TDEP_NUM_EH_REGS   4
+
+typedef struct unw_tdep_save_loc
+  {
+    /* Additional target-dependent info on a save location.  */
+    /* ANDROID support update. */
+    char __reserved;
+    /* End of ANDROID update. */
+  }
+unw_tdep_save_loc_t;
+
+/* On ppc, we can directly use ucontext_t as the unwind context.  */
+typedef ucontext_t unw_tdep_context_t;
+
+/* XXX this is not ideal: an application should not be prevented from
+   using the "getcontext" name just because it's using libunwind.  We
+   can't just use __getcontext() either, because that isn't exported
+   by glibc...  */
+#define unw_tdep_getcontext(uc)                (getcontext (uc), 0)
+
+#include "libunwind-dynamic.h"
+
+typedef struct
+  {
+    /* no ppc32-specific auxiliary proc-info */
+    /* ANDROID support update. */
+    char __reserved;
+    /* End of ANDROID update. */
+  }
+unw_tdep_proc_info_t;
+
+#include "libunwind-common.h"
+
+#define unw_tdep_is_fpreg              UNW_ARCH_OBJ(is_fpreg)
+extern int unw_tdep_is_fpreg (int);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* LIBUNWIND_H */
diff --git a/external/android-libunwind/include/libunwind-ppc64.h b/external/android-libunwind/include/libunwind-ppc64.h
new file mode 100644 (file)
index 0000000..e0dbaaa
--- /dev/null
@@ -0,0 +1,270 @@
+/* libunwind - a platform-independent unwind library
+   Copyright (C) 2006-2007 IBM
+   Contributed by
+     Corey Ashford <cjashfor@us.ibm.com>
+     Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
+
+   Copied from libunwind-x86_64.h, modified slightly for building
+   frysk successfully on ppc64, by Wu Zhou <woodzltc@cn.ibm.com>
+   Will be replaced when libunwind is ready on ppc64 platform.
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
+
+#ifndef LIBUNWIND_H
+#define LIBUNWIND_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#include <inttypes.h>
+#include <ucontext.h>
+
+#define UNW_TARGET             ppc64
+#define UNW_TARGET_PPC64       1
+
+#define _U_TDEP_QP_TRUE        0       /* see libunwind-dynamic.h  */
+
+/*
+ * This needs to be big enough to accommodate "struct cursor", while
+ * leaving some slack for future expansion.  Changing this value will
+ * require recompiling all users of this library.  Stack allocation is
+ * relatively cheap and unwind-state copying is relatively rare, so we want
+ * to err on making it rather too big than too small.
+ *
+ * To simplify this whole process, we are at least initially taking the
+ * tack that UNW_PPC64_* map straight across to the .eh_frame column register
+ * numbers.  These register numbers come from gcc's source in
+ * gcc/config/rs6000/rs6000.h
+ *
+ * UNW_TDEP_CURSOR_LEN is in terms of unw_word_t size.  Since we have 115
+ * elements in the loc array, each sized 2 * unw_word_t, plus the rest of
+ * the cursor struct, this puts us at about 2 * 115 + 40 = 270.  Let's
+ * round that up to 280.
+ */
+
+#define UNW_TDEP_CURSOR_LEN 280
+
+#if __WORDSIZE==32
+typedef uint32_t unw_word_t;
+typedef int32_t unw_sword_t;
+#else
+typedef uint64_t unw_word_t;
+typedef int64_t unw_sword_t;
+#endif
+
+typedef long double unw_tdep_fpreg_t;
+
+/*
+ * Vector register (in PowerPC64 used for AltiVec registers)
+ */
+typedef struct {
+    uint64_t halves[2];
+} unw_tdep_vreg_t;
+
+typedef enum
+  {
+    UNW_PPC64_R0,
+    UNW_PPC64_R1, /* called STACK_POINTER in gcc */
+    UNW_PPC64_R2,
+    UNW_PPC64_R3,
+    UNW_PPC64_R4,
+    UNW_PPC64_R5,
+    UNW_PPC64_R6,
+    UNW_PPC64_R7,
+    UNW_PPC64_R8,
+    UNW_PPC64_R9,
+    UNW_PPC64_R10,
+    UNW_PPC64_R11, /* called STATIC_CHAIN in gcc */
+    UNW_PPC64_R12,
+    UNW_PPC64_R13,
+    UNW_PPC64_R14,
+    UNW_PPC64_R15,
+    UNW_PPC64_R16,
+    UNW_PPC64_R17,
+    UNW_PPC64_R18,
+    UNW_PPC64_R19,
+    UNW_PPC64_R20,
+    UNW_PPC64_R21,
+    UNW_PPC64_R22,
+    UNW_PPC64_R23,
+    UNW_PPC64_R24,
+    UNW_PPC64_R25,
+    UNW_PPC64_R26,
+    UNW_PPC64_R27,
+    UNW_PPC64_R28,
+    UNW_PPC64_R29,
+    UNW_PPC64_R30,
+    UNW_PPC64_R31, /* called HARD_FRAME_POINTER in gcc */
+
+    UNW_PPC64_F0 = 32,
+    UNW_PPC64_F1,
+    UNW_PPC64_F2,
+    UNW_PPC64_F3,
+    UNW_PPC64_F4,
+    UNW_PPC64_F5,
+    UNW_PPC64_F6,
+    UNW_PPC64_F7,
+    UNW_PPC64_F8,
+    UNW_PPC64_F9,
+    UNW_PPC64_F10,
+    UNW_PPC64_F11,
+    UNW_PPC64_F12,
+    UNW_PPC64_F13,
+    UNW_PPC64_F14,
+    UNW_PPC64_F15,
+    UNW_PPC64_F16,
+    UNW_PPC64_F17,
+    UNW_PPC64_F18,
+    UNW_PPC64_F19,
+    UNW_PPC64_F20,
+    UNW_PPC64_F21,
+    UNW_PPC64_F22,
+    UNW_PPC64_F23,
+    UNW_PPC64_F24,
+    UNW_PPC64_F25,
+    UNW_PPC64_F26,
+    UNW_PPC64_F27,
+    UNW_PPC64_F28,
+    UNW_PPC64_F29,
+    UNW_PPC64_F30,
+    UNW_PPC64_F31,
+    /* Note that there doesn't appear to be an .eh_frame register column
+       for the FPSCR register.  I don't know why this is.  Since .eh_frame
+       info is what this implementation uses for unwinding, we have no way
+       to unwind this register, and so we will not expose an FPSCR register
+       number in the libunwind API.
+     */
+
+    UNW_PPC64_LR = 65,
+    UNW_PPC64_CTR = 66,
+    UNW_PPC64_ARG_POINTER = 67,
+
+    UNW_PPC64_CR0 = 68,
+    UNW_PPC64_CR1,
+    UNW_PPC64_CR2,
+    UNW_PPC64_CR3,
+    UNW_PPC64_CR4,
+    /* CR5 .. CR7 are currently unused */
+    UNW_PPC64_CR5,
+    UNW_PPC64_CR6,
+    UNW_PPC64_CR7,
+
+    UNW_PPC64_XER = 76,
+
+    UNW_PPC64_V0 = 77,
+    UNW_PPC64_V1,
+    UNW_PPC64_V2,
+    UNW_PPC64_V3,
+    UNW_PPC64_V4,
+    UNW_PPC64_V5,
+    UNW_PPC64_V6,
+    UNW_PPC64_V7,
+    UNW_PPC64_V8,
+    UNW_PPC64_V9,
+    UNW_PPC64_V10,
+    UNW_PPC64_V11,
+    UNW_PPC64_V12,
+    UNW_PPC64_V13,
+    UNW_PPC64_V14,
+    UNW_PPC64_V15,
+    UNW_PPC64_V16,
+    UNW_PPC64_V17,
+    UNW_PPC64_V18,
+    UNW_PPC64_V19,
+    UNW_PPC64_V20,
+    UNW_PPC64_V21,
+    UNW_PPC64_V22,
+    UNW_PPC64_V23,
+    UNW_PPC64_V24,
+    UNW_PPC64_V25,
+    UNW_PPC64_V26,
+    UNW_PPC64_V27,
+    UNW_PPC64_V28,
+    UNW_PPC64_V29,
+    UNW_PPC64_V30,
+    UNW_PPC64_V31,
+
+    UNW_PPC64_VRSAVE = 109,
+    UNW_PPC64_VSCR = 110,
+    UNW_PPC64_SPE_ACC = 111,
+    UNW_PPC64_SPEFSCR = 112,
+
+    /* frame info (read-only) */
+    UNW_PPC64_FRAME_POINTER,
+    UNW_PPC64_NIP,
+
+
+    UNW_TDEP_LAST_REG = UNW_PPC64_NIP,
+
+    UNW_TDEP_IP = UNW_PPC64_NIP,
+    UNW_TDEP_SP = UNW_PPC64_R1,
+    UNW_TDEP_EH = UNW_PPC64_R12
+  }
+ppc64_regnum_t;
+
+/*
+ * According to David Edelsohn, GNU gcc uses R3, R4, R5, and maybe R6 for
+ * passing parameters to exception handlers.
+ */
+
+#define UNW_TDEP_NUM_EH_REGS   4
+
+typedef struct unw_tdep_save_loc
+  {
+    /* Additional target-dependent info on a save location.  */
+    /* ANDROID support update. */
+    char __reserved;
+    /* End of ANDROID update. */
+  }
+unw_tdep_save_loc_t;
+
+/* On ppc64, we can directly use ucontext_t as the unwind context.  */
+typedef ucontext_t unw_tdep_context_t;
+
+/* XXX this is not ideal: an application should not be prevented from
+   using the "getcontext" name just because it's using libunwind.  We
+   can't just use __getcontext() either, because that isn't exported
+   by glibc...  */
+#define unw_tdep_getcontext(uc)                (getcontext (uc), 0)
+
+#include "libunwind-dynamic.h"
+
+typedef struct
+  {
+    /* no ppc64-specific auxiliary proc-info */
+    /* ANDROID support update. */
+    char __reserved;
+    /* End of ANDROID update. */
+  }
+unw_tdep_proc_info_t;
+
+#include "libunwind-common.h"
+
+#define unw_tdep_is_fpreg              UNW_ARCH_OBJ(is_fpreg)
+extern int unw_tdep_is_fpreg (int);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* LIBUNWIND_H */
diff --git a/external/android-libunwind/include/libunwind-ptrace.h b/external/android-libunwind/include/libunwind-ptrace.h
new file mode 100644 (file)
index 0000000..7fca205
--- /dev/null
@@ -0,0 +1,63 @@
+/* libunwind - a platform-independent unwind library
+   Copyright (C) 2004 Hewlett-Packard Co
+       Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
+
+#ifndef libunwind_ptrace_h
+#define libunwind_ptrace_h
+
+#include <libunwind.h>
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/* Helper routines which make it easy to use libunwind via ptrace().
+   They're available only if UNW_REMOTE_ONLY is _not_ defined and they
+   aren't really part of the libunwind API.  They are implemented in a
+   archive library called libunwind-ptrace.a.  */
+
+extern void *_UPT_create (pid_t);
+extern void _UPT_destroy (void *);
+extern int _UPT_find_proc_info (unw_addr_space_t, unw_word_t,
+                               unw_proc_info_t *, int, void *);
+extern void _UPT_put_unwind_info (unw_addr_space_t, unw_proc_info_t *, void *);
+extern int _UPT_get_dyn_info_list_addr (unw_addr_space_t, unw_word_t *,
+                                       void *);
+extern int _UPT_access_mem (unw_addr_space_t, unw_word_t, unw_word_t *, int,
+                           void *);
+extern int _UPT_access_reg (unw_addr_space_t, unw_regnum_t, unw_word_t *,
+                           int, void *);
+extern int _UPT_access_fpreg (unw_addr_space_t, unw_regnum_t, unw_fpreg_t *,
+                             int, void *);
+extern int _UPT_get_proc_name (unw_addr_space_t, unw_word_t, char *, size_t,
+                              unw_word_t *, void *);
+extern int _UPT_resume (unw_addr_space_t, unw_cursor_t *, void *);
+extern unw_accessors_t _UPT_accessors;
+
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* libunwind_ptrace_h */
diff --git a/external/android-libunwind/include/libunwind-sh.h b/external/android-libunwind/include/libunwind-sh.h
new file mode 100644 (file)
index 0000000..8f36a25
--- /dev/null
@@ -0,0 +1,120 @@
+/* libunwind - a platform-independent unwind library
+   Copyright (C) 2008 CodeSourcery
+   Copyright (C) 2012 Tommi Rantala <tt.rantala@gmail.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
+
+#ifndef LIBUNWIND_H
+#define LIBUNWIND_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#include <inttypes.h>
+#include <stddef.h>
+#include <ucontext.h>
+
+#define UNW_TARGET     sh
+#define UNW_TARGET_SH  1
+
+#define _U_TDEP_QP_TRUE        0       /* see libunwind-dynamic.h  */
+
+/* This needs to be big enough to accommodate "struct cursor", while
+   leaving some slack for future expansion.  Changing this value will
+   require recompiling all users of this library.  Stack allocation is
+   relatively cheap and unwind-state copying is relatively rare, so we
+   want to err on making it rather too big than too small.  */
+
+#define UNW_TDEP_CURSOR_LEN    4096
+
+typedef uint32_t unw_word_t;
+typedef int32_t unw_sword_t;
+
+typedef long double unw_tdep_fpreg_t;
+
+typedef enum
+  {
+    UNW_SH_R0,
+    UNW_SH_R1,
+    UNW_SH_R2,
+    UNW_SH_R3,
+    UNW_SH_R4,
+    UNW_SH_R5,
+    UNW_SH_R6,
+    UNW_SH_R7,
+    UNW_SH_R8,
+    UNW_SH_R9,
+    UNW_SH_R10,
+    UNW_SH_R11,
+    UNW_SH_R12,
+    UNW_SH_R13,
+    UNW_SH_R14,
+    UNW_SH_R15,
+
+    UNW_SH_PC,
+    UNW_SH_PR,
+
+    UNW_TDEP_LAST_REG = UNW_SH_PR,
+
+    UNW_TDEP_IP = UNW_SH_PR,
+    UNW_TDEP_SP = UNW_SH_R15,
+    UNW_TDEP_EH = UNW_SH_R0
+  }
+sh_regnum_t;
+
+#define UNW_TDEP_NUM_EH_REGS   2
+
+typedef ucontext_t unw_tdep_context_t;
+
+#define unw_tdep_getcontext(uc)                (getcontext (uc), 0)
+
+typedef struct unw_tdep_save_loc
+  {
+    /* Additional target-dependent info on a save location.  */
+    /* ANDROID support update. */
+    char __reserved;
+    /* End of ANDROID update. */
+  }
+unw_tdep_save_loc_t;
+
+#include "libunwind-dynamic.h"
+
+typedef struct
+  {
+    /* no sh-specific auxiliary proc-info */
+    /* ANDROID support update. */
+    char __reserved;
+    /* End of ANDROID update. */
+  }
+unw_tdep_proc_info_t;
+
+#include "libunwind-common.h"
+
+#define unw_tdep_is_fpreg              UNW_ARCH_OBJ(is_fpreg)
+extern int unw_tdep_is_fpreg (int);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* LIBUNWIND_H */
diff --git a/external/android-libunwind/include/libunwind-x86.h b/external/android-libunwind/include/libunwind-x86.h
new file mode 100644 (file)
index 0000000..e46632d
--- /dev/null
@@ -0,0 +1,193 @@
+/* libunwind - a platform-independent unwind library
+   Copyright (C) 2002-2004 Hewlett-Packard Co
+       Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
+
+#ifndef LIBUNWIND_H
+#define LIBUNWIND_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <ucontext.h>
+
+#define UNW_TARGET     x86
+#define UNW_TARGET_X86 1
+
+#define _U_TDEP_QP_TRUE        0       /* see libunwind-dynamic.h  */
+
+/* This needs to be big enough to accommodate "struct cursor", while
+   leaving some slack for future expansion.  Changing this value will
+   require recompiling all users of this library.  Stack allocation is
+   relatively cheap and unwind-state copying is relatively rare, so we
+   want to err on making it rather too big than too small.  */
+#define UNW_TDEP_CURSOR_LEN    127
+
+typedef uint32_t unw_word_t;
+typedef int32_t unw_sword_t;
+
+typedef union {
+  struct { uint8_t b[4]; } val32;
+  struct { uint8_t b[10]; } val80;
+  struct { uint8_t b[16]; } val128;
+} unw_tdep_fpreg_t;
+
+typedef enum
+  {
+    /* Note: general registers are expected to start with index 0.
+       This convention facilitates architecture-independent
+       implementation of the C++ exception handling ABI.  See
+       _Unwind_SetGR() and _Unwind_GetGR() for details.
+
+       The described register usage convention is based on "System V
+       Application Binary Interface, Intel386 Architecture Processor
+       Supplement, Fourth Edition" at
+
+         http://www.linuxbase.org/spec/refspecs/elf/abi386-4.pdf
+
+       It would have been nice to use the same register numbering as
+       DWARF, but that doesn't work because the libunwind requires
+       that the exception argument registers be consecutive, which the
+       wouldn't be with the DWARF numbering.  */
+    UNW_X86_EAX,       /* scratch (exception argument 1) */
+    UNW_X86_EDX,       /* scratch (exception argument 2) */
+    UNW_X86_ECX,       /* scratch */
+    UNW_X86_EBX,       /* preserved */
+    UNW_X86_ESI,       /* preserved */
+    UNW_X86_EDI,       /* preserved */
+    UNW_X86_EBP,       /* (optional) frame-register */
+    UNW_X86_ESP,       /* (optional) frame-register */
+    UNW_X86_EIP,       /* frame-register */
+    UNW_X86_EFLAGS,    /* scratch (except for "direction", which is fixed */
+    UNW_X86_TRAPNO,    /* scratch */
+
+    /* MMX/stacked-fp registers */
+    UNW_X86_ST0,       /* fp return value */
+    UNW_X86_ST1,       /* scratch */
+    UNW_X86_ST2,       /* scratch */
+    UNW_X86_ST3,       /* scratch */
+    UNW_X86_ST4,       /* scratch */
+    UNW_X86_ST5,       /* scratch */
+    UNW_X86_ST6,       /* scratch */
+    UNW_X86_ST7,       /* scratch */
+
+    UNW_X86_FCW,       /* scratch */
+    UNW_X86_FSW,       /* scratch */
+    UNW_X86_FTW,       /* scratch */
+    UNW_X86_FOP,       /* scratch */
+    UNW_X86_FCS,       /* scratch */
+    UNW_X86_FIP,       /* scratch */
+    UNW_X86_FEA,       /* scratch */
+    UNW_X86_FDS,       /* scratch */
+
+    /* SSE registers */
+    UNW_X86_XMM0_lo,   /* scratch */
+    UNW_X86_XMM0_hi,   /* scratch */
+    UNW_X86_XMM1_lo,   /* scratch */
+    UNW_X86_XMM1_hi,   /* scratch */
+    UNW_X86_XMM2_lo,   /* scratch */
+    UNW_X86_XMM2_hi,   /* scratch */
+    UNW_X86_XMM3_lo,   /* scratch */
+    UNW_X86_XMM3_hi,   /* scratch */
+    UNW_X86_XMM4_lo,   /* scratch */
+    UNW_X86_XMM4_hi,   /* scratch */
+    UNW_X86_XMM5_lo,   /* scratch */
+    UNW_X86_XMM5_hi,   /* scratch */
+    UNW_X86_XMM6_lo,   /* scratch */
+    UNW_X86_XMM6_hi,   /* scratch */
+    UNW_X86_XMM7_lo,   /* scratch */
+    UNW_X86_XMM7_hi,   /* scratch */
+
+    UNW_X86_MXCSR,     /* scratch */
+
+    /* segment registers */
+    UNW_X86_GS,                /* special */
+    UNW_X86_FS,                /* special */
+    UNW_X86_ES,                /* special */
+    UNW_X86_DS,                /* special */
+    UNW_X86_SS,                /* special */
+    UNW_X86_CS,                /* special */
+    UNW_X86_TSS,       /* special */
+    UNW_X86_LDT,       /* special */
+
+    /* frame info (read-only) */
+    UNW_X86_CFA,
+
+    UNW_X86_XMM0,      /* scratch */
+    UNW_X86_XMM1,      /* scratch */
+    UNW_X86_XMM2,      /* scratch */
+    UNW_X86_XMM3,      /* scratch */
+    UNW_X86_XMM4,      /* scratch */
+    UNW_X86_XMM5,      /* scratch */
+    UNW_X86_XMM6,      /* scratch */
+    UNW_X86_XMM7,      /* scratch */
+
+    UNW_TDEP_LAST_REG = UNW_X86_XMM7,
+
+    UNW_TDEP_IP = UNW_X86_EIP,
+    UNW_TDEP_SP = UNW_X86_ESP,
+    UNW_TDEP_EH = UNW_X86_EAX
+  }
+x86_regnum_t;
+
+#define UNW_TDEP_NUM_EH_REGS   2       /* eax and edx are exception args */
+
+typedef struct unw_tdep_save_loc
+  {
+    /* Additional target-dependent info on a save location.  */
+    /* ANDROID support update. */
+    char __reserved;
+    /* End of ANDROID update. */
+  }
+unw_tdep_save_loc_t;
+
+/* On x86, we can directly use ucontext_t as the unwind context.  */
+typedef ucontext_t unw_tdep_context_t;
+
+#include "libunwind-dynamic.h"
+
+typedef struct
+  {
+    /* no x86-specific auxiliary proc-info */
+    /* ANDROID support update. */
+    char __reserved;
+    /* End of ANDROID update. */
+  }
+unw_tdep_proc_info_t;
+
+#include "libunwind-common.h"
+
+#define unw_tdep_getcontext            UNW_ARCH_OBJ(getcontext)
+extern int unw_tdep_getcontext (unw_tdep_context_t *);
+
+#define unw_tdep_is_fpreg              UNW_ARCH_OBJ(is_fpreg)
+extern int unw_tdep_is_fpreg (int);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* LIBUNWIND_H */
diff --git a/external/android-libunwind/include/libunwind-x86_64.h b/external/android-libunwind/include/libunwind-x86_64.h
new file mode 100644 (file)
index 0000000..ed8cb11
--- /dev/null
@@ -0,0 +1,145 @@
+/* libunwind - a platform-independent unwind library
+   Copyright (C) 2002-2004 Hewlett-Packard Co
+       Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+   Modified for x86_64 by Max Asbock <masbock@us.ibm.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
+
+#ifndef LIBUNWIND_H
+#define LIBUNWIND_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <ucontext.h>
+
+#define UNW_TARGET             x86_64
+#define UNW_TARGET_X86_64      1
+
+#define _U_TDEP_QP_TRUE        0       /* see libunwind-dynamic.h  */
+
+/* This needs to be big enough to accommodate "struct cursor", while
+   leaving some slack for future expansion.  Changing this value will
+   require recompiling all users of this library.  Stack allocation is
+   relatively cheap and unwind-state copying is relatively rare, so we
+   want to err on making it rather too big than too small.  */
+#define UNW_TDEP_CURSOR_LEN    127
+
+typedef uint64_t unw_word_t;
+typedef int64_t unw_sword_t;
+
+typedef long double unw_tdep_fpreg_t;
+
+typedef enum
+  {
+    UNW_X86_64_RAX,
+    UNW_X86_64_RDX,
+    UNW_X86_64_RCX,
+    UNW_X86_64_RBX,
+    UNW_X86_64_RSI,
+    UNW_X86_64_RDI,
+    UNW_X86_64_RBP,
+    UNW_X86_64_RSP,
+    UNW_X86_64_R8,
+    UNW_X86_64_R9,
+    UNW_X86_64_R10,
+    UNW_X86_64_R11,
+    UNW_X86_64_R12,
+    UNW_X86_64_R13,
+    UNW_X86_64_R14,
+    UNW_X86_64_R15,
+    UNW_X86_64_RIP,
+#ifdef CONFIG_MSABI_SUPPORT
+    UNW_X86_64_XMM0,
+    UNW_X86_64_XMM1,
+    UNW_X86_64_XMM2,
+    UNW_X86_64_XMM3,
+    UNW_X86_64_XMM4,
+    UNW_X86_64_XMM5,
+    UNW_X86_64_XMM6,
+    UNW_X86_64_XMM7,
+    UNW_X86_64_XMM8,
+    UNW_X86_64_XMM9,
+    UNW_X86_64_XMM10,
+    UNW_X86_64_XMM11,
+    UNW_X86_64_XMM12,
+    UNW_X86_64_XMM13,
+    UNW_X86_64_XMM14,
+    UNW_X86_64_XMM15,
+    UNW_TDEP_LAST_REG = UNW_X86_64_XMM15,
+#else
+    UNW_TDEP_LAST_REG = UNW_X86_64_RIP,
+#endif
+
+    /* XXX Add other regs here */
+
+    /* frame info (read-only) */
+    UNW_X86_64_CFA,
+
+    UNW_TDEP_IP = UNW_X86_64_RIP,
+    UNW_TDEP_SP = UNW_X86_64_RSP,
+    UNW_TDEP_BP = UNW_X86_64_RBP,
+    UNW_TDEP_EH = UNW_X86_64_RAX
+  }
+x86_64_regnum_t;
+
+#define UNW_TDEP_NUM_EH_REGS   2       /* XXX Not sure what this means */
+
+typedef struct unw_tdep_save_loc
+  {
+    /* Additional target-dependent info on a save location.  */
+    /* ANDROID support update. */
+    char __reserved;
+    /* End of ANDROID update. */
+  }
+unw_tdep_save_loc_t;
+
+/* On x86_64, we can directly use ucontext_t as the unwind context.  */
+typedef ucontext_t unw_tdep_context_t;
+
+typedef struct
+  {
+    /* no x86-64-specific auxiliary proc-info */
+    /* ANDROID support update. */
+    char __reserved;
+    /* End of ANDROID update. */
+  }
+unw_tdep_proc_info_t;
+
+#include "libunwind-dynamic.h"
+#include "libunwind-common.h"
+
+#define unw_tdep_getcontext            UNW_ARCH_OBJ(getcontext)
+#define unw_tdep_is_fpreg              UNW_ARCH_OBJ(is_fpreg)
+
+extern int unw_tdep_getcontext (unw_tdep_context_t *);
+extern int unw_tdep_is_fpreg (int);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* LIBUNWIND_H */
diff --git a/external/android-libunwind/include/libunwind.h b/external/android-libunwind/include/libunwind.h
new file mode 100644 (file)
index 0000000..0fafda6
--- /dev/null
@@ -0,0 +1,34 @@
+/* Provide a real file - not a symlink - as it would cause multiarch conflicts
+   when multiple different arch releases are installed simultaneously.  */
+
+#ifndef UNW_REMOTE_ONLY
+
+#if defined __aarch64__
+#include "libunwind-aarch64.h"
+#elif defined __arm__
+# include "libunwind-arm.h"
+#elif defined __hppa__
+# include "libunwind-hppa.h"
+#elif defined __ia64__
+# include "libunwind-ia64.h"
+#elif defined __mips__
+# include "libunwind-mips.h"
+#elif defined __powerpc__ && !defined __powerpc64__
+# include "libunwind-ppc32.h"
+#elif defined __powerpc64__
+# include "libunwind-ppc64.h"
+#elif defined __sh__
+# include "libunwind-sh.h"
+#elif defined __i386__
+# include "libunwind-x86.h"
+#elif defined __x86_64__
+# include "libunwind-x86_64.h"
+#else
+# error "Unsupported arch"
+#endif
+
+#else /* UNW_REMOTE_ONLY */
+
+# include "libunwind-arm.h"
+
+#endif /* UNW_REMOTE_ONLY */
diff --git a/external/android-libunwind/include/unwind.h b/external/android-libunwind/include/unwind.h
new file mode 100644 (file)
index 0000000..f8d43d0
--- /dev/null
@@ -0,0 +1,154 @@
+/* libunwind - a platform-independent unwind library
+   Copyright (C) 2003 Hewlett-Packard Co
+       Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
+
+#ifndef _UNWIND_H
+#define _UNWIND_H
+
+/* For uint64_t */
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Minimal interface as per C++ ABI draft standard:
+
+       http://www.codesourcery.com/cxx-abi/abi-eh.html */
+
+typedef enum
+  {
+    _URC_NO_REASON = 0,
+    _URC_FOREIGN_EXCEPTION_CAUGHT = 1,
+    _URC_FATAL_PHASE2_ERROR = 2,
+    _URC_FATAL_PHASE1_ERROR = 3,
+    _URC_NORMAL_STOP = 4,
+    _URC_END_OF_STACK = 5,
+    _URC_HANDLER_FOUND = 6,
+    _URC_INSTALL_CONTEXT = 7,
+    _URC_CONTINUE_UNWIND = 8
+  }
+_Unwind_Reason_Code;
+
+typedef int _Unwind_Action;
+
+#define _UA_SEARCH_PHASE       1
+#define _UA_CLEANUP_PHASE      2
+#define _UA_HANDLER_FRAME      4
+#define _UA_FORCE_UNWIND       8
+
+struct _Unwind_Context;                /* opaque data-structure */
+struct _Unwind_Exception;      /* forward-declaration */
+
+typedef void (*_Unwind_Exception_Cleanup_Fn) (_Unwind_Reason_Code,
+                                             struct _Unwind_Exception *);
+
+typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn) (int, _Unwind_Action,
+                                               uint64_t,
+                                               struct _Unwind_Exception *,
+                                               struct _Unwind_Context *,
+                                               void *);
+
+/* The C++ ABI requires exception_class, private_1, and private_2 to
+   be of type uint64 and the entire structure to be
+   double-word-aligned. Please note that exception_class stays 64-bit 
+   even on 32-bit machines for gcc compatibility.  */
+struct _Unwind_Exception
+  {
+    uint64_t exception_class;
+    _Unwind_Exception_Cleanup_Fn exception_cleanup;
+    unsigned long private_1;
+    unsigned long private_2;
+  } __attribute__((__aligned__));
+
+extern _Unwind_Reason_Code _Unwind_RaiseException (struct _Unwind_Exception *);
+extern _Unwind_Reason_Code _Unwind_ForcedUnwind (struct _Unwind_Exception *,
+                                                _Unwind_Stop_Fn, void *);
+extern void _Unwind_Resume (struct _Unwind_Exception *);
+extern void _Unwind_DeleteException (struct _Unwind_Exception *);
+extern unsigned long _Unwind_GetGR (struct _Unwind_Context *, int);
+extern void _Unwind_SetGR (struct _Unwind_Context *, int, unsigned long);
+extern unsigned long _Unwind_GetIP (struct _Unwind_Context *);
+extern unsigned long _Unwind_GetIPInfo (struct _Unwind_Context *, int *);
+extern void _Unwind_SetIP (struct _Unwind_Context *, unsigned long);
+extern unsigned long _Unwind_GetLanguageSpecificData (struct _Unwind_Context*);
+extern unsigned long _Unwind_GetRegionStart (struct _Unwind_Context *);
+
+#ifdef _GNU_SOURCE
+
+/* Callback for _Unwind_Backtrace().  The backtrace stops immediately
+   if the callback returns any value other than _URC_NO_REASON. */
+typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn) (struct _Unwind_Context *,
+                                                void *);
+
+/* See http://gcc.gnu.org/ml/gcc-patches/2001-09/msg00082.html for why
+   _UA_END_OF_STACK exists.  */
+# define _UA_END_OF_STACK      16
+
+/* If the unwind was initiated due to a forced unwind, resume that
+   operation, else re-raise the exception.  This is used by
+   __cxa_rethrow().  */
+extern _Unwind_Reason_Code
+         _Unwind_Resume_or_Rethrow (struct _Unwind_Exception *);
+
+/* See http://gcc.gnu.org/ml/gcc-patches/2003-09/msg00154.html for why
+   _Unwind_GetBSP() exists.  */
+extern unsigned long _Unwind_GetBSP (struct _Unwind_Context *);
+
+/* Return the "canonical frame address" for the given context.
+   This is used by NPTL... */
+extern unsigned long _Unwind_GetCFA (struct _Unwind_Context *);
+
+/* Return the base-address for data references.  */
+extern unsigned long _Unwind_GetDataRelBase (struct _Unwind_Context *);
+
+/* Return the base-address for text references.  */
+extern unsigned long _Unwind_GetTextRelBase (struct _Unwind_Context *);
+
+/* Call _Unwind_Trace_Fn once for each stack-frame, without doing any
+   cleanup.  The first frame for which the callback is invoked is the
+   one for the caller of _Unwind_Backtrace().  _Unwind_Backtrace()
+   returns _URC_END_OF_STACK when the backtrace stopped due to
+   reaching the end of the call-chain or _URC_FATAL_PHASE1_ERROR if it
+   stops for any other reason.  */
+extern _Unwind_Reason_Code _Unwind_Backtrace (_Unwind_Trace_Fn, void *);
+
+/* Find the start-address of the procedure containing the specified IP
+   or NULL if it cannot be found (e.g., because the function has no
+   unwind info).  Note: there is not necessarily a one-to-one
+   correspondence between source-level functions and procedures: some
+   functions don't have unwind-info and others are split into multiple
+   procedures.  */
+extern void *_Unwind_FindEnclosingFunction (void *);
+
+/* See also Linux Standard Base Spec:
+    http://www.linuxbase.org/spec/refspecs/LSB_1.3.0/gLSB/gLSB/libgcc-s.html */
+
+#endif /* _GNU_SOURCE */
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif /* _UNWIND_H */
index 6fd7954ab42c949f141c90ef3aeeec886a16c22d..bb85df584df4eb0e8f41e58f61c9a855bacec375 100644 (file)
@@ -41,6 +41,8 @@ namespace Microsoft.Build.Tasks {
                ITaskItem[]     assignedProjects;
                string          solutionConfigurationContents;
                ITaskItem[]     unassignedProjects;
+               Dictionary<Guid, string> guidToConfigPlatform;
+               Dictionary<string, string> absolutePathToConfigPlatform;
        
                public AssignProjectConfiguration ()
                {
@@ -53,10 +55,10 @@ namespace Microsoft.Build.Tasks {
                                return true;
 
                        XmlReader xr = null;
-                       Dictionary<Guid, string> guidToConfigPlatform = null;
+                       guidToConfigPlatform = new Dictionary<Guid, string> ();
+                       absolutePathToConfigPlatform = new Dictionary<string, string> ();
                        try {
                                xr = XmlReader.Create (new StringReader (solutionConfigurationContents));
-                               guidToConfigPlatform = new Dictionary<Guid, string> ();
 
                                xr.Read ();
                                while (!xr.EOF) {
@@ -65,12 +67,20 @@ namespace Microsoft.Build.Tasks {
                                                continue;
 
                                        string guid_str = xr.GetAttribute ("Project");
+                                       string abs_path = xr.GetAttribute ("AbsolutePath");
                                        string config_str = xr.ReadString ();
 
+                                       if (String.IsNullOrEmpty (config_str))
+                                               continue;
+
                                        Guid guid;
-                                       if (!String.IsNullOrEmpty (guid_str) && !String.IsNullOrEmpty (config_str) &&
-                                               TryParseGuid (guid_str, out guid))
+                                       if (TryParseGuid (guid_str, out guid))
                                                guidToConfigPlatform [guid] = config_str;
+
+                                       if (!String.IsNullOrEmpty (abs_path)) {
+                                               abs_path = Path.GetFullPath (abs_path);
+                                               absolutePathToConfigPlatform [abs_path] = config_str;
+                                       }
                                }
                        } catch (XmlException xe) {
                                Log.LogError ("XmlException while parsing SolutionConfigurationContents: {0}",
@@ -84,32 +94,22 @@ namespace Microsoft.Build.Tasks {
                        List<ITaskItem> tempAssignedProjects = new List<ITaskItem> ();
                        List<ITaskItem> tempUnassignedProjects = new List<ITaskItem> ();
                        foreach (ITaskItem item in ProjectReferences) {
-                               string config;
-
-                               string guid_str = item.GetMetadata ("Project");
+                               string config = GetConfigPlatformFromProjectReference (item);
 
-                               Guid guid = Guid.Empty;
-                               if (!string.IsNullOrEmpty(guid_str) && !TryParseGuid (guid_str, out guid)) {
-                                       Log.LogError ("Project reference '{0}' has invalid or missing guid for metadata 'Project'.",
-                                                       item.ItemSpec);
-                                       return false;
+                               if (String.IsNullOrEmpty (config)) {
+                                       tempUnassignedProjects.Add (item);
+                                       continue;
                                }
 
-                               if (guid != Guid.Empty && guidToConfigPlatform.TryGetValue (guid, out config)) {
-                                       string [] parts = config.Split (new char [] {'|'}, 2);
+                               string [] parts = config.Split (new char [] {'|'}, 2);
 
-                                       ITaskItem new_item = new TaskItem (item);
+                               ITaskItem new_item = new TaskItem (item);
 
-                                       new_item.SetMetadata ("SetConfiguration", "Configuration=" + parts [0]);
-                                       new_item.SetMetadata ("SetPlatform", "Platform=" +
-                                                       ((parts.Length > 1) ? parts [1] : String.Empty));
+                               new_item.SetMetadata ("SetConfiguration", "Configuration=" + parts [0]);
+                               new_item.SetMetadata ("SetPlatform", "Platform=" +
+                                               ((parts.Length > 1) ? parts [1] : String.Empty));
 
-                                       tempAssignedProjects.Add (new_item);
-                               } else {
-                                       Log.LogWarning ("Project reference '{0}' could not be resolved.",
-                                                       item.ItemSpec);
-                                       tempUnassignedProjects.Add (item);
-                               }
+                               tempAssignedProjects.Add (new_item);
                        }
 
                        assignedProjects = tempAssignedProjects.ToArray ();
@@ -118,9 +118,29 @@ namespace Microsoft.Build.Tasks {
                        return true;
                }
 
+               string GetConfigPlatformFromProjectReference (ITaskItem item)
+               {
+                       string guid_str = item.GetMetadata ("Project");
+                       string proj_full_path = item.GetMetadata ("FullPath");
+
+                       string config;
+                       Guid guid = Guid.Empty;
+                       if (TryParseGuid (guid_str, out guid) && guidToConfigPlatform.TryGetValue (guid, out config))
+                               return config;
+
+                       string abs_path = item.GetMetadata ("FullPath");
+                       if (absolutePathToConfigPlatform.TryGetValue (abs_path, out config))
+                               return config;
+
+                       return null;
+               }
+
                bool TryParseGuid (string guid_str, out Guid guid)
                {
                        guid = Guid.Empty;
+                       if (String.IsNullOrEmpty (guid_str))
+                               return false;
+
                        try {
                                guid = new Guid (guid_str);
                        } catch (ArgumentNullException) {
index f7d25591a8ce8973f4046ed5dbb53331841463c1..be1ea2c0fb787a177fcd0c7f659e97df04b10427 100644 (file)
@@ -32,6 +32,7 @@ using Microsoft.Build.Framework;
 using Microsoft.Build.Tasks;
 using Microsoft.Build.Utilities;
 using NUnit.Framework;
+using System.IO;
 using System.Text;
 
 namespace MonoTests.Microsoft.Build.Tasks
@@ -58,22 +59,73 @@ namespace MonoTests.Microsoft.Build.Tasks
                                "{DAE34193-B5C7-4488-A911-29EE15C84CBE}"
                        };
 
-                       CreateAndCheckProject (guids, project_ref_guids, new string[] {
-                                       "AssignedProjects : foo0.csproj;foo1.csproj;foo2.csproj;foo3.csproj: SetConfig: Configuration=Release",
+                       CreateAndCheckProject (guids, new bool[] {true, true, true, true, true, true},
+                                       project_ref_guids, new string[] {
+                                       "AssignedProjects : foo0.csproj;foo1.csproj;foo2.csproj;foo3.csproj;foo4.csproj: SetConfig: Configuration=Release",
                                        "AssignedProjects : foo0.csproj: SetPlatform: Platform=AnyCPU0",
                                        "AssignedProjects : foo1.csproj: SetPlatform: Platform=AnyCPU1",
                                        "AssignedProjects : foo2.csproj: SetPlatform: Platform=AnyCPU2",
                                        "AssignedProjects : foo3.csproj: SetPlatform: Platform=AnyCPU3",
-                                       "UnassignedProjects : foo4.csproj"},
+                                       "AssignedProjects : foo4.csproj: SetPlatform: Platform=AnyCPU4",
+                                       "UnassignedProjects : "},
                                        true,
                                         "A1#");
                }
 
                [Test]
-               public void TestInvalidProjectGuid ()
+               public void TestNoGuidAndNoAbsolutePathFound()
                {
                        string[] guids = new string[] {
+                               "asd"
+                       };
+
+                       string[] project_ref_guids = new string[] {
+                               "{DAE34193-B5C7-4488-A911-29EE15C84CB8}",
+                               "invalid guid",
+                               ""
+                       };
+
+                       CreateAndCheckProject (guids, new bool[]{false},
+                                       project_ref_guids,
+                                       new string[] {
+                                               "AssignedProjects : : SetConfig: ",
+                                               "AssignedProjects : : SetPlatform: ",
+                                               "UnassignedProjects : foo0.csproj;foo1.csproj;foo2.csproj"
+                                       },
+                                       true, "A1#");
+               }
+
+               [Test]
+               public void TestInvalidProjectGuidWithAbsolutePath ()
+               {
+                       string[] guids = new string[] {
+                               null, // no AbsPath
+                               "another invalid guid", // has AbsPath
+                       };
+
+                       string[] project_ref_guids = new string[] {
+                               "1234zxc", // this won't match because no AbsPath
+                               "xzxoiu",  // match with the second project, foo1.csproj
                                "{23F291D9-78DF-4133-8CF2-78CE104DDE63}",
+                               "badref"   // no corresponding project at all
+                       };
+
+                       CreateAndCheckProject (guids, new bool[]{false, true},
+                                       project_ref_guids,
+                                       new string[] {
+                                               "AssignedProjects : foo1.csproj: SetConfig: Configuration=Release",
+                                               "AssignedProjects : foo1.csproj: SetPlatform: Platform=AnyCPU1",
+                                               "UnassignedProjects : foo0.csproj;foo2.csproj;foo3.csproj"
+                                       },
+                                       true, "A1#");
+               }
+
+               [Test]
+               public void TestNoGuidWithAbsolutePath ()
+               {
+                       string[] guids = new string[] {
+                               "",
+                               null
                        };
 
                        string[] project_ref_guids = new string[] {
@@ -82,7 +134,14 @@ namespace MonoTests.Microsoft.Build.Tasks
                                "invalid guid"
                        };
 
-                       CreateAndCheckProject (guids, project_ref_guids, null, false, "A1#");
+                       CreateAndCheckProject (guids, new bool[]{true, false},
+                                       project_ref_guids,
+                                       new string[] {
+                                               "AssignedProjects : foo0.csproj: SetConfig: Configuration=Release",
+                                               "AssignedProjects : foo0.csproj: SetPlatform: Platform=AnyCPU0",
+                                               "UnassignedProjects : foo1.csproj;foo2.csproj"
+                                       },
+                                       true, "A1#");
                }
 
                [Test]
@@ -97,7 +156,8 @@ namespace MonoTests.Microsoft.Build.Tasks
                                "{23F291D9-78DF-4133-8CF2-78CE104DDE63}"
                        };
 
-                       CreateAndCheckProject (guids, project_ref_guids,
+                       CreateAndCheckProject (guids, new bool[]{false, true},
+                               project_ref_guids,
                                new string [] {
                                        "AssignedProjects : foo1.csproj: SetConfig: Configuration=Release",
                                        "AssignedProjects : foo1.csproj: SetPlatform: Platform=AnyCPU0",
@@ -106,14 +166,14 @@ namespace MonoTests.Microsoft.Build.Tasks
                }
 
 
-               void CreateAndCheckProject (string[] guids, string[] project_ref_guids, string[] messages, bool build_result, string prefix)
+               void CreateAndCheckProject (string[] guids, bool[] set_project_paths, string[] project_ref_guids, string[] messages, bool build_result, string prefix)
                {
                        Engine engine = new Engine (Consts.BinPath);
                        Project project = engine.CreateNewProject ();
                        TestMessageLogger testLogger = new TestMessageLogger ();
                        engine.RegisterLogger (testLogger);
 
-                       string projectString = CreateProject (guids, project_ref_guids);
+                       string projectString = CreateProject (guids, set_project_paths, project_ref_guids);
                        project.LoadXml (projectString);
 
                        try {
@@ -131,12 +191,12 @@ namespace MonoTests.Microsoft.Build.Tasks
                        }
                }
 
-               string CreateProject (string[] guids, string[] project_ref_guids)
+               string CreateProject (string[] guids, bool[] set_project_paths, string[] project_ref_guids)
                {
                        StringBuilder sb = new StringBuilder ();
                        sb.Append (@"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">");
                        sb.Append ("\n" + GetUsingTask ("AssignProjectConfiguration"));
-                       sb.AppendFormat (@"<PropertyGroup>{0}</PropertyGroup>", CreateSolutionConfigurationProperty (guids, "Release|AnyCPU"));
+                       sb.AppendFormat (@"<PropertyGroup>{0}</PropertyGroup>", CreateSolutionConfigurationProperty (guids, set_project_paths, "Release|AnyCPU"));
                        sb.Append (CreateProjectReferencesItemGroup (project_ref_guids));
 
                        sb.Append ("\n\t<Target Name=\"1\">\n");
@@ -154,13 +214,19 @@ namespace MonoTests.Microsoft.Build.Tasks
                        return sb.ToString ();
                }
 
-               string CreateSolutionConfigurationProperty (string[] guids, string config_str)
+               string CreateSolutionConfigurationProperty (string[] guids, bool[] set_project_paths, string config_str)
                {
+                       string abs_proj_path_prefix = Path.GetFullPath ("foo");
                        StringBuilder sb = new StringBuilder ();
                        sb.Append ("\n<CurrentSolutionConfigurationContents>\n");
                                sb.Append ("\t<foo xmlns=\"\">\n");
                                for (int i = 0; i < guids.Length; i++) {
-                                       sb.AppendFormat ("\t\t<bar Project=\"{0}\">{1}{2}</bar>\n",
+                                       sb.Append ("\t\t<bar");
+                                       if (guids[i] != null)
+                                               sb.AppendFormat (" Project=\"{0}\"", guids[i]);
+                                       if (set_project_paths[i])
+                                               sb.AppendFormat (" AbsolutePath=\"{0}{1}.csproj\" ", abs_proj_path_prefix, i);
+                                       sb.AppendFormat (">{1}{2}</bar>\n",
                                                guids[i], config_str, i);
                                }
                                sb.Append ("\t</foo>\n");
@@ -173,8 +239,12 @@ namespace MonoTests.Microsoft.Build.Tasks
                {
                        StringBuilder sb = new StringBuilder ();
                        sb.Append ("\n<ItemGroup>\n");
-                       for (int i = 0; i < guids.Length; i ++)
-                               sb.AppendFormat ("\t<ProjectReference Include=\"foo{1}.csproj\"><Project>{0}</Project></ProjectReference>\n", guids [i], i);
+                       for (int i = 0; i < guids.Length; i ++) {
+                               sb.AppendFormat ("\t<ProjectReference Include=\"foo{0}.csproj\">", i);
+                               if (guids[i] != null)
+                                       sb.AppendFormat ("<Project>{0}</Project>", guids[i]);
+                               sb.Append ("</ProjectReference>\n");
+                       }
                        sb.Append ("</ItemGroup>\n");
                        return sb.ToString ();
                }
index bf44c515970b467421ac6bcb6a1a6df5874fd203..44ac70d2f963f328fd8bb2ad840912446e262454 100644 (file)
@@ -510,8 +510,8 @@ namespace Mono.XBuild.CommandLine {
                                if (solutionTarget.Configuration == targetInfo.Key.Configuration &&
                                                solutionTarget.Platform == targetInfo.Key.Platform) {
                                        solutionConfigurationContents.AppendFormat (
-                                                       "<ProjectConfiguration Project=\"{0}\">{1}|{2}</ProjectConfiguration>",
-                                       guid.ToString ("B").ToUpper (), targetInfo.Value.Configuration, targetInfo.Value.Platform);
+                                                       "<ProjectConfiguration Project=\"{0}\" AbsolutePath=\"{1}\">{2}|{3}</ProjectConfiguration>",
+                                                       guid.ToString ("B").ToUpper (), projectInfo.FileName, targetInfo.Value.Configuration, targetInfo.Value.Platform);
                                }
                        }
                }
index 93169cda59d4ba1ac7fb1a526b6a1b9a352bd489..aaeab57d56729239d8b9bcb99d7405cb72360375 100644 (file)
@@ -2431,6 +2431,7 @@ unload_thread_main (void *arg)
        /* Force it to be attached to avoid racing during shutdown. */
        thread = mono_thread_attach_full (mono_get_root_domain (), TRUE, &error);
        mono_error_raise_exception (&error); /* FIXME don't raise here */
+       mono_thread_set_name_internal (thread->internal_thread, mono_string_new (mono_get_root_domain (), "Domain unloader"), TRUE);
 
        /* 
         * FIXME: Abort our parent thread last, so we can return a failure 
index 9e54462633cf92da422cb9e8d06a9783b4dae022..688f816a407a841dd228169b151abd27ad24794f 100644 (file)
@@ -480,6 +480,8 @@ receiver_thread (void *arg)
        guint8 *p, *p_end;
        MonoObject *exc;
 
+       mono_thread_info_set_name (mono_native_thread_id_get (), "Attach receiver");
+
        printf ("attach: Listening on '%s'...\n", server_uri);
 
        while (TRUE) {
@@ -490,11 +492,12 @@ receiver_thread (void *arg)
 
                printf ("attach: Connected.\n");
 
-               mono_thread_attach (mono_get_root_domain ());
+               MonoThread *thread = mono_thread_attach (mono_get_root_domain ());
+               mono_thread_set_name_internal (thread->internal_thread, mono_string_new (mono_get_root_domain (), "Attach receiver"), TRUE);
                /* Ask the runtime to not abort this thread */
                //mono_thread_current ()->flags |= MONO_THREAD_FLAG_DONT_MANAGE;
                /* Ask the runtime to not wait for this thread */
-               mono_thread_internal_current ()->state |= ThreadState_Background;
+               thread->internal_thread->state |= ThreadState_Background;
 
                while (TRUE) {
                        char *cmd, *agent_name, *agent_args;
index 148bbedee6444a74666934c4a37d4b5377e69b2e..edba423b8a6b237d802d484de46611da1f7e04d5 100644 (file)
@@ -748,6 +748,8 @@ finalize_domain_objects (DomainFinalizationReq *req)
 static guint32
 finalizer_thread (gpointer unused)
 {
+       mono_thread_set_name_internal (mono_thread_internal_current (), mono_string_new (mono_get_root_domain (), "Finalizer"), FALSE);
+
        gboolean wait = TRUE;
 
        /* Register a hazard free queue pump callback */
@@ -823,7 +825,6 @@ void
 mono_gc_init_finalizer_thread (void)
 {
        gc_thread = mono_thread_create_internal (mono_domain_get (), finalizer_thread, NULL, FALSE, 0);
-       ves_icall_System_Threading_Thread_SetName_internal (gc_thread, mono_string_new (mono_domain_get (), "Finalizer"));
 }
 
 void
index 4191be81d5e2301ef9df01a056506a380a8d3bb3..a847b0f58624a0587765b4bd6e526bda2787d1d6 100644 (file)
@@ -2346,7 +2346,7 @@ mono_marshal_get_string_to_ptr_conv (MonoMethodPInvoke *piinfo, MonoMarshalSpec
        case MONO_NATIVE_BSTR:
                return MONO_MARSHAL_CONV_STR_BSTR;
        default:
-               return (MonoMarshalConv)-1;
+               return MONO_MARSHAL_CONV_INVALID;
        }
 }
 
@@ -2366,7 +2366,7 @@ mono_marshal_get_stringbuilder_to_ptr_conv (MonoMethodPInvoke *piinfo, MonoMarsh
                return MONO_MARSHAL_CONV_SB_LPTSTR;
                break;
        default:
-               return (MonoMarshalConv)-1;
+               return MONO_MARSHAL_CONV_INVALID;
        }
 }
 
@@ -2389,7 +2389,7 @@ mono_marshal_get_ptr_to_string_conv (MonoMethodPInvoke *piinfo, MonoMarshalSpec
        case MONO_NATIVE_BSTR:
                return MONO_MARSHAL_CONV_BSTR_STR;
        default:
-               return (MonoMarshalConv)-1;
+               return MONO_MARSHAL_CONV_INVALID;
        }
 }
 
@@ -2415,7 +2415,7 @@ mono_marshal_get_ptr_to_stringbuilder_conv (MonoMethodPInvoke *piinfo, MonoMarsh
                return MONO_MARSHAL_CONV_LPTSTR_SB;
                break;
        default:
-               return (MonoMarshalConv)-1;
+               return MONO_MARSHAL_CONV_INVALID;
        }
 }
 
@@ -5105,7 +5105,7 @@ emit_marshal_string (EmitMarshalContext *m, int argnum, MonoType *t,
                        mono_mb_emit_ldarg (mb, argnum);
                }
 
-               if (conv == (MonoMarshalConv)-1) {
+               if (conv == MONO_MARSHAL_CONV_INVALID) {
                        char *msg = g_strdup_printf ("string marshalling conversion %d not implemented", encoding);
                        mono_mb_emit_exception_marshal_directive (mb, msg);
                } else {
@@ -5117,7 +5117,7 @@ emit_marshal_string (EmitMarshalContext *m, int argnum, MonoType *t,
 
        case MARSHAL_ACTION_CONV_OUT:
                conv = mono_marshal_get_ptr_to_string_conv (m->piinfo, spec, &need_free);
-               if (conv == (MonoMarshalConv)-1) {
+               if (conv == MONO_MARSHAL_CONV_INVALID) {
                        char *msg = g_strdup_printf ("string marshalling conversion %d not implemented", encoding);
                        mono_mb_emit_exception_marshal_directive (mb, msg);
                        break;
@@ -5177,7 +5177,7 @@ emit_marshal_string (EmitMarshalContext *m, int argnum, MonoType *t,
                mono_mb_emit_stloc (mb, 0);
                                
                conv = mono_marshal_get_ptr_to_string_conv (m->piinfo, spec, &need_free);
-               if (conv == (MonoMarshalConv)-1) {
+               if (conv == MONO_MARSHAL_CONV_INVALID) {
                        char *msg = g_strdup_printf ("string marshalling conversion %d not implemented", encoding);
                        mono_mb_emit_exception_marshal_directive (mb, msg);
                        break;
@@ -5206,7 +5206,7 @@ emit_marshal_string (EmitMarshalContext *m, int argnum, MonoType *t,
                }
 
                conv = mono_marshal_get_ptr_to_string_conv (m->piinfo, spec, &need_free);
-               if (conv == (MonoMarshalConv)-1) {
+               if (conv == MONO_MARSHAL_CONV_INVALID) {
                        char *msg = g_strdup_printf ("string marshalling conversion %d not implemented", encoding);
                        mono_mb_emit_exception_marshal_directive (mb, msg);
                        break;
@@ -5534,7 +5534,7 @@ emit_marshal_object (EmitMarshalContext *m, int argnum, MonoType *t,
                        if (t->byref && !(t->attrs & PARAM_ATTRIBUTE_IN) && (t->attrs & PARAM_ATTRIBUTE_OUT))
                                break;
 
-                       if (conv == (MonoMarshalConv)-1) {
+                       if (conv == MONO_MARSHAL_CONV_INVALID) {
                                char *msg = g_strdup_printf ("stringbuilder marshalling conversion %d not implemented", encoding);
                                mono_mb_emit_exception_marshal_directive (mb, msg);
                                break;
@@ -6170,9 +6170,9 @@ emit_marshal_array (EmitMarshalContext *m, int argnum, MonoType *t,
                                conv = mono_marshal_get_stringbuilder_to_ptr_conv (m->piinfo, spec);
                        }
                        else
-                               conv = (MonoMarshalConv)-1;
+                               conv = MONO_MARSHAL_CONV_INVALID;
 
-                       if (is_string && conv == (MonoMarshalConv)-1) {
+                       if (is_string && conv == MONO_MARSHAL_CONV_INVALID) {
                                char *msg = g_strdup_printf ("string/stringbuilder marshalling conversion %d not implemented", encoding);
                                mono_mb_emit_exception_marshal_directive (mb, msg);
                                break;
@@ -6344,7 +6344,7 @@ emit_marshal_array (EmitMarshalContext *m, int argnum, MonoType *t,
                                gboolean need_free2;
                                MonoMarshalConv conv = mono_marshal_get_ptr_to_stringbuilder_conv (m->piinfo, spec, &need_free2);
 
-                               g_assert (conv != (MonoMarshalConv)-1);
+                               g_assert (conv != MONO_MARSHAL_CONV_INVALID);
 
                                /* dest */
                                mono_mb_emit_ldarg (mb, argnum);
@@ -6491,7 +6491,7 @@ emit_marshal_array (EmitMarshalContext *m, int argnum, MonoType *t,
                        conv = mono_marshal_get_ptr_to_stringbuilder_conv (m->piinfo, spec, &need_free);
                }
                else
-                       conv = (MonoMarshalConv)-1;
+                       conv = MONO_MARSHAL_CONV_INVALID;
 
                mono_marshal_load_type_info (eklass);
 
@@ -6586,7 +6586,7 @@ emit_marshal_array (EmitMarshalContext *m, int argnum, MonoType *t,
 
                /* Emit marshalling code */
                if (is_string) {
-                       g_assert (conv != (MonoMarshalConv)-1);
+                       g_assert (conv != MONO_MARSHAL_CONV_INVALID);
 
                        mono_mb_emit_ldloc (mb, conv_arg);
                        mono_mb_emit_ldloc (mb, index_var);
@@ -6654,7 +6654,7 @@ emit_marshal_array (EmitMarshalContext *m, int argnum, MonoType *t,
                        conv = mono_marshal_get_stringbuilder_to_ptr_conv (m->piinfo, spec);
                }
                else
-                       conv = (MonoMarshalConv)-1;
+                       conv = MONO_MARSHAL_CONV_INVALID;
 
                mono_marshal_load_type_info (eklass);
 
@@ -6702,7 +6702,7 @@ emit_marshal_array (EmitMarshalContext *m, int argnum, MonoType *t,
 
                /* Emit marshalling code */
                if (is_string) {
-                       g_assert (conv != (MonoMarshalConv)-1);
+                       g_assert (conv != MONO_MARSHAL_CONV_INVALID);
 
                        /* dest */
                        mono_mb_emit_ldloc (mb, dest_ptr);
@@ -6736,7 +6736,7 @@ emit_marshal_array (EmitMarshalContext *m, int argnum, MonoType *t,
                MonoClass *eklass;
                guint32 label1, label2, label3;
                int index_var, src, dest, esize;
-               MonoMarshalConv conv = (MonoMarshalConv)-1;
+               MonoMarshalConv conv = MONO_MARSHAL_CONV_INVALID;
                gboolean is_string = FALSE;
                
                g_assert (!t->byref);
@@ -6799,7 +6799,7 @@ emit_marshal_array (EmitMarshalContext *m, int argnum, MonoType *t,
 
                /* Emit marshalling code */
                if (is_string) {
-                       g_assert (conv != (MonoMarshalConv)-1);
+                       g_assert (conv != MONO_MARSHAL_CONV_INVALID);
 
                        /* dest */
                        mono_mb_emit_ldloc (mb, dest);
index afc21d48e66a222e41b33846c4b5368659b977f0..35afec7e3eac6f0a4eea92c57f7aededa9b4c917 100644 (file)
 
 MONO_BEGIN_DECLS
 
-/*
- * When embedding, you have to define MONO_ZERO_LEN_ARRAY before including any
- * other Mono header file if you use a different compiler from the one used to
- * build Mono.
- */
-#ifndef MONO_ZERO_LEN_ARRAY
-#ifdef __GNUC__
-#define MONO_ZERO_LEN_ARRAY 0
-#else
-#define MONO_ZERO_LEN_ARRAY 1
-#endif
-#endif
-
 #define MONO_TYPE_ISSTRUCT(t) mono_type_is_struct (t)
 #define MONO_TYPE_IS_VOID(t) mono_type_is_void (t)
 #define MONO_TYPE_IS_POINTER(t) mono_type_is_pointer (t)
@@ -178,6 +165,8 @@ typedef enum {
        MONO_MARSHAL_CONV_HANDLEREF
 } MonoMarshalConv;
 
+#define MONO_MARSHAL_CONV_INVALID ((MonoMarshalConv)-1)
+
 typedef struct {
        MonoMarshalNative native;
        union {
index af85ac1b3c3eb1c8423c252eed10cf9fa82f77d9..ad28290bcc93a30e979f7e7d7cc3b1e09e8fafb4 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef __METADATA_REFLECTION_H__
 #define __METADATA_REFLECTION_H__
 
+#include <mono/utils/mono-compiler.h>
 #include <mono/metadata/object.h>
 
 MONO_BEGIN_DECLS
index 2956d95420a1460145c6ab4a3c8e688ef5ce00f4..cadd83f30fd0d1f37a30312a54e32b9f213d1401 100644 (file)
@@ -2298,6 +2298,7 @@ void
 sgen_client_thread_register_worker (void)
 {
        mono_thread_info_register_small_id ();
+       mono_thread_info_set_name (mono_native_thread_id_get (), "SGen worker");
 }
 
 /* Variables holding start/end nursery so it won't have to be passed at every call */
@@ -2938,9 +2939,14 @@ sgen_client_describe_invalid_pointer (GCObject *ptr)
        sgen_bridge_describe_pointer (ptr);
 }
 
+static gboolean gc_inited;
+
 void
 mono_gc_base_init (void)
 {
+       if (gc_inited)
+               return;
+
        mono_counters_init ();
 
 #ifdef HEAVY_STATISTICS
@@ -2963,6 +2969,8 @@ mono_gc_base_init (void)
        if (mono_tls_key_get_offset (TLS_KEY_SGEN_TLAB_NEXT_ADDR) == -1)
                sgen_set_use_managed_allocator (FALSE);
 #endif
+
+       gc_inited = TRUE;
 }
 
 void
index 62fc34aef3f2b11e470b7a8912c819bbf68a6db1..eef559e9926c0d2dc18578c602ab5a5d376031a7 100644 (file)
@@ -592,7 +592,7 @@ worker_thread (gpointer data)
        thread = mono_thread_internal_current ();
        g_assert (thread);
 
-       mono_thread_set_name_internal (thread, mono_string_new (mono_domain_get (), "Threadpool worker"), FALSE);
+       mono_thread_set_name_internal (thread, mono_string_new (mono_get_root_domain (), "Threadpool worker"), FALSE);
 
        mono_coop_mutex_lock (&threadpool->active_threads_lock);
        g_ptr_array_add (threadpool->working_threads, thread);
index 5884d0270e58ee9ce7dd577fc37d3d16a8a4fced..0246491124d24e947d208c29737290f0fc627509 100644 (file)
@@ -454,7 +454,9 @@ static void thread_cleanup (MonoInternalThread *thread)
        }
        mono_release_type_locks (thread);
 
-       mono_profiler_thread_end (thread->tid);
+       /* Can happen when we attach the profiler helper thread in order to heapshot. */
+       if (!mono_thread_info_lookup (thread->tid)->tools_thread)
+               mono_profiler_thread_end (thread->tid);
 
        if (thread == mono_thread_internal_current ()) {
                /*
@@ -725,6 +727,7 @@ static guint32 WINAPI start_wrapper_internal(void *data)
        if (internal->name && (internal->flags & MONO_THREAD_FLAG_NAME_SET)) {
                char *tname = g_utf16_to_utf8 (internal->name, internal->name_len, NULL, NULL, NULL);
                mono_profiler_thread_name (internal->tid, tname);
+               mono_thread_info_set_name (internal->tid, tname);
                g_free (tname);
        }
        /* start_func is set only for unmanaged start functions */
@@ -1036,8 +1039,10 @@ mono_thread_attach_full (MonoDomain *domain, gboolean force_attach, MonoError *e
                        mono_thread_attach_cb (MONO_NATIVE_THREAD_ID_TO_UINT (tid), staddr + stsize);
        }
 
-       // FIXME: Need a separate callback
-       mono_profiler_thread_start (MONO_NATIVE_THREAD_ID_TO_UINT (tid));
+       /* Can happen when we attach the profiler helper thread in order to heapshot. */
+       if (!info->tools_thread)
+               // FIXME: Need a separate callback
+               mono_profiler_thread_start (MONO_NATIVE_THREAD_ID_TO_UINT (tid));
 
        return current_thread;
 }
index e5c6251623964421473bfd22f74f78135eb30212..f0f79d7c40d170416ea662b3832a938e380cfe43 100644 (file)
@@ -7865,7 +7865,8 @@ compile_thread_main (gpointer *user_data)
        GPtrArray *methods = (GPtrArray *)user_data [2];
        int i;
 
-       mono_thread_attach (domain);
+       MonoThread *thread = mono_thread_attach (domain);
+       mono_thread_set_name_internal (thread->internal_thread, mono_string_new (mono_get_root_domain (), "AOT compiler"), TRUE);
 
        for (i = 0; i < methods->len; ++i)
                compile_method (acfg, (MonoMethod *)g_ptr_array_index (methods, i));
index 3aac1ed77d05af7b0a46867ac3e5d1d2ac102c4c..ba127514b1bacda0a733af3ee9b110c4326ecd5a 100644 (file)
@@ -9690,8 +9690,10 @@ debugger_thread (void *arg)
        debugger_thread_id = mono_native_thread_id_get ();
 
        attach_cookie = mono_jit_thread_attach (mono_get_root_domain (), &attach_dummy);
+       MonoInternalThread *thread = mono_thread_internal_current ();
+       mono_thread_set_name_internal (thread, mono_string_new (mono_get_root_domain (), "Debugger agent"), TRUE);
 
-       mono_thread_internal_current ()->flags |= MONO_THREAD_FLAG_DONT_MANAGE;
+       thread->flags |= MONO_THREAD_FLAG_DONT_MANAGE;
 
        mono_set_is_debugger_attached (TRUE);
        
index cc5ac4bbad64790b6aaa34f6db94d1b06fd7bf3f..f1c27d7dc404fe214ff5d13837dfd7677988ea65 100644 (file)
@@ -1987,8 +1987,16 @@ mono_main (int argc, char* argv[])
        /* Set rootdir before loading config */
        mono_set_rootdir ();
 
-       if (enable_profile)
+       /*
+        * We only set the native name of the thread since MS.NET leaves the
+        * managed thread name for the main thread as null.
+        */
+       mono_thread_info_set_name (mono_native_thread_id_get (), "Main");
+
+       if (enable_profile) {
                mono_profiler_load (profile_options);
+               mono_profiler_thread_name (mono_native_thread_id_get (), "Main");
+       }
 
        mono_attach_parse_options (attach_options);
 
index 47a6dbb5ba2fda5c38e2923c67edefd4f4f5635c..c8fa1c9519b8a3cd82b81e7b38120ab20f2c0fbd 100644 (file)
@@ -130,7 +130,7 @@ DECLARE_GLOBAL_SYMBOL mono_fallback_set_tls_key
        .align 4
 DECLARE_GLOBAL_SYMBOL mono_fast_get_tls_key2
        bic     r0, r0, #0x80000000
-       mrc     15, 0, r1, cr13, cr0, #3
+       mrc     p15, 0, r1, cr13, cr0, #3
        lsls    r0, r0, #3
        ldr     r1, [r1, #4]
        add     r0, r1
@@ -146,7 +146,7 @@ DECLARE_GLOBAL_SYMBOL mono_fast_get_tls_key2_end
        .align 4
 DECLARE_GLOBAL_SYMBOL mono_fast_set_tls_key2
        bic     r0, r0, #0x80000000
-       mrc     15, 0, r2, cr13, cr0, #3
+       mrc     p15, 0, r2, cr13, cr0, #3
        lsls    r0, r0, #3
        ldr     r2, [r2, #4]
        add     r0, r2
index 3d9664b56bfde0998bb87aefb64287777b929571..df24c53c6581c444f8c8c02ce774215617ad4f0b 100644 (file)
@@ -14,7 +14,7 @@
 /*
  * GSHAREDVT
  */
-#ifdef MONO_ARCH_GSHARED_SUPPORTED
+#ifdef MONO_ARCH_GSHAREDVT_SUPPORTED
 
 #define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1))
 
@@ -415,4 +415,4 @@ mono_arm_gsharedvt_init (void)
 {
 }
 
-#endif /* MONO_ARCH_GSHARED_SUPPORTED */
\ No newline at end of file
+#endif /* MONO_ARCH_GSHAREDVT_SUPPORTED */
index 64e0e39eae4bd2d46ec85ab3b4f01070ae6336d1..08fa26bb1abfbfb0a7e98e5d353dec1a9cf623ce 100644 (file)
@@ -9,6 +9,8 @@
  */
 #include <config.h>
 
+#include <mono/utils/mono-logger-internals.h>
+
 /*
  * Attempt to handle native SIGSEGVs with libunwind or libcorkscrew.
  */
@@ -28,7 +30,7 @@
 
 #define UNW_LOCAL_ONLY
 #undef _U /* ctype.h apparently defines this and it screws up the libunwind headers. */
-#include "android-libunwind/libunwind.h"
+#include "../../external/android-libunwind/include/libunwind.h"
 #define _U 0x01
 
 #define FUNC_NAME_LENGTH 512
index 6a9f99f9c5e09b4d8b36af246ad4d52ab878e145..d5787acf13b6dff1e2468d5002302a1aca978a16 100644 (file)
@@ -668,6 +668,7 @@ static mono_native_thread_return_t
 sampling_thread_func (void *data)
 {
        mono_threads_attach_tools_thread ();
+       mono_thread_info_set_name (mono_native_thread_id_get (), "Profiler sampler");
 
        gint64 rate = 1000000000 / mono_profiler_get_sampling_rate ();
 
index f331f0c083556d2ac50db68b50ebf6139cdfd82f..795bab9e41d319ebb23ec690c14ee6cf6c288980 100644 (file)
@@ -4182,12 +4182,12 @@ mini_cleanup (MonoDomain *domain)
        /* This accesses metadata so needs to be called before runtime shutdown */
        print_jit_stats ();
 
-       mono_profiler_shutdown ();
-
 #ifndef MONO_CROSS_COMPILE
        mono_runtime_cleanup (domain);
 #endif
 
+       mono_profiler_shutdown ();
+
        free_jit_tls_data ((MonoJitTlsData *)mono_native_tls_get_value (mono_jit_tls_id));
 
        mono_icall_cleanup ();
index 13f73d9983b46ce0257f6f3b7c788866180425e3..175f75ddaab47c94e9875726f6f0b6bab579a731 100644 (file)
@@ -16,7 +16,7 @@
 /*
  * GSHAREDVT
  */
-#ifdef MONO_ARCH_GSHARED_SUPPORTED
+#ifdef MONO_ARCH_GSHAREDVT_SUPPORTED
 
 /*
  * mono_arch_get_gsharedvt_arg_trampoline:
@@ -562,21 +562,4 @@ mono_arch_get_gsharedvt_trampoline (MonoTrampInfo **info, gboolean aot)
 
 #endif
 
-#else
-
-gpointer
-mono_arch_get_gsharedvt_trampoline (MonoTrampInfo **info, gboolean aot)
-{
-       if (info)
-               *info = NULL;
-       return NULL;
-}
-
-gpointer
-mono_arch_get_gsharedvt_arg_trampoline (MonoDomain *domain, gpointer arg, gpointer addr)
-{
-       g_assert_not_reached ();
-       return NULL;
-}
-
-#endif /* MONO_ARCH_GSHARED_SUPPORTED */
\ No newline at end of file
+#endif /* MONO_ARCH_GSHAREDVT_SUPPORTED */
index d88694d198ebb4fcb7fec4e2a0705c2fe63f3395..10eaba51c6ce6d7bce0d68888f4666b44bf9c18c 100644 (file)
@@ -2256,8 +2256,6 @@ decode_buffer (ProfContext *ctx)
                        time_from += startup_time;
                        time_to += startup_time;
                }
-               if (!thread->name)
-                       thread->name = pstrdup ("Main");
        }
        for (i = 0; i < thread->stack_id; ++i)
                thread->stack [i]->recurse_count++;
@@ -3152,7 +3150,9 @@ dump_threads (ProfContext *ctx)
        ThreadContext *thread;
        fprintf (outfile, "\nThread summary\n");
        for (thread = ctx->threads; thread; thread = thread->next) {
-               fprintf (outfile, "\tThread: %p, name: \"%s\"\n", (void*)thread->thread_id, thread->name? thread->name: "");
+               if (thread->thread_id) {
+                       fprintf (outfile, "\tThread: %p, name: \"%s\"\n", (void*)thread->thread_id, thread->name? thread->name: "");
+               }
        }
 }
 
index 188a40a26479643bb1e32c3b4ca84e439d8d22da..63c1fd8f9a0da336067eaacdd42b288f745887e8 100644 (file)
@@ -933,7 +933,7 @@ process_requests (MonoProfiler *profiler)
 }
 
 static void counters_init (MonoProfiler *profiler);
-static void counters_sample (MonoProfiler *profiler, uint64_t timestamp);
+static void counters_sample (MonoProfiler *profiler, uint64_t timestamp, gboolean threadless);
 
 /*
  * Can be called only at safe callback locations.
@@ -963,6 +963,15 @@ safe_send (MonoProfiler *profiler, LogBuffer *logbuffer)
        TLS_GET (LogBuffer, tlsbuffer)->call_depth = cd;
 }
 
+static void
+safe_send_threadless (MonoProfiler *prof, LogBuffer *buf)
+{
+       for (LogBuffer *iter = buf; iter; iter = iter->next)
+               iter->thread_id = 0;
+
+       safe_send (prof, buf);
+}
+
 static int
 gc_reference (MonoObject *obj, MonoClass *klass, uintptr_t size, uintptr_t num, MonoObject **refs, uintptr_t *offsets, void *data)
 {
@@ -2911,7 +2920,7 @@ counters_init (MonoProfiler *profiler)
 }
 
 static void
-counters_emit (MonoProfiler *profiler)
+counters_emit (MonoProfiler *profiler, gboolean threadless)
 {
        MonoCounterAgent *agent;
        LogBuffer *logbuffer;
@@ -2970,13 +2979,16 @@ counters_emit (MonoProfiler *profiler)
        }
        EXIT_LOG (logbuffer);
 
-       safe_send (profiler, logbuffer);
+       if (threadless)
+               safe_send_threadless (profiler, logbuffer);
+       else
+               safe_send (profiler, logbuffer);
 
        mono_os_mutex_unlock (&counters_mutex);
 }
 
 static void
-counters_sample (MonoProfiler *profiler, uint64_t timestamp)
+counters_sample (MonoProfiler *profiler, uint64_t timestamp, gboolean threadless)
 {
        MonoCounterAgent *agent;
        MonoCounter *counter;
@@ -2989,7 +3001,7 @@ counters_sample (MonoProfiler *profiler, uint64_t timestamp)
        if (!counters_initialized)
                return;
 
-       counters_emit (profiler);
+       counters_emit (profiler, threadless);
 
        buffer_size = 8;
        buffer = calloc (1, buffer_size);
@@ -3101,7 +3113,10 @@ counters_sample (MonoProfiler *profiler, uint64_t timestamp)
        emit_value (logbuffer, 0);
        EXIT_LOG (logbuffer);
 
-       safe_send (profiler, logbuffer);
+       if (threadless)
+               safe_send_threadless (profiler, logbuffer);
+       else
+               safe_send (profiler, logbuffer);
 
        mono_os_mutex_unlock (&counters_mutex);
 }
@@ -3122,7 +3137,7 @@ struct _PerfCounterAgent {
 static PerfCounterAgent *perfcounters = NULL;
 
 static void
-perfcounters_emit (MonoProfiler *profiler)
+perfcounters_emit (MonoProfiler *profiler, gboolean threadless)
 {
        PerfCounterAgent *pcagent;
        LogBuffer *logbuffer;
@@ -3173,7 +3188,10 @@ perfcounters_emit (MonoProfiler *profiler)
        }
        EXIT_LOG (logbuffer);
 
-       safe_send (profiler, logbuffer);
+       if (threadless)
+               safe_send_threadless (profiler, logbuffer);
+       else
+               safe_send (profiler, logbuffer);
 }
 
 static gboolean
@@ -3210,7 +3228,7 @@ perfcounters_foreach (char *category_name, char *name, unsigned char type, gint6
 }
 
 static void
-perfcounters_sample (MonoProfiler *profiler, uint64_t timestamp)
+perfcounters_sample (MonoProfiler *profiler, uint64_t timestamp, gboolean threadless)
 {
        PerfCounterAgent *pcagent;
        LogBuffer *logbuffer;
@@ -3227,7 +3245,7 @@ perfcounters_sample (MonoProfiler *profiler, uint64_t timestamp)
 
        mono_perfcounter_foreach (perfcounters_foreach, perfcounters);
 
-       perfcounters_emit (profiler);
+       perfcounters_emit (profiler, threadless);
 
        size =
                EVENT_SIZE /* event */ +
@@ -3267,13 +3285,16 @@ perfcounters_sample (MonoProfiler *profiler, uint64_t timestamp)
        emit_value (logbuffer, 0);
        EXIT_LOG (logbuffer);
 
-       safe_send (profiler, logbuffer);
+       if (threadless)
+               safe_send_threadless (profiler, logbuffer);
+       else
+               safe_send (profiler, logbuffer);
 
        mono_os_mutex_unlock (&counters_mutex);
 }
 
 static void
-counters_and_perfcounters_sample (MonoProfiler *prof)
+counters_and_perfcounters_sample (MonoProfiler *prof, gboolean threadless)
 {
        static uint64_t start = -1;
        uint64_t now;
@@ -3282,8 +3303,8 @@ counters_and_perfcounters_sample (MonoProfiler *prof)
                start = current_time ();
 
        now = current_time ();
-       counters_sample (prof, (now - start) / 1000/ 1000);
-       perfcounters_sample (prof, (now - start) / 1000/ 1000);
+       counters_sample (prof, (now - start) / 1000/ 1000, threadless);
+       perfcounters_sample (prof, (now - start) / 1000/ 1000, threadless);
 }
 
 #define COVERAGE_DEBUG(x) if (debug_coverage) {x}
@@ -3933,7 +3954,7 @@ log_shutdown (MonoProfiler *prof)
 
        in_shutdown = 1;
 #ifndef DISABLE_HELPER_THREAD
-       counters_and_perfcounters_sample (prof);
+       counters_and_perfcounters_sample (prof, FALSE);
 
        dump_coverage (prof);
 
@@ -4067,6 +4088,8 @@ helper_thread (void* arg)
        MonoThread *thread = NULL;
 
        mono_threads_attach_tools_thread ();
+       mono_thread_info_set_name (mono_native_thread_id_get (), "Profiler helper");
+
        //fprintf (stderr, "Server listening\n");
        command_socket = -1;
        while (1) {
@@ -4097,7 +4120,7 @@ helper_thread (void* arg)
                }
 #endif
 
-               counters_and_perfcounters_sample (prof);
+               counters_and_perfcounters_sample (prof, TRUE);
 
                tv.tv_sec = 1;
                tv.tv_usec = 0;
@@ -4126,7 +4149,7 @@ helper_thread (void* arg)
                                if (sbuf) {
                                        dump_sample_hits (prof, sbuf);
                                        free_buffer (sbuf, sbuf->size);
-                                       safe_send (prof, ensure_logbuf (0));
+                                       safe_send_threadless (prof, ensure_logbuf (0));
                                }
                                continue;
                        }
@@ -4147,7 +4170,7 @@ helper_thread (void* arg)
                                }
                        }
 #endif
-                       safe_send (prof, ensure_logbuf (0));
+                       safe_send_threadless (prof, ensure_logbuf (0));
                        return NULL;
                }
 #if USE_PERF_EVENTS
@@ -4158,7 +4181,7 @@ helper_thread (void* arg)
                                        continue;
                                if (FD_ISSET (perf_data [i].perf_fd, &rfds)) {
                                        read_perf_mmap (prof, i);
-                                       safe_send (prof, ensure_logbuf (0));
+                                       safe_send_threadless (prof, ensure_logbuf (0));
                                }
                        }
                }
@@ -4196,6 +4219,9 @@ helper_thread (void* arg)
                        continue;
                //fprintf (stderr, "Accepted connection\n");
        }
+
+       mono_thread_info_detach ();
+
        return NULL;
 }
 
@@ -4249,6 +4275,7 @@ writer_thread (void *arg)
        MonoProfiler *prof = (MonoProfiler *)arg;
 
        mono_threads_attach_tools_thread ();
+       mono_thread_info_set_name (mono_native_thread_id_get (), "Profiler writer");
 
        dump_header (prof);
 
@@ -4318,9 +4345,12 @@ writer_thread (void *arg)
 
                        g_ptr_array_free (entry->methods, TRUE);
 
-                       if (new_methods)
+                       if (new_methods) {
+                               for (LogBuffer *iter = method_buffer; iter; iter = iter->next)
+                                       iter->thread_id = 0;
+
                                dump_buffer (prof, method_buffer);
-                       else if (method_buffer)
+                       else if (method_buffer)
                                free_buffer (method_buffer, method_buffer->size);
 
                        dump_buffer (prof, entry->buffer);
@@ -4329,6 +4359,8 @@ writer_thread (void *arg)
                }
        }
 
+       mono_thread_info_detach ();
+
        return NULL;
 }
 
@@ -4355,7 +4387,7 @@ runtime_initialized (MonoProfiler *profiler)
        InterlockedWrite (&runtime_inited, 1);
 #ifndef DISABLE_HELPER_THREAD
        counters_init (profiler);
-       counters_sample (profiler, 0);
+       counters_sample (profiler, 0, FALSE);
 #endif
        /* ensure the main thread data and startup are available soon */
        safe_send (profiler, ensure_logbuf (0));
index 57e6f6931fc85ae980bee580694ee17c045b6d6f..e6b8d672dce53fbb73037cc2c4dbfe39bca1a9a7 100644 (file)
@@ -1074,6 +1074,12 @@ finish_gray_stack (int generation, ScanCopyContext ctx)
        if (sgen_client_bridge_need_processing ())
                sgen_client_bridge_reset_data ();
 
+       /*
+        * Mark all strong toggleref objects. This must be done before we walk ephemerons or finalizers
+        * to ensure they see the full set of live objects.
+        */
+       sgen_client_mark_togglerefs (start_addr, end_addr, ctx);
+
        /*
         * Walk the ephemeron tables marking all values with reachable keys. This must be completely done
         * before processing finalizable objects and non-tracking weak links to avoid finalizing/clearing
@@ -1086,8 +1092,6 @@ finish_gray_stack (int generation, ScanCopyContext ctx)
                ++ephemeron_rounds;
        } while (!done_with_ephemerons);
 
-       sgen_client_mark_togglerefs (start_addr, end_addr, ctx);
-
        if (sgen_client_bridge_need_processing ()) {
                /*Make sure the gray stack is empty before we process bridge objects so we get liveness right*/
                sgen_drain_gray_stack (ctx);
index d604294fee0884166128bd9687335ba1cd394e03..f4f2df11555816c07308e4935012b020ea486dd1 100644 (file)
@@ -3,6 +3,7 @@ using System.Collections;
 using System.Collections.Generic;
 using System.Threading;
 using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
 
 public class Toggleref {
        public int __test;
@@ -42,23 +43,23 @@ class Driver {
                mono_gc_toggleref_add (Helper.ObjToPtr (obj), true);
        }
 
+       static Toggleref a, b;
+
        static void SetupLinks () {
-               var a = new Toggleref () { id = "root" };
-               var b = new Toggleref () { id = "child" };
-               a.link.Add (b);
-               a.__test = Toggleref.STRONG;
-               b.__test = Toggleref.WEAK;
-               Register (a);
-               Register (b);
-               root = new WeakReference<Toggleref> (a, false);
-               child = new WeakReference<Toggleref> (b, false);
+               var r = new Toggleref () { id = "root" };
+               var c = new Toggleref () { id = "child" };
+               r.link.Add (c);
+               r.__test = Toggleref.STRONG;
+               c.__test = Toggleref.WEAK;
+               Register (r);
+               Register (c);
+               root = new WeakReference<Toggleref> (r, false);
+               child = new WeakReference<Toggleref> (c, false);
        }
 
-       static Toggleref a, b;
-
-       static int Main ()
+       static int test_0_root_keeps_child ()
        {
-               
+               Console.WriteLine ("test_0_root_keeps_child");
                var t = new Thread (SetupLinks);
                t.Start ();
                t.Join ();
@@ -94,6 +95,116 @@ class Driver {
 
 
                return 0;
+       }
+
+       static void SetupLinks2 () {
+               var r = new Toggleref () { id = "root" };
+               var c = new Toggleref () { id = "child" };
+
+               r.__test = Toggleref.STRONG;
+               c.__test = Toggleref.WEAK;
+               Register (r);
+               Register (c);
+               root = new WeakReference<Toggleref> (r, false);
+               child = new WeakReference<Toggleref> (c, false);
+       }
+
+       static int test_0_child_goes_away ()
+       {
+               Console.WriteLine ("test_0_child_goes_away");
+
+               var t = new Thread (SetupLinks2);
+               t.Start ();
+               t.Join ();
+
+               GC.Collect ();
+               GC.WaitForPendingFinalizers ();
+
+               Console.WriteLine ("try get A {0}", root.TryGetTarget (out a));
+               Console.WriteLine ("try get B {0}", child.TryGetTarget (out b));
+               Console.WriteLine ("a is null {0}", a == null);
+               Console.WriteLine ("b is null {0}", b == null);
+               if (a == null || b != null)
+                       return 1;
+               Console.WriteLine ("a test {0}", a.__test);
+
+               return 0;
+       }
+
+       static ConditionalWeakTable<Toggleref, object> cwt = new ConditionalWeakTable<Toggleref, object> ();
+       static WeakReference<object> root_value, child_value;
+       static object a_val, b_val;
+
+
+       static void SetupLinks3 () {
+               var r = new Toggleref () { id = "root" };
+               var c = new Toggleref () { id = "child" };
+
+               r.__test = Toggleref.STRONG;
+               c.__test = Toggleref.WEAK;
+               Register (r);
+               Register (c);
+               root = new WeakReference<Toggleref> (r, false);
+               child = new WeakReference<Toggleref> (c, false);
+
+               var root_val = new object ();
+               var child_val = new object ();
+
+               cwt.Add (r, root_val);
+               cwt.Add (c, child_val);
+
+               root_value = new WeakReference<object> (root_val, false);
+               child_value = new WeakReference<object> (child_val, false);
+       }
+
+       static int test_0_CWT_keep_child_alive ()
+       {
+               Console.WriteLine ("test_0_CWT_keep_child_alive");
+
+               var t = new Thread (SetupLinks3);
+               t.Start ();
+               t.Join ();
+
+               GC.Collect ();
+               GC.WaitForPendingFinalizers ();
+
+               Console.WriteLine ("try get A {0}", root.TryGetTarget (out a));
+               Console.WriteLine ("try get B {0}", child.TryGetTarget (out b));
+               Console.WriteLine ("a is null {0}", a == null);
+               Console.WriteLine ("b is null {0}", b == null);
+               if (a == null || b != null)
+                       return 1;
+               Console.WriteLine ("a test {0}", a.__test);
+
+               Console.WriteLine ("try get a_val {0}", root_value.TryGetTarget (out a_val));
+               Console.WriteLine ("try get v_val {0}", child_value.TryGetTarget (out b_val));
+
+               //the strong toggleref must keep the CWT value to remains alive
+               if (a_val == null)
+                       return 2;
+
+               //the weak toggleref should allow the CWT value to go away
+               if (b_val != null)
+                       return 3;
+
+               object res_value = null;
+               bool res = cwt.TryGetValue (a, out res_value);
+               Console.WriteLine ("CWT result {0} -> {1}", res, res_value == a_val);
+
+               //the strong val is not on the CWT
+               if (!res)
+                       return 4;
+
+               //for some reason the value is not the right one
+               if (res_value != a_val)
+                       return 5;
+
+               return 0;
+       }
 
+       static int Main (string[] args)
+       {
+               return TestDriver.RunTests (typeof (Driver), args);
        }
+
 }
\ No newline at end of file
index 2b3b86e2ef2e305dd8de427b6eb4902b999283de..04bc26e4f53ff3ef3796dc25ba3536144b6ba48d 100644 (file)
@@ -7,6 +7,19 @@
  */
 #include <config.h>
 
+/*
+ * When embedding, you have to define MONO_ZERO_LEN_ARRAY before including any
+ * other Mono header file if you use a different compiler from the one used to
+ * build Mono.
+ */
+#ifndef MONO_ZERO_LEN_ARRAY
+#ifdef __GNUC__
+#define MONO_ZERO_LEN_ARRAY 0
+#else
+#define MONO_ZERO_LEN_ARRAY 1
+#endif
+#endif
+
 #ifdef __GNUC__
 #define MONO_ATTR_USED __attribute__ ((used))
 #else
index 54f183e58f03659937730f70797d3de5b411c0db..7fe86b96273e80ded338c90b945f0dd256646806 100644 (file)
@@ -279,7 +279,24 @@ mono_native_thread_create (MonoNativeThreadId *tid, gpointer func, gpointer arg)
 void
 mono_threads_core_set_name (MonoNativeThreadId tid, const char *name)
 {
-#if defined (HAVE_PTHREAD_SETNAME_NP) && !defined (__MACH__)
+#ifdef __MACH__
+       /*
+        * We can't set the thread name for other threads, but we can at least make
+        * it work for threads that try to change their own name.
+        */
+       if (tid != mono_native_thread_id_get ())
+               return;
+
+       if (!name) {
+               pthread_setname_np ("");
+       } else {
+               char n [63];
+
+               strncpy (n, name, 63);
+               n [62] = '\0';
+               pthread_setname_np (n);
+       }
+#elif defined (HAVE_PTHREAD_SETNAME_NP)
        if (!name) {
                pthread_setname_np (tid, "");
        } else {
index 7e7fc371c6a4c9f5df4c0526e5ec94340d8c765a..97c77de6e7df32e02c97b643813bec873cbd7dc6 100644 (file)
@@ -333,7 +333,7 @@ mono_thread_info_register_small_id (void);
 THREAD_INFO_TYPE *
 mono_thread_info_attach (void *baseptr);
 
-void
+MONO_API void
 mono_thread_info_detach (void);
 
 gboolean
@@ -357,7 +357,7 @@ mono_thread_info_lookup (MonoNativeThreadId id);
 gboolean
 mono_thread_info_resume (MonoNativeThreadId tid);
 
-void
+MONO_API void
 mono_thread_info_set_name (MonoNativeThreadId tid, const char *name);
 
 void
@@ -523,7 +523,7 @@ void mono_threads_core_set_name (MonoNativeThreadId tid, const char *name);
 void mono_threads_coop_begin_global_suspend (void);
 void mono_threads_coop_end_global_suspend (void);
 
-MonoNativeThreadId
+MONO_API MonoNativeThreadId
 mono_native_thread_id_get (void);
 
 gboolean
index 8abe83907ceeb5cbdb419f03c0a12bc92c0365e2..e95f4847e6cf61f0b5ae64e6993212eecde4098a 100644 (file)
@@ -2,26 +2,14 @@
 #define __MONO_BITSET_H__
 
 #include <glib.h>
+#include <mono/utils/mono-compiler.h>
+
 #ifdef SGEN_WITHOUT_MONO
-#include "mono/utils/mono-compiler.h"
 #define MONO_API
 #else
 #include <mono/utils/mono-publib.h>
 #endif
 
-/*
- * When embedding, you have to define MONO_ZERO_LEN_ARRAY before including any
- * other Mono header file if you use a different compiler from the one used to
- * build Mono.
- */
-#ifndef MONO_ZERO_LEN_ARRAY
-#ifdef __GNUC__
-#define MONO_ZERO_LEN_ARRAY 0
-#else
-#define MONO_ZERO_LEN_ARRAY 1
-#endif
-#endif
-
 #define MONO_BITSET_BITS_PER_CHUNK (8 * sizeof (gsize))
 
 typedef struct {
index a8a93ae26efd4ae418360a0cb4a6de902d473cfa..2507bc9777f73cc10e4a5ab25b4c6b85450f5eb9 100755 (executable)
@@ -12,8 +12,8 @@ if [[ ${label} == 'w64' ]]; then PLATFORM=x64; EXTRA_CONF_FLAGS="--host=i686-pc-
 ${TESTCMD} --label=configure --timeout=60m --fatal ./autogen.sh --with-monodroid --with-monotouch --with-monotouch_watch --with-monotouch_tv --with-xammac --with-mobile_static $EXTRA_CONF_FLAGS
 if [[ ${label} == w* ]];
     then
-    ${TESTCMD} --label=make-msvc --timeout=60m --fatal /cygdrive/c/Program\ Files\ \(x86\)/MSBuild/12.0/Bin/MSBuild.exe /p:Platform=${PLATFORM} /p:Configuration=Release msvc/mono.sln
-    ${TESTCMD} --label=make-msvc-sgen --timeout=60m --fatal /cygdrive/c/Program\ Files\ \(x86\)/MSBuild/12.0/Bin/MSBuild.exe /p:Platform=${PLATFORM} /p:Configuration=Release_SGen msvc/mono.sln
+    ${TESTCMD} --label=make-msvc --timeout=60m --fatal "/cygdrive/c/Program\ Files\ \(x86\)/MSBuild/12.0/Bin/MSBuild.exe" /p:Platform=${PLATFORM} /p:Configuration=Release msvc/mono.sln
+    ${TESTCMD} --label=make-msvc-sgen --timeout=60m --fatal "/cygdrive/c/Program\ Files\ \(x86\)/MSBuild/12.0/Bin/MSBuild.exe" /p:Platform=${PLATFORM} /p:Configuration=Release_SGen msvc/mono.sln
 fi
 ${TESTCMD} --label=make --timeout=300m --fatal make -w V=1
 if [[ -n "${ghprbPullId}" ]] && [[ ${label} == w* ]];