More cancellation handling fixups.
	* sysdeps/unix/sysv/linux/not-cancel.h: Add waitpid_not_cancel.
	* sysdeps/generic/not-cancel.h: Likewise.
	* catgets/open_catalog.c: Use not-cancelable syscalls.
	* time/Makefile (CFLAGS-getdate.c): Add -fexceptions.
	* sysdeps/unix/sysv/linux/llseek.c: Must not be cancelable.
	* sysdeps/unix/syscalls.list: Don't mark lseek as cancelable.
	* dlfcn/dlfcn.h: Mark dlopen with __THROW again.
	* io/fcntl.h: Don't mark posix_fallocate with __THROW.
	* libio/fileops.c: Use not-cancelable syscalls for fclose.
	* libio/iopopen.c: Use no-cancelable syscalls.
	* libio/stdio.h: Mark popen and pclose with __THROW again.
	* misc/Makefile (CFLAGS-syslog.c): Add -fexceptions.
	* misc/syslog.c: Fix locking and cancellation cleanup handling.
	* posix/unistd.h: Mark ttyname and ttyname_r again with __THROW.
	* stdio-common/Makefile (CFLAGS-tmpfile.c, CFLAGS-tmpfile64.c,
	CFLAGS-tempname.c): Add -fexceptions.
	* stdlib/Makefile (CFLAGS-mkstemp.c): Add -fexceptions.
	* string/string.h: Mark strerror and strerror_r with _THROW again.
	* sysdeps/generic/unwind.inc: New file.  Copied from gcc.
	* sysdeps/generic/unwind-dw2.c: Update from gcc version.  Remove
	#ifs since we now need all the code compiled.
	* sysdeps/posix/spawni.c: Use close_not_cancel instead of close.
	* sysdeps/unix/closedir.c: Use not-cancelable syscalls.
	* sysdeps/unix/opendir.c: Likewise.
This commit is contained in:
Ulrich Drepper 2003-07-15 07:52:52 +00:00
parent da35d15e2b
commit 7329994338
27 changed files with 543 additions and 179 deletions

View File

@ -1,5 +1,31 @@
2003-07-14 Ulrich Drepper <drepper@redhat.com>
More cancellation handling fixups.
* sysdeps/unix/sysv/linux/not-cancel.h: Add waitpid_not_cancel.
* sysdeps/generic/not-cancel.h: Likewise.
* catgets/open_catalog.c: Use not-cancelable syscalls.
* time/Makefile (CFLAGS-getdate.c): Add -fexceptions.
* sysdeps/unix/sysv/linux/llseek.c: Must not be cancelable.
* sysdeps/unix/syscalls.list: Don't mark lseek as cancelable.
* dlfcn/dlfcn.h: Mark dlopen with __THROW again.
* io/fcntl.h: Don't mark posix_fallocate with __THROW.
* libio/fileops.c: Use not-cancelable syscalls for fclose.
* libio/iopopen.c: Use no-cancelable syscalls.
* libio/stdio.h: Mark popen and pclose with __THROW again.
* misc/Makefile (CFLAGS-syslog.c): Add -fexceptions.
* misc/syslog.c: Fix locking and cancellation cleanup handling.
* posix/unistd.h: Mark ttyname and ttyname_r again with __THROW.
* stdio-common/Makefile (CFLAGS-tmpfile.c, CFLAGS-tmpfile64.c,
CFLAGS-tempname.c): Add -fexceptions.
* stdlib/Makefile (CFLAGS-mkstemp.c): Add -fexceptions.
* string/string.h: Mark strerror and strerror_r with _THROW again.
* sysdeps/generic/unwind.inc: New file. Copied from gcc.
* sysdeps/generic/unwind-dw2.c: Update from gcc version. Remove
#ifs since we now need all the code compiled.
* sysdeps/posix/spawni.c: Use close_not_cancel instead of close.
* sysdeps/unix/closedir.c: Use not-cancelable syscalls.
* sysdeps/unix/opendir.c: Likewise.
* iconvdata/Makefile (modules): Add CP932 and EUC-JP-MS.
Add rule for EUC-JP-MS dependency.
* iconvdata/cp932.c: New file.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1996-2000, 2001, 2002 Free Software Foundation, Inc.
/* Copyright (C) 1996-2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper, <drepper@gnu.org>.
@ -30,6 +30,7 @@
#include <sys/stat.h>
#include "catgetsinfo.h"
#include <not-cancel.h>
#define SWAPU32(w) bswap_32 (w)
@ -49,7 +50,7 @@ __open_catalog (const char *cat_name, const char *nlspath, const char *env_var,
int result = -1;
if (strchr (cat_name, '/') != NULL || nlspath == NULL)
fd = __open (cat_name, O_RDONLY);
fd = open_not_cancel_2 (cat_name, O_RDONLY);
else
{
const char *run_nlspath = nlspath;
@ -177,7 +178,7 @@ __open_catalog (const char *cat_name, const char *nlspath, const char *env_var,
if (bufact != 0)
{
fd = __open (buf, O_RDONLY);
fd = open_not_cancel_2 (buf, O_RDONLY);
if (fd >= 0)
break;
}
@ -233,8 +234,8 @@ __open_catalog (const char *cat_name, const char *nlspath, const char *env_var,
/* Save read, handle partial reads. */
do
{
size_t now = __read (fd, (((char *) catalog->file_ptr)
+ (st.st_size - todo)), todo);
size_t now = read_not_cancel (fd, (((char *) catalog->file_ptr)
+ (st.st_size - todo)), todo);
if (now == 0 || now == (size_t) -1)
{
#ifdef EINTR
@ -324,7 +325,7 @@ __open_catalog (const char *cat_name, const char *nlspath, const char *env_var,
/* Release the lock again. */
close_unlock_return:
__close (fd);
close_not_cancel_no_status (fd);
return result;
}

View File

@ -45,11 +45,8 @@
__BEGIN_DECLS
/* Open the shared object FILE and map it in; return a handle that can be
passed to `dlsym' to get symbol values from it.
This function is a possible cancellation point and therefore not
marked with __THROW. */
extern void *dlopen (__const char *__file, int __mode);
passed to `dlsym' to get symbol values from it. */
extern void *dlopen (__const char *__file, int __mode) __THROW;
/* Unmap and close a shared object opened by `dlopen'.
The handle cannot be used again after calling `dlclose'. */

View File

@ -151,21 +151,23 @@ extern int posix_fadvise64 (int __fd, __off64_t __offset, size_t __len,
# endif
/* Reserve storage for the data of the file associated with FD. */
/* Reserve storage for the data of the file associated with FD.
This function is a possible cancellation points and therefore not
marked with __THROW. */
# ifndef __USE_FILE_OFFSET64
extern int posix_fallocate (int __fd, __off_t __offset, size_t __len) __THROW;
extern int posix_fallocate (int __fd, __off_t __offset, size_t __len);
# else
# ifdef __REDIRECT
extern int __REDIRECT (posix_fallocate, (int __fd, __off64_t __offset,
size_t __len) __THROW,
size_t __len),
posix_fallocate64);
# else
# define posix_fallocate posix_fallocate64
# endif
# endif
# ifdef __USE_LARGEFILE64
extern int posix_fallocate64 (int __fd, __off64_t __offset, size_t __len)
__THROW;
extern int posix_fallocate64 (int __fd, __off64_t __offset, size_t __len);
# endif
#endif

View File

@ -47,6 +47,7 @@
# include "../iconv/gconv_charset.h"
# include "../iconv/gconv_int.h"
# include <shlib-compat.h>
# include <not-cancel.h>
#endif
#ifndef errno
extern int errno;
@ -1240,14 +1241,18 @@ _IO_file_close_mmap (fp)
/* In addition to closing the file descriptor we have to unmap the file. */
(void) __munmap (fp->_IO_buf_base, fp->_IO_buf_end - fp->_IO_buf_base);
fp->_IO_buf_base = fp->_IO_buf_end = NULL;
return close (fp->_fileno);
/* Cancelling close should be avoided if possible since it leaves an
unrecoverable state behind. */
return close_not_cancel (fp->_fileno);
}
int
_IO_file_close (fp)
_IO_FILE *fp;
{
return close (fp->_fileno);
/* Cancelling close should be avoided if possible since it leaves an
unrecoverable state behind. */
return close_not_cancel (fp->_fileno);
}
INTDEF(_IO_file_close)

View File

@ -39,6 +39,7 @@
#ifdef _LIBC
# include <unistd.h>
# include <shlib-compat.h>
# include <not-cancel.h>
#endif
#include <sys/types.h>
#include <sys/wait.h>
@ -74,7 +75,7 @@ extern int _IO_dup2 __P ((int fd, int fd2));
#ifndef _IO_waitpid
#ifdef _LIBC
#define _IO_waitpid __waitpid
#define _IO_waitpid waitpid_not_cancel
#else
#define _IO_waitpid waitpid
#endif
@ -89,7 +90,7 @@ extern int _IO_dup2 __P ((int fd, int fd2));
#ifndef _IO_close
#ifdef _LIBC
#define _IO_close __close
#define _IO_close close_not_cancel
#else
#define _IO_close close
#endif

View File

@ -757,17 +757,11 @@ extern int fileno_unlocked (FILE *__stream) __THROW;
#if (defined __USE_POSIX2 || defined __USE_SVID || defined __USE_BSD || \
defined __USE_MISC)
/* Create a new stream connected to a pipe running the given command.
/* Create a new stream connected to a pipe running the given command. */
extern FILE *popen (__const char *__command, __const char *__modes) __THROW;
This function is a possible cancellation point and therefore not
marked with __THROW. */
extern FILE *popen (__const char *__command, __const char *__modes);
/* Close a stream opened by popen and return the status of its child.
This function is a possible cancellation point and therefore not
marked with __THROW. */
extern int pclose (FILE *__stream);
/* Close a stream opened by popen and return the status of its child. */
extern int pclose (FILE *__stream) __THROW;
#endif

View File

@ -81,6 +81,7 @@ CFLAGS-pselect.c = -fexceptions
CFLAGS-readv.c = -fexceptions -fasynchronous-unwind-tables
CFLAGS-writev.c = -fexceptions -fasynchronous-unwind-tables
CFLAGS-usleep.c = -fexceptions
CFLAGS-syslog.c = -fexceptions
include ../Rules

View File

@ -41,6 +41,7 @@ static char sccsid[] = "@(#)syslog.c 8.4 (Berkeley) 3/18/94";
#include <fcntl.h>
#include <paths.h>
#include <stdio.h>
#include <stdio_ext.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
@ -74,9 +75,27 @@ __libc_lock_define_initialized (static, syslog_lock)
static void openlog_internal(const char *, int, int) internal_function;
static void closelog_internal(void);
static void sigpipe_handler (int);
#ifdef _LIBC_REENTRANT
static void cancel_handler (void *);
#endif
struct cleanup_arg
{
void *buf;
struct sigaction *oldaction;
};
static void
cancel_handler (void *ptr)
{
/* Restore the old signal handler. */
struct cleanup_arg *clarg = (struct cleanup_arg *) ptr;
if (clarg != NULL && clarg->oldaction != NULL)
__sigaction (SIGPIPE, clarg->oldaction, NULL);
/* Free the lock. */
__libc_lock_unlock (syslog_lock);
}
/*
* syslog, vsyslog --
@ -118,7 +137,6 @@ vsyslog(pri, fmt, ap)
size_t bufsize = 0;
size_t prioff, msgoff;
struct sigaction action, oldaction;
struct sigaction *oldaction_ptr = NULL;
int sigpipe;
int saved_errno = errno;
char failbuf[3 * sizeof (pid_t) + sizeof "out of memory []"];
@ -165,6 +183,7 @@ vsyslog(pri, fmt, ap)
}
else
{
__fsetlocking (f, FSETLOCKING_BYCALLER);
prioff = fprintf (f, "<%d>", pri);
(void) time (&now);
#ifdef USE_IN_LIBIO
@ -182,9 +201,12 @@ vsyslog(pri, fmt, ap)
if (LogTag != NULL)
fputs_unlocked (LogTag, f);
if (LogStat & LOG_PID)
fprintf (f, "[%d]", __getpid ());
fprintf (f, "[%d]", (int) __getpid ());
if (LogTag != NULL)
putc_unlocked (':', f), putc_unlocked (' ', f);
{
putc_unlocked (':', f);
putc_unlocked (' ', f);
}
/* Restore errno for %m format. */
__set_errno (saved_errno);
@ -212,16 +234,22 @@ vsyslog(pri, fmt, ap)
v->iov_base = (char *) "\n";
v->iov_len = 1;
}
__libc_cleanup_push (free, buf);
/* writev is a cancellation point. */
(void)__writev(STDERR_FILENO, iov, v - iov + 1);
__libc_cleanup_pop (0);
}
#ifdef _LIBC_REENTRANT
/* Prepare for multiple users. We have to take care: open and
write are cancellation points. */
__libc_cleanup_region_start (1, (void (*) (void *)) cancel_handler,
&oldaction_ptr);
struct cleanup_arg clarg;
clarg.buf = buf;
clarg.oldaction = NULL;
__libc_cleanup_push (cancel_handler, &clarg);
__libc_lock_lock (syslog_lock);
#endif
/* Prepare for a broken connection. */
memset (&action, 0, sizeof (action));
@ -229,7 +257,7 @@ vsyslog(pri, fmt, ap)
sigemptyset (&action.sa_mask);
sigpipe = __sigaction (SIGPIPE, &action, &oldaction);
if (sigpipe == 0)
oldaction_ptr = &oldaction;
clarg.oldaction = &oldaction;
/* Get connected, output the message to the local logger. */
if (!connected)
@ -271,11 +299,9 @@ vsyslog(pri, fmt, ap)
if (sigpipe == 0)
__sigaction (SIGPIPE, &oldaction, (struct sigaction *) NULL);
#ifdef _LIBC_REENTRANT
/* End of critical section. */
__libc_cleanup_region_end (0);
__libc_cleanup_pop (0);
__libc_lock_unlock (syslog_lock);
#endif
free (buf);
}
@ -283,6 +309,7 @@ libc_hidden_def (vsyslog)
static struct sockaddr SyslogAddr; /* AF_UNIX address of local logger */
static void
internal_function
openlog_internal(const char *ident, int logstat, int logfac)
@ -312,8 +339,9 @@ openlog_internal(const char *ident, int logstat, int logfac)
== -1)
{
int saved_errno = errno;
(void)__close(LogFile);
int fd = LogFile;
LogFile = -1;
(void)__close(fd);
if (LogType == SOCK_DGRAM
&& saved_errno == EPROTOTYPE)
{
@ -329,28 +357,16 @@ openlog_internal(const char *ident, int logstat, int logfac)
}
}
static void
log_cleanup (void *arg)
{
__libc_lock_unlock (syslog_lock);
}
void
openlog (const char *ident, int logstat, int logfac)
{
#ifdef _LIBC_REENTRANT
/* Protect against multiple users. */
__libc_cleanup_region_start (1, log_cleanup, NULL);
/* Protect against multiple users and cancellation. */
__libc_cleanup_push (cancel_handler, NULL);
__libc_lock_lock (syslog_lock);
#endif
openlog_internal (ident, logstat, logfac);
#ifdef _LIBC_REENTRANT
/* Free the lock. */
__libc_cleanup_region_end (1);
#endif
__libc_cleanup_pop (1);
}
static void
@ -373,37 +389,18 @@ closelog_internal()
void
closelog ()
{
#ifdef _LIBC_REENTRANT
/* Protect against multiple users. */
__libc_cleanup_region_start (1, log_cleanup, NULL);
/* Protect against multiple users and cancellation. */
__libc_cleanup_push (cancel_handler, NULL);
__libc_lock_lock (syslog_lock);
#endif
closelog_internal ();
LogTag = NULL;
LogType = SOCK_DGRAM; /* this is the default */
#ifdef _LIBC_REENTRANT
/* Free the lock. */
__libc_cleanup_region_end (1);
#endif
__libc_cleanup_pop (1);
}
#ifdef _LIBC_REENTRANT
static void
cancel_handler (void *ptr)
{
/* Restore the old signal handler. */
struct sigaction *oldaction = *((struct sigaction **) ptr);
if (oldaction != (struct sigaction *) NULL)
__sigaction (SIGPIPE, oldaction, (struct sigaction *) NULL);
/* Free the lock. */
__libc_lock_unlock (syslog_lock);
}
#endif
/* setlogmask -- set the log mask level */
int
setlogmask(pmask)

View File

@ -1 +1 @@
NPTL 0.52 by Ulrich Drepper
NPTL 0.53 by Ulrich Drepper

View File

@ -1,3 +1,7 @@
2003-07-15 Ulrich Drepper <drepper@redhat.com>
* tst-tcancel-wrappers.sh: lseek and llseek are not cancelation points.
2003-07-14 Ulrich Drepper <drepper@redhat.com>
* sysdeps/pthread/configure.in: Require CFI directives also for

View File

@ -6,7 +6,7 @@ echo "$as_me: error: compiler support for __thread is required" >&2;}
{ (exit 1); exit 1; }; }
fi
if test "sx$libc_cv_asm_cfi_directives" != xyes; then
if test "x$libc_cv_asm_cfi_directives" != xyes; then
case "$base_machine" in
i386 | x86_64 | powerpc | s390)
{ { echo "$as_me:$LINENO: error: CFI directive support in assembler is required" >&5

View File

@ -699,18 +699,12 @@ extern __pid_t vfork (void) __THROW;
/* Return the pathname of the terminal FD is open on, or NULL on errors.
The returned storage is good only until the next call to this function.
This function is a possible cancellation points and therefore not
marked with __THROW. */
extern char *ttyname (int __fd);
The returned storage is good only until the next call to this function. */
extern char *ttyname (int __fd) __THROW;
/* Store at most BUFLEN characters of the pathname of the terminal FD is
open on in BUF. Return 0 on success, otherwise an error number.
This function is a possible cancellation points and therefore not
marked with __THROW. */
extern int ttyname_r (int __fd, char *__buf, size_t __buflen);
open on in BUF. Return 0 on success, otherwise an error number. */
extern int ttyname_r (int __fd, char *__buf, size_t __buflen) __THROW;
/* Return 1 if FD is a valid descriptor associated
with a terminal, zero if not. */

View File

@ -81,6 +81,10 @@ CFLAGS-scanf4.c = -Wno-format
CFLAGS-scanf7.c = -Wno-format
CFLAGS-tst-printfsz.c = -Wno-format
CFLAGS-tmpfile.c = -fexceptions
CFLAGS-tmpfile64.c = -fexceptions
CFLAGS-tempname.c = -fexceptions
tst-sscanf-ENV = LOCPATH=$(common-objpfx)localedata
tst-swprintf-ENV = LOCPATH=$(common-objpfx)localedata
test-vfprintf-ENV = LOCPATH=$(common-objpfx)localedata

View File

@ -83,6 +83,7 @@ CFLAGS-bsearch.c = $(exceptions)
CFLAGS-msort.c = $(exceptions)
CFLAGS-qsort.c = $(exceptions)
CFLAGS-system.c = -fexceptions
CFLAGS-mkstemp.c = -fexceptions
include ../Makeconfig

View File

@ -239,19 +239,13 @@ extern size_t strnlen (__const char *__string, size_t __maxlen)
__BEGIN_NAMESPACE_STD
/* Return a string describing the meaning of the `errno' code in ERRNUM.
This function is a possible cancellation points and therefore not
marked with __THROW. */
extern char *strerror (int __errnum);
/* Return a string describing the meaning of the `errno' code in ERRNUM. */
extern char *strerror (int __errnum) __THROW;
__END_NAMESPACE_STD
#if defined __USE_XOPEN2K || defined __USE_MISC
/* Reentrant version of `strerror'. If a temporary buffer is required, at
most BUFLEN bytes of BUF will be used.
This function is a possible cancellation points and therefore not
marked with __THROW. */
extern char *strerror_r (int __errnum, char *__buf, size_t __buflen);
most BUFLEN bytes of BUF will be used. */
extern char *strerror_r (int __errnum, char *__buf, size_t __buflen) __THROW;
#endif
/* We define this function always since `bzero' is sometimes needed when

View File

@ -19,8 +19,12 @@
02111-1307 USA. */
/* By default we have none. Map the name to the normal functions. */
#define open_not_cancel(name, flags, mode...) \
__libc_open (name, flags, ##mode)
#define open_not_cancel(name, flags, mode) \
__libc_open (name, flags, mode)
#define open_not_cancel_2(name, flags) \
__libc_open (name, flags)
#define close_not_cancel(fd) \
__close (fd)
#define close_not_cancel_no_status(fd) \
(void) __close (fd)
#define read_not_cancel(fd, buf, n) \
@ -29,3 +33,5 @@
__write (fd, buf, n)
#define writev_not_cancel_no_status(fd, iov, n) \
(void) __writev (fd, iov, n)
# define waitpid_not_cancel(pid, stat_loc, options) \
__waitpid (pid, stat_loc, options)

View File

@ -72,10 +72,8 @@ struct _Unwind_Context
_Unwind_Word args_size;
};
#ifndef _LIBC
/* Byte size of every register managed by these routines. */
static unsigned char dwarf_reg_size_table[DWARF_FRAME_REGISTERS];
#endif
/* The result of interpreting the frame unwind info for a frame.
@ -184,7 +182,7 @@ _Unwind_GetGR (struct _Unwind_Context *context, int index)
_Unwind_Word
_Unwind_GetCFA (struct _Unwind_Context *context)
{
return (_Unwind_Word) context->cfa;
return (_Unwind_Ptr) context->cfa;
}
/* Overwrite the saved value for register REG in CONTEXT with VAL. */
@ -323,7 +321,7 @@ extract_cie_info (struct dwarf_cie *cie, struct _Unwind_Context *context,
return ret ? ret : p;
}
#ifndef _LIBC
/* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
onto the stack to start. */
@ -713,7 +711,7 @@ execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
/* Most things push a result value. */
if ((size_t) stack_elt >= sizeof(stack)/sizeof(*stack))
abort ();
stack[++stack_elt] = result;
stack[stack_elt++] = result;
no_push:;
}
@ -723,7 +721,7 @@ execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
abort ();
return stack[stack_elt];
}
#endif
/* Decode DWARF 2 call frame information. Takes pointers the
instruction sequence to decode, current register information and
@ -863,17 +861,17 @@ execute_cfa_program (const unsigned char *insn_ptr,
break;
case DW_CFA_def_cfa_expression:
insn_ptr = read_uleb128 (insn_ptr, &utmp);
fs->cfa_exp = insn_ptr;
fs->cfa_how = CFA_EXP;
insn_ptr = read_uleb128 (insn_ptr, &utmp);
insn_ptr += utmp;
break;
case DW_CFA_expression:
insn_ptr = read_uleb128 (insn_ptr, &reg);
insn_ptr = read_uleb128 (insn_ptr, &utmp);
fs->regs.reg[reg].how = REG_SAVED_EXP;
fs->regs.reg[reg].loc.exp = insn_ptr;
insn_ptr = read_uleb128 (insn_ptr, &utmp);
insn_ptr += utmp;
break;
@ -1061,8 +1059,6 @@ __frame_state_for (void *pc_target, struct frame_state *state_in)
return state_in;
}
#ifndef _LIBC
static void
uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
{
@ -1070,34 +1066,48 @@ uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
void *cfa;
long i;
#ifdef EH_RETURN_STACKADJ_RTX
/* Special handling here: Many machines do not use a frame pointer,
and track the CFA only through offsets from the stack pointer from
one frame to the next. In this case, the stack pointer is never
stored, so it has no saved address in the context. What we do
have is the CFA from the previous stack frame.
In very special situations (such as unwind info for signal return),
there may be location expressions that use the stack pointer as well.
Do this conditionally for one frame. This allows the unwind info
for one frame to save a copy of the stack pointer from the previous
frame, and be able to use much easier CFA mechanisms to do it.
Always zap the saved stack pointer value for the next frame; carrying
the value over from one frame to another doesn't make sense. */
_Unwind_Word tmp_sp;
if (!orig_context.reg[__builtin_dwarf_sp_column ()])
{
tmp_sp = (_Unwind_Ptr) context->cfa;
orig_context.reg[__builtin_dwarf_sp_column ()] = &tmp_sp;
}
context->reg[__builtin_dwarf_sp_column ()] = NULL;
#endif
/* Compute this frame's CFA. */
switch (fs->cfa_how)
{
case CFA_REG_OFFSET:
/* Special handling here: Many machines do not use a frame pointer,
and track the CFA only through offsets from the stack pointer from
one frame to the next. In this case, the stack pointer is never
stored, so it has no saved address in the context. What we do
have is the CFA from the previous stack frame. */
if (context->reg[fs->cfa_reg] == NULL)
cfa = context->cfa;
else
cfa = (void *) (_Unwind_Ptr) _Unwind_GetGR (context, fs->cfa_reg);
cfa = (void *) (_Unwind_Ptr) _Unwind_GetGR (&orig_context, fs->cfa_reg);
cfa += fs->cfa_offset;
break;
case CFA_EXP:
/* ??? No way of knowing what register number is the stack pointer
to do the same sort of handling as above. Assume that if the
CFA calculation is so complicated as to require a stack program
that this will not be a problem. */
{
const unsigned char *exp = fs->cfa_exp;
_Unwind_Word len;
exp = read_uleb128 (exp, &len);
cfa = (void *) (_Unwind_Ptr)
execute_stack_op (exp, exp + len, context, 0);
execute_stack_op (exp, exp + len, &orig_context, 0);
break;
}
@ -1112,12 +1122,15 @@ uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
{
case REG_UNSAVED:
break;
case REG_SAVED_OFFSET:
context->reg[i] = cfa + fs->regs.reg[i].loc.offset;
break;
case REG_SAVED_REG:
context->reg[i] = orig_context.reg[fs->regs.reg[i].loc.reg];
break;
case REG_SAVED_EXP:
{
const unsigned char *exp = fs->regs.reg[i].loc.exp;
@ -1169,6 +1182,7 @@ uw_init_context_1 (struct _Unwind_Context *context,
{
void *ra = __builtin_extract_return_addr (__builtin_return_address (0));
_Unwind_FrameState fs;
_Unwind_Word sp_slot;
memset (context, 0, sizeof (struct _Unwind_Context));
context->ra = ra;
@ -1177,9 +1191,10 @@ uw_init_context_1 (struct _Unwind_Context *context,
abort ();
/* Force the frame state to use the known cfa value. */
context->cfa = outer_cfa;
sp_slot = (_Unwind_Ptr) outer_cfa;
context->reg[__builtin_dwarf_sp_column ()] = &sp_slot;
fs.cfa_how = CFA_REG_OFFSET;
fs.cfa_reg = 0;
fs.cfa_reg = __builtin_dwarf_sp_column ();
fs.cfa_offset = 0;
uw_update_context_1 (context, &fs);
@ -1236,11 +1251,26 @@ uw_install_context_1 (struct _Unwind_Context *current,
memcpy (c, t, dwarf_reg_size_table[i]);
}
/* We adjust SP by the difference between CURRENT and TARGET's CFA. */
if (STACK_GROWS_DOWNWARD)
return target->cfa - current->cfa + target->args_size;
else
return current->cfa - target->cfa - target->args_size;
#ifdef EH_RETURN_STACKADJ_RTX
{
void *target_cfa;
/* If the last frame records a saved stack pointer, use it. */
if (target->reg[__builtin_dwarf_sp_column ()])
target_cfa = (void *)(_Unwind_Ptr)
_Unwind_GetGR (target, __builtin_dwarf_sp_column ());
else
target_cfa = target->cfa;
/* We adjust SP by the difference between CURRENT and TARGET's CFA. */
if (STACK_GROWS_DOWNWARD)
return target_cfa - current->cfa + target->args_size;
else
return current->cfa - target_cfa - target->args_size;
}
#else
return 0;
#endif
}
static inline _Unwind_Ptr
@ -1252,5 +1282,4 @@ uw_identify_context (struct _Unwind_Context *context)
#include "unwind.inc"
#endif /* _LIBC */
#endif /* !USING_SJLJ_EXCEPTIONS */

309
sysdeps/generic/unwind.inc Normal file
View File

@ -0,0 +1,309 @@
/* Exception handling and frame unwind runtime interface routines. -*- C -*-
Copyright (C) 2001 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GCC 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 General Public
License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 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 "@@@".
This file is included from unwind-dw2.c or unwind-ia64.c. */
/* Subroutine of _Unwind_RaiseException also invoked from _Unwind_Resume.
Unwind the stack calling the personality routine to find both the
exception handler and intermediary cleanup code. We'll only locate
the first such frame here. Cleanup code will call back into
_Unwind_Resume and we'll continue Phase 2 there. */
static _Unwind_Reason_Code
_Unwind_RaiseException_Phase2(struct _Unwind_Exception *exc,
struct _Unwind_Context *context)
{
_Unwind_Reason_Code code;
while (1)
{
_Unwind_FrameState fs;
int match_handler;
code = uw_frame_state_for (context, &fs);
/* Identify when we've reached the designated handler context. */
match_handler = (uw_identify_context (context) == exc->private_2
? _UA_HANDLER_FRAME : 0);
if (code != _URC_NO_REASON)
/* Some error encountered. Usually the unwinder doesn't
diagnose these and merely crashes. */
return _URC_FATAL_PHASE2_ERROR;
/* Unwind successful. Run the personality routine, if any. */
if (fs.personality)
{
code = (*fs.personality) (1, _UA_CLEANUP_PHASE | match_handler,
exc->exception_class, exc, context);
if (code == _URC_INSTALL_CONTEXT)
break;
if (code != _URC_CONTINUE_UNWIND)
return _URC_FATAL_PHASE2_ERROR;
}
/* Don't let us unwind past the handler context. */
if (match_handler)
abort ();
uw_update_context (context, &fs);
}
return code;
}
/* Raise an exception, passing along the given exception object. */
#ifndef _LIBC
_Unwind_Reason_Code
_Unwind_RaiseException(struct _Unwind_Exception *exc)
{
struct _Unwind_Context this_context, cur_context;
_Unwind_Reason_Code code;
/* Set up this_context to describe the current stack frame. */
uw_init_context (&this_context);
cur_context = this_context;
/* Phase 1: Search. Unwind the stack, calling the personality routine
with the _UA_SEARCH_PHASE flag set. Do not modify the stack yet. */
while (1)
{
_Unwind_FrameState fs;
/* Set up fs to describe the FDE for the caller of cur_context. The
first time through the loop, that means __cxa_throw. */
code = uw_frame_state_for (&cur_context, &fs);
if (code == _URC_END_OF_STACK)
/* Hit end of stack with no handler found. */
return _URC_END_OF_STACK;
if (code != _URC_NO_REASON)
/* Some error encountered. Ususally the unwinder doesn't
diagnose these and merely crashes. */
return _URC_FATAL_PHASE1_ERROR;
/* Unwind successful. Run the personality routine, if any. */
if (fs.personality)
{
code = (*fs.personality) (1, _UA_SEARCH_PHASE, exc->exception_class,
exc, &cur_context);
if (code == _URC_HANDLER_FOUND)
break;
else if (code != _URC_CONTINUE_UNWIND)
return _URC_FATAL_PHASE1_ERROR;
}
/* Update cur_context to describe the same frame as fs. */
uw_update_context (&cur_context, &fs);
}
/* Indicate to _Unwind_Resume and associated subroutines that this
is not a forced unwind. Further, note where we found a handler. */
exc->private_1 = 0;
exc->private_2 = uw_identify_context (&cur_context);
cur_context = this_context;
code = _Unwind_RaiseException_Phase2 (exc, &cur_context);
if (code != _URC_INSTALL_CONTEXT)
return code;
uw_install_context (&this_context, &cur_context);
}
#endif
/* Subroutine of _Unwind_ForcedUnwind also invoked from _Unwind_Resume. */
static _Unwind_Reason_Code
_Unwind_ForcedUnwind_Phase2(struct _Unwind_Exception *exc,
struct _Unwind_Context *context)
{
_Unwind_Stop_Fn stop = (_Unwind_Stop_Fn) (_Unwind_Ptr) exc->private_1;
void *stop_argument = (void *) (_Unwind_Ptr) exc->private_2;
_Unwind_Reason_Code code, stop_code;
while (1)
{
_Unwind_FrameState fs;
int action;
/* Set up fs to describe the FDE for the caller of cur_context. */
code = uw_frame_state_for (context, &fs);
if (code != _URC_NO_REASON && code != _URC_END_OF_STACK)
return _URC_FATAL_PHASE2_ERROR;
/* Unwind successful. */
action = _UA_FORCE_UNWIND | _UA_CLEANUP_PHASE;
if (code == _URC_END_OF_STACK)
action |= _UA_END_OF_STACK;
stop_code = (*stop) (1, action, exc->exception_class, exc,
context, stop_argument);
if (stop_code != _URC_NO_REASON)
return _URC_FATAL_PHASE2_ERROR;
/* Stop didn't want to do anything. Invoke the personality
handler, if applicable, to run cleanups. */
if (code == _URC_END_OF_STACK)
break;
if (fs.personality)
{
code = (*fs.personality) (1, _UA_FORCE_UNWIND | _UA_CLEANUP_PHASE,
exc->exception_class, exc, context);
if (code == _URC_INSTALL_CONTEXT)
break;
if (code != _URC_CONTINUE_UNWIND)
return _URC_FATAL_PHASE2_ERROR;
}
/* Update cur_context to describe the same frame as fs. */
uw_update_context (context, &fs);
}
return code;
}
/* Raise an exception for forced unwinding. */
#ifndef _LIBC
_Unwind_Reason_Code
_Unwind_ForcedUnwind (struct _Unwind_Exception *exc,
_Unwind_Stop_Fn stop, void * stop_argument)
{
struct _Unwind_Context this_context, cur_context;
_Unwind_Reason_Code code;
uw_init_context (&this_context);
cur_context = this_context;
exc->private_1 = (_Unwind_Ptr) stop;
exc->private_2 = (_Unwind_Ptr) stop_argument;
code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context);
if (code != _URC_INSTALL_CONTEXT)
return code;
uw_install_context (&this_context, &cur_context);
}
#endif
/* Resume propagation of an existing exception. This is used after
e.g. executing cleanup code, and not to implement rethrowing. */
void
_Unwind_Resume (struct _Unwind_Exception *exc)
{
struct _Unwind_Context this_context, cur_context;
_Unwind_Reason_Code code;
uw_init_context (&this_context);
cur_context = this_context;
/* Choose between continuing to process _Unwind_RaiseException
or _Unwind_ForcedUnwind. */
if (exc->private_1 == 0)
code = _Unwind_RaiseException_Phase2 (exc, &cur_context);
else
code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context);
if (code != _URC_INSTALL_CONTEXT)
abort ();
uw_install_context (&this_context, &cur_context);
}
/* Resume propagation of an FORCE_UNWIND exception, or to rethrow
a normal exception that was handled. */
#ifndef _LIBC
_Unwind_Reason_Code
_Unwind_Resume_or_Rethrow (struct _Unwind_Exception *exc)
{
struct _Unwind_Context this_context, cur_context;
_Unwind_Reason_Code code;
/* Choose between continuing to process _Unwind_RaiseException
or _Unwind_ForcedUnwind. */
if (exc->private_1 == 0)
return _Unwind_RaiseException (exc);
uw_init_context (&this_context);
cur_context = this_context;
code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context);
if (code != _URC_INSTALL_CONTEXT)
abort ();
uw_install_context (&this_context, &cur_context);
}
#endif
/* A convenience function that calls the exception_cleanup field. */
#ifndef _LIBC
void
_Unwind_DeleteException (struct _Unwind_Exception *exc)
{
if (exc->exception_cleanup)
(*exc->exception_cleanup) (_URC_FOREIGN_EXCEPTION_CAUGHT, exc);
}
#endif
/* Perform stack backtrace through unwind data. */
#ifndef _LIBC
_Unwind_Reason_Code
_Unwind_Backtrace(_Unwind_Trace_Fn trace, void * trace_argument)
{
struct _Unwind_Context context;
_Unwind_Reason_Code code;
uw_init_context (&context);
while (1)
{
_Unwind_FrameState fs;
/* Set up fs to describe the FDE for the caller of context. */
code = uw_frame_state_for (&context, &fs);
if (code != _URC_NO_REASON && code != _URC_END_OF_STACK)
return _URC_FATAL_PHASE1_ERROR;
/* Call trace function. */
if ((*trace) (&context, trace_argument) != _URC_NO_REASON)
return _URC_FATAL_PHASE1_ERROR;
/* We're done at end of stack. */
if (code == _URC_END_OF_STACK)
break;
/* Update context to describe the same frame as fs. */
uw_update_context (&context, &fs);
}
return code;
}
#endif

View File

@ -1,5 +1,5 @@
/* Guts of POSIX spawn interface. Generic POSIX.1 version.
Copyright (C) 2000,01,02 Free Software Foundation, Inc.
Copyright (C) 2000,01,02, 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
@ -25,6 +25,7 @@
#include <string.h>
#include <unistd.h>
#include "spawn_int.h"
#include <not-cancel.h>
/* The Unix standard contains a long explanation of the way to signal
@ -158,7 +159,7 @@ __spawni (pid_t *pid, const char *file,
switch (action->tag)
{
case spawn_do_close:
if (__close (action->action.close_action.fd) != 0)
if (close_not_cancel (action->action.close_action.fd) != 0)
/* Signal the error. */
_exit (SPAWN_ERROR);
break;

View File

@ -1,4 +1,5 @@
/* Copyright (C) 1991,1993,1995,1996,1998,2002 Free Software Foundation, Inc.
/* Copyright (C) 1991,1993,1995,1996,1998,2002,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
@ -22,6 +23,8 @@
#include <dirent.h>
#include <unistd.h>
#include <dirstream.h>
#include <not-cancel.h>
/* Close the directory stream DIRP.
Return 0 if successful, -1 if not. */
@ -46,6 +49,6 @@ __closedir (DIR *dirp)
free ((void *) dirp);
return __close (fd);
return close_not_cancel (fd);
}
weak_alias (__closedir, closedir)

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1991-1996,98,2000-2002 Free Software Foundation, Inc.
/* Copyright (C) 1991-1996,98,2000-2002, 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
@ -28,6 +28,8 @@
#include <stdio.h>
#include <dirstream.h>
#include <not-cancel.h>
/* opendir() must not accidentally open something other than a directory.
Some OS's have kernel support for that, some don't. In the worst
@ -50,11 +52,11 @@ static void
tryopen_o_directory (void)
{
int serrno = errno;
int x = __open ("/dev/null", O_RDONLY|O_NDELAY|O_DIRECTORY);
int x = open_not_cancel_2 ("/dev/null", O_RDONLY|O_NDELAY|O_DIRECTORY);
if (x >= 0)
{
__close (x);
close_not_cancel_no_status (x);
o_directory_works = -1;
}
else if (errno != ENOTDIR)
@ -110,7 +112,7 @@ __opendir (const char *name)
}
}
fd = __open64 (name, O_RDONLY|O_NDELAY|EXTRA_FLAGS);
fd = open_not_cancel_2 (name, O_RDONLY|O_NDELAY|EXTRA_FLAGS|O_LARGEFILE);
if (__builtin_expect (fd, 0) < 0)
return NULL;
@ -148,7 +150,7 @@ __opendir (const char *name)
lose:
{
save_errno = errno;
(void) __close (fd);
close_not_cancel_no_status (fd);
__set_errno (save_errno);
return NULL;
}

View File

@ -24,7 +24,7 @@ getuid - getuid Ei: __getuid getuid
ioctl - ioctl i:iiI __ioctl ioctl
kill - kill i:ii __kill kill
link - link i:ss __link link
lseek - lseek Ci:iii __libc_lseek __lseek lseek
lseek - lseek i:iii __libc_lseek __lseek lseek
mkdir - mkdir i:si __mkdir mkdir
open - open Ci:siv __libc_open __open open
profil - profil i:piii __profil profil

View File

@ -351,7 +351,7 @@
it was introduced in 2.6.0-test1 which unfortunately cannot be
distinguished from 2.6.0. */
#if (__LINUX_KERNEL_VERSION >= 132427 && defined __i386__) \
|| (__LINUX_KERNEL_VERSION >= 132609 && defined __alpha__) \
|| (__LINUX_KERNEL_VERSION >= 132609 && defined __alpha__)
# define __ASSUME_TGKILL 1
#endif

View File

@ -1,5 +1,5 @@
/* Long-long seek operation.
Copyright (C) 1996,1997,1998,1999,2000,2002 Free Software Foundation, Inc.
Copyright (C) 1996-2000,2002,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
@ -20,7 +20,7 @@
#include <errno.h>
#include <sys/types.h>
#include <sysdep-cancel.h>
#include <sysdep.h>
#include <sys/syscall.h>
extern int __syscall__llseek (int fd, off_t offset_hi, off_t offset_lo,
@ -34,20 +34,9 @@ __llseek (int fd, loff_t offset, int whence)
{
loff_t retval;
if (SINGLE_THREAD_P)
return (loff_t) (INLINE_SYSCALL (_llseek, 5, fd, (off_t) (offset >> 32),
(off_t) (offset & 0xffffffff),
__ptrvalue (&retval), whence) ?: retval);
int oldtype = LIBC_CANCEL_ASYNC ();
int result = (loff_t) INLINE_SYSCALL (_llseek, 5, fd, (off_t) (offset >> 32),
(off_t) (offset & 0xffffffff),
__ptrvalue (&retval), whence);
LIBC_CANCEL_RESET (oldtype);
return (loff_t) result ?: retval;
return (loff_t) (INLINE_SYSCALL (_llseek, 5, fd, (off_t) (offset >> 32),
(off_t) (offset & 0xffffffff),
__ptrvalue (&retval), whence) ?: retval);
}
weak_alias (__llseek, llseek)
strong_alias (__llseek, __libc_lseek64)

View File

@ -21,33 +21,36 @@
#include <sysdep.h>
/* Uncancelable open. */
#ifdef INLINE_SYSCALL
# define open_not_cancel(name, flags, mode) \
#define open_not_cancel(name, flags, mode) \
INLINE_SYSCALL (open, 3, (const char *) (name), (flags), (mode))
#endif
#define open_not_cancel_2(name, flags) \
INLINE_SYSCALL (open, 2, (const char *) (name), (flags))
/* Uncancelable close. */
#ifdef INLINE_SYSCALL
# define close_not_cancel_no_status(fd) \
#define close_not_cancel(fd) \
INLINE_SYSCALL (close, 1, fd)
#define close_not_cancel_no_status(fd) \
(void) ({ INTERNAL_SYSCALL_DECL (err); \
INTERNAL_SYSCALL (close, err, 1, (fd)); })
#endif
/* Uncancelable read. */
#ifdef INLINE_SYSCALL
# define read_not_cancel(fd, buf, n) \
#define read_not_cancel(fd, buf, n) \
INLINE_SYSCALL (read, 3, (fd), (buf), (n))
#endif
/* Uncancelable write. */
#ifdef INLINE_SYSCALL
# define write_not_cancel(fd, buf, n) \
#define write_not_cancel(fd, buf, n) \
INLINE_SYSCALL (write, 3, (fd), (buf), (n))
#endif
/* Uncancelable writev. */
#ifdef INLINE_SYSCALL
# define writev_not_cancel_no_status(fd, iov, n) \
#define writev_not_cancel_no_status(fd, iov, n) \
(void) ({ INTERNAL_SYSCALL_DECL (err); \
INTERNAL_SYSCALL (writev, err, 3, (fd), (iov), (n)); })
/* Uncancelable waitpid. */
#ifdef __NR_waitpid
# define waitpid_not_cancel(pid, stat_loc, options) \
INLINE_SYSCALL (waitpid, 3, pid, stat_loc, options)
#else
# define waitpid_not_cancel(pid, stat_loc, options) \
INLINE_SYSCALL (wait4, 4, pid, stat_loc, options, NULL)
#endif

View File

@ -44,6 +44,7 @@ tz-cflags = -DTZDIR='"$(zonedir)"' \
CFLAGS-tzfile.c = $(tz-cflags)
CFLAGS-tzset.c = $(tz-cflags)
CFLAGS-getdate.c = -fexceptions
# Don't warn about Y2k problem in strftime format string.
CFLAGS-test_time.c = -Wno-format