mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-22 13:00:06 +00:00
* 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.
This commit is contained in:
parent
02a9f771e3
commit
34e59f5bfb
@ -1,3 +1,12 @@
|
||||
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
|
||||
|
1
sysdeps/arm/framestate.c
Normal file
1
sysdeps/arm/framestate.c
Normal file
@ -0,0 +1 @@
|
||||
/* Empty */
|
80
sysdeps/arm/unwind-dw2-fde-glibc.c
Normal file
80
sysdeps/arm/unwind-dw2-fde-glibc.c
Normal file
@ -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 ();
|
||||
}
|
1
sysdeps/arm/unwind-pe.c
Normal file
1
sysdeps/arm/unwind-pe.c
Normal file
@ -0,0 +1 @@
|
||||
/* Empty */
|
128
sysdeps/unix/sysv/linux/arm/nptl/sysdep-cancel.h
Normal file
128
sysdeps/unix/sysv/linux/arm/nptl/sysdep-cancel.h
Normal file
@ -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
|
117
sysdeps/unix/sysv/linux/arm/nptl/unwind-forcedunwind.c
Normal file
117
sysdeps/unix/sysv/linux/arm/nptl/unwind-forcedunwind.c
Normal file
@ -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);
|
||||
}
|
87
sysdeps/unix/sysv/linux/arm/nptl/unwind-resume.c
Normal file
87
sysdeps/unix/sysv/linux/arm/nptl/unwind-resume.c
Normal file
@ -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);
|
||||
}
|
31
sysdeps/unix/sysv/linux/arm/nptl/unwind.h
Normal file
31
sysdeps/unix/sysv/linux/arm/nptl/unwind.h
Normal file
@ -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 */
|
Loading…
Reference in New Issue
Block a user