diff options
Diffstat (limited to 'libc/sysdeps/linux/common')
| -rw-r--r-- | libc/sysdeps/linux/common/Makefile.in | 10 | ||||
| -rw-r--r-- | libc/sysdeps/linux/common/bits/kernel-features.h | 25 | ||||
| -rw-r--r-- | libc/sysdeps/linux/common/epoll.c | 53 | ||||
| -rw-r--r-- | libc/sysdeps/linux/common/getcwd.c | 3 | ||||
| -rw-r--r-- | libc/sysdeps/linux/common/longjmp.c | 4 | ||||
| -rw-r--r-- | libc/sysdeps/linux/common/pipe2.c | 16 | ||||
| -rw-r--r-- | libc/sysdeps/linux/common/stubs.c | 106 | ||||
| -rw-r--r-- | libc/sysdeps/linux/common/sys/epoll.h | 64 | ||||
| -rw-r--r-- | libc/sysdeps/linux/common/unwind.h | 220 | 
9 files changed, 487 insertions, 14 deletions
| diff --git a/libc/sysdeps/linux/common/Makefile.in b/libc/sysdeps/linux/common/Makefile.in index 8811268d0..8f936ffcc 100644 --- a/libc/sysdeps/linux/common/Makefile.in +++ b/libc/sysdeps/linux/common/Makefile.in @@ -19,14 +19,14 @@ CSRC-$(UCLIBC_LINUX_MODULE_24) += create_module.c query_module.c \  	get_kernel_syms.c  # we need these internally: fstatfs.c statfs.c  CSRC-$(UCLIBC_LINUX_SPECIFIC) += capget.c capset.c inotify.c ioperm.c iopl.c \ -	madvise.c modify_ldt.c personality.c ppoll.c prctl.c readahead.c reboot.c \ +	modify_ldt.c pipe2.c personality.c ppoll.c prctl.c \ +	readahead.c reboot.c \  	remap_file_pages.c sched_getaffinity.c sched_setaffinity.c \  	sendfile64.c sendfile.c setfsgid.c setfsuid.c setresuid.c \  	splice.c vmsplice.c tee.c signalfd.c swapoff.c swapon.c \  	sync_file_range.c sysctl.c sysinfo.c timerfd.c uselib.c vhangup.c -ifeq ($(UCLIBC_LINUX_SPECIFIC)$(UCLIBC_HAS_THREADS_NATIVE),yy) -CSRC-y += madvise.c -endif +# NPTL needs these internally: madvise.c +CSRC-$(findstring y,$(UCLIBC_LINUX_SPECIFIC)$(UCLIBC_HAS_THREADS_NATIVE)) += madvise.c  ifeq ($(UCLIBC_HAS_THREADS_NATIVE),y)  CSRC- += fork.c getpid.c raise.c open.c close.c read.c write.c  CSRC- += $(if $(findstring =arm=,=$(TARGET_ARCH)=),vfork.c) @@ -52,7 +52,7 @@ CSRC-$(UCLIBC_HAS_XATTR) += xattr.c  CSRC-$(UCLIBC_HAS_PROFILING) += noophooks.c #pcprofile.c  CSRC-$(UCLIBC_SV4_DEPRECATED) += ustat.c  CSRC- += $(if $(findstring =c6x=,=$(TARGET_ARCH)=),vfork.c) -CSRC- += $(if $(findstring =sh=,=$(TARGET_ARCH)=),longjmp.c vfork.c) +CSRC- += $(if $(findstring =sh=,=$(TARGET_ARCH)=),vfork.c)  CSRC- += $(if $(findstring =sparc=,=$(TARGET_ARCH)=),vfork.c)  CSRC- += $(if $(findstring =i386=,=$(TARGET_ARCH)=),vfork.c) diff --git a/libc/sysdeps/linux/common/bits/kernel-features.h b/libc/sysdeps/linux/common/bits/kernel-features.h index 68b881c09..6bf554457 100644 --- a/libc/sysdeps/linux/common/bits/kernel-features.h +++ b/libc/sysdeps/linux/common/bits/kernel-features.h @@ -309,6 +309,19 @@  # define __ASSUME_O_CLOEXEC 1  #endif +/* Support for various CLOEXEC and NONBLOCK flags was added for x86, + *    x86-64, PPC, IA-64, and SPARC in 2.6.27.  */ +#if __LINUX_KERNEL_VERSION >= 0x02061b \ +    && (defined __i386__ || defined __x86_64__ || defined __powerpc__ \ +        || defined __ia64__ || defined __sparc__ || defined __s390__) +/* # define __ASSUME_SOCK_CLOEXEC  1 */ +/* # define __ASSUME_IN_NONBLOCK   1 */ +# define __ASSUME_PIPE2         1 +/* # define __ASSUME_EVENTFD2      1 */ +/* # define __ASSUME_SIGNALFD4     1 */ +#endif + +  /* These features were surely available with 2.4.12.  */  #if __LINUX_KERNEL_VERSION >= 132108 && defined __mc68000__  # define __ASSUME_MMAP2_SYSCALL		1 @@ -454,6 +467,18 @@  #define __ASSUME_IEEE_RAISE_EXCEPTION	1  #endif +/* Support for the accept4 syscall was added in 2.6.28.  */ +#if __LINUX_KERNEL_VERSION >= 0x02061c \ +    && (defined __i386__ || defined __x86_64__ || defined __powerpc__ \ +        || defined __sparc__ || defined __s390__) +# define __ASSUME_ACCEPT4       1 +#endif + +/* Support for the accept4 syscall for alpha was added after 2.6.33-rc1.  */ +#if __LINUX_KERNEL_VERSION >= 0x020621 && defined __alpha__ +# define __ASSUME_ACCEPT4       1 +#endif +  /* Support for the FUTEX_CLOCK_REALTIME flag was added in 2.6.29.  */  #if __LINUX_KERNEL_VERSION >= 0x02061d  # define __ASSUME_FUTEX_CLOCK_REALTIME	1 diff --git a/libc/sysdeps/linux/common/epoll.c b/libc/sysdeps/linux/common/epoll.c index dda92282e..ab3e73bb7 100644 --- a/libc/sysdeps/linux/common/epoll.c +++ b/libc/sysdeps/linux/common/epoll.c @@ -9,6 +9,11 @@  #include <sys/syscall.h>  #include <sys/epoll.h> +#ifdef __UCLIBC_HAS_THREADS_NATIVE__ +# include <sysdep-cancel.h> +#else +# define SINGLE_THREAD_P 1 +#endif  /*   * epoll_create() @@ -18,6 +23,13 @@ _syscall1(int, epoll_create, int, size)  #endif  /* + * epoll_create1() + */ +#ifdef __NR_epoll_create1 +_syscall1(int, epoll_create1, int, flags) +#endif + +/*   * epoll_ctl()   */  #ifdef __NR_epoll_ctl @@ -28,5 +40,44 @@ _syscall4(int,epoll_ctl, int, epfd, int, op, int, fd, struct epoll_event *, even   * epoll_wait()   */  #ifdef __NR_epoll_wait -_syscall4(int, epoll_wait, int, epfd, struct epoll_event *, events, int, maxevents, int, timeout) +extern __typeof(epoll_wait) __libc_epoll_wait; +int __libc_epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout) +{ +	if (SINGLE_THREAD_P) +		return INLINE_SYSCALL(epoll_wait, 4, epfd, events, maxevents, timeout); +# ifdef __UCLIBC_HAS_THREADS_NATIVE__ +	else { +		int oldtype = LIBC_CANCEL_ASYNC (); +		int result = INLINE_SYSCALL(epoll_wait, 4, epfd, events, maxevents, timeout); +		LIBC_CANCEL_RESET (oldtype); +		return result; +	} +# endif +} +weak_alias(__libc_epoll_wait, epoll_wait) +#endif + +/* + * epoll_pwait() + */ +#ifdef __NR_epoll_pwait +# include <signal.h> + +extern __typeof(epoll_pwait) __libc_epoll_pwait; +int __libc_epoll_pwait(int epfd, struct epoll_event *events, int maxevents, +						int timeout, const sigset_t *set) +{ +    int nsig = _NSIG / 8; +	if (SINGLE_THREAD_P) +		return INLINE_SYSCALL(epoll_pwait, 6, epfd, events, maxevents, timeout, set, nsig); +# ifdef __UCLIBC_HAS_THREADS_NATIVE__ +	else { +		int oldtype = LIBC_CANCEL_ASYNC (); +		int result = INLINE_SYSCALL(epoll_pwait, 6, epfd, events, maxevents, timeout, set, nsig); +		LIBC_CANCEL_RESET (oldtype); +		return result; +	} +# endif +} +weak_alias(__libc_epoll_pwait, epoll_pwait)  #endif diff --git a/libc/sysdeps/linux/common/getcwd.c b/libc/sysdeps/linux/common/getcwd.c index 75d7a1c8b..87510019e 100644 --- a/libc/sysdeps/linux/common/getcwd.c +++ b/libc/sysdeps/linux/common/getcwd.c @@ -69,7 +69,7 @@ static char *search_dir(dev_t this_dev, ino_t this_ino, char *path_buf, int path  	slen++;  	dp = opendir(path_buf); -	if (dp == 0) { +	if (!dp) {  	    goto oops;  	} @@ -78,6 +78,7 @@ static char *search_dir(dev_t this_dev, ino_t this_ino, char *path_buf, int path  		if (slow_search || this_ino == d->d_ino) {  # endif  			if (slen + strlen(d->d_name) > path_size) { +			    closedir(dp);  			    goto oops;  			}  			strcpy(ptr + 1, d->d_name); diff --git a/libc/sysdeps/linux/common/longjmp.c b/libc/sysdeps/linux/common/longjmp.c index b07eced6a..f3448bc6f 100644 --- a/libc/sysdeps/linux/common/longjmp.c +++ b/libc/sysdeps/linux/common/longjmp.c @@ -24,7 +24,7 @@  extern void __longjmp (__jmp_buf __env, int __val) attribute_noreturn;  libc_hidden_proto(__longjmp) -#if 0 +#ifdef __UCLIBC_HAS_THREADS_NATIVE__  extern void _longjmp_unwind (jmp_buf env, int val);  #endif @@ -34,7 +34,7 @@ extern __typeof(longjmp) __libc_longjmp attribute_noreturn;     call there to return VAL, or 1 if VAL is 0.  */  void __libc_longjmp (sigjmp_buf env, int val)  { -#if 0 +#ifdef __UCLIBC_HAS_THREADS_NATIVE__    /* Perform any cleanups needed by the frames being unwound.  */    _longjmp_unwind (env, val);  #endif diff --git a/libc/sysdeps/linux/common/pipe2.c b/libc/sysdeps/linux/common/pipe2.c new file mode 100644 index 000000000..0a3686d81 --- /dev/null +++ b/libc/sysdeps/linux/common/pipe2.c @@ -0,0 +1,16 @@ +/* vi: set sw=4 ts=4: */ +/* + * pipe2() for uClibc + * + * Copyright (C) 2011 Bernhard Reutner-Fischer <uclibc@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#include <sys/syscall.h> +#include <unistd.h> + +#ifdef __NR_pipe2 +_syscall2(int, pipe2, int *, filedes, int, flags) +libc_hidden_def(pipe2) +#endif diff --git a/libc/sysdeps/linux/common/stubs.c b/libc/sysdeps/linux/common/stubs.c index 655c64001..e14bbc3a0 100644 --- a/libc/sysdeps/linux/common/stubs.c +++ b/libc/sysdeps/linux/common/stubs.c @@ -31,10 +31,48 @@ static int enosys_stub(void)  # undef __NR_sync_file_range  #endif +#ifndef __UCLIBC_LINUX_SPECIFIC__ +# undef __NR_pipe2 +#endif + +#ifndef __UCLIBC_HAS_SOCKET__ +# undef __NR_accept +# undef __NR_accept4 +# undef __NR_bind +# undef __NR_connect +# undef __NR_getpeername +# undef __NR_getsockname +# undef __NR_getsockopt +# undef __NR_listen +# undef __NR_recv +# undef __NR_recvfrom +# undef __NR_recvmsg +# undef __NR_send +# undef __NR_sendmsg +# undef __NR_sendto +# undef __NR_setsockopt +# undef __NR_shutdown +# undef __NR_socket +# undef __NR_socketcall +# undef __NR_socketpair +#endif + +#if !defined __NR_accept && !defined __NR_socketcall && !defined __UCLIBC_HAS_SOCKET__ +make_stub(accept) +#endif + +#if !defined __NR_accept4 && !defined __NR_socketcall && !defined __UCLIBC_HAS_SOCKET__ +make_stub(accept4) +#endif +  #ifndef __NR_bdflush  make_stub(bdflush)  #endif +#if !defined __NR_bind && !defined __NR_socketcall && !defined __UCLIBC_HAS_SOCKET__ +make_stub(bind) +#endif +  #ifndef __NR_capget  make_stub(capget)  #endif @@ -43,6 +81,10 @@ make_stub(capget)  make_stub(capset)  #endif +#if !defined __NR_connect && !defined __NR_socketcall && !defined __UCLIBC_HAS_SOCKET__ +make_stub(connect) +#endif +  #ifndef __NR_create_module  make_stub(create_module)  #endif @@ -91,10 +133,22 @@ make_stub(fsetxattr)  make_stub(get_kernel_syms)  #endif +#if !defined __NR_getpeername && !defined __NR_socketcall && !defined __UCLIBC_HAS_SOCKET__ +make_stub(getpeername) +#endif +  #if !defined(__NR_getpgrp) && (defined(__NR_getpgid) && (defined(__NR_getpid) || defined(__NR_getxpid)))  make_stub(getpgrp)  #endif +#if !defined __NR_getsockname && !defined __NR_socketcall && !defined __UCLIBC_HAS_SOCKET__ +make_stub(getsockname) +#endif + +#if !defined __NR_getsockopt && !defined __NR_socketcall && !defined __UCLIBC_HAS_SOCKET__ +make_stub(getsockopt) +#endif +  #ifndef __NR_getxattr  make_stub(getxattr)  #endif @@ -107,6 +161,10 @@ make_stub(init_module)  make_stub(lgetxattr)  #endif +#if !defined __NR_listen && !defined __NR_socketcall && !defined __UCLIBC_HAS_SOCKET__ +make_stub(listen) +#endif +  #ifndef __NR_listxattr  make_stub(listxattr)  #endif @@ -123,6 +181,10 @@ make_stub(lremovexattr)  make_stub(lsetxattr)  #endif +#ifndef __NR_pipe2 +make_stub(pipe2) +#endif +  #ifndef __NR_pivot_root  make_stub(pivot_root)  #endif @@ -131,6 +193,18 @@ make_stub(pivot_root)  make_stub(query_module)  #endif +#if !defined __NR_recv && !defined __NR_socketcall && !defined __UCLIBC_HAS_SOCKET__ +make_stub(recv) +#endif + +#if !defined __NR_recvfrom && !defined __NR_socketcall && !defined __UCLIBC_HAS_SOCKET__ +make_stub(recvfrom) +#endif + +#if !defined __NR_recvmsg && !defined __NR_socketcall && !defined __UCLIBC_HAS_SOCKET__ +make_stub(recvmsg) +#endif +  #ifndef __NR_removexattr  make_stub(removexattr)  #endif @@ -143,14 +217,46 @@ make_stub(sched_getaffinity)  make_stub(sched_setaffinity)  #endif +#if !defined __NR_send && !defined __NR_socketcall && !defined __UCLIBC_HAS_SOCKET__ +make_stub(send) +#endif + +#if !defined __NR_sendmsg && !defined __NR_socketcall && !defined __UCLIBC_HAS_SOCKET__ +make_stub(sendmsg) +#endif + +#if !defined __NR_sendto && !defined __NR_socketcall && !defined __UCLIBC_HAS_SOCKET__ +make_stub(sendto) +#endif + +#if !defined __NR_setsockopt && !defined __NR_socketcall && !defined __UCLIBC_HAS_SOCKET__ +make_stub(setsockopt) +#endif +  #ifndef __NR_setxattr  make_stub(setxattr)  #endif +#if !defined __NR_shutdown && !defined __NR_socketcall && !defined __UCLIBC_HAS_SOCKET__ +make_stub(shutdown) +#endif +  #if !defined(__NR_signalfd4) && !defined(__NR_signalfd)  make_stub(signalfd)  #endif +#if !defined __NR_socket && !defined __NR_socketcall && !defined __UCLIBC_HAS_SOCKET__ +make_stub(socket) +#endif + +#if !defined __NR_socketcall && !defined __NR_socketcall && !defined __UCLIBC_HAS_SOCKET__ +make_stub(socketcall) +#endif + +#if !defined __NR_socketpair && !defined __NR_socketcall && !defined __UCLIBC_HAS_SOCKET__ +make_stub(socketpair) +#endif +  #ifndef __NR_rt_sigtimedwait  make_stub(sigtimedwait)  make_stub(sigwaitinfo) diff --git a/libc/sysdeps/linux/common/sys/epoll.h b/libc/sysdeps/linux/common/sys/epoll.h index 44e814bfd..a04bd704c 100644 --- a/libc/sysdeps/linux/common/sys/epoll.h +++ b/libc/sysdeps/linux/common/sys/epoll.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. +/* Copyright (C) 2002-2006, 2007, 2008, 2009 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 @@ -22,6 +22,42 @@  #include <stdint.h>  #include <sys/types.h> +/* Get __sigset_t.  */ +#include <bits/sigset.h> + +#ifndef __sigset_t_defined +# define __sigset_t_defined +typedef __sigset_t sigset_t; +#endif + + +/* Flags to be passed to epoll_create1.  */ + +enum +  { +#if defined __alpha__ +    EPOLL_CLOEXEC = 010000000, +# define EPOLL_CLOEXEC EPOLL_CLOEXEC +    EPOLL_NONBLOCK = 04 +# define EPOLL_NONBLOCK EPOLL_NONBLOCK +#else +# if defined __sparc__ +    EPOLL_CLOEXEC = 020000000, +# else +    EPOLL_CLOEXEC = 02000000, +# endif +# define EPOLL_CLOEXEC EPOLL_CLOEXEC +# if defined __mips__ +    EPOLL_NONBLOCK = 0200 +# elif defined __sparc__ +    EPOLL_NONBLOCK = 040000 +# else +    EPOLL_NONBLOCK = 04000 +# endif +#define EPOLL_NONBLOCK EPOLL_NONBLOCK +#endif +  }; +  enum EPOLL_EVENTS    { @@ -55,9 +91,9 @@ enum EPOLL_EVENTS  /* Valid opcodes ( "op" parameter ) to issue to epoll_ctl().  */ -#define EPOLL_CTL_ADD 1	/* Add a file decriptor to the interface.  */ -#define EPOLL_CTL_DEL 2	/* Remove a file decriptor from the interface.  */ -#define EPOLL_CTL_MOD 3	/* Change file decriptor epoll_event structure.  */ +#define EPOLL_CTL_ADD 1	/* Add a file descriptor to the interface.  */ +#define EPOLL_CTL_DEL 2	/* Remove a file descriptor from the interface.  */ +#define EPOLL_CTL_MOD 3	/* Change file descriptor epoll_event structure.  */  typedef union epoll_data @@ -72,7 +108,11 @@ struct epoll_event  {    uint32_t events;	/* Epoll events */    epoll_data_t data;	/* User data variable */ -}; +} +#if defined __x86_64__ +__attribute__((packed)) +#endif +;  __BEGIN_DECLS @@ -83,6 +123,10 @@ __BEGIN_DECLS     returned by epoll_create() should be closed with close().  */  extern int epoll_create (int __size) __THROW; +/* Same as epoll_create but with a FLAGS parameter.  The unused SIZE +   parameter has been dropped.  */ +extern int epoll_create1 (int __flags) __THROW; +  /* Manipulate an epoll instance "epfd". Returns 0 in case of success,     -1 in case of error ( the "errno" variable will contain the @@ -107,6 +151,16 @@ extern int epoll_ctl (int __epfd, int __op, int __fd,  extern int epoll_wait (int __epfd, struct epoll_event *__events,  		       int __maxevents, int __timeout); + +/* Same as epoll_wait, but the thread's signal mask is temporarily +   and atomically replaced with the one provided as parameter. + +   This function is a cancellation point and therefore not marked with +   __THROW.  */ +extern int epoll_pwait (int __epfd, struct epoll_event *__events, +			int __maxevents, int __timeout, +			__const __sigset_t *__ss); +  __END_DECLS  #endif /* sys/epoll.h */ diff --git a/libc/sysdeps/linux/common/unwind.h b/libc/sysdeps/linux/common/unwind.h new file mode 100644 index 000000000..81fc4db55 --- /dev/null +++ b/libc/sysdeps/linux/common/unwind.h @@ -0,0 +1,220 @@ +/* Exception handling and frame unwind runtime interface routines. +   Copyright (C) 2001, 2003 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.  */ + +/* This is derived from the C++ ABI for IA-64.  Where we diverge +   for cross-architecture compatibility are noted with "@@@".  */ + +#ifndef _UNWIND_H +#define _UNWIND_H	1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* Level 1: Base ABI  */ + +/* @@@ The IA-64 ABI uses uint64 throughout.  Most places this is +   inefficient for 32-bit and smaller machines.  */ +typedef unsigned _Unwind_Word __attribute__((__mode__(__word__))); +typedef signed _Unwind_Sword __attribute__((__mode__(__word__))); +#if defined(__ia64__) && defined(__hpux__) +typedef unsigned _Unwind_Ptr __attribute__((__mode__(__word__))); +#else +typedef unsigned _Unwind_Ptr __attribute__((__mode__(__pointer__))); +#endif +typedef unsigned _Unwind_Internal_Ptr __attribute__((__mode__(__pointer__))); + +/* @@@ The IA-64 ABI uses a 64-bit word to identify the producer and +   consumer of an exception.  We'll go along with this for now even on +   32-bit machines.  We'll need to provide some other option for +   16-bit machines and for machines with > 8 bits per byte.  */ +typedef unsigned _Unwind_Exception_Class __attribute__((__mode__(__DI__))); + +/* The unwind interface uses reason codes in several contexts to +   identify the reasons for failures or other actions.  */ +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; + + +/* The unwind interface uses a pointer to an exception header object +   as its representation of an exception being thrown. In general, the +   full representation of an exception object is language- and +   implementation-specific, but it will be prefixed by a header +   understood by the unwind interface.  */ + +struct _Unwind_Exception; + +typedef void (*_Unwind_Exception_Cleanup_Fn) (_Unwind_Reason_Code, +					      struct _Unwind_Exception *); + +struct _Unwind_Exception +{ +  _Unwind_Exception_Class exception_class; +  _Unwind_Exception_Cleanup_Fn exception_cleanup; +  _Unwind_Word private_1; +  _Unwind_Word private_2; + +  /* @@@ The IA-64 ABI says that this structure must be double-word aligned. +     Taking that literally does not make much sense generically.  Instead we +     provide the maximum alignment required by any type for the machine.  */ +} __attribute__((__aligned__)); + + +/* The ACTIONS argument to the personality routine is a bitwise OR of one +   or more of the following constants.  */ +typedef int _Unwind_Action; + +#define _UA_SEARCH_PHASE	1 +#define _UA_CLEANUP_PHASE	2 +#define _UA_HANDLER_FRAME	4 +#define _UA_FORCE_UNWIND	8 +#define _UA_END_OF_STACK	16 + +/* This is an opaque type used to refer to a system-specific data +   structure used by the system unwinder. This context is created and +   destroyed by the system, and passed to the personality routine +   during unwinding.  */ +struct _Unwind_Context; + +/* Raise an exception, passing along the given exception object.  */ +extern _Unwind_Reason_Code _Unwind_RaiseException (struct _Unwind_Exception *); + +/* Raise an exception for forced unwinding.  */ + +typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn) +     (int, _Unwind_Action, _Unwind_Exception_Class, +      struct _Unwind_Exception *, struct _Unwind_Context *, void *); + +extern _Unwind_Reason_Code _Unwind_ForcedUnwind (struct _Unwind_Exception *, +						 _Unwind_Stop_Fn, +						 void *); + +/* Helper to invoke the exception_cleanup routine.  */ +extern void _Unwind_DeleteException (struct _Unwind_Exception *); + +/* Resume propagation of an existing exception.  This is used after +   e.g. executing cleanup code, and not to implement rethrowing.  */ +extern void _Unwind_Resume (struct _Unwind_Exception *); + +/* @@@ Use unwind data to perform a stack backtrace.  The trace callback +   is called for every stack frame in the call chain, but no cleanup +   actions are performed.  */ +typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn) +     (struct _Unwind_Context *, void *); + +extern _Unwind_Reason_Code _Unwind_Backtrace (_Unwind_Trace_Fn, void *); + +/* These functions are used for communicating information about the unwind +   context (i.e. the unwind descriptors and the user register state) between +   the unwind library and the personality routine and landing pad.  Only +   selected registers maybe manipulated.  */ + +extern _Unwind_Word _Unwind_GetGR (struct _Unwind_Context *, int); +extern void _Unwind_SetGR (struct _Unwind_Context *, int, _Unwind_Word); + +extern _Unwind_Ptr _Unwind_GetIP (struct _Unwind_Context *); +extern void _Unwind_SetIP (struct _Unwind_Context *, _Unwind_Ptr); + +/* @@@ Retrieve the CFA of the given context.  */ +extern _Unwind_Word _Unwind_GetCFA (struct _Unwind_Context *); + +extern void *_Unwind_GetLanguageSpecificData (struct _Unwind_Context *); + +extern _Unwind_Ptr _Unwind_GetRegionStart (struct _Unwind_Context *); + + +/* The personality routine is the function in the C++ (or other language) +   runtime library which serves as an interface between the system unwind +   library and language-specific exception handling semantics.  It is +   specific to the code fragment described by an unwind info block, and +   it is always referenced via the pointer in the unwind info block, and +   hence it has no ABI-specified name. + +   Note that this implies that two different C++ implementations can +   use different names, and have different contents in the language +   specific data area.  Moreover, that the language specific data +   area contains no version info because name of the function invoked +   provides more effective versioning by detecting at link time the +   lack of code to handle the different data format.  */ + +typedef _Unwind_Reason_Code (*_Unwind_Personality_Fn) +     (int, _Unwind_Action, _Unwind_Exception_Class, +      struct _Unwind_Exception *, struct _Unwind_Context *); + +/* @@@ The following alternate entry points are for setjmp/longjmp +   based unwinding.  */ + +struct SjLj_Function_Context; +extern void _Unwind_SjLj_Register (struct SjLj_Function_Context *); +extern void _Unwind_SjLj_Unregister (struct SjLj_Function_Context *); + +extern _Unwind_Reason_Code _Unwind_SjLj_RaiseException +     (struct _Unwind_Exception *); +extern _Unwind_Reason_Code _Unwind_SjLj_ForcedUnwind +     (struct _Unwind_Exception *, _Unwind_Stop_Fn, void *); +extern void _Unwind_SjLj_Resume (struct _Unwind_Exception *); + +/* @@@ The following provide access to the base addresses for text +   and data-relative addressing in the LDSA.  In order to stay link +   compatible with the standard ABI for IA-64, we inline these.  */ + +#ifdef __ia64__ +#include <stdlib.h> + +static inline _Unwind_Ptr +_Unwind_GetDataRelBase (struct _Unwind_Context *_C) +{ +  /* The GP is stored in R1.  */ +  return _Unwind_GetGR (_C, 1); +} + +static inline _Unwind_Ptr +_Unwind_GetTextRelBase (struct _Unwind_Context *_C) +{ +  abort (); +  return 0; +} + +/* @@@ Retrieve the Backing Store Pointer of the given context.  */ +extern _Unwind_Word _Unwind_GetBSP (struct _Unwind_Context *); +#else +extern _Unwind_Ptr _Unwind_GetDataRelBase (struct _Unwind_Context *); +extern _Unwind_Ptr _Unwind_GetTextRelBase (struct _Unwind_Context *); +#endif + +/* @@@ Given an address, return the entry point of the function that +   contains it.  */ +extern void * _Unwind_FindEnclosingFunction (void *pc); + +#ifdef __cplusplus +} +#endif + +#endif	/* unwind.h */ | 
