+1998-06-07 13:32 Ulrich Drepper <drepper@cygnus.com>
+
+ * libc.map: Add _dl_profile.
+ * elf/dl-reloc.c (_dl_relocate_object): Take extra argument, pass
+ this to ELF_DYNAMIC_RELOCATE.
+ Always allocate array for relocation result if LD_PROFILE is defined.
+ * elf/ldsodefs.h: Adjust prototypes.
+ * elf/dl-open.c (_dl_open): Call relocation function with extra
+ argument.
+ * elf/rtld.c: Likewise.
+ * elf/dl-profile.c (_dl_mcount): Don't mark as internal function.
+ Correct loop condition.
+ * elf/dynamic-link.h: Don't examine _dl_profile variable, pass
+ consider_profile to runtime setup function.
+ * sysdeps/i386/dl-machine.h (elf_machine_runtime_setup): Use
+ _dl_runtime_profile for all shared objects if LD_PROFILE is defined.
+
+ * elf/dl-support.c: Define __libc_stack_end.
+ * elf/rtld.c: Likewise.
+ * sysdeps/generic/libc-start.c: Store last stack address in
+ __libc_stack_end.
+ * sysdeps/i386/dl-machine.h (_dl_start_user): Store stack address.
+ * sysdeps/i386/elf/start.s: Call __libc_start_main with extra argument.
+
+ * elf/elf.h: Include <features.h>, not <sys/cdefs.h>.
+ Include <stdint.h>, not <inttypes.h>.
+
+ * elf/sprof.c: Implement flat profiling.
+
+ * libio/fgetc.c: Call _IO_cleanup_region_end with 0 and call
+ _IO_funlockfile explicitly.
+ * libio/fileops.c: Likewise.
+ * libio/fputc.c: Likewise.
+ * libio/freopen.c: Likewise.
+ * libio/freopen64.c: Likewise.
+ * libio/fseek.c: Likewise.
+ * libio/fseeko.c: Likewise.
+ * libio/fseeko64.c: Likewise.
+ * libio/ftello.c: Likewise.
+ * libio/ftello64.c: Likewise.
+ * libio/getc.c: Likewise.
+ * libio/getchar.c: Likewise.
+ * libio/iofclose.c: Likewise.
+ * libio/iofflush.c: Likewise.
+ * libio/iofgetpos.c: Likewise.
+ * libio/iofgetpos64.c: Likewise.
+ * libio/iofgets.c: Likewise.
+ * libio/iofputs.c: Likewise.
+ * libio/iofread.c: Likewise.
+ * libio/iofsetpos.c: Likewise.
+ * libio/iofsetpos64.c: Likewise.
+ * libio/ioftell.c: Likewise.
+ * libio/iofwrite.c: Likewise.
+ * libio/iogetdelim.c: Likewise.
+ * libio/iogets.c: Likewise.
+ * libio/ioputs.c: Likewise.
+ * libio/ioseekoff.c: Likewise.
+ * libio/ioseekpos.c: Likewise.
+ * libio/iosetbuffer.c: Likewise.
+ * libio/iosetvbuf.c: Likewise.
+ * libio/ioungetc.c: Likewise.
+ * libio/iovsprintf.c: Likewise.
+ * libio/iovsscanf.c: Likewise.
+ * libio/oldfileops.c: Likewise.
+ * libio/oldiofclose.c: Likewise.
+ * libio/peekc.c: Likewise.
+ * libio/putc.c: Likewise.
+ * libio/putchar.c: Likewise.
+ * libio/rewind.c: Likewise.
+
+ * malloc/mtrace.c: Pretty print.
+
+ * misc/mntent.h (struct mentent): Make string elements const char *.
+
+ * nis/nis_printf.c: Optimize I/O a little bit.
+
+ * signal/Makefile (distribute): Add sigset-cvt-mask.h.
+ * sysdeps/generic/sigset-cvt-mask.h: New file.
+ * sysdeps/unix/sysv/linux/sigset-cvt-mask.h: New file.
+ * sysdeps/unix/sysv/sysv4/sigset-cvt-mask.h: New file.
+ * sysdeps/posix/sigvec.c: Rewrite the use definitions from
+ sigset-cvt-mask.h to do the dirty work.
+ Patches by Joe Keane.
+
+ * sysdeps/posix/mkstemp.c: Save one precious byte of rodata.
+
+ * sysdeps/unix/sysv/linux/i386/sysdep.h: Rewrite PSEUDO etc to make
+ syscall_error label in case of PIC anonymous.
+ * sysdeps/unix/sysv/linux/i386/i686/sysdep.h: Likewise.
+ * sysdeps/unix/sysv/linux/i386/clone.S: Adapt for this change.
+ * sysdeps/unix/sysv/linux/i386/mmap.S: Adapt for this change.
+ * sysdeps/unix/sysv/linux/i386/s_pread64.S: Adapt for this change.
+ * sysdeps/unix/sysv/linux/i386/s_pwrite64.S: Adapt for this change.
+ * sysdeps/unix/sysv/linux/i386/socket.S: Adapt for this change.
+ * sysdeps/unix/sysv/linux/i386/syscall.S: Adapt for this change.
+
1998-06-05 Ulrich Drepper <drepper@cygnus.com>
* sunrpc/xdr_rec.c (xdrrec_create): Add cast for *_ops array since
done
EOF
cat >> $CONFIG_STATUS <<EOF
-echo '$config_vars' >> config.make; test -d bits || mkdir bits
+config_vars='$config_vars'
EOF
cat >> $CONFIG_STATUS <<\EOF
+case $CONFIG_FILES in *config.make*)
+echo "$config_vars" >> config.make;;
+esac
+test -d bits || mkdir bits
exit 0
EOF
chmod +x $CONFIG_STATUS
asm ("" : "=r" (reloc) : "0" (reloc));
(*reloc) (l, _dl_object_relocation_scope (l),
- (mode & RTLD_BINDING_MASK) == RTLD_LAZY);
+ ((mode & RTLD_BINDING_MASK) == RTLD_LAZY
+ || _dl_profile != NULL), _dl_profile != NULL);
*_dl_global_scope_end = NULL;
}
void
-internal_function
_dl_mcount (ElfW(Addr) frompc, ElfW(Addr) selfpc)
{
uint16_t *topcindex;
/* We have to look through the chain of arcs whether there is already
an entry for our arc. */
- while (fromp->here->from_pc == frompc)
+ while (fromp->here->from_pc != frompc)
{
if (fromp->link != 0)
do
data[newarc].self_pc = selfpc;
data[newarc].count = 0;
fromp->link = 0;
-
- narcs++;
+ ++narcs;
break;
}
void
internal_function
-_dl_relocate_object (struct link_map *l, struct link_map *scope[], int lazy)
+_dl_relocate_object (struct link_map *l, struct link_map *scope[], int lazy,
+ int consider_profiling)
{
if (l->l_relocated)
return;
l->l_name, (flags)))
#include "dynamic-link.h"
- ELF_DYNAMIC_RELOCATE (l, lazy, 1);
+ ELF_DYNAMIC_RELOCATE (l, lazy, consider_profiling);
- if (_dl_profile_map == l)
+ if (_dl_profile != NULL)
{
/* Allocate the array which will contain the already found
relocations. */
/* Names of shared object for which the RPATHs should be ignored. */
const char *_dl_inhibit_rpath;
+/* This is the address of the last stack address ever used. */
+void *__libc_stack_end;
+
static void non_dynamic_init (void) __attribute__ ((unused));
/* Inline functions for dynamic linking.
- Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1997, 1998 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
to inline functions containing inlines themselves. */
#define ELF_DYNAMIC_RELOCATE(map, lazy, consider_profile) \
do { \
- int profile = (consider_profile && _dl_profile != NULL \
- && _dl_name_match_p (_dl_profile, (map))); \
- int edr_lazy = elf_machine_runtime_setup ((map), (lazy) || profile, \
- profile); \
+ int edr_lazy = elf_machine_runtime_setup ((map), (lazy), \
+ (consider_profile)); \
ELF_DYNAMIC_DO_REL ((map), edr_lazy); \
ELF_DYNAMIC_DO_RELA ((map), edr_lazy); \
} while (0)
/* This file defines standard ELF types, structures, and macros.
- Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ian Lance Taylor <ian@cygnus.com>.
#ifndef _ELF_H
#define _ELF_H 1
-#include <sys/cdefs.h>
+#include <features.h>
__BEGIN_DECLS
/* Standard ELF types. */
-#include <inttypes.h>
+#include <stdint.h>
/* Type for a 16-bit quantity. */
typedef uint16_t Elf32_Half;
If LAZY is nonzero, don't relocate its PLT. */
extern void _dl_relocate_object (struct link_map *map,
struct link_map *scope[],
- int lazy) internal_function;
+ int lazy, int consider_profiling)
+ internal_function;
/* Check the version dependencies of all objects available through
MAP. If VERBOSE print some more diagnostics. */
internal_function;
/* The actual functions used to keep book on the calls. */
-extern void _dl_mcount (ElfW(Addr) frompc, ElfW(Addr) selfpc)
- internal_function;
+extern void _dl_mcount (ElfW(Addr) frompc, ElfW(Addr) selfpc);
/* Show the members of the auxiliary array passed up from the kernel. */
never be called. */
int _dl_starting_up;
+/* This variable contains the lowest stack address ever used. */
+void *__libc_stack_end;
+
static void dl_main (const ElfW(Phdr) *phdr,
ElfW(Half) phent,
ElfW(Addr) *user_entry);
struct relocate_args *args = (struct relocate_args *) a;
_dl_relocate_object (args->l, _dl_object_relocation_scope (args->l),
- args->lazy);
+ args->lazy, 0);
}
static void
know that because it is self-contained). */
struct link_map *l;
+ int consider_profiling = _dl_profile != NULL;
+
+ /* If we are profiling we also must do lazy reloaction. */
+ lazy |= consider_profiling;
+
l = _dl_loaded;
while (l->l_next)
l = l->l_next;
{
if (l != &_dl_rtld_map)
{
- _dl_relocate_object (l, _dl_object_relocation_scope (l), lazy);
+ _dl_relocate_object (l, _dl_object_relocation_scope (l), lazy,
+ consider_profiling);
*_dl_global_scope_end = NULL;
}
l = l->l_prev;
if (_dl_rtld_map.l_opencount > 0)
/* There was an explicit ref to the dynamic linker as a shared lib.
Re-relocate ourselves with user-controlled symbol definitions. */
- _dl_relocate_object (&_dl_rtld_map, &_dl_default_scope[2], 0);
+ _dl_relocate_object (&_dl_rtld_map, &_dl_default_scope[2], 0, 0);
}
{
static void print_version (FILE *stream, struct argp_state *state);
void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
-#define OPT_COUNT_TOTAL 1
-#define OPT_TEST 2
+#define OPT_TEST 1
/* Definitions of arguments for argp functions. */
static const struct argp_option options[] =
{
{ NULL, 0, NULL, 0, N_("Output selection:") },
- { "count-total", OPT_COUNT_TOTAL, NULL, 0,
- N_("print number of invocations for each function") },
+ { "flat-profile", 'p', NULL, 0,
+ N_("generate flat profile with counts and ticks") },
+
{ "test", OPT_TEST, NULL, OPTION_HIDDEN, NULL },
{ NULL, 0, NULL, 0, NULL }
};
static enum
{
NONE = 0,
- COUNT_TOTAL
+ FLAT_MODE = 1 << 0,
+
+ DEFAULT_MODE = FLAT_MODE
} mode;
/* If nonzero the total number of invocations of a function is emitted. */
size_t size;
uintmax_t ticks;
+ uintmax_t calls;
};
off_t size;
char *hist;
+ struct gmon_hist_hdr *hist_hdr;
uint16_t *kcount;
uint32_t narcs; /* Number of arcs in toset. */
struct here_cg_arc_record *data;
static struct profdata *load_profdata (const char *name, struct shobj *shobj);
static void unload_profdata (struct profdata *profdata);
static void count_total_ticks (struct shobj *shobj, struct profdata *profdata);
+static void count_calls (struct shobj *shobj, struct profdata *profdata);
static void read_symbols (struct shobj *shobj);
+static void generate_flat_profile (struct profdata *profdata);
int
read_symbols (shobj_handle);
+ /* Count the ticks. */
+ count_total_ticks (shobj_handle, profdata_handle);
+
+ /* Count the calls. */
+ count_calls (shobj_handle, profdata_handle);
+
+ /* If no mode is specified fall back to the default mode. */
+ if (mode == NONE)
+ mode = DEFAULT_MODE;
+
/* Do some work. */
- switch (mode)
- {
- case COUNT_TOTAL:
- count_total_ticks (shobj_handle, profdata_handle);
- {
- size_t n;
- for (n = 0; n < symidx; ++n)
- if (sortsym[n]->ticks != 0)
- printf ("Name: %-30s, Ticks: %" PRIdMAX "\n", sortsym[n]->name,
- sortsym[n]->ticks);
- printf ("Total ticks: %" PRIdMAX "\n", total_ticks);
- }
- break;
- case NONE:
- /* Do nothing. */
- break;
- default:
- assert (! "Internal error");
- }
+ if (mode & FLAT_MODE)
+ generate_flat_profile (profdata_handle);
/* Free the resources. */
unload_shobj (shobj_handle);
{
switch (key)
{
- case OPT_COUNT_TOTAL:
- mode = COUNT_TOTAL;
- break;
case OPT_TEST:
do_test = 1;
break;
/* Pointer to data after the header. */
result->hist = (char *) ((struct gmon_hdr *) addr + 1);
+ result->hist_hdr = (struct gmon_hist_hdr *) ((char *) result->hist
+ + sizeof (uint32_t));
result->kcount = (uint16_t *) ((char *) result->hist + sizeof (uint32_t)
+ sizeof (struct gmon_hist_hdr));
*(char **) hist_hdr.high_pc = (char *) shobj->highpc - shobj->map->l_addr;
if (do_test)
printf ("low_pc = %p\nhigh_pc = %p\n",
- hist_hdr.low_pc, hist_hdr.high_pc);
+ *(char **) hist_hdr.low_pc, *(char **) hist_hdr.high_pc);
*(int32_t *) hist_hdr.hist_size = shobj->kcountsize / sizeof (HISTCOUNTER);
*(int32_t *) hist_hdr.prof_rate = __profile_frequency ();
strncpy (hist_hdr.dimen, "seconds", sizeof (hist_hdr.dimen));
/* Test whether the header of the profiling data is ok. */
if (memcmp (addr, &gmon_hdr, sizeof (struct gmon_hdr)) != 0
|| *(uint32_t *) result->hist != GMON_TAG_TIME_HIST
- || memcmp (result->hist + sizeof (uint32_t), &hist_hdr,
+ || memcmp (result->hist_hdr, &hist_hdr,
sizeof (struct gmon_hist_hdr)) != 0
|| narcsp[-1] != GMON_TAG_CG_ARC)
{
}
+static struct known_symbol *
+find_symbol (uintptr_t addr)
+{
+ size_t sidx = 0;
+
+ while (sidx < symidx)
+ {
+ uintptr_t start = sortsym[sidx]->addr;
+ uintptr_t end = start + sortsym[sidx]->size;
+
+ if (addr >= start && addr < end)
+ return sortsym[sidx];
+
+ if (addr < start)
+ break;
+
+ ++sidx;
+ }
+
+ return NULL;
+}
+
+
+static void
+count_calls (struct shobj *shobj, struct profdata *profdata)
+{
+ struct here_cg_arc_record *data = profdata->data;
+ uint32_t narcs = profdata->narcs;
+ uint32_t cnt;
+
+ for (cnt = 0; cnt < narcs; ++cnt)
+ {
+ uintptr_t here = data[cnt].self_pc;
+ struct known_symbol *symbol;
+
+ /* Find the symbol for this address. */
+ symbol = find_symbol (here);
+ if (symbol != NULL)
+ symbol->calls += data[cnt].count;
+ }
+}
+
+
static int
symorder (const void *o1, const void *o2)
{
|| ELFW(ST_TYPE) (sym->st_info) == STT_NOTYPE)
&& sym->st_size != 0)
{
+ struct known_symbol **existp;
struct known_symbol *newsym
= (struct known_symbol *) obstack_alloc (&shobj->ob_sym,
sizeof (*newsym));
newsym->addr = sym->st_value;
newsym->size = sym->st_size;
newsym->ticks = 0;
-
- tsearch (newsym, &symroot, symorder);
- ++n;
+ newsym->calls = 0;
+
+ existp = tfind (newsym, &symroot, symorder);
+ if (existp == NULL)
+ {
+ /* New function. */
+ tsearch (newsym, &symroot, symorder);
+ ++n;
+ }
+ else
+ {
+ /* The function is already defined. See whether we have
+ a better name here. */
+ if ((*existp)->name[0] == '_' && newsym->name[0] != '_')
+ *existp = newsym;
+ else
+ /* We don't need the allocated memory. */
+ obstack_free (&shobj->ob_sym, newsym);
+ }
}
}
else
dynamic symbol table!! */
while ((void *) symtab < (void *) strtab)
{
- if (/*(ELFW(ST_TYPE)(symtab->st_info) == STT_FUNC
- || ELFW(ST_TYPE)(symtab->st_info) == STT_NOTYPE)
- &&*/ symtab->st_size != 0)
+ if ((ELFW(ST_TYPE)(symtab->st_info) == STT_FUNC
+ || ELFW(ST_TYPE)(symtab->st_info) == STT_NOTYPE)
+ && symtab->st_size != 0)
{
struct known_symbol *newsym;
+ struct known_symbol **existp;
newsym =
(struct known_symbol *) obstack_alloc (&shobj->ob_sym,
newsym->size = symtab->st_size;
newsym->ticks = 0;
- tsearch (newsym, &symroot, symorder);
- ++n;
+ existp = tfind (newsym, &symroot, symorder);
+ if (existp == NULL)
+ {
+ /* New function. */
+ tsearch (newsym, &symroot, symorder);
+ ++n;
+ }
+ else
+ {
+ /* The function is already defined. See whether we have
+ a better name here. */
+ if ((*existp)->name[0] == '_' && newsym->name[0] != '_')
+ *existp = newsym;
+ else
+ /* We don't need the allocated memory. */
+ obstack_free (&shobj->ob_sym, newsym);
+ }
}
}
twalk (symroot, printsym);
}
+
+
+static int
+countorder (const void *p1, const void *p2)
+{
+ struct known_symbol *s1 = (struct known_symbol *) p1;
+ struct known_symbol *s2 = (struct known_symbol *) p2;
+
+ if (s1->ticks != s2->ticks)
+ return (int) (s2->ticks - s1->ticks);
+
+ if (s1->calls != s2->calls)
+ return (int) (s2->calls - s1->calls);
+
+ return strcmp (s1->name, s2->name);
+}
+
+
+static double tick_unit;
+static uintmax_t cumu_ticks;
+
+static void
+printflat (const void *node, VISIT value, int level)
+{
+ if (value == leaf || value == postorder)
+ {
+ struct known_symbol *s = *(struct known_symbol **) node;
+
+ cumu_ticks += s->ticks;
+
+ printf ("%6.2f%10.2f%9.2f%9" PRIdMAX "%9.2f%9.2f %s\n",
+ total_ticks ? (100.0 * s->ticks) / total_ticks : 0.0,
+ tick_unit * cumu_ticks,
+ tick_unit * s->ticks,
+ s->calls,
+ s->calls ? (s->ticks * 1000000) * tick_unit / s->calls : 0,
+ 0.0, /* FIXME: don't know about called functions. */
+ s->name);
+ }
+}
+
+
+/* ARGUSED */
+static void
+freenoop (void *p)
+{
+}
+
+
+static void
+generate_flat_profile (struct profdata *profdata)
+{
+ size_t n;
+ void *data = NULL;
+
+ tick_unit = 1.0 / *(uint32_t *) profdata->hist_hdr->prof_rate;
+
+ printf ("Flat profile:\n\n"
+ "Each sample counts as %g %s.\n",
+ tick_unit, profdata->hist_hdr->dimen);
+ fputs (" % cumulative self self total\n"
+ " time seconds seconds calls us/call us/call name\n",
+ stdout);
+
+ for (n = 0; n < symidx; ++n)
+ if (sortsym[n]->calls != 0 || sortsym[n]->ticks != 0)
+ tsearch (sortsym[n], &data, countorder);
+
+ twalk (data, printflat);
+
+ tdestroy (data, freenoop);
+}
# global variables
_IO_2_1_stdin_; _IO_2_1_stdout_; _IO_2_1_stderr_;
__gconv_alias_db; __gconv_nmodules; __gconv_modules_db;
+ _dl_profile;
# This is for ix86 only.
_fp_hw;
__syscall_rt_sigqueueinfo;
__xstat64; __fxstat64; __lxstat64;
__pread64; __pwrite64;
+ __backtrace; __backtracesyms;
# helper functions
__libc_current_sigrtmin; __libc_current_sigrtmax; __libc_allocate_rtsig;
authdes_create; authdes_getucred; authdes_pk_create;
+ # b*
+ backtrace; backtracesyms;
+
# c*
capget; capset; cbc_crypt; creat64;
-/* Copyright (C) 1993, 1995, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
_IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
_IO_flockfile (fp);
result = _IO_getc_unlocked (fp);
- _IO_cleanup_region_end (1);
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
return result;
}
fp->_offset = _IO_pos_BAD;
/* FIXME: Cleanup - can this be shared? */
/* setg(base(), ptr, ptr); */
- _IO_cleanup_region_end (1);
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
return retval;
}
-/* Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
_IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
_IO_flockfile (fp);
result = _IO_putc_unlocked (c, fp);
- _IO_cleanup_region_end (1);
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
return result;
}
else
#endif
result = _IO_freopen (filename, mode, fp);
- _IO_cleanup_region_end (1);
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
return result;
}
-/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
_IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
_IO_flockfile (fp);
result = _IO_freopen64 (filename, mode, fp);
- _IO_cleanup_region_end (1);
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
return result;
#else
__set_errno (ENOSYS);
-/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
_IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
_IO_flockfile (fp);
result = _IO_fseek (fp, offset, whence);
- _IO_cleanup_region_end (1);
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
return result;
}
-/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
_IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
_IO_flockfile (fp);
result = _IO_fseek (fp, offset, whence);
- _IO_cleanup_region_end (1);
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
return result;
}
-/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
_IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
_IO_flockfile (fp);
result = _IO_fseek (fp, offset, whence);
- _IO_cleanup_region_end (1);
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
return result;
#else
__set_errno (ENOSYS);
-/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
_IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
_IO_flockfile (fp);
pos = _IO_seekoff (fp, 0, _IO_seek_cur, 0);
- _IO_cleanup_region_end (1);
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
if (pos == _IO_pos_BAD)
{
#ifdef EIO
-/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
_IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
_IO_flockfile (fp);
pos = _IO_seekoff (fp, 0, _IO_seek_cur, 0);
- _IO_cleanup_region_end (1);
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
if (pos == _IO_pos_BAD)
{
#ifdef EIO
-/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
_IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
_IO_flockfile (fp);
result = _IO_getc_unlocked (fp);
- _IO_cleanup_region_end (1);
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
return result;
}
-/* Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
{
int result;
_IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, stdin);
- _IO_flockfile (stdin);
+ _IO_flockfile (_IO_stdin);
result = _IO_getc_unlocked (stdin);
- _IO_cleanup_region_end (1);
+ _IO_funlockfile (_IO_stdin);
+ _IO_cleanup_region_end (0);
return result;
}
else
status = fp->_flags & _IO_ERR_SEEN ? -1 : 0;
_IO_FINISH (fp);
- _IO_cleanup_region_end (1);
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
if (fp != _IO_stdin && fp != _IO_stdout && fp != _IO_stderr)
{
fp->_IO_file_flags = 0;
-/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
_IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
_IO_flockfile (fp);
result = _IO_SYNC (fp) ? EOF : 0;
- _IO_cleanup_region_end (1);
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
return result;
}
}
-/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
_IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
_IO_flockfile (fp);
pos = _IO_seekoff (fp, 0, _IO_seek_cur, 0);
- _IO_cleanup_region_end (1);
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
if (pos == _IO_pos_BAD)
{
/* ANSI explicitly requires setting errno to a positive value on
-/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
_IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
_IO_flockfile (fp);
pos = _IO_seekoff (fp, 0, _IO_seek_cur, 0);
- _IO_cleanup_region_end (1);
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
if (pos == _IO_pos_BAD)
{
/* ANSI explicitly requires setting errno to a positive value on
-/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
result = buf;
}
fp->_IO_file_flags |= old_error;
- _IO_cleanup_region_end (1);
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
return result;
}
-/* Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
result = EOF;
else
result = 1;
- _IO_cleanup_region_end (1);
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
return result;
}
-/* Copyright (C) 1993, 1995, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
_IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
_IO_flockfile (fp);
bytes_read = _IO_sgetn (fp, (char *) buf, bytes_requested);
- _IO_cleanup_region_end (1);
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
return bytes_requested == bytes_read ? count : bytes_read / size;
}
-/* Copyright (C) 1993, 1995, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
}
else
result = 0;
- _IO_cleanup_region_end (1);
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
return result;
}
-/* Copyright (C) 1993, 1995, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
}
else
result = 0;
- _IO_cleanup_region_end (1);
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
return result;
#else
__set_errno (ENOSYS);
-/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
_IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
_IO_flockfile (fp);
pos = _IO_seekoff (fp, 0, _IO_seek_cur, 0);
- _IO_cleanup_region_end (1);
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
if (pos == _IO_pos_BAD)
{
#ifdef EIO
-/* Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
_IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
_IO_flockfile (fp);
written = _IO_sputn (fp, (const char *) buf, request);
- _IO_cleanup_region_end (1);
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
/* Many traditional implementations return 0 if size==0 && count > 0,
but ANSI requires us to return count in this case. */
if (written == request)
-/* Copyright (C) 1994, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1994, 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
result = cur_len;
unlock_return:
- _IO_cleanup_region_end (1);
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
return result;
}
-/* Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
buf[count] = 0;
retval = buf;
unlock_return:
- _IO_cleanup_region_end (1);
+ _IO_funlockfile (_IO_stdin);
+ _IO_cleanup_region_end (0);
return retval;
}
-/* Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
result = len + 1;
else
result = EOF;
- _IO_cleanup_region_end (1);
+ _IO_funlockfile (_IO_stdout);
+ _IO_cleanup_region_end (0);
return result;
}
-/* Copyright (C) 1993, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
}
retval = _IO_SEEKOFF (fp, offset, dir, mode);
- _IO_cleanup_region_end (1);
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
return retval;
}
-/* Copyright (C) 1993, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
_IO_free_backup_area (fp);
retval = _IO_SEEKPOS (fp, pos, mode);
- _IO_cleanup_region_end (1);
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
return retval;
}
-/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
if (!buf)
size = 0;
(void) _IO_SETBUF (fp, buf, size);
- _IO_cleanup_region_end (1);
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
}
#ifdef weak_alias
-/* Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
}
result = _IO_SETBUF (fp, buf, size) == NULL ? EOF : 0;
unlock_return:
- _IO_cleanup_region_end (1);
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
return result;
}
-/* Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
_IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
_IO_flockfile (fp);
result = _IO_sputbackc (fp, (unsigned char) c);
- _IO_cleanup_region_end (1);
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
return result;
}
-/* Copyright (C) 1993, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
_IO_init (&sf._sbf._f, 0);
_IO_JUMPS (&sf._sbf._f) = &_IO_str_jumps;
_IO_str_init_static (&sf._sbf._f, string, -1, string);
- _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, &sf);
- _IO_flockfile (&sf._sbf._f);
ret = _IO_vfprintf (&sf._sbf._f, format, args);
_IO_putc_unlocked ('\0', &sf._sbf._f);
- _IO_cleanup_region_end (1);
return ret;
}
_IO_init (&sf._sbf._f, 0);
_IO_JUMPS (&sf._sbf._f) = &_IO_str_jumps;
_IO_str_init_static (&sf._sbf._f, (char*)string, 0, NULL);
- _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, &sf);
- _IO_flockfile (&sf._sbf._f);
ret = _IO_vfscanf (&sf._sbf._f, format, args, NULL);
- _IO_cleanup_region_end (1);
return ret;
}
fp->_old_offset = _IO_pos_BAD;
/* FIXME: Cleanup - can this be shared? */
/* setg(base(), ptr, ptr); */
- _IO_cleanup_region_end (1);
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
return retval;
}
-/* Copyright (C) 1993, 1995, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
else
status = fp->_flags & _IO_ERR_SEEN ? -1 : 0;
_IO_FINISH (fp);
- _IO_cleanup_region_end (1);
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
if (fp != _IO_stdin && fp != _IO_stdout && fp != _IO_stderr)
{
fp->_IO_file_flags = 0;
-/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
_IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
_IO_flockfile (fp);
result = _IO_peekc_unlocked (fp);
- _IO_cleanup_region_end (1);
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
return result;
}
-/* Copyright (C) 1991, 1995, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1995, 1996, 1997, 1998 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
_IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
_IO_flockfile (fp);
result = _IO_putc_unlocked (c, fp);
- _IO_cleanup_region_end (1);
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
return result;
}
-/* Copyright (C) 1991, 1995, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1995, 1996, 1997, 1998 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
_IO_stdout);
_IO_flockfile (_IO_stdout);
result = _IO_putc_unlocked (c, _IO_stdout);
- _IO_cleanup_region_end (1);
+ _IO_funlockfile (_IO_stdout);
+ _IO_cleanup_region_end (0);
return result;
}
-/* Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
_IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
_IO_flockfile (fp);
_IO_rewind (fp);
- _IO_cleanup_region_end (1);
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
}
+1998-06-07 13:47 Ulrich Drepper <drepper@cygnus.com>
+
+ * sysdeps/pthread/bits/libc-lock.h: Optimize cleanup handlers a bit.
+
1998-06-03 Andreas Jaeger <aj@arthur.rhein-neckar.de>
* attr.c: Correct typo.
/* libc-internal interface for mutex locks. LinuxThreads version.
- Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 1998 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
/* Start critical region with cleanup. */
#define __libc_cleanup_region_start(FCT, ARG) \
{ struct _pthread_cleanup_buffer _buffer; \
- if (_pthread_cleanup_push_defer != NULL) { \
+ int _avail = _pthread_cleanup_push_defer != NULL; \
+ if (_avail) { \
_pthread_cleanup_push_defer (&_buffer, (FCT), (ARG)); \
}
/* End critical region with cleanup. */
#define __libc_cleanup_region_end(DOIT) \
- if (_pthread_cleanup_push_defer != NULL) { \
+ if (_avail) { \
_pthread_cleanup_pop_restore (&_buffer, (DOIT)); \
} \
}
tr_where (caller);
/* We could be printing a NULL here; that's OK. */
- fprintf (mallstream, "+ %p %#lx\n", hdr, (unsigned long)size);
+ fprintf (mallstream, "+ %p %#lx\n", hdr, (unsigned long int) size);
if (hdr == mallwatch)
tr_break ();
tr_where (caller);
if (hdr == NULL)
/* Failed realloc. */
- fprintf (mallstream, "! %p %#lx\n", ptr, (unsigned long)size);
+ fprintf (mallstream, "! %p %#lx\n", ptr, (unsigned long int) size);
else if (ptr == NULL)
- fprintf (mallstream, "+ %p %#lx\n", hdr, (unsigned long)size);
+ fprintf (mallstream, "+ %p %#lx\n", hdr, (unsigned long int) size);
else
- fprintf (mallstream, "< %p\n> %p %#lx\n", ptr, hdr, (unsigned long)size);
+ fprintf (mallstream, "< %p\n> %p %#lx\n", ptr, hdr,
+ (unsigned long int) size);
if (hdr == mallwatch)
tr_break ();
/* Utilities for reading/writing fstab, mtab, etc.
- Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1997, 1998 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
/* Structure describing a mount table entry. */
struct mntent
{
- char *mnt_fsname; /* Device or server for filesystem. */
- char *mnt_dir; /* Directory mounted on. */
- char *mnt_type; /* Type of filesystem: ufs, nfs, etc. */
- char *mnt_opts; /* Comma-separated options for fs. */
+ const char *mnt_fsname; /* Device or server for filesystem. */
+ const char *mnt_dir; /* Directory mounted on. */
+ const char *mnt_type; /* Type of filesystem: ufs, nfs, etc. */
+ const char *mnt_opts; /* Comma-separated options for fs. */
int mnt_freq; /* Dump frequency (in days). */
int mnt_passno; /* Pass number for `fsck'. */
};
-/* Copyright (c) 1997 Free Software Foundation, Inc.
+/* Copyright (c) 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
acc >>= 8;
}
- printf ("%s", result);
+ fputs (result, stdout);
}
void
fputs (_("None.\n"), stdout);
break;
case NIS_PK_DH:
- fprintf (stdout, _("Diffie-Hellmann (%d bits)\n"),
- (sptr->pkey.n_len - 1) * 4);
+ printf (_("Diffie-Hellmann (%d bits)\n"),
+ (sptr->pkey.n_len - 1) * 4);
/* sptr->pkey.n_len counts the last 0, too */
break;
case NIS_PK_RSA:
- fprintf (stdout, _("RSA (%d bits)\n"),
- (sptr->pkey.n_len - 1) * 4);
+ printf (_("RSA (%d bits)\n"), (sptr->pkey.n_len - 1) * 4);
break;
case NIS_PK_KERB:
fputs (_("Kerberos.\n"), stdout);
break;
default:
- fprintf (stdout, _("Unknown (type = %d, bits = %d)\n"),
- sptr->key_type, (sptr->pkey.n_len - 1) * 4);
+ printf (_("Unknown (type = %d, bits = %d)\n"), sptr->key_type,
+ (sptr->pkey.n_len - 1) * 4);
break;
}
if (ptr->uaddr != NULL && strlen (ptr->uaddr) > 0)
printf ("%s\n", ptr->uaddr);
else
- printf ("-\n");
+ fputs ("-\n", stdout);
ptr++;
}
}
{
nis_print_rights (ptr->oa_rights);
printf (_("\tType : %s\n"), nis_nstype2str (ptr->oa_otype));
- printf (_("\tAccess rights: "));
+ fputs (_("\tAccess rights: "), stdout);
nis_print_rights (ptr->oa_rights);
fputs ("\n", stdout);
ptr++;
tests := tst-signal
-distribute := sigsetops.h testrtsig.h
+distribute := sigsetops.h testrtsig.h sigset-cvt-mask.h
include ../Rules
all_done:
/* Unlock the stream. */
- __libc_cleanup_region_end (1);
+#ifdef USE_IN_LIBIO
+ _IO_funlockfile (s);
+#else
+ __funlockfile (s);
+#endif
+ __libc_cleanup_region_end (0);
return done;
}
# define LOCK_STREAM(S) \
__libc_cleanup_region_start ((void (*) (void *)) &_IO_funlockfile, (S)); \
_IO_flockfile (S)
-# define UNLOCK_STREAM __libc_cleanup_region_end (1)
+# define UNLOCK_STREAM(S) \
+ _IO_funlockfile (S); \
+ __libc_cleanup_region_end (0)
#else
# define ungetc(c, s) ((void) (c != EOF && --read_in), ungetc (c, s))
# define inchar() (c == EOF ? EOF \
# define flockfile(S) /* nothing */
# define funlockfile(S) /* nothing */
# define LOCK_STREAM(S)
-# define UNLOCK_STREAM
+# define UNLOCK_STREAM(S)
#else
# define LOCK_STREAM(S) \
__libc_cleanup_region_start (&__funlockfile, (S)); \
__flockfile (S)
-# define UNLOCK_STREAM __libc_cleanup_region_end (1)
+# define UNLOCK_STREAM(S) \
+ __funlockfile (S); \
+ __libc_cleanup_region_end (0)
#endif
#endif
}
/* Unlock stream. */
- UNLOCK_STREAM;
+ UNLOCK_STREAM (s);
return done;
}
extern int _dl_starting_up;
weak_extern (_dl_starting_up)
extern int __libc_multiple_libcs;
+extern void *__libc_stack_end;
int
__libc_start_main (int (*main) (int, char **, char **), int argc,
char **argv, void (*init) (void), void (*fini) (void),
- void (*rtld_fini) (void))
+ void (*rtld_fini) (void), void *stack_end)
{
#ifndef PIC
/* The next variable is only here to work around a bug in gcc <= 2.7.2.2.
int *dummy_addr = &_dl_starting_up;
__libc_multiple_libcs = dummy_addr && !_dl_starting_up;
+
+ /* Store the lowest stack address. */
+ __libc_stack_end = stack_end;
#endif
/* Set the global _environ variable correctly. */
--- /dev/null
+/* Convert between lowlevel sigmask and libc representation of sigset_t.
+ Generic version.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Joe Keane <jgk@jgk.org>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library 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. */
+
+#define sigset_set_old_mask(set, mask) (*(set) = (unsigned long int) (mask))
+
+#define sigset_get_old_mask(set, mask) ((mask) = (unsigned int) *(set))
if (profile)
{
got[2] = (Elf32_Addr) &_dl_runtime_profile;
- /* Say that we really want profiling and the timers are started. */
- _dl_profile_map = l;
+
+ if (_dl_name_match_p (_dl_profile, l))
+ /* This is the object we are looking for. Say that we really
+ want profiling and the timers are started. */
+ _dl_profile_map = l;
}
else
/* This function will get called to fix up the GOT entry indicated by
call 0f\n\
0: popl %ebx\n\
addl $_GLOBAL_OFFSET_TABLE_+[.-0b], %ebx\n\
+ # Store the highest stack address\n\
+ movl %esp,__libc_stack_end@GOT(%ebx)\n\
# See if we were run as a command with the executable file\n\
# name as an extra leading argument.\n\
movl _dl_skip_args@GOT(%ebx), %eax\n\
boundary to avoid penalties from misaligned accesses. Thanks
to Edward Seidl <seidl@janed.com> for pointing this out. */
andl $0xfffffff8, %esp
+
+ /* Provide the highest stack address to the user code (for stacks
+ which grow downwards). */
+ pushl %esp
+
pushl %edx /* Push address of the shared library
termination function. */
mkstemp (template)
char *template;
{
- static const char letters[]
+ static const char letters[62]
= "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
static uint64_t value;
struct timeval tv;
-/* Copyright (C) 1991, 92, 94, 95, 96, 97 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 92, 94, 95, 96, 97, 98 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
#include <errno.h>
#include <stddef.h>
+/* Include macros to convert between `sigset_t' and old-style mask. */
+#include "sigset-cvt-mask.h"
/* We use a wrapper handler to support SV_RESETHAND. */
-
-static __sighandler_t wrapped_handlers[NSIG];
-static sigset_t wrapped_masks[NSIG];
-
-static void wrapper_handler __P ((int sig));
-static inline int convert_mask __P ((sigset_t *set, const int mask));
-
-static void
-wrapper_handler (sig)
- int sig;
+struct sigvec_wrapper_data
{
- int save;
- struct sigaction act;
+ __sighandler_t sw_handler;
+ unsigned int sw_mask;
+};
- act.sa_handler = SIG_DFL;
- act.sa_mask = wrapped_masks[sig];
- act.sa_flags = 0;
- save = errno;
- (void) __sigaction (sig, &act, (struct sigaction *) NULL);
- __set_errno (save);
+static void sigvec_wrapper_handler __P ((int sig));
- (*wrapped_handlers[sig]) (sig);
-}
+static struct sigvec_wrapper_data sigvec_wrapper_data[NSIG];
-static inline int
-convert_mask (set, mask)
- sigset_t *set;
- const int mask;
-{
- register int sig;
-
- if (sizeof (*set) == sizeof (mask))
- *(int *) set = mask;
- else if (sizeof (*set) == sizeof (unsigned long int))
- *(unsigned long int *) set = (unsigned int) mask;
- else
- {
- if (__sigemptyset (set) < 0)
- return -1;
-
- for (sig = 1; sig < NSIG && sig <= sizeof (mask) * 8; ++sig)
- if ((mask & sigmask (sig)) && __sigaddset (set, sig) < 0)
- return -1;
- }
-
- return 0;
-}
/* If VEC is non-NULL, set the handler for SIG to the `sv_handler' member
of VEC. The signals in `sv_mask' will be blocked while the handler runs.
n = NULL;
else
{
- n = &new;
- n->sa_handler = vec->sv_handler;
- if (convert_mask (&n->sa_mask, vec->sv_mask) < 0)
- return -1;
- n->sa_flags = 0;
-
- if (vec->sv_flags & SV_ONSTACK)
+ __sighandler_t handler;
+ unsigned int mask;
+ unsigned int sv_flags;
+ unsigned int sa_flags;
+
+ handler = vec->sv_handler;
+ mask = vec->sv_mask;
+ sv_flags = vec->sv_flags;
+ sa_flags = 0;
+ if (sv_flags & SV_ONSTACK)
{
#ifdef SA_ONSTACK
- n->sa_flags |= SA_ONSTACK;
+ sa_flags |= SA_ONSTACK;
#else
__set_errno (ENOSYS);
return -1;
#endif
}
#ifdef SA_RESTART
- if (!(vec->sv_flags & SV_INTERRUPT))
- n->sa_flags |= SA_RESTART;
+ if (!(sv_flags & SV_INTERRUPT))
+ sa_flags |= SA_RESTART;
#endif
+ n = &new;
+ new.sa_handler = handler;
+ sigset_set_old_mask (&new.sa_mask, mask);
+ new.sa_flags = sa_flags;
}
if (__sigaction (sig, n, &old) < 0)
}
else
{
+ __sighandler_t handler;
+ unsigned int mask;
+ struct sigvec_wrapper_data *data;
struct sigaction wrapper;
- wrapper.sa_handler = wrapper_handler;
- wrapped_handlers[sig] = vec->sv_handler;
- if (convert_mask (&wrapped_masks[sig], vec->sv_mask) < 0)
- return -1;
+ handler = vec->sv_handler;
+ mask = (unsigned int)vec->sv_mask;
+ data = &sigvec_wrapper_data[sig];
+ wrapper.sa_handler = sigvec_wrapper_handler;
+ /* FIXME: should we set wrapper.sa_mask, wrapper.sa_flags?? */
+ data->sw_handler = handler;
+ data->sw_mask = mask;
if (__sigaction (sig, &wrapper, &old) < 0)
return -1;
if (ovec != NULL)
{
- register int i;
- int mask = 0;
-
- if (sizeof (int) == sizeof (sigset_t))
- mask = *(int *) &old.sa_mask;
- else if (sizeof (unsigned long int) == sizeof (sigset_t))
- mask = *(unsigned long int *) &old.sa_mask;
- else
- for (i = 1; i < NSIG && i <= sizeof (mask) * 8; ++i)
- if (__sigismember (&old.sa_mask, i))
- mask |= sigmask (i);
-
- ovec->sv_mask = mask;
- ovec->sv_flags = 0;
+ __sighandler_t handler;
+ unsigned int sv_flags;
+ unsigned int sa_flags;
+ unsigned int mask;
+
+ handler = old.sa_handler;
+ sv_flags = 0;
+ sa_flags = old.sa_flags;
+ if (handler == sigvec_wrapper_handler)
+ {
+ handler = sigvec_wrapper_data[sig].sw_handler;
+ /* should we use data->sw_mask?? */
+ sv_flags |= SV_RESETHAND;
+ }
+ sigset_get_old_mask (&old.sa_mask, mask);
#ifdef SA_ONSTACK
- if (old.sa_flags & SA_ONSTACK)
- ovec->sv_flags |= SV_ONSTACK;
+ if (sa_flags & SA_ONSTACK)
+ sv_flags |= SV_ONSTACK;
#endif
#ifdef SA_RESTART
- if (!(old.sa_flags & SA_RESTART))
+ if (!(sa_flags & SA_RESTART))
#endif
- ovec->sv_flags |= SV_INTERRUPT;
- if (old.sa_handler == wrapper_handler)
- {
- ovec->sv_flags |= SV_RESETHAND;
- ovec->sv_handler = wrapped_handlers[sig];
- }
- else
- ovec->sv_handler = old.sa_handler;
+ sv_flags |= SV_INTERRUPT;
+ ovec->sv_handler = handler;
+ ovec->sv_mask = (int)mask;
+ ovec->sv_flags = (int)sv_flags;
}
return 0;
}
weak_alias (__sigvec, sigvec)
+
+
+static void
+sigvec_wrapper_handler (sig)
+ int sig;
+{
+ struct sigvec_wrapper_data *data;
+ unsigned int mask;
+ struct sigaction act;
+ int save;
+ __sighandler_t handler;
+
+ data = &sigvec_wrapper_data[sig];
+ mask = data->sw_mask;
+ act.sa_handler = SIG_DFL;
+ sigset_set_old_mask (&act.sa_mask, mask);
+ act.sa_flags = 0;
+ save = errno;
+ handler = data->sw_handler;
+ (void) __sigaction (sig, &act, (struct sigaction *) NULL);
+ __set_errno (save);
+ (*handler) (sig);
+}
movl $-EINVAL,%eax
movl 4(%esp),%ecx /* no NULL function pointers */
testl %ecx,%ecx
- jz syscall_error
+ jz SYSCALL_ERROR_LABEL
movl 8(%esp),%ecx /* no NULL stack pointers */
testl %ecx,%ecx
- jz syscall_error
+ jz SYSCALL_ERROR_LABEL
/* Insert the argument onto the new stack. */
subl $8,%ecx
popl %ebx
test %eax,%eax
- jl syscall_error
+ jl SYSCALL_ERROR_LABEL
jz thread_start
L(pseudo_end):
/* Store (- %eax) into errno through the GOT. */
# ifdef _LIBC_REENTRANT
# define SYSCALL_ERROR_HANDLER \
- .type syscall_error,@function; \
-0:movl (%esp),%ebx; \
+1:movl (%esp),%ebx; \
ret; \
-syscall_error: \
- pushl %ebx; \
- call 0b; \
+0:pushl %ebx; \
+ call 1b; \
addl $_GLOBAL_OFFSET_TABLE_, %ebx; \
xorl %edx, %edx; \
subl %eax, %edx; \
popl %ebx; \
movl %ecx, (%eax); \
movl $-1, %eax; \
- jmp L(pseudo_end); \
- .size syscall_error,.-syscall_error;
+ jmp L(pseudo_end);
/* A quick note: it is assumed that the call to `__errno_location' does
not modify the stack! */
# else
# define SYSCALL_ERROR_HANDLER \
.type syscall_error,@function; \
-0:movl (%esp),%ecx; \
+1:movl (%esp),%ecx; \
ret; \
-syscall_error: \
- call 0b; \
+0:call 1b; \
addl $_GLOBAL_OFFSET_TABLE_, %ecx; \
xorl %edx, %edx; \
subl %eax, %edx; \
movl errno@GOT(%ecx), %ecx; \
movl %edx, (%ecx); \
movl $-1, %eax; \
- jmp L(pseudo_end); \
- .size syscall_error,.-syscall_error;
+ jmp L(pseudo_end);
# endif /* _LIBC_REENTRANT */
#endif /* PIC */
/* If 0 > %eax > -4096 there was an error. */
cmpl $-4096, %eax
- ja syscall_error
+ ja SYSCALL_ERROR_LABEL
/* Successful; return the syscall's value. */
L(pseudo_end):
movl 0x10(%esp,1),%ebx
/* Load syscall number into %eax. */
movl $SYS_ify(pread), %eax
- int $0x80 /* Do the system call. */
- POPARGS_5 /* Restore register contents. */
- cmpl $-4095, %eax /* Check %eax for error. */
- jae syscall_error /* Jump to error handler if error. */
+ int $0x80 /* Do the system call. */
+ POPARGS_5 /* Restore register contents. */
+ cmpl $-4095, %eax /* Check %eax for error. */
+ jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */
#endif
L(pseudo_end):
ret /* Return to caller. */
movl 0x10(%esp,1),%ebx
/* Load syscall number into %eax. */
movl $SYS_ify(pwrite), %eax
- int $0x80 /* Do the system call. */
- POPARGS_5 /* Restore register contents. */
- cmpl $-4095, %eax /* Check %eax for error. */
- jae syscall_error /* Jump to error handler if error. */
+ int $0x80 /* Do the system call. */
+ POPARGS_5 /* Restore register contents. */
+ cmpl $-4095, %eax /* Check %eax for error. */
+ jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */
#endif
L(pseudo_end):
ret /* Return to caller. */
/* %eax is < 0 if there was an error. */
cmpl $-125, %eax
- jae syscall_error
+ jae SYSCALL_ERROR_LABEL
/* Successful; return the syscall's value. */
L(pseudo_end):
int $0x80 /* Do the system call. */
POPARGS_5 /* Restore register contents. */
cmpl $-4095, %eax /* Check %eax for error. */
- jae syscall_error /* Jump to error handler if error. */
+ jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */
L(pseudo_end):
ret /* Return to caller. */
is a real error number. Linus said he will make sure the no syscall
returns a value in -1 .. -4095 as a valid result so we can savely
test with -4095. */
+
+/* We don't want the label for the error handle to be global when we define
+ it here. */
+#ifdef PIC
+# define SYSCALL_ERROR_LABEL 0f
+#else
+# define SYSCALL_ERROR_LABEL syscall_error
+#endif
+
#undef PSEUDO
#define PSEUDO(name, syscall_name, args) \
.text; \
ENTRY (name) \
DO_CALL (args, syscall_name); \
cmpl $-4095, %eax; \
- jae syscall_error; \
+ jae SYSCALL_ERROR_LABEL; \
L(pseudo_end):
#undef PSEUDO_END
/* Store (- %eax) into errno through the GOT. */
#ifdef _LIBC_REENTRANT
#define SYSCALL_ERROR_HANDLER \
- .type syscall_error,@function; \
-syscall_error: \
- pushl %ebx; \
- call 0f; \
-0:popl %ebx; \
+0:pushl %ebx; \
+ call 1f; \
+1:popl %ebx; \
xorl %edx, %edx; \
- addl $_GLOBAL_OFFSET_TABLE_+[.-0b], %ebx; \
+ addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx; \
subl %eax, %edx; \
pushl %edx; \
call __errno_location@PLT; \
popl %ebx; \
movl %ecx, (%eax); \
movl $-1, %eax; \
- jmp L(pseudo_end); \
- .size syscall_error,.-syscall_error;
+ jmp L(pseudo_end);
/* A quick note: it is assumed that the call to `__errno_location' does
not modify the stack! */
#else
#define SYSCALL_ERROR_HANDLER \
- .type syscall_error,@function; \
-syscall_error: \
- call 0f; \
-0:popl %ecx; \
+0:call 1f; \
+1:popl %ecx; \
xorl %edx, %edx; \
- addl $_GLOBAL_OFFSET_TABLE_+[.-0b], %ecx; \
+ addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx; \
subl %eax, %edx; \
movl errno@GOT(%ecx), %ecx; \
movl %edx, (%ecx); \
movl $-1, %eax; \
- jmp L(pseudo_end); \
- .size syscall_error,.-syscall_error;
+ jmp L(pseudo_end);
#endif /* _LIBC_REENTRANT */
#endif /* PIC */
--- /dev/null
+/* Convert between lowlevel sigmask and libc representation of sigset_t.
+ Linux version.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Joe Keane <jgk@jgk.org>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library 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. */
+
+#define sigset_set_old_mask(set, mask) \
+ do { \
+ unsigned long int *__ptr; \
+ int __cnt; \
+ __ptr = &(set)->__val[0]; \
+ *__ptr++ = (unsigned long int) (mask); \
+ __cnt = _SIGSET_NWORDS - 2; \
+ do \
+ *__ptr++ = 0ul; \
+ while (--__cnt >= 0); \
+ } while (0)
+
+#define sigset_get_old_mask(set, mask) \
+ ((mask) = (unsigned int) (set)->__val[0])
--- /dev/null
+/* Convert between lowlevel sigmask and libc representation of sigset_t.
+ SysVr4 version.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Joe Keane <jgk@jgk.org>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library 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. */
+
+#define sigset_set_old_mask(set, mask) \
+ do { \
+ unsigned long int *__ptr; \
+ __ptr = &(set)->__sigbits[0]; \
+ __ptr[0] = (mask); \
+ __ptr[1] = 0ul; \
+ __ptr[2] = 0ul; \
+ __ptr[3] = 0ul; \
+ } while (0)
+
+#define sigset_get_old_mask(set, mask) \
+ ((mask) = (unsigned int) (set)->__sigbits[0])