* sysdeps/unix/sysv/linux/arm/nptl/sysdep-cancel.h,
authorDaniel Jacobowitz <dan@codesourcery.com>
Wed, 16 Nov 2005 19:22:59 +0000 (19:22 +0000)
committerDaniel Jacobowitz <dan@codesourcery.com>
Wed, 16 Nov 2005 19:22:59 +0000 (19:22 +0000)
sysdeps/unix/sysv/linux/arm/nptl/unwind-forcedunwind.c,
sysdeps/unix/sysv/linux/arm/nptl/unwind-resume.c,
sysdeps/unix/sysv/linux/arm/nptl/unwind.h,
sysdeps/arm/unwind-dw2-fde-glibc.c,
sysdeps/arm/unwind-pe.c, sysdeps/arm/framestate.c: New files.

ChangeLog.arm
sysdeps/arm/framestate.c [new file with mode: 0644]
sysdeps/arm/unwind-dw2-fde-glibc.c [new file with mode: 0644]
sysdeps/arm/unwind-pe.c [new file with mode: 0644]
sysdeps/unix/sysv/linux/arm/nptl/sysdep-cancel.h [new file with mode: 0644]
sysdeps/unix/sysv/linux/arm/nptl/unwind-forcedunwind.c [new file with mode: 0644]
sysdeps/unix/sysv/linux/arm/nptl/unwind-resume.c [new file with mode: 0644]
sysdeps/unix/sysv/linux/arm/nptl/unwind.h [new file with mode: 0644]

index 795b363..81f98f7 100644 (file)
@@ -1,5 +1,14 @@
 2005-11-16  Daniel Jacobowitz  <dan@codesourcery.com>
 
+       * sysdeps/unix/sysv/linux/arm/nptl/sysdep-cancel.h,
+       sysdeps/unix/sysv/linux/arm/nptl/unwind-forcedunwind.c,
+       sysdeps/unix/sysv/linux/arm/nptl/unwind-resume.c,
+       sysdeps/unix/sysv/linux/arm/nptl/unwind.h,
+       sysdeps/arm/unwind-dw2-fde-glibc.c,
+       sysdeps/arm/unwind-pe.c, sysdeps/arm/framestate.c: New files.
+
+2005-11-16  Daniel Jacobowitz  <dan@codesourcery.com>
+
        * sysdeps/arm/bits/setjmp.h, sysdeps/arm/fpu/bits/setjmp.h: Update
        include guards.
 
diff --git a/sysdeps/arm/framestate.c b/sysdeps/arm/framestate.c
new file mode 100644 (file)
index 0000000..710cecc
--- /dev/null
@@ -0,0 +1 @@
+/* Empty */
diff --git a/sysdeps/arm/unwind-dw2-fde-glibc.c b/sysdeps/arm/unwind-dw2-fde-glibc.c
new file mode 100644 (file)
index 0000000..6c0d735
--- /dev/null
@@ -0,0 +1,80 @@
+/* Dummy exception handling and frame unwind runtime interface routines.
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+/* ARM uses setjmp-longjmp exceptions.  However, previous versions of
+   GNU libc exported some DWARF-2 exception handling support routines.
+   They are not necessary, but older (or broken) configurations of GCC
+   will do so.  Even though all references to these are weak, because
+   they refer to versioned symbols, they must be provided.  */
+
+#include <stdlib.h>
+#include <unwind.h>
+#include <unwind-dw2-fde.h>
+
+/* These may be called from startup code, but don't need to do
+   anything.  */
+
+void __register_frame_info_bases (void *a1, struct object *a2,
+                                 void *a3, void *a4)
+{
+}
+
+void __register_frame_info (void *a1, struct object *a2)
+{
+}
+
+void __register_frame (void *a1)
+{
+}
+
+void __register_frame_info_table_bases (void *a1, struct object *a2,
+                                       void *a3, void *a4)
+{
+}
+
+void __register_frame_info_table (void *a1, struct object *a2)
+{
+}
+
+void __register_frame_table (void *a1)
+{
+}
+
+void *__deregister_frame_info (void *a1)
+{
+  return NULL;
+}
+
+void *__deregister_frame_info_bases (void *a1)
+{
+  return NULL;
+}
+
+void __deregister_frame (void *a1)
+{
+}
+
+/* This should not be called.  */
+
+fde *
+_Unwind_Find_FDE (void *a1, struct dwarf_eh_bases *a2)
+{
+  abort ();
+}
diff --git a/sysdeps/arm/unwind-pe.c b/sysdeps/arm/unwind-pe.c
new file mode 100644 (file)
index 0000000..710cecc
--- /dev/null
@@ -0,0 +1 @@
+/* Empty */
diff --git a/sysdeps/unix/sysv/linux/arm/nptl/sysdep-cancel.h b/sysdeps/unix/sysv/linux/arm/nptl/sysdep-cancel.h
new file mode 100644 (file)
index 0000000..a44ee95
--- /dev/null
@@ -0,0 +1,128 @@
+/* Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <tls.h>
+#ifndef __ASSEMBLER__
+# include <nptl/pthreadP.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args)                              \
+  .section ".text";                                                    \
+    PSEUDO_PROLOGUE;                                                   \
+  .type __##syscall_name##_nocancel,%function;                         \
+  .globl __##syscall_name##_nocancel;                                  \
+  __##syscall_name##_nocancel:                                         \
+    DO_CALL (syscall_name, args);                                      \
+    PSEUDO_RET;                                                                \
+  .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel;     \
+  ENTRY (name);                                                                \
+    SINGLE_THREAD_P;                                                   \
+    DOARGS_##args;                                                     \
+    bne .Lpseudo_cancel;                                               \
+    DO_CALL (syscall_name, 0);                                         \
+    UNDOARGS_##args;                                                   \
+    cmn r0, $4096;                                                     \
+    PSEUDO_RET;                                                                \
+  .Lpseudo_cancel:                                                     \
+    DOCARGS_##args;    /* save syscall args etc. around CENABLE.  */   \
+    CENABLE;                                                           \
+    mov ip, r0;                /* put mask in safe place.  */                  \
+    UNDOCARGS_##args;  /* restore syscall args.  */                    \
+    swi SYS_ify (syscall_name);        /* do the call.  */                     \
+    str r0, [sp, $-4]!; /* save syscall return value.  */              \
+    mov r0, ip;                /* get mask back.  */                           \
+    CDISABLE;                                                          \
+    ldmfd sp!, {r0, lr}; /* retrieve return value and address.  */     \
+    UNDOARGS_##args;                                                   \
+    cmn r0, $4096;
+
+# define DOCARGS_0     str lr, [sp, #-4]!;
+# define UNDOCARGS_0
+
+# define DOCARGS_1     stmfd sp!, {r0, lr};
+# define UNDOCARGS_1   ldr r0, [sp], #4;
+
+# define DOCARGS_2     stmfd sp!, {r0, r1, lr};
+# define UNDOCARGS_2   ldmfd sp!, {r0, r1};
+
+# define DOCARGS_3     stmfd sp!, {r0, r1, r2, lr};
+# define UNDOCARGS_3   ldmfd sp!, {r0, r1, r2};
+
+# define DOCARGS_4     stmfd sp!, {r0, r1, r2, r3, lr};
+# define UNDOCARGS_4   ldmfd sp!, {r0, r1, r2, r3};
+
+# define DOCARGS_5     DOCARGS_4
+# define UNDOCARGS_5   UNDOCARGS_4
+
+# ifdef IS_IN_libpthread
+#  define CENABLE      bl PLTJMP(__pthread_enable_asynccancel)
+#  define CDISABLE     bl PLTJMP(__pthread_disable_asynccancel)
+#  define __local_multiple_threads __pthread_multiple_threads
+# elif !defined NOT_IN_libc
+#  define CENABLE      bl PLTJMP(__libc_enable_asynccancel)
+#  define CDISABLE     bl PLTJMP(__libc_disable_asynccancel)
+#  define __local_multiple_threads __libc_multiple_threads
+# elif defined IS_IN_librt
+#  define CENABLE      bl PLTJMP(__librt_enable_asynccancel)
+#  define CDISABLE     bl PLTJMP(__librt_disable_asynccancel)
+# else
+#  error Unsupported library
+# endif
+
+# if defined IS_IN_libpthread || !defined NOT_IN_libc
+#  ifndef __ASSEMBLER__
+extern int __local_multiple_threads attribute_hidden;
+#   define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
+#  else
+#   define SINGLE_THREAD_P                                             \
+  ldr ip, 1b;                                                          \
+2:                                                                     \
+  ldr ip, [pc, ip];                                                    \
+  teq ip, #0;
+#   define PSEUDO_PROLOGUE                                             \
+  1:  .word __local_multiple_threads - 2f - 8;
+#  endif
+# else
+/*  There is no __local_multiple_threads for librt, so use the TCB.  */
+#  ifndef __ASSEMBLER__
+#   define SINGLE_THREAD_P                                             \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF,                                \
+                                  header.multiple_threads) == 0, 1)
+#  else
+#   define PSEUDO_PROLOGUE
+#   define SINGLE_THREAD_P                                             \
+  stmfd        sp!, {r0, lr};                                                  \
+  bl   __aeabi_read_tp;                                                \
+  ldr  ip, [r0, #MULTIPLE_THREADS_OFFSET];                             \
+  ldmfd        sp!, {r0, lr};                                                  \
+  teq  ip, #0
+#   define SINGLE_THREAD_P_PIC(x) SINGLE_THREAD_P
+#  endif
+# endif
+
+#elif !defined __ASSEMBLER__
+
+/* For rtld, et cetera.  */
+# define SINGLE_THREAD_P 1
+# define NO_CANCELLATION 1
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/arm/nptl/unwind-forcedunwind.c b/sysdeps/unix/sysv/linux/arm/nptl/unwind-forcedunwind.c
new file mode 100644 (file)
index 0000000..ba5327a
--- /dev/null
@@ -0,0 +1,117 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@redhat.com>.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <dlfcn.h>
+#include <stdio.h>
+#include <unwind.h>
+#include <pthreadP.h>
+
+static void (*libgcc_s_resume) (struct _Unwind_Exception *exc);
+static _Unwind_Reason_Code (*libgcc_s_personality)
+  (int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *,
+   struct _Unwind_Context *);
+static _Unwind_Reason_Code (*libgcc_s_forcedunwind)
+  (struct _Unwind_Exception *, _Unwind_Stop_Fn, void *);
+static _Unwind_Word (*libgcc_s_getcfa) (struct _Unwind_Context *);
+static void (*libgcc_s_sjlj_register) (struct SjLj_Function_Context *);
+static void (*libgcc_s_sjlj_unregister) (struct SjLj_Function_Context *);
+
+void
+pthread_cancel_init (void)
+{
+  void *resume, *personality, *forcedunwind, *getcfa;
+  void *handle;
+  void *sjlj_register, *sjlj_unregister;
+
+  if (__builtin_expect (libgcc_s_getcfa != NULL, 1))
+    return;
+
+  handle = __libc_dlopen ("libgcc_s.so.1");
+
+  if (handle == NULL
+      || (sjlj_register = __libc_dlsym (handle, "_Unwind_SjLj_Register")) == NULL
+      || (sjlj_unregister = __libc_dlsym (handle, "_Unwind_SjLj_Unregister")) == NULL
+      || (resume = __libc_dlsym (handle, "_Unwind_SjLj_Resume")) == NULL
+      || (personality = __libc_dlsym (handle, "__gcc_personality_sj0")) == NULL
+      || (forcedunwind = __libc_dlsym (handle, "_Unwind_SjLj_ForcedUnwind"))
+        == NULL
+      || (getcfa = __libc_dlsym (handle, "_Unwind_GetCFA")) == NULL
+      )
+    __libc_fatal ("libgcc_s.so.1 must be installed for pthread_cancel to work\n");
+
+  libgcc_s_resume = resume;
+  libgcc_s_personality = personality;
+  libgcc_s_forcedunwind = forcedunwind;
+  libgcc_s_getcfa = getcfa;
+  libgcc_s_sjlj_register = sjlj_register;
+  libgcc_s_sjlj_unregister = sjlj_unregister;
+}
+
+void
+_Unwind_Resume (struct _Unwind_Exception *exc)
+{
+  if (__builtin_expect (libgcc_s_resume == NULL, 0))
+    pthread_cancel_init ();
+  libgcc_s_resume (exc);
+}
+
+_Unwind_Reason_Code
+__gcc_personality_v0 (int version, _Unwind_Action actions,
+                     _Unwind_Exception_Class exception_class,
+                      struct _Unwind_Exception *ue_header,
+                      struct _Unwind_Context *context)
+{
+  if (__builtin_expect (libgcc_s_personality == NULL, 0))
+    pthread_cancel_init ();
+  return libgcc_s_personality (version, actions, exception_class,
+                              ue_header, context);
+}
+
+_Unwind_Reason_Code
+_Unwind_ForcedUnwind (struct _Unwind_Exception *exc, _Unwind_Stop_Fn stop,
+                     void *stop_argument)
+{
+  if (__builtin_expect (libgcc_s_forcedunwind == NULL, 0))
+    pthread_cancel_init ();
+  return libgcc_s_forcedunwind (exc, stop, stop_argument);
+}
+
+_Unwind_Word
+_Unwind_GetCFA (struct _Unwind_Context *context)
+{
+  if (__builtin_expect (libgcc_s_getcfa == NULL, 0))
+    pthread_cancel_init ();
+  return libgcc_s_getcfa (context);
+}
+
+void
+_Unwind_SjLj_Register (struct SjLj_Function_Context *fc)
+{
+  if (__builtin_expect (libgcc_s_sjlj_register == NULL, 0))
+    pthread_cancel_init ();
+  libgcc_s_sjlj_register (fc);
+}
+
+void
+_Unwind_SjLj_Unregister (struct SjLj_Function_Context *fc)
+{
+  if (__builtin_expect (libgcc_s_sjlj_unregister == NULL, 0))
+    pthread_cancel_init ();
+  libgcc_s_sjlj_unregister (fc);
+}
diff --git a/sysdeps/unix/sysv/linux/arm/nptl/unwind-resume.c b/sysdeps/unix/sysv/linux/arm/nptl/unwind-resume.c
new file mode 100644 (file)
index 0000000..8dcfd34
--- /dev/null
@@ -0,0 +1,87 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@redhat.com>.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <dlfcn.h>
+#include <stdio.h>
+#include <unwind.h>
+
+static void (*libgcc_s_resume) (struct _Unwind_Exception *exc);
+static _Unwind_Reason_Code (*libgcc_s_personality)
+  (int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *,
+   struct _Unwind_Context *);
+static void (*libgcc_s_sjlj_register) (struct SjLj_Function_Context *);
+static void (*libgcc_s_sjlj_unregister) (struct SjLj_Function_Context *);
+
+static void
+init (void)
+{
+  void *resume, *personality;
+  void *handle;
+  void *sjlj_register, *sjlj_unregister;
+
+  handle = __libc_dlopen ("libgcc_s.so.1");
+
+  if (handle == NULL
+      || (sjlj_register = __libc_dlsym (handle, "_Unwind_SjLj_Register")) == NULL
+      || (sjlj_unregister = __libc_dlsym (handle, "_Unwind_SjLj_Unregister")) == NULL
+      || (resume = __libc_dlsym (handle, "_Unwind_SjLj_Resume")) == NULL
+      || (personality = __libc_dlsym (handle, "__gcc_personality_sj0")) == NULL)
+    __libc_fatal ("libgcc_s.so.1 must be installed for pthread_cancel to work\n");
+
+  libgcc_s_resume = resume;
+  libgcc_s_personality = personality;
+  libgcc_s_sjlj_register = sjlj_register;
+  libgcc_s_sjlj_unregister = sjlj_unregister;
+}
+
+void
+_Unwind_Resume (struct _Unwind_Exception *exc)
+{
+  if (__builtin_expect (libgcc_s_resume == NULL, 0))
+    init ();
+  libgcc_s_resume (exc);
+}
+
+_Unwind_Reason_Code
+__gcc_personality_v0 (int version, _Unwind_Action actions,
+                     _Unwind_Exception_Class exception_class,
+                      struct _Unwind_Exception *ue_header,
+                      struct _Unwind_Context *context)
+{
+  if (__builtin_expect (libgcc_s_personality == NULL, 0))
+    init ();
+  return libgcc_s_personality (version, actions, exception_class,
+                              ue_header, context);
+}
+
+void
+_Unwind_SjLj_Register (struct SjLj_Function_Context *fc)
+{
+  if (__builtin_expect (libgcc_s_sjlj_register == NULL, 0))
+    init ();
+  libgcc_s_sjlj_register (fc);
+}
+
+void
+_Unwind_SjLj_Unregister (struct SjLj_Function_Context *fc)
+{
+  if (__builtin_expect (libgcc_s_sjlj_unregister == NULL, 0))
+    init ();
+  libgcc_s_sjlj_unregister (fc);
+}
diff --git a/sysdeps/unix/sysv/linux/arm/nptl/unwind.h b/sysdeps/unix/sysv/linux/arm/nptl/unwind.h
new file mode 100644 (file)
index 0000000..8dd834e
--- /dev/null
@@ -0,0 +1,31 @@
+/* Exception handling and frame unwind runtime interface routines.
+   Copyright (C) 2005 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _ARM_UNWIND_H
+#define _ARM_UNWIND_H  1
+
+#include <sysdeps/generic/unwind.h>
+
+/* Call the SjLj versions of these functions.  */
+#define _Unwind_ForcedUnwind _Unwind_SjLj_ForcedUnwind
+#define _Unwind_Resume _Unwind_SjLj_Resume
+#define __gcc_personality_v0 __gcc_personality_sj0
+
+#endif /* unwind.h */