aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog78
-rw-r--r--FAQ2
-rw-r--r--Makeconfig6
-rw-r--r--gmon/gmon.c94
-rw-r--r--gmon/sys/gmon_out.h48
-rw-r--r--misc/sys/uio.h6
-rw-r--r--nis/nis_file.c18
-rw-r--r--nis/nis_free.c4
-rw-r--r--nis/rpcsvc/nislib.h4
-rw-r--r--posix/glob.c294
-rw-r--r--stdlib/testdiv.c12
-rw-r--r--stdlib/tst-strtod.c33
-rw-r--r--stdlib/tst-strtol.c13
-rw-r--r--sunrpc/rpc/netdb.h2
-rw-r--r--sysdeps/alpha/div.S21
-rw-r--r--sysdeps/alpha/ldiv.S19
-rw-r--r--sysdeps/generic/machine-gmon.h34
-rw-r--r--sysdeps/i386/Dist2
-rw-r--r--sysdeps/i386/Makefile4
-rw-r--r--sysdeps/i386/dl-machine.h32
-rw-r--r--sysdeps/i386/i386-mcount.S65
-rw-r--r--sysdeps/i386/machine-gmon.h41
-rw-r--r--sysdeps/posix/readv.c9
-rw-r--r--sysdeps/posix/writev.c9
-rw-r--r--sysdeps/stub/readv.c31
-rw-r--r--sysdeps/stub/writev.c31
-rw-r--r--sysdeps/unix/syscalls.list4
-rw-r--r--sysdeps/unix/sysv/linux/alpha/ioperm.c1
-rw-r--r--sysdeps/unix/sysv/linux/i386/sysdep.S5
-rw-r--r--sysdeps/unix/sysv/linux/readv.c32
-rw-r--r--sysdeps/unix/sysv/linux/writev.c31
31 files changed, 668 insertions, 317 deletions
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 <drepper@cygnus.com>
+
+ * 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 <aj@arthur.pfalz.de>
+
+ * 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 <drepper@cygnus.com>
+
+ * posix/glob.c (glob): Fix completely broken handling of
+ GLOB_BRACE and partly broken handling of GLOB_TILDE.
+ Reported by Dennis Henriksen <opus@flamingo.osrl.dk>.
+
+1997-03-20 20:22 Ulrich Drepper <drepper@cygnus.com>
+
+ * 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 <roland@baalperazim.frob.com>
+
+ * 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 <rth@tamu.edu>
+
+ * 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 <davidm@azstarnet.com>.
+ * 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 <drepper@cygnus.com>
+
+ * nis/nis_file.c: Unify error handling.
+
+1997-03-19 18:36 Thorsten Kukuk <kukuk@vt.uni-paderborn.de>
+
+ * 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 <drepper@cygnus.com>
* 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 <sys/time.h>
#include <sys/gmon.h>
#include <sys/gmon_out.h>
+#include <sys/uio.h>
#include <stdio.h>
#include <fcntl.h>
@@ -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 <davidm@cs.arizona.edu>.
@@ -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 <unistd.h>) 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 <unistd.h>) 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 <rpcsvc/nis.h>
#include <rpcsvc/nislib.h>
+
+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 <sys/types.h>
#include <sys/stat.h>
+/* Outcomment the following line for production quality code. */
+/* #define NDEBUG 1 */
+#include <assert.h>
+
/* 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 <rth@tamu.edu>.
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 <sysdep.h>
@@ -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 <rth@tamu.edu>.
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 <sysdep.h>
@@ -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 <drepper@cygnus.com>, 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 <sysdep.h>
+
+/* 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 <drepper@cygnus.com>, 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 <sysdep.h>
+
+/* 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 <unistd.h>) 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 <unistd.h>) 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 <errno.h>
#include <unistd.h>
@@ -26,7 +26,7 @@ Cambridge, MA 02139, USA. */
Operates just like `read' (see <unistd.h>) 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 <errno.h>
#include <unistd.h>
@@ -26,7 +26,7 @@ Cambridge, MA 02139, USA. */
Operates just like `write' (see <unistd.h>) 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 <errno.h>
#include <fcntl.h>
#include <stdio.h>
+#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
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 <sys/uio.h>
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 <sysdeps/posix/readv.c>
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 <sys/uio.h>
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 <sysdeps/posix/writev.c>