From 5ae9d168f66cc6b40f74cfb4a8f2631fc1df6a2a Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Fri, 21 Mar 1997 20:00:48 +0000 Subject: Update. 1997-03-21 20:55 Ulrich Drepper * sysdeps/generic/machine-gmon.h: Update copyright. * sysdeps/i386/Makefile [$(subdir)=gmon] (sysdep_routines): Add i386-mcount. * sysdeps/i386/dl-machine.h [PROF] (_dl_runtime_resolve): Don't use regparam mechanism for call of `fixup' call. * sysdeps/i386/Dist: New file. * sysdeps/i386/i386-mcount.S: New file. `mcount' entry point. * sysdeps/i386/machine-gmon.h: New file. i386 specific version of gmon definitions. 1997-03-20 13:39 Andreas Jaeger * stdlib/tst-strtol.c (main): Save the value of errno since printf may modify it, use the saved errno everywhere. * stdlib/tst-strtod.c (main): Likewise. 1997-03-21 05:54 Ulrich Drepper * posix/glob.c (glob): Fix completely broken handling of GLOB_BRACE and partly broken handling of GLOB_TILDE. Reported by Dennis Henriksen . 1997-03-20 20:22 Ulrich Drepper * sysdeps/unix/sysv/linux/readv.c: Don't emulate readv with small UIO_FASTIOV value by multiple readv calls since we need atomicity. * sysdeps/unix/sysv/linux/writev.c: Likewise. Reported by Matthis Urlichs. 1997-03-20 04:34 Roland McGrath * sysdeps/unix/sysv/linux/i386/sysdep.S (CALL_MCOUNT): Clear this macro so ENTRY(__syscall_error) doesn't insert a call to _mcount, which clobbers %eax. * Makeconfig [$(elf)=yes] (+prector, +postctor): New variables for crtbegin.o/crtend.o, using gcc to find them. (+link): Use them. 1997-03-20 00:06 Richard Henderson * gmon/sys/gmon.h: Revert the bulk of the 960930 changes, as they affect the alignment, and therefore the end padding of the structs. Reported by David Mosberger . * gmon.c: Declare the variables with aligned tags to compensate. Use __writev instead of write for the I/O. * misc/sys/uio.h: Declare __writev and __readv. * sysdeps/posix/readv.c: Rename and alias readv to __readv. * sysdeps/posix/writev.c: Likewise for writev. * sysdeps/stub/readv.c: Likewise. * sysdeps/stub/writev.c: Likewise. * sysdeps/unix/syscalls.list: Likewise. * sysdeps/unix/sysv/linux/readv.c: Likewise. * sysdeps/unix/sysv/linux/writev.c: Likewise. * stdlib/testdiv.c: Exit with error status when we have an error. * sysdeps/alpha/div.S: Initialize `quotient' and `mask'. * sysdeps/alpha/ldiv.S: Likewise. * sysdeps/unix/sysv/linux/alpha/ioperm.c: Include ctype.h for isdigit. 1997-03-20 14:51 Ulrich Drepper * nis/nis_file.c: Unify error handling. 1997-03-19 18:36 Thorsten Kukuk * nis/nis_file.c (writeColdStartFile): Fix typo. * nis/nis_free.c (nis_free_endpoints): Use unsigned int. * nis/nis_free.c (nis_free_servers): Likewise. * nis/rpcsvc/nislib.h: Likewise. * sunrpc/rpc/netdb.h: Add setrpcent and endrpcent prototypes. --- ChangeLog | 78 +++++++++ FAQ | 2 +- Makeconfig | 6 +- gmon/gmon.c | 94 +++++++---- gmon/sys/gmon_out.h | 48 +++--- misc/sys/uio.h | 6 +- nis/nis_file.c | 18 +- nis/nis_free.c | 4 +- nis/rpcsvc/nislib.h | 4 +- posix/glob.c | 294 +++++++++++++++++++++------------ stdlib/testdiv.c | 12 +- stdlib/tst-strtod.c | 33 ++-- stdlib/tst-strtol.c | 13 +- sunrpc/rpc/netdb.h | 2 + sysdeps/alpha/div.S | 21 ++- sysdeps/alpha/ldiv.S | 19 +-- sysdeps/generic/machine-gmon.h | 34 ++-- sysdeps/i386/Dist | 2 + sysdeps/i386/Makefile | 4 + sysdeps/i386/dl-machine.h | 32 +++- sysdeps/i386/i386-mcount.S | 65 ++++++++ sysdeps/i386/machine-gmon.h | 41 +++++ sysdeps/posix/readv.c | 9 +- sysdeps/posix/writev.c | 9 +- sysdeps/stub/readv.c | 31 ++-- sysdeps/stub/writev.c | 31 ++-- sysdeps/unix/syscalls.list | 4 +- sysdeps/unix/sysv/linux/alpha/ioperm.c | 1 + sysdeps/unix/sysv/linux/i386/sysdep.S | 5 +- sysdeps/unix/sysv/linux/readv.c | 32 ++-- sysdeps/unix/sysv/linux/writev.c | 31 ++-- 31 files changed, 668 insertions(+), 317 deletions(-) create mode 100644 sysdeps/i386/Dist create mode 100644 sysdeps/i386/i386-mcount.S create mode 100644 sysdeps/i386/machine-gmon.h diff --git a/ChangeLog b/ChangeLog index df79015bbd..57b1588e66 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,81 @@ +1997-03-21 20:55 Ulrich Drepper + + * sysdeps/generic/machine-gmon.h: Update copyright. + + * sysdeps/i386/Makefile [$(subdir)=gmon] (sysdep_routines): Add + i386-mcount. + * sysdeps/i386/dl-machine.h [PROF] (_dl_runtime_resolve): Don't + use regparam mechanism for call of `fixup' call. + * sysdeps/i386/Dist: New file. + * sysdeps/i386/i386-mcount.S: New file. `mcount' entry point. + * sysdeps/i386/machine-gmon.h: New file. i386 specific version + of gmon definitions. + +1997-03-20 13:39 Andreas Jaeger + + * stdlib/tst-strtol.c (main): Save the value of errno since printf + may modify it, use the saved errno everywhere. + * stdlib/tst-strtod.c (main): Likewise. + +1997-03-21 05:54 Ulrich Drepper + + * posix/glob.c (glob): Fix completely broken handling of + GLOB_BRACE and partly broken handling of GLOB_TILDE. + Reported by Dennis Henriksen . + +1997-03-20 20:22 Ulrich Drepper + + * sysdeps/unix/sysv/linux/readv.c: Don't emulate readv with small + UIO_FASTIOV value by multiple readv calls since we need atomicity. + * sysdeps/unix/sysv/linux/writev.c: Likewise. + Reported by Matthis Urlichs. + +1997-03-20 04:34 Roland McGrath + + * sysdeps/unix/sysv/linux/i386/sysdep.S (CALL_MCOUNT): Clear this + macro so ENTRY(__syscall_error) doesn't insert a call to _mcount, + which clobbers %eax. + + * Makeconfig [$(elf)=yes] (+prector, +postctor): New variables for + crtbegin.o/crtend.o, using gcc to find them. + (+link): Use them. + +1997-03-20 00:06 Richard Henderson + + * gmon/sys/gmon.h: Revert the bulk of the 960930 changes, as they + affect the alignment, and therefore the end padding of the structs. + Reported by David Mosberger . + * gmon.c: Declare the variables with aligned tags to compensate. + Use __writev instead of write for the I/O. + + * misc/sys/uio.h: Declare __writev and __readv. + * sysdeps/posix/readv.c: Rename and alias readv to __readv. + * sysdeps/posix/writev.c: Likewise for writev. + * sysdeps/stub/readv.c: Likewise. + * sysdeps/stub/writev.c: Likewise. + * sysdeps/unix/syscalls.list: Likewise. + * sysdeps/unix/sysv/linux/readv.c: Likewise. + * sysdeps/unix/sysv/linux/writev.c: Likewise. + + * stdlib/testdiv.c: Exit with error status when we have an error. + * sysdeps/alpha/div.S: Initialize `quotient' and `mask'. + * sysdeps/alpha/ldiv.S: Likewise. + + * sysdeps/unix/sysv/linux/alpha/ioperm.c: Include ctype.h for isdigit. + +1997-03-20 14:51 Ulrich Drepper + + * nis/nis_file.c: Unify error handling. + +1997-03-19 18:36 Thorsten Kukuk + + * nis/nis_file.c (writeColdStartFile): Fix typo. + * nis/nis_free.c (nis_free_endpoints): Use unsigned int. + * nis/nis_free.c (nis_free_servers): Likewise. + * nis/rpcsvc/nislib.h: Likewise. + + * sunrpc/rpc/netdb.h: Add setrpcent and endrpcent prototypes. + 1997-03-20 06:07 Ulrich Drepper * sysdeps/powerpc/dl-machine.h: Fix typo in last change. diff --git a/FAQ b/FAQ index c7d6445ea6..f8a638fd3b 100644 --- a/FAQ +++ b/FAQ @@ -609,7 +609,7 @@ e.g. i486-linux. # GNU libc version 2 does not supply these; # we want them from GCC. - extra_parts="crtbegin.o crtend.o" -+ extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS..o" ++ extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" ;; i[3456]86-go32-msdos | i[3456]86-*-go32) cpu_type=i386 diff --git a/Makeconfig b/Makeconfig index 10bca6018a..38437d4dd2 100644 --- a/Makeconfig +++ b/Makeconfig @@ -320,10 +320,10 @@ endif ifndef +link +link = $(CC) -nostdlib -nostartfiles -o $@ \ $(sysdep-LDFLAGS) $(config-LDFLAGS) $(LDFLAGS) \ - $(addprefix $(csu-objpfx),start.o) $(+preinit) \ + $(addprefix $(csu-objpfx),start.o) $(+preinit) $(+prector) \ $(filter-out $(addprefix $(csu-objpfx),start.o) $(+preinit) \ $(link-extra-libs) $(common-objpfx)libc% $(+postinit),$^) \ - $(link-extra-libs) $(link-libc) $(+postinit) + $(link-extra-libs) $(link-libc) $(+postctor) $(+postinit) endif ifndef config-LDFLAGS ifeq (yes,$(build-shared)) @@ -374,6 +374,8 @@ endif ifeq ($(elf),yes) +preinit = $(addprefix $(csu-objpfx),crti.o) +postinit = $(addprefix $(csu-objpfx),crtn.o) ++prector = `$(CC) --print-file-name=crtbegin.o` ++postctor = `$(CC) --print-file-name=crtend.o` endif csu-objpfx = $(common-objpfx)csu/ elf-objpfx = $(common-objpfx)elf/ diff --git a/gmon/gmon.c b/gmon/gmon.c index 6dc4cb5998..e00b339367 100644 --- a/gmon/gmon.c +++ b/gmon/gmon.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -165,21 +166,26 @@ static void write_hist (fd) int fd; { - const u_char tag = GMON_TAG_TIME_HIST; - struct gmon_hist_hdr thdr; + u_char tag = GMON_TAG_TIME_HIST; + struct gmon_hist_hdr thdr __attribute__ ((aligned (__alignof__ (char *)))); if (_gmonparam.kcountsize > 0) { - thdr.low_pc = _gmonparam.lowpc; - thdr.high_pc = _gmonparam.highpc; - thdr.hist_size = _gmonparam.kcountsize / sizeof(HISTCOUNTER); - thdr.prof_rate = __profile_frequency(); - strncpy(thdr.dimen, "seconds", sizeof(thdr.dimen)); + struct iovec iov[3] = + { + { &tag, sizeof (tag) }, + { &thdr, sizeof (struct gmon_hist_hdr) }, + { _gmonparam.kcount, _gmonparam.kcountsize } + }; + + *(char **) thdr.low_pc = (char *) _gmonparam.lowpc; + *(char **) thdr.high_pc = (char *) _gmonparam.highpc; + *(int *) thdr.hist_size = _gmonparam.kcountsize / sizeof (HISTCOUNTER); + *(int *) thdr.prof_rate = __profile_frequency (); + strncpy (thdr.dimen, "seconds", sizeof (thdr.dimen)); thdr.dimen_abbrev = 's'; - write(fd, &tag, sizeof(tag)); - write(fd, &thdr, sizeof(thdr)); - write(fd, _gmonparam.kcount, _gmonparam.kcountsize); + __writev (fd, iov, 3); } } @@ -188,12 +194,19 @@ static void write_call_graph (fd) int fd; { - const u_char tag = GMON_TAG_CG_ARC; - struct gmon_cg_arc_record raw_arc; + u_char tag = GMON_TAG_CG_ARC; + struct gmon_cg_arc_record raw_arc + __attribute__ ((aligned (__alignof__ (char*)))); int from_index, to_index, from_len; u_long frompc; - from_len = _gmonparam.fromssize / sizeof(*_gmonparam.froms); + struct iovec iov[2] = + { + { &tag, sizeof (tag) }, + { &raw_arc, sizeof (struct gmon_cg_arc_record) } + }; + + from_len = _gmonparam.fromssize / sizeof (*_gmonparam.froms); for (from_index = 0; from_index < from_len; ++from_index) { if (_gmonparam.froms[from_index] == 0) @@ -201,17 +214,16 @@ write_call_graph (fd) frompc = _gmonparam.lowpc; frompc += (from_index * _gmonparam.hashfraction - * sizeof(*_gmonparam.froms)); + * sizeof (*_gmonparam.froms)); for (to_index = _gmonparam.froms[from_index]; to_index != 0; to_index = _gmonparam.tos[to_index].link) { - raw_arc.from_pc = frompc; - raw_arc.self_pc = _gmonparam.tos[to_index].selfpc; - raw_arc.count = _gmonparam.tos[to_index].count; + *(char **) raw_arc.from_pc = (char *)frompc; + *(char **) raw_arc.self_pc = (char *)_gmonparam.tos[to_index].selfpc; + *(int *) raw_arc.count = _gmonparam.tos[to_index].count; - write(fd, &tag, sizeof(tag)); - write(fd, &raw_arc, sizeof(raw_arc)); + __writev (fd, iov, 2); } } } @@ -222,22 +234,32 @@ write_bb_counts (fd) int fd; { struct __bb *grp; - const u_char tag = GMON_TAG_BB_COUNT; + u_char tag = GMON_TAG_BB_COUNT; int ncounts; int i; + struct iovec bbhead[2] = + { + { &tag, sizeof (tag) }, + { &ncounts, sizeof (ncounts) } + }; + struct iovec bbbody[2]; + + bbbody[0].iov_len = sizeof (grp->addresses[0]); + bbbody[1].iov_len = sizeof (grp->addresses[0]); + /* Write each group of basic-block info (all basic-blocks in a compilation unit form a single group). */ for (grp = __bb_head; grp; grp = grp->next) { ncounts = grp->ncounts; - write(fd, &tag, sizeof(tag)); - write(fd, &ncounts, sizeof(ncounts)); + __writev (fd, bbhead, 2); for (i = 0; i < ncounts; ++i) { - write(fd, &grp->addresses[i], sizeof(grp->addresses[0])); - write(fd, &grp->counts[i], sizeof(grp->counts[0])); + bbbody[0].iov_base = (char *) &grp->addresses[i]; + bbbody[1].iov_base = &grp->counts[i]; + __writev (fd, bbbody, 2); } } } @@ -246,31 +268,31 @@ write_bb_counts (fd) void _mcleanup () { - struct gmon_hdr ghdr; + struct gmon_hdr ghdr __attribute__ ((aligned (__alignof__ (int)))); int fd; - moncontrol(0); - fd = open("gmon.out", O_CREAT|O_TRUNC|O_WRONLY, 0666); + moncontrol (0); + fd = __open ("gmon.out", O_CREAT|O_TRUNC|O_WRONLY, 0666); if (fd < 0) { - perror("_mcleanup: gmon.out"); + perror ("_mcleanup: gmon.out"); return; } /* write gmon.out header: */ - memset(&ghdr, 0, sizeof(ghdr)); - memcpy(&ghdr.cookie[0], GMON_MAGIC, sizeof(ghdr.cookie)); - ghdr.version = GMON_VERSION; - write(fd, &ghdr, sizeof(ghdr)); + memset (&ghdr, 0, sizeof (struct gmon_hdr)); + memcpy (&ghdr.cookie[0], GMON_MAGIC, sizeof (ghdr.cookie)); + *(int *) ghdr.version = GMON_VERSION; + __write (fd, &ghdr, sizeof (struct gmon_hdr)); /* write PC histogram: */ - write_hist(fd); + write_hist (fd); /* write call-graph: */ - write_call_graph(fd); + write_call_graph (fd); /* write basic-block execution counts: */ - write_bb_counts(fd); + write_bb_counts (fd); - close(fd); + __close (fd); } diff --git a/gmon/sys/gmon_out.h b/gmon/sys/gmon_out.h index 94e815d94b..36059cc572 100644 --- a/gmon/sys/gmon_out.h +++ b/gmon/sys/gmon_out.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1996 Free Software Foundation, Inc. +/* Copyright (C) 1996, 1997 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by David Mosberger . @@ -40,30 +40,36 @@ __BEGIN_DECLS * always comes first in gmon.out and is then followed by a series * records defined below. */ -struct gmon_hdr { - char cookie[4]; - int version; - int spare[3]; -}; +struct gmon_hdr + { + char cookie[4]; + char version[4]; + char spare[3 * 4]; + }; /* types of records in this file: */ -typedef enum { - GMON_TAG_TIME_HIST = 0, GMON_TAG_CG_ARC = 1, GMON_TAG_BB_COUNT = 2 -} GMON_Record_Tag; +typedef enum + { + GMON_TAG_TIME_HIST = 0, + GMON_TAG_CG_ARC = 1, + GMON_TAG_BB_COUNT = 2 + } GMON_Record_Tag; -struct gmon_hist_hdr { - unsigned long low_pc; /* base pc address of sample buffer */ - unsigned long high_pc; /* max pc address of sampled buffer */ - int hist_size; /* size of sample buffer */ - int prof_rate; /* profiling clock rate */ - char dimen[15]; /* phys. dim., usually "seconds" */ - char dimen_abbrev; /* usually 's' for "seconds" */ -}; +struct gmon_hist_hdr + { + char low_pc[sizeof (char *)]; /* base pc address of sample buffer */ + char high_pc[sizeof (char *)]; /* max pc address of sampled buffer */ + char hist_size[4]; /* size of sample buffer */ + char prof_rate[4]; /* profiling clock rate */ + char dimen[15]; /* phys. dim., usually "seconds" */ + char dimen_abbrev; /* usually 's' for "seconds" */ + }; -struct gmon_cg_arc_record { - unsigned long from_pc; /* address within caller's body */ - unsigned long self_pc; /* address within callee's body */ - int count; /* number of arc traversals */ +struct gmon_cg_arc_record + { + char from_pc[sizeof (char *)]; /* address within caller's body */ + char self_pc[sizeof (char *)]; /* address within callee's body */ + char count[4]; /* number of arc traversals */ }; __END_DECLS diff --git a/misc/sys/uio.h b/misc/sys/uio.h index bc49324cc5..901f9bbc25 100644 --- a/misc/sys/uio.h +++ b/misc/sys/uio.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1992, 1996 Free Software Foundation, Inc. +/* Copyright (C) 1991, 1992, 1996, 1997 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 @@ -34,6 +34,8 @@ __BEGIN_DECLS The buffers are filled in the order specified. Operates just like `read' (see ) except that data are put in VECTOR instead of a contiguous buffer. */ +extern ssize_t __readv __P ((int __fd, __const struct iovec *__vector, + int __count)); extern ssize_t readv __P ((int __fd, __const struct iovec *__vector, int __count)); @@ -42,6 +44,8 @@ extern ssize_t readv __P ((int __fd, __const struct iovec *__vector, The data is written in the order specified. Operates just like `write' (see ) except that the data are taken from VECTOR instead of a contiguous buffer. */ +extern ssize_t __writev __P ((int __fd, __const struct iovec *__vector, + int __count)); extern ssize_t writev __P ((int __fd, __const struct iovec *__vector, int __count)); diff --git a/nis/nis_file.c b/nis/nis_file.c index 002e72ed20..ccff52f0bc 100644 --- a/nis/nis_file.c +++ b/nis/nis_file.c @@ -23,6 +23,9 @@ #include #include + +static const char cold_start_file[] = "/var/nis/NIS_COLD_START"; + directory_obj * readColdStartFile (void) { @@ -30,17 +33,17 @@ readColdStartFile (void) FILE *in; directory_obj obj; - in = fopen ("/var/nis/NIS_COLD_START", "rb"); + in = fopen (cold_start_file, "rb"); if (in == NULL) { - fputs (_("Error: Could not open /var/nis/NIS_COLD_START!\n"), stdout); + printf (_("Error while opening %s for reading: %m"), cold_start_file); return NULL; } memset (&obj, '\0', sizeof (obj)); xdrstdio_create (&xdrs, in, XDR_DECODE); if (!xdr_directory_obj (&xdrs, &obj)) { - fputs (("Error while reading /var/nis/NIS_COLD_START!\n"), stdout); + printf (_("Error while reading %s: %m"), cold_start_file); return NULL; } @@ -53,16 +56,19 @@ writeColdStartFile (const directory_obj *obj) XDR xdrs; FILE *out; - out = fopen ("/var/nis/NIS_COLD_START", "wb"); + out = fopen (cold_start_file, "wb"); if (out == NULL) - return FALSE; + { + printf (_("Error while opening %s for writing: %m"), cold_start_file); + return FALSE; + } xdrstdio_create (&xdrs, out, XDR_ENCODE); /* XXX The following cast is bad! Shouldn't the XDR functions take pointers to const objects? */ if (!xdr_directory_obj (&xdrs, (directory_obj *) obj)) { - fputs (_("Error while reading /var/nis/NIS_COLD_START!\n"), stdout); + printf (_("Error while writing %s: %m"), cold_start_file); return FALSE; } diff --git a/nis/nis_free.c b/nis/nis_free.c index 35b7331372..60399c1655 100644 --- a/nis/nis_free.c +++ b/nis/nis_free.c @@ -67,7 +67,7 @@ nis_free_request (ib_request *ibreq) } void -nis_free_endpoints (endpoint *ep, int len) +nis_free_endpoints (endpoint *ep, unsigned int len) { int i; @@ -95,7 +95,7 @@ nis_free_endpoints (endpoint *ep, int len) } void -nis_free_servers (nis_server *obj, int len) +nis_free_servers (nis_server *obj, unsigned int len) { int i; diff --git a/nis/rpcsvc/nislib.h b/nis/rpcsvc/nislib.h index 2ad38ef9c8..b01270b22d 100644 --- a/nis/rpcsvc/nislib.h +++ b/nis/rpcsvc/nislib.h @@ -144,8 +144,8 @@ extern void nis_freeresult __P ((nis_result *)); /* (XXX INTERNAL FUNCTIONS, SHOULD NOT BE USED !!) */ extern void nis_free_attr __P ((nis_attr *)); extern void nis_free_request __P ((ib_request *)); -extern void nis_free_endpoints __P ((endpoint *, int)); -extern void nis_free_servers __P ((nis_server *, int)); +extern void nis_free_endpoints __P ((endpoint *, unsigned int)); +extern void nis_free_servers __P ((nis_server *, unsigned int)); extern void nis_free_directory __P ((directory_obj *)); extern void nis_free_group __P ((group_obj *)); extern void nis_free_table __P ((table_obj *)); diff --git a/posix/glob.c b/posix/glob.c index ac26a1af21..86a79b08a1 100644 --- a/posix/glob.c +++ b/posix/glob.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 92, 93, 94, 95, 96 Free Software Foundation, Inc. +/* Copyright (C) 1991, 92, 93, 94, 95, 96, 97 Free Software Foundation, Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as @@ -33,6 +33,10 @@ #include #include +/* Outcomment the following line for production quality code. */ +/* #define NDEBUG 1 */ +#include + /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C @@ -159,7 +163,7 @@ extern void bcopy (); ((void) ((better_be_zero) == 0 ? (bzero((s), (n)), 0) : (abort(), 0))) #endif /* Not ANSI_STRING. */ -#ifndef HAVE_STRCOLL +#if !defined HAVE_STRCOLL && !defined _LIBC #define strcoll strcmp #endif @@ -254,6 +258,51 @@ static int glob_in_dir __P ((const char *pattern, const char *directory, static int prefix_array __P ((const char *prefix, char **array, size_t n)); static int collated_compare __P ((const __ptr_t, const __ptr_t)); + +/* Find the end of the sub-pattern in a brace expression. We define + this as an inline function if the compiler permits. */ +static +#if __GNUC__ - 0 >= 2 +inline +#endif +const char * +next_brace_sub (const char *begin) +{ + unsigned int depth = 0; + const char *cp = begin; + + while (1) + { + if (depth == 0) + { + if (*cp != ',' && *cp != '}' && *cp != '\0') + { + if (*cp == '{') + ++depth; + ++cp; + continue; + } + } + else + { + while (*cp != '\0' && (*cp != '}' || depth > 0)) + { + if (*cp == '}') + ++depth; + ++cp; + } + if (*cp == '\0') + /* An incorrectly terminated brace expression. */ + return NULL; + + continue; + } + break; + } + + return cp; +} + /* Do glob searching for PATTERN, placing results in PGLOB. The bits defined above may be set in FLAGS. If a directory cannot be opened or read and ERRFUNC is not nil, @@ -286,38 +335,59 @@ glob (pattern, flags, errfunc, pglob) const char *begin = strchr (pattern, '{'); if (begin != NULL) { + /* Allocate working buffer large enough for our work. Note that + we have at least an opening and closing brace. */ int firstc; - size_t restlen; - const char *p, *end, *next; - unsigned int depth = 0; - - /* Find the end of the brace expression, by counting braces. - While we're at it, notice the first comma at top brace level. */ - end = begin + 1; - next = NULL; - while (1) + char *alt_start; + const char *p; + const char *next; + const char *rest; + size_t rest_len; +#ifdef __GNUC__ + char onealt[strlen (pattern) - 1]; +#else + char *onealt = (char *) malloc (strlen (pattern) - 1); + if (onealt == NULL) { - switch (*end++) + if (!(flags & GLOB_APPEND)) + globfree (pglob); + return GLOB_NOSPACE; + } +#endif + + /* We know the prefix for all sub-patterns. */ + memcpy (onealt, pattern, begin - pattern); + alt_start = &onealt[begin - pattern]; + + /* Find the first sub-pattern and at the same time find the + rest after the closing brace. */ + next = next_brace_sub (begin + 1); + if (next == NULL) + { + /* It is an illegal expression. */ +#ifndef __GNUC__ + free (onealt); +#endif + return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob); + } + + /* Now find the end of the whole brace expression. */ + rest = next; + while (*rest != '}') + { + rest = next_brace_sub (rest + 1); + if (rest == NULL) { - case ',': - if (depth == 0 && next == NULL) - next = end; - continue; - case '{': - ++depth; - continue; - case '}': - if (depth-- == 0) - break; - continue; - case '\0': - return glob (pattern, flags &~ GLOB_BRACE, errfunc, pglob); + /* It is an illegal expression. */ +#ifndef __GNUC__ + free (onealt); +#endif + return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob); } - break; } - restlen = strlen (end) + 1; - if (next == NULL) - next = end; + /* Please note that we now can be sure the brace expression + is well-formed. */ + rest_len = strlen (++rest) + 1; /* We have a brace expression. BEGIN points to the opening {, NEXT points past the terminator of the first element, and END @@ -334,72 +404,47 @@ glob (pattern, flags, errfunc, pglob) } firstc = pglob->gl_pathc; - /* In this loop P points to the beginning of the current element - and NEXT points past its terminator. */ p = begin + 1; while (1) { - /* Construct a whole name that is one of the brace - alternatives in a temporary buffer. */ int result; - size_t bufsz = (begin - pattern) + (next - 1 - p) + restlen; -#ifdef __GNUC__ - char onealt[bufsz]; -#else - char *onealt = malloc (bufsz); - if (onealt == NULL) - { - if (!(flags & GLOB_APPEND)) - globfree (pglob); - return GLOB_NOSPACE; - } -#endif - memcpy (onealt, pattern, begin - pattern); - memcpy (&onealt[begin - pattern], p, next - 1 - p); - memcpy (&onealt[(begin - pattern) + (next - 1 - p)], - end, restlen); + + /* Construct the new glob expression. */ + memcpy (alt_start, p, next - p); + memcpy (&alt_start[next - p], rest, rest_len); + result = glob (onealt, - ((flags & ~(GLOB_NOCHECK|GLOB_NOMAGIC)) | - GLOB_APPEND), errfunc, pglob); -#ifndef __GNUC__ - free (onealt); -#endif + ((flags & ~(GLOB_NOCHECK|GLOB_NOMAGIC)) + | GLOB_APPEND), errfunc, pglob); /* If we got an error, return it. */ if (result && result != GLOB_NOMATCH) { +#ifndef __GNUC__ + free (onealt); +#endif if (!(flags & GLOB_APPEND)) globfree (pglob); return result; } - /* Advance past this alternative and process the next. */ - p = next; - depth = 0; - scan: - switch (*p++) - { - case ',': - if (depth == 0) - { - /* Found the next alternative. Loop to glob it. */ - next = p; - continue; - } - goto scan; - case '{': - ++depth; - goto scan; - case '}': - if (depth-- == 0) - /* End of the brace expression. Break out of the loop. */ - break; - goto scan; - } + if (*next == '}') + /* We saw the last entry. */ + break; + + p = next + 1; + next = next_brace_sub (p); + assert (next != NULL); } - if (pglob->gl_pathc == firstc && - !(flags & (GLOB_NOCHECK|GLOB_NOMAGIC))) +#ifndef __GNUC__ + free (onealt); +#endif + + if (pglob->gl_pathc != firstc) + /* We found some entries. */ + return 0; + else if (!(flags & (GLOB_NOCHECK|GLOB_NOMAGIC))) return GLOB_NOMATCH; } } @@ -452,19 +497,19 @@ glob (pattern, flags, errfunc, pglob) #ifndef VMS if ((flags & GLOB_TILDE) && dirname[0] == '~') { - if (dirname[1] == '\0') + if (dirname[1] == '\0' || dirname[1] == '/') { /* Look up home directory. */ - dirname = getenv ("HOME"); + char *home_dir = getenv ("HOME"); #ifdef _AMIGA - if (dirname == NULL || dirname[0] == '\0') - dirname = "SYS:"; + if (home_dir == NULL || home_dir[0] == '\0') + home_dir = "SYS:"; #else #ifdef WIN32 - if (dirname == NULL || dirname[0] == '\0') - dirname = "c:/users/default"; /* poor default */ + if (home_dir == NULL || home_dir[0] == '\0') + home_dir = "c:/users/default"; /* poor default */ #else - if (dirname == NULL || dirname[0] == '\0') + if (home_dir == NULL || home_dir[0] == '\0') { extern char *getlogin __P ((void)); extern int getlogin_r __P ((char *, size_t)); @@ -501,39 +546,74 @@ glob (pattern, flags, errfunc, pglob) success = p != NULL; #endif if (success) - dirname = p->pw_dir; + home_dir = p->pw_dir; } } - if (dirname == NULL || dirname[0] == '\0') - dirname = (char *) "~"; /* No luck. */ + if (home_dir == NULL || home_dir[0] == '\0') + home_dir = (char *) "~"; /* No luck. */ #endif /* WIN32 */ #endif + /* Now construct the full directory. */ + if (dirname[1] == '\0') + dirname = home_dir; + else + { + char *newp; + size_t home_len = strlen (home_dir); + newp = __alloca (home_len + dirlen); + memcpy (newp, home_dir, home_len); + memcpy (&newp[home_len], &dirname[1], dirlen); + dirname = newp; + } } +#if !defined _AMIGA && !defined WIN32 else { -#ifdef _AMIGA - if (dirname == NULL || dirname[0] == '\0') - dirname = "SYS:"; -#else -#ifdef WIN32 - if (dirname == NULL || dirname[0] == '\0') - dirname = "c:/users/default"; /* poor default */ -#else + char *end_name = strchr (dirname, '/'); + char *user_name; + char *home_dir; + + if (end_name == NULL) + user_name = dirname + 1; + else + { + user_name = __alloca (end_name - dirname); + memcpy (user_name, dirname + 1, end_name - dirname); + user_name[end_name - dirname - 1] = '\0'; + } + /* Look up specific user's home directory. */ + { #if defined HAVE_GETPWNAM_R || defined _LIBC - size_t buflen = sysconf (_SC_GETPW_R_SIZE_MAX); - char *pwtmpbuf = __alloca (buflen); - struct passwd pwbuf, *p; - if (__getpwnam_r (dirname + 1, &pwbuf, pwtmpbuf, buflen, &p) >= 0) - dirname = p->pw_dir; + size_t buflen = sysconf (_SC_GETPW_R_SIZE_MAX); + char *pwtmpbuf = __alloca (buflen); + struct passwd pwbuf, *p; + if (__getpwnam_r (user_name, &pwbuf, pwtmpbuf, buflen, &p) >= 0) + home_dir = p->pw_dir; + else + home_dir = NULL; #else - struct passwd *p = getpwnam (dirname + 1); - if (p != NULL) - dirname = p->pw_dir; -#endif -#endif /* WIN32 */ + struct passwd *p = getpwnam (user_name); + if (p != NULL) + home_dir = p->pw_dir; + else + home_dir = NULL; #endif + } + /* If we found a home directory use this. */ + if (home_dir != NULL) + { + char *newp; + size_t home_len = strlen (home_dir); + size_t rest_len = end_name == NULL ? 0 : strlen (end_name); + newp = __alloca (home_len + rest_len + 1); + memcpy (newp, home_dir, home_len); + memcpy (&newp[home_len], end_name, rest_len); + newp[home_len + rest_len] = '\0'; + dirname = newp; + } } +#endif /* Not Amiga && not Win32. */ } #endif /* Not VMS. */ diff --git a/stdlib/testdiv.c b/stdlib/testdiv.c index a3ae5c98d0..9a5341cf50 100644 --- a/stdlib/testdiv.c +++ b/stdlib/testdiv.c @@ -22,11 +22,19 @@ int main (void) { + int err = 0; int i, j; while (scanf ("%d %d\n", &i, &j) == 2) { div_t d = div (i, j); - printf ("%d / %d = %d + %d/%d\n", i, j, d.quot, d.rem, j); + printf ("%d / %d = %d + %d/%d", i, j, d.quot, d.rem, j); + if (i == d.quot * j + d.rem) + fputs (" OK\n", stdout); + else + { + fputs (" FAILED\n", stdout); + err = 1; + } } - return 0; + return err; } diff --git a/stdlib/tst-strtod.c b/stdlib/tst-strtod.c index a76529c4dd..316fff93b9 100644 --- a/stdlib/tst-strtod.c +++ b/stdlib/tst-strtod.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1996 Free Software Foundation, Inc. +/* Copyright (C) 1991, 1996, 1997 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 @@ -49,6 +49,7 @@ main (int argc, char ** argv) register const struct ltest *lt; char *ep; int status = 0; + int save_errno; for (lt = tests; lt->str != NULL; ++lt) { @@ -56,30 +57,32 @@ main (int argc, char ** argv) errno = 0; d = strtod(lt->str, &ep); - printf("strtod(\"%s\") test %u", + save_errno = errno; + printf ("strtod (\"%s\") test %u", lt->str, (unsigned int) (lt - tests)); - if (d == lt->expect && *ep == lt->left && errno == lt->err) - puts("\tOK"); + if (d == lt->expect && *ep == lt->left && save_errno == lt->err) + puts ("\tOK"); else { - puts("\tBAD"); + puts ("\tBAD"); if (d != lt->expect) - printf(" returns %.60g, expected %.60g\n", d, lt->expect); + printf (" returns %.60g, expected %.60g\n", d, lt->expect); if (lt->left != *ep) { char exp1[5], exp2[5]; - expand(exp1, *ep); - expand(exp2, lt->left); - printf(" leaves '%s', expected '%s'\n", exp1, exp2); + expand (exp1, *ep); + expand (exp2, lt->left); + printf (" leaves '%s', expected '%s'\n", exp1, exp2); } - if (errno != lt->err) - printf(" errno %d (%s) instead of %d (%s)\n", - errno, strerror(errno), lt->err, strerror(lt->err)); + if (save_errno != lt->err) + printf (" errno %d (%s) instead of %d (%s)\n", + save_errno, strerror (save_errno), + lt->err, strerror (lt->err)); status = 1; } } - exit(status ? EXIT_FAILURE : EXIT_SUCCESS); + exit (status ? EXIT_FAILURE : EXIT_SUCCESS); } static void @@ -87,11 +90,11 @@ expand (dst, c) char *dst; register int c; { - if (isprint(c)) + if (isprint (c)) { dst[0] = c; dst[1] = '\0'; } else - (void) sprintf(dst, "%#.3o", (unsigned int) c); + (void) sprintf (dst, "%#.3o", (unsigned int) c); } diff --git a/stdlib/tst-strtol.c b/stdlib/tst-strtol.c index 085787196b..13286912c7 100644 --- a/stdlib/tst-strtol.c +++ b/stdlib/tst-strtol.c @@ -106,9 +106,10 @@ main (int argc, char ** argv) expand (exp2, lt->left); printf (" leaves '%s', expected '%s'\n", exp1, exp2); } - if (errno != lt->err) + if (save_errno != lt->err) printf (" errno %d (%s) instead of %d (%s)\n", - errno, strerror (errno), lt->err, strerror (lt->err)); + save_errno, strerror (save_errno), + lt->err, strerror (lt->err)); status = 1; } } @@ -119,9 +120,10 @@ main (int argc, char ** argv) errno = 0; ul = strtoul (lt->str, &ep, lt->base); + save_errno = errno; printf ("strtoul(\"%s\", , %d) test %u", lt->str, lt->base, (unsigned int) (lt - tests)); - if (ul == lt->expect && *ep == lt->left && errno == lt->err) + if (ul == lt->expect && *ep == lt->left && save_errno == lt->err) puts("\tOK"); else { @@ -136,9 +138,10 @@ main (int argc, char ** argv) expand (exp2, lt->left); printf (" leaves '%s', expected '%s'\n", exp1, exp2); } - if (errno != lt->err) + if (save_errno != lt->err) printf (" errno %d (%s) instead of %d (%s)\n", - errno, strerror (errno), lt->err, strerror (lt->err)); + save_errno, strerror (save_errno), + lt->err, strerror (lt->err)); status = 1; } } diff --git a/sunrpc/rpc/netdb.h b/sunrpc/rpc/netdb.h index e0c1d7de6e..914f825ad4 100644 --- a/sunrpc/rpc/netdb.h +++ b/sunrpc/rpc/netdb.h @@ -50,6 +50,8 @@ struct rpcent int r_number; /* RPC program number. */ }; +extern void setrpcent __P ((int _stayopen)); +extern void endrpcent __P ((void)); extern struct rpcent *getrpcbyname __P ((__const char *__name)); extern struct rpcent *getrpcbynumber __P ((int __number)); extern struct rpcent *getrpcent __P ((void)); diff --git a/sysdeps/alpha/div.S b/sysdeps/alpha/div.S index 6c461c40d4..6a5c4429e8 100644 --- a/sysdeps/alpha/div.S +++ b/sysdeps/alpha/div.S @@ -1,7 +1,6 @@ -/* Copyright (C) 1996 Free Software Foundation, Inc. - Contributed by Richard Henderson (rth@tamu.edu) - +/* Copyright (C) 1996, 1997 Free Software Foundation, Inc. This file is part of the GNU C Library. + Contributed by Richard Henderson . 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 @@ -14,10 +13,9 @@ 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., 675 Mass Ave, - Cambridge, MA 02139, USA. */ - + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ #include @@ -44,7 +42,6 @@ div: .prologue 0 #endif -#define dividend t0 #define divisor t1 #define mask t2 #define quotient t3 @@ -54,11 +51,13 @@ div: #define compare t7 /* find correct sign for input to unsigned divide loop. */ + negl a1, modulus # e0 : + negl a2, divisor # .. e1 : sextl a1, a1 # e0 : sextl a2, a2 # .. e1 : - negl a1, dividend # e0 : - negl a2, divisor # .. e1 : - cmovge a1, a1, dividend # e0 : + mov zero, quotient # e0 : + mov 1, mask # .. e1 : + cmovge a1, a1, modulus # e0 : cmovge a2, a2, divisor # .. e1 : beq a2, $divbyzero # e1 : unop # : diff --git a/sysdeps/alpha/ldiv.S b/sysdeps/alpha/ldiv.S index ebbe055870..08bf8eb08d 100644 --- a/sysdeps/alpha/ldiv.S +++ b/sysdeps/alpha/ldiv.S @@ -1,7 +1,6 @@ -/* Copyright (C) 1996 Free Software Foundation, Inc. - Contributed by Richard Henderson (rth@tamu.edu) - +/* Copyright (C) 1996, 1997 Free Software Foundation, Inc. This file is part of the GNU C Library. + Contributed by Richard Henderson . 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 @@ -14,10 +13,9 @@ 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., 675 Mass Ave, - Cambridge, MA 02139, USA. */ - + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ #include @@ -44,7 +42,6 @@ ldiv: .prologue 0 #endif -#define dividend t0 #define divisor t1 #define mask t2 #define quotient t3 @@ -54,11 +51,13 @@ ldiv: #define compare t7 /* find correct sign for input to unsigned divide loop. */ - mov a1, dividend # e0 : + mov a1, modulus # e0 : mov a2, divisor # .. e1 : negq a1, tmp1 # e0 : negq a2, tmp2 # .. e1 : - cmovlt a1, tmp1, dividend # e0 : + mov zero, quotient # e0 : + mov 1, mask # .. e1 : + cmovlt a1, tmp1, modulus # e0 : cmovlt a2, tmp2, divisor # .. e1 : beq a2, $divbyzero # e1 : unop # : diff --git a/sysdeps/generic/machine-gmon.h b/sysdeps/generic/machine-gmon.h index 31f852dece..c4a2168322 100644 --- a/sysdeps/generic/machine-gmon.h +++ b/sysdeps/generic/machine-gmon.h @@ -1,21 +1,21 @@ /* Machine-dependent definitions for profiling support. Generic GCC 2 version. -Copyright (C) 1996 Free Software Foundation, Inc. -This file is part of the GNU C Library. - -The GNU C Library is free software; you can redistribute it and/or -modify it under the terms of the GNU 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., 675 Mass Ave, -Cambridge, MA 02139, USA. */ + Copyright (C) 1996, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU 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. */ /* GCC version 2 gives us a perfect magical function to get just the information we need: diff --git a/sysdeps/i386/Dist b/sysdeps/i386/Dist new file mode 100644 index 0000000000..50c07d120a --- /dev/null +++ b/sysdeps/i386/Dist @@ -0,0 +1,2 @@ +i386-mcount.S +machine-gmon.h diff --git a/sysdeps/i386/Makefile b/sysdeps/i386/Makefile index 21caf42052..35e0422bdb 100644 --- a/sysdeps/i386/Makefile +++ b/sysdeps/i386/Makefile @@ -5,6 +5,10 @@ asm-CPPFLAGS := $(asm-CPPFLAGS) -DGAS_SYNTAX # The i386 `long double' is a distinct type we support. long-double-fcts = yes +ifeq ($(subdir),gmon) +sysdep_routines += i386-mcount +endif + ifeq ($(subdir),elf) CFLAGS-rtld.c += -Wno-uninitialized -Wno-unused CFLAGS-dl-load.c += -Wno-unused diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h index 90ec6ce9f9..40623e795c 100644 --- a/sysdeps/i386/dl-machine.h +++ b/sysdeps/i386/dl-machine.h @@ -70,11 +70,16 @@ elf_machine_load_address (void) (dynamic_info)[DT_RELSZ]->d_un.d_val -= sizeof (Elf32_Rel); +#ifndef PROF /* We add a declaration of this function here so that in dl-runtime.c the ELF_MACHINE_RUNTIME_TRAMPOLINE macro really can pass the parameters - in registers. */ + in registers. + + We cannot use this scheme for profiling because the _mcount call + destroys the passed register information. */ static ElfW(Addr) fixup (struct link_map *l, ElfW(Word) reloc_offset) __attribute__ ((regparm (2), unused)); +#endif /* Set up the loaded object described by L so its unrelocated PLT entries will jump to the on-demand fixup code in dl-runtime.c. */ @@ -101,7 +106,8 @@ elf_machine_runtime_setup (struct link_map *l, int lazy) /* This code is used in dl-runtime.c to call the `fixup' function and then redirect to the address it returns. */ -#define ELF_MACHINE_RUNTIME_TRAMPOLINE asm ("\ +#ifndef PROF +# define ELF_MACHINE_RUNTIME_TRAMPOLINE asm ("\ .globl _dl_runtime_resolve .type _dl_runtime_resolve, @function _dl_runtime_resolve: @@ -117,6 +123,28 @@ _dl_runtime_resolve: ret $8 # Jump to function address. .size _dl_runtime_resolve, .-_dl_runtime_resolve "); +#else +# define ELF_MACHINE_RUNTIME_TRAMPOLINE asm ("\ + .globl _dl_runtime_resolve + .type _dl_runtime_resolve, @function +_dl_runtime_resolve: + pushl %eax # Preserve registers otherwise clobbered. + pushl %ecx + pushl %edx + movl 16(%esp), %edx # Push the arguments for `fixup' + movl 12(%esp), %eax + pushl %edx + pushl %eax + call fixup # Call resolver. + popl %edx # Pop the parameters + popl %ecx + popl %edx # Get register content back. + popl %ecx + xchgl %eax, (%esp) # Get %eax contents end store function address. + ret $8 # Jump to function address. + .size _dl_runtime_resolve, .-_dl_runtime_resolve +"); +#endif /* The PLT uses Elf32_Rel relocs. */ #define elf_machine_relplt elf_machine_rel } diff --git a/sysdeps/i386/i386-mcount.S b/sysdeps/i386/i386-mcount.S new file mode 100644 index 0000000000..60d52e98fa --- /dev/null +++ b/sysdeps/i386/i386-mcount.S @@ -0,0 +1,65 @@ +/* i386-specific implemetation of profiling support. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + 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. */ + +#include + +/* We need a special version of the `mcount' function since for ix86 it + must not clobber any register. This has several reasons: + - there is a bug in gcc as of version 2.7.2.2 which prohibits the + use of profiling together with nested functions + - the ELF `fixup' function uses GCC's regparm feature + - some (future) systems might want to pass parameters in registers. */ + + ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(_mcount) + ASM_TYPE_DIRECTIVE(C_SYMBOL_NAME(_mcount), @function) + .align ALIGNARG(4) +C_LABEL(_mcount) + /* Save the caller-clobbered registers. */ + pushl %eax + pushl %ecx + pushl %edx + + movl 12(%esp), %eax + movl 4(%ebp), %ecx + pushl %eax + pushl %ecx + +#ifdef PIC + call 1f +1: popl %ecx + addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx + movl C_SYMBOL_NAME(__mcount_internal@GOTOFF)(%ecx), %eax + call *%eax +#else + call C_SYMBOL_NAME(__mcount_internal) +#endif + popl %ecx + popl %eax /* Pop the parameters. */ + + /* Pop the saved registers. Please note that `mcount' has no + return value. */ + popl %edx + popl %ecx + popl %eax + ret + ASM_SIZE_DIRECTIVE(C_SYMBOL_NAME(_mcount)) + +#undef mcount +weak_alias(_mcount, mcount) diff --git a/sysdeps/i386/machine-gmon.h b/sysdeps/i386/machine-gmon.h new file mode 100644 index 0000000000..496a57eb84 --- /dev/null +++ b/sysdeps/i386/machine-gmon.h @@ -0,0 +1,41 @@ +/* i386-specific implemetation of profiling support. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + 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. */ + +#include + +/* We need a special version of the `mcount' function since for ix86 it + must not clobber any register. This has several reasons: + - there is a bug in gcc as of version 2.7.2.2 which prohibits the + use of profiling together with nested functions + - the ELF `fixup' function uses GCC's regparm feature + - some (future) systems might want to pass parameters in registers. */ + +/* We must not pollute the global namespace. */ +#define mcount_internal __mcount_internal + +void mcount_internal (u_long frompc, u_long selfpc); + +#define _MCOUNT_DECL(frompc, selfpc) \ +void mcount_internal (u_long frompc, u_long selfpc) + + +/* Define MCOUNT as empty since we have a the implementation in another + file. */ +#define MCOUNT diff --git a/sysdeps/posix/readv.c b/sysdeps/posix/readv.c index 878accaf92..e4a2163f6d 100644 --- a/sysdeps/posix/readv.c +++ b/sysdeps/posix/readv.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1992, 1996 Free Software Foundation, Inc. +/* Copyright (C) 1991, 1992, 1996, 1997 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 @@ -27,7 +27,7 @@ Operates just like `read' (see ) except that data are put in VECTOR instead of a contiguous buffer. */ ssize_t -readv (fd, vector, count) +__readv (fd, vector, count) int fd; const struct iovec *vector; int count; @@ -46,7 +46,7 @@ readv (fd, vector, count) buffer = (char *) __alloca (bytes); /* Read the data. */ - bytes_read = read (fd, buffer, bytes); + bytes_read = __read (fd, buffer, bytes); if (bytes_read <= 0) return -1; @@ -67,3 +67,6 @@ readv (fd, vector, count) return bytes_read; } +#ifndef __readv +weak_alias (__readv, readv) +#endif diff --git a/sysdeps/posix/writev.c b/sysdeps/posix/writev.c index 2f0572f837..f6f685ce7a 100644 --- a/sysdeps/posix/writev.c +++ b/sysdeps/posix/writev.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1992, 1996 Free Software Foundation, Inc. +/* Copyright (C) 1991, 1992, 1996, 1997 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 @@ -27,7 +27,7 @@ Operates just like `write' (see ) except that the data are taken from VECTOR instead of a contiguous buffer. */ ssize_t -writev (fd, vector, count) +__writev (fd, vector, count) int fd; const struct iovec *vector; int count; @@ -61,5 +61,8 @@ writev (fd, vector, count) break; } - return write (fd, buffer, bytes); + return __write (fd, buffer, bytes); } +#ifndef __writev +weak_alias (__writev, writev) +#endif diff --git a/sysdeps/stub/readv.c b/sysdeps/stub/readv.c index b537499b07..a3240df239 100644 --- a/sysdeps/stub/readv.c +++ b/sysdeps/stub/readv.c @@ -1,20 +1,20 @@ -/* Copyright (C) 1991, 1995, 1996 Free Software Foundation, Inc. -This file is part of the GNU C Library. +/* Copyright (C) 1991, 1995, 1996, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. -The GNU C Library is free software; you can redistribute it and/or -modify it under the terms of the GNU 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 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. + 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., 675 Mass Ave, -Cambridge, MA 02139, USA. */ + 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. */ #include #include @@ -26,7 +26,7 @@ Cambridge, MA 02139, USA. */ Operates just like `read' (see ) except that data are put in VECTOR instead of a contiguous buffer. */ int -readv (fd, vector, count) +__readv (fd, vector, count) int fd; const struct iovec *vector; size_t count; @@ -34,5 +34,6 @@ readv (fd, vector, count) __set_errno (ENOSYS); return -1; } +weak_alias (__readv, readv) stub_warning (readv) diff --git a/sysdeps/stub/writev.c b/sysdeps/stub/writev.c index 593880c0e9..1fd7c2ec73 100644 --- a/sysdeps/stub/writev.c +++ b/sysdeps/stub/writev.c @@ -1,20 +1,20 @@ -/* Copyright (C) 1991, 1995, 1996 Free Software Foundation, Inc. -This file is part of the GNU C Library. +/* Copyright (C) 1991, 1995, 1996, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. -The GNU C Library is free software; you can redistribute it and/or -modify it under the terms of the GNU 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 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. + 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., 675 Mass Ave, -Cambridge, MA 02139, USA. */ + 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. */ #include #include @@ -26,7 +26,7 @@ Cambridge, MA 02139, USA. */ Operates just like `write' (see ) except that the data are taken from VECTOR instead of a contiguous buffer. */ int -writev (fd, vector, count) +__writev (fd, vector, count) int fd; const struct iovec *vector; size_t count; @@ -34,5 +34,6 @@ writev (fd, vector, count) __set_errno (ENOSYS); return -1; } +weak_alias (__writev, writev) stub_warning (writev) diff --git a/sysdeps/unix/syscalls.list b/sysdeps/unix/syscalls.list index 9a2325c35c..5ececa058c 100644 --- a/sysdeps/unix/syscalls.list +++ b/sysdeps/unix/syscalls.list @@ -31,7 +31,7 @@ profil - profil 4 profil ptrace - ptrace 4 ptrace read - read 3 __libc_read __read read readlink - readlink 3 __readlink readlink -readv - readv 3 readv +readv - readv 3 __readv readv reboot - reboot 1 reboot rename - rename 2 rename rmdir - rmdir 1 __rmdir rmdir @@ -62,4 +62,4 @@ uname - uname 1 uname unlink - unlink 1 __unlink unlink utimes - utimes 2 __utimes utimes write - write 3 __libc_write __write write -writev - writev 3 writev +writev - writev 3 __writev writev diff --git a/sysdeps/unix/sysv/linux/alpha/ioperm.c b/sysdeps/unix/sysv/linux/alpha/ioperm.c index b39f39a0d7..63bf17588a 100644 --- a/sysdeps/unix/sysv/linux/alpha/ioperm.c +++ b/sysdeps/unix/sysv/linux/alpha/ioperm.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include diff --git a/sysdeps/unix/sysv/linux/i386/sysdep.S b/sysdeps/unix/sysv/linux/i386/sysdep.S index 4b86d1dfe7..a686495818 100644 --- a/sysdeps/unix/sysv/linux/i386/sysdep.S +++ b/sysdeps/unix/sysv/linux/i386/sysdep.S @@ -1,4 +1,4 @@ -/* Copyright (C) 1995, 1996 Free Software Foundation, Inc. +/* Copyright (C) 1995, 1996, 1997 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 @@ -45,6 +45,9 @@ _errno = errno /* This name is expected by hj's libc.so.5 startup code. */ The code for Linux is almost identical to the canonical Unix/i386 code, except that the error number in %eax is negated. */ +#undef CALL_MCOUNT +#define CALL_MCOUNT /* Don't insert the profiling call, it clobbers %eax. */ + ENTRY (__syscall_error) negl %eax diff --git a/sysdeps/unix/sysv/linux/readv.c b/sysdeps/unix/sysv/linux/readv.c index c8ff55ab45..2c215ce920 100644 --- a/sysdeps/unix/sysv/linux/readv.c +++ b/sysdeps/unix/sysv/linux/readv.c @@ -23,6 +23,8 @@ #include extern ssize_t __syscall_readv __P ((int, __const struct iovec *, int)); +static ssize_t __atomic_readv_replacement __P ((int, __const struct iovec *, + int)); /* Not all versions of the kernel support the large number of records. */ @@ -34,7 +36,7 @@ extern ssize_t __syscall_readv __P ((int, __const struct iovec *, int)); /* We should deal with kernel which have a smaller UIO_FASTIOV as well as a very big count. */ ssize_t -readv (fd, vector, count) +__readv (fd, vector, count) int fd; const struct iovec *vector; int count; @@ -44,25 +46,15 @@ readv (fd, vector, count) bytes_read = __syscall_readv (fd, vector, count); - if (bytes_read < 0 && errno == EINVAL && count > UIO_FASTIOV) - { - int i; + if (bytes_read >= 0 || errno != EINVAL || count <= UIO_FASTIOV) + return bytes_read; - /* Restore the old error value as if nothing happened. */ - __set_errno (errno_saved); + /* Restore the old error value as if nothing happened. */ + __set_errno (errno_saved); - bytes_read = 0; - for (i = 0; i < count; i += UIO_FASTIOV) - { - ssize_t bytes = __syscall_readv (fd, vector + i, - MIN (count - i, UIO_FASTIOV)); - - if (bytes < 0) - return bytes; - - bytes_read += bytes; - } - } - - return bytes_read; + return __atomic_readv_replacement (fd, vector, count); } +weak_alias (__readv, readv) + +#define __readv static __atomic_readv_replacement +#include diff --git a/sysdeps/unix/sysv/linux/writev.c b/sysdeps/unix/sysv/linux/writev.c index d147186b51..31e794fb04 100644 --- a/sysdeps/unix/sysv/linux/writev.c +++ b/sysdeps/unix/sysv/linux/writev.c @@ -23,6 +23,9 @@ #include extern ssize_t __syscall_writev __P ((int, const struct iovec *, int)); +static ssize_t __atomic_writev_replacement __P ((int, const struct iovec *, + int)); + /* Not all versions of the kernel support the large number of records. */ #ifndef UIO_FASTIOV @@ -33,7 +36,7 @@ extern ssize_t __syscall_writev __P ((int, const struct iovec *, int)); /* We should deal with kernel which have a smaller UIO_FASTIOV as well as a very big count. */ ssize_t -writev (fd, vector, count) +__writev (fd, vector, count) int fd; const struct iovec *vector; int count; @@ -43,23 +46,15 @@ writev (fd, vector, count) bytes_written = __syscall_writev (fd, vector, count); - if (bytes_written < 0 && errno == EINVAL && count > UIO_FASTIOV) - { - int i; - - /* Restore the old error value as if nothing happened. */ - __set_errno (errno_saved); + if (bytes_written >= 0 || errno != EINVAL || count <= UIO_FASTIOV) + return bytes_written; - bytes_written = 0; - for (i = 0; i < count; i += UIO_FASTIOV) - { - ssize_t bytes = __syscall_writev (fd, vector + i, - MIN (count - i, UIO_FASTIOV)); + /* Restore the old error value as if nothing happened. */ + __set_errno (errno_saved); - if (bytes < 0) - return bytes_written > 0 ? bytes_written : bytes; - } - } - - return bytes_written; + return __atomic_writev_replacement (fd, vector, count); } +weak_alias (__writev, writev) + +#define __writev static __atomic_writev_replacement +#include -- cgit v1.2.3