summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog88
-rw-r--r--bits/byteswap.h43
-rw-r--r--elf/dl-deps.c371
-rw-r--r--inet/Makefile2
-rw-r--r--inet/htontest.c70
-rw-r--r--inet/netinet/in.h41
-rw-r--r--manual/argp.texi9
-rw-r--r--math/test-fenv.c26
-rw-r--r--misc/search.h60
-rw-r--r--nss/nsswitch.c8
-rw-r--r--resolv/gethnamaddr.c6
-rw-r--r--resolv/nss_dns/dns-host.c5
-rw-r--r--string/Makefile2
-rw-r--r--string/byteswap.h40
-rw-r--r--sunrpc/clnt_udp.c2
-rw-r--r--sysdeps/alpha/htonl.S8
-rw-r--r--sysdeps/alpha/htons.S8
-rw-r--r--sysdeps/generic/bits/byteswap.h43
-rw-r--r--sysdeps/generic/htonl.c17
-rw-r--r--sysdeps/generic/htons.c15
-rw-r--r--sysdeps/i386/bits/byteswap.h92
-rw-r--r--sysdeps/i386/bits/htontoh.h79
-rw-r--r--sysdeps/i386/htonl.S8
-rw-r--r--sysdeps/i386/htons.S8
-rw-r--r--sysdeps/i386/i486/htonl.S8
-rw-r--r--sysdeps/m68k/fpu/fraiseexcpt.c30
-rw-r--r--sysdeps/unix/i386/sysdep.h4
-rw-r--r--sysdeps/unix/sysv/linux/Dist1
-rw-r--r--sysdeps/unix/sysv/linux/Makefile2
-rw-r--r--sysdeps/unix/sysv/linux/sys/fsuid.h (renamed from sysdeps/generic/bits/htontoh.h)21
-rw-r--r--sysdeps/vax/htonl.s6
-rw-r--r--sysdeps/vax/htons.s4
32 files changed, 787 insertions, 340 deletions
diff --git a/ChangeLog b/ChangeLog
index 0e0750c485..9f3ed378a5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,91 @@
+1997-07-24 03:14  Ulrich Drepper  <drepper@cygnus.com>
+
+	* elf/dl-deps.c: Complete rewrite to handle DT_AUXILIARY correctly.
+
+	* inet/Makefile (tests): Add htontest.
+	* inet/htontest.c: New file.
+
+	* inet/netinet/in.h: Cleanup optimization of ntoh/hton functions
+	when they are no noops.
+	* sysdeps/alpha/htonl.S: Don't define __ protected names.
+	* sysdeps/alpha/htons.S: Likewise.
+	* sysdeps/generic/htonl.c: Likewise.
+	* sysdeps/generic/htons.c: Likewise.
+	* sysdeps/i386/htonl.S: Likewise.
+	* sysdeps/i386/htons.S: Likewise.
+	* sysdeps/i386/i486/htonl.S: Likewise.
+	* sysdeps/vax/htonl.s: Likewise.
+	* sysdeps/vax/htons.s: Likewise.
+
+	* string/Makefile (headers): Add byteswap.h and bits/byteswap.h.
+	* string/byteswap.h: New file.
+	* sysdeps/generic/bits/byteswap.h: New file.
+	* sysdeps/i386/bits/byteswap.h: New file.
+	* sysdeps/generic/bits/htontoh.h: Removed.
+	* sysdeps/i386/bits/htontoh.h: Removed.
+
+	* misc/search.h: General cleanup.  Don't define reentrant hsearch
+	functions uless __USE_GNU.
+
+	* nss/nsswitch.c: Pretty print.
+
+	* sunrpc/clnt_udp.c (clntudp_call): Initialize outlen to prevent
+	warning.
+
+	* sysdeps/unix/i386/sysdep.h (DO_CALL): Use lcall, binutils have
+	been fixed meanwhile.
+	Reported by Zack Weinberg <zack@rabi.phys.columbia.edu>.
+
+1997-07-24 00:53  Philip Blundell  <Philip.Blundell@pobox.com>
+
+	* db/hash/hash.c (init_hash): Only use statbuf.st_blksize if it
+	exists for this port.
+
+1997-07-24 00:12  Philip Blundell  <Philip.Blundell@pobox.com>
+
+	* sysdeps/standalone/arm/bits/errno.h (ESTALE): Add.
+
+1997-07-22  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>
+
+	* manual/argp.texi (Argp Option Vectors): Use @minus, not @math,
+	to format a proper minus sign.
+
+1997-07-22  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>
+
+	* sysdeps/m68k/fpu/fraiseexcpt.c: Don't handle FE_INEXACT
+	specially, the standard doesn't require it.
+
+	* math/test-fenv.c (test_exceptions): Add IGNORE_INEXACT argument,
+	if non-zero then don't test inexact flag.  Callers changed.
+	(set_single_exc): Ignore inexact flag if underflow or overflow
+	exception is raised.
+
+1997-07-23 05:10  Ulrich Drepper  <drepper@cygnus.com>
+
+	* sysdeps/unix/sysv/linux/sys/fsuid.h: New file.
+	Provided by Michael Deutschmann <ldeutsch@mail.netshop.net>.
+	* sysdeps/unix/sysv/linux/Makefile (headers): Add sys/fsuid.h.
+	* sysdeps/unix/sysv/linux/Dist: Add sys/fsuid.h.
+
+1997-07-16 10:09  Fila Kolodny  <fila@ibi.com>
+
+	* resolv/gethnamaddr.c: Define MAXHOSTNAMELEN as 256, since RFC 1034
+	and 1035 state that a fully qualified domain name cannot exceed 255
+	octets in length.
+	* resolv/nss_dns/dns-host.c: Likewise.
+
+1997-07-22 09:54  H.J. Lu   <hjl@gnu.ai.mit.edu>
+
+	* inet/netinet/in.h (htons): Fix typos.
+
+	* sysdeps/i386/bits/htontoh.h (__ntohs): Return the value.
+
+1997-07-22 11:47  Ulrich Drepper  <drepper@cygnus.com>
+
+	* nss/nsswitch.c (nss_lookup_function): Include function.def, not
+	functions.def.
+	Patch by Klaus Espenlaub <kespenla@hydra.informatik.uni-ulm.de>.
+
 1997-07-22 01:35  Ulrich Drepper  <drepper@cygnus.com>
 
 	* Makerules (+make-deps): Use $(CFLAGS) in run of $(+mkdep) so
diff --git a/bits/byteswap.h b/bits/byteswap.h
new file mode 100644
index 0000000000..9404cc452e
--- /dev/null
+++ b/bits/byteswap.h
@@ -0,0 +1,43 @@
+/* Macros to swap the order of bytes in integer values.
+   Copyright (C) 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.  */
+
+#ifndef _BITS_BYTESWAP_H
+#define _BITS_BYTESWAP_H	1
+
+/* Swap bytes in 16 bit value.  */
+#define __bswap_16(x) \
+     ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))
+
+/* Swap bytes in 32 bit value.  */
+#define __bswap_32(x) \
+     ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >>  8) |		      \
+      (((x) & 0x0000ff00) <<  8) | (((x) & 0x000000ff) << 24))
+
+#if defined __GNUC__ && __GNUC__ >= 2
+/* Swap bytes in 64 bit value.  */
+# define __bswap_64(x) \
+     ({ union { unsigned long long int __ll;				      \
+		unsigned long int __l[2]; } __v, __r;			      \
+        __v.__ll = (x);							      \
+	__r.__l[0] = __bswap_32 (__v.__l[1]);				      \
+	__r.__l[1] = __bswap_32 (__v.__l[0]);				      \
+	__r.__ll; })
+#endif
+
+#endif /* bits/byteswap.h */
diff --git a/elf/dl-deps.c b/elf/dl-deps.c
index e2fd340822..36f5ee0606 100644
--- a/elf/dl-deps.c
+++ b/elf/dl-deps.c
@@ -22,17 +22,27 @@
 #include <dlfcn.h>
 #include <stdlib.h>
 
+#include <assert.h>
+
+/* Whether an shared object references one or more auxiliary objects
+   is signaled by the AUXTAG entry in l_info.  */
+#define AUXTAG	(DT_NUM + DT_PROCNUM + DT_VERSIONTAGNUM \
+		 + DT_EXTRATAGIDX (DT_AUXILIARY))
+
+
+/* When loading auxiliary objects we must ignore errors.  It's ok if
+   an object is missing.  */
 struct openaux_args
-{
-  /* The arguments to openaux.  */
-  struct link_map *map;
-  int trace_mode;
-  const char *strtab;
-  ElfW(Dyn) *d;
+  {
+    /* The arguments to openaux.  */
+    struct link_map *map;
+    int trace_mode;
+    const char *strtab;
+    const ElfW(Dyn) *d;
 
-  /* The return value of openaux.  */
-  struct link_map *aux;
-};
+    /* The return value of openaux.  */
+    struct link_map *aux;
+  };
 
 static void
 openaux (void *a)
@@ -45,78 +55,56 @@ openaux (void *a)
 			      args->trace_mode);
 }
 
+
+
+/* We use a very special kind of list to track the three kinds paths
+   through the list of loaded shared objects.  We have to
+
+   - go through all objects in the correct order, which includes the
+     possible recursive loading of auxiliary objects and dependencies
+
+   - produce a flat list with unique members of all involved objects
+
+   - produce a flat list of all shared objects.
+*/
+struct list
+  {
+    int done;			/* Nonzero if this map was processed.  */
+    struct link_map *map;	/* The data.  */
+
+    struct list *unique;	/* Elements for normal list.  */
+    struct list *dup;		/* Elements in complete list.  */
+  };
+
+
 void
 _dl_map_object_deps (struct link_map *map,
 		     struct link_map **preloads, unsigned int npreloads,
 		     int trace_mode)
 {
-  struct list
-    {
-      struct link_map *map;
-      struct list *next;
-    };
-  struct list *head, *tailp, *scanp;
-  struct list duphead, *duptailp;
-  unsigned int nduplist;
-  unsigned int nlist, naux, i;
+  struct list known[1 + npreloads + 1];
+  struct list *runp, *head, *utail, *dtail;
+  unsigned int nlist, nduplist, i;
+
   inline void preload (struct link_map *map)
     {
-      head[nlist].next = &head[nlist + 1];
-      head[nlist++].map = map;
+      known[nlist].done = 0;
+      known[nlist].map = map;
+
+      known[nlist].unique = &known[nlist + 1];
+      known[nlist].dup = &known[nlist + 1];
 
+      ++nlist;
       /* We use `l_reserved' as a mark bit to detect objects we have
 	 already put in the search list and avoid adding duplicate
 	 elements later in the list.  */
       map->l_reserved = 1;
     }
 
-  naux = nlist = 0;
-
-  /* XXX The AUXILIARY implementation isn't correct in the moment. XXX
-     XXX The problem is that we currently do not handle auxiliary  XXX
-     XXX entries in the loaded objects.				   XXX */
-
-#define AUXTAG	(DT_NUM + DT_PROCNUM + DT_VERSIONTAGNUM \
-		 + DT_EXTRATAGIDX (DT_AUXILIARY))
-
-  /* First determine the number of auxiliary objects we have to load.  */
-  if (map->l_info[AUXTAG])
-    {
-      ElfW(Dyn) *d;
-      for (d = map->l_ld; d->d_tag != DT_NULL; ++d)
-	if (d->d_tag == DT_AUXILIARY)
-	  ++naux;
-    }
-
-  /* Now we can allocate the array for the linker maps. */
-  head = (struct list *) alloca (sizeof (struct list)
-				 * (naux + npreloads + 2));
-
-  /* Load the auxiliary objects, even before the object itself.  */
-  if (map->l_info[AUXTAG])
-    {
-      /* There is at least one auxiliary library specified.  We try to
-	 load it, and if we can, use its symbols in preference to our
-	 own.  But if we can't load it, we just silently ignore it.  */
-      struct openaux_args args;
-      args.strtab
-	= ((void *) map->l_addr + map->l_info[DT_STRTAB]->d_un.d_ptr);
-      args.map = map;
-      args.trace_mode = trace_mode;
-
-      for (args.d = map->l_ld; args.d->d_tag != DT_NULL; ++args.d)
-	if (args.d->d_tag == DT_AUXILIARY)
-	  {
-	    char *errstring;
-	    const char *objname;
-	    if (! _dl_catch_error (&errstring, &objname, openaux, &args))
-	      /* The auxiliary object is actually there.  Use it as
-		 the first search element, even before MAP itself.  */
-	      preload (args.aux);
-	  }
-    }
+  /* No loaded object so far.  */
+  nlist = 0;
 
-  /* Next load MAP itself.  */
+  /* First load MAP itself.  */
   preload (map);
 
   /* Add the preloaded items after MAP but before any of its dependencies.  */
@@ -124,30 +112,51 @@ _dl_map_object_deps (struct link_map *map,
     preload (preloads[i]);
 
   /* Terminate the lists.  */
-  head[nlist - 1].next = NULL;
-  duphead.next = NULL;
+  known[nlist - 1].unique = NULL;
+  known[nlist - 1].dup = NULL;
+
+  /* Pointer to the first member of the unique and duplicate list.  */
+  head = known;
 
-  /* Start here for adding dependencies to the list.  */
-  tailp = &head[nlist - 1];
+  /* Pointer to last unique object.  */
+  utail = &known[nlist - 1];
+  /* Pointer to last loaded object.  */
+  dtail = &known[nlist - 1];
 
   /* Until now we have the same number of libraries in the normal and
      the list with duplicates.  */
   nduplist = nlist;
-  duptailp = &duphead;
 
-  /* Process each element of the search list, loading each of its immediate
-     dependencies and appending them to the list as we step through it.
-     This produces a flat, ordered list that represents a breadth-first
-     search of the dependency tree.  */
-  for (scanp = head; scanp; scanp = scanp->next)
+  /* Process each element of the search list, loading each of its
+     auxiliary objects and immediate dependencies.  Auxiliary objects
+     will be added in the list before the object itself and
+     dependencies will be appended to the list as we step through it.
+     This produces a flat, ordered list that represents a
+     breadth-first search of the dependency tree.
+
+     The whole process is complicated by the fact that we better
+     should use alloca for the temporary list elements.  But using
+     alloca means we cannot use recursive function calls.  */
+  for (runp = known; runp; )
     {
-      struct link_map *l = scanp->map;
+      struct link_map *l = runp->map;
 
-      if (l->l_info[DT_NEEDED])
+      if (runp->done == 0 && (l->l_info[AUXTAG] || l->l_info[DT_NEEDED]))
 	{
-	  const char *strtab
-	    = ((void *) l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr);
+	  const char *strtab = ((void *) l->l_addr
+				+ l->l_info[DT_STRTAB]->d_un.d_ptr);
+	  struct openaux_args args;
+	  struct list *orig;
 	  const ElfW(Dyn) *d;
+
+	  /* Mark map as processed.  */
+	  runp->done = 1;
+
+	  args.strtab = strtab;
+	  args.map = l;
+	  args.trace_mode = trace_mode;
+	  orig = runp;
+
 	  for (d = l->l_ld; d->d_tag != DT_NULL; ++d)
 	    if (d->d_tag == DT_NEEDED)
 	      {
@@ -156,32 +165,182 @@ _dl_map_object_deps (struct link_map *map,
 		  = _dl_map_object (l, strtab + d->d_un.d_val,
 				    l->l_type == lt_executable ? lt_library :
 				    l->l_type, trace_mode);
+		/* Allocate new entry.  */
+		struct list *newp = alloca (sizeof (struct list));
+
+		/* Add it in any case to the duplicate list.  */
+		newp->map = dep;
+		newp->dup = NULL;
+		dtail->dup = newp;
+		dtail = newp;
+		++nduplist;
 
 		if (dep->l_reserved)
 		  /* This object is already in the search list we are
-                     building.  Don't add a duplicate pointer.  Release the
-                     reference just added by _dl_map_object.  */
+		     building.  Don't add a duplicate pointer.
+		     Release the reference just added by
+		     _dl_map_object.  */
 		  --dep->l_opencount;
 		else
 		  {
-		    /* Append DEP to the search list.  */
-		    tailp->next = alloca (sizeof *tailp);
-		    tailp = tailp->next;
-		    tailp->map = dep;
-		    tailp->next = NULL;
+		    /* Append DEP to the unique list.  */
+		    newp->done = 0;
+		    newp->unique = NULL;
+		    utail->unique = newp;
+		    utail = newp;
 		    ++nlist;
 		    /* Set the mark bit that says it's already in the list.  */
 		    dep->l_reserved = 1;
 		  }
+	      }
+	    else if (d->d_tag == DT_AUXILIARY)
+	      {
+		char *errstring;
+		const char *objname;
 
-		/* In any case append DEP to the duplicates search list.  */
-		duptailp->next = alloca (sizeof *duptailp);
-		duptailp = duptailp->next;
-		duptailp->map = dep;
-		duptailp->next = NULL;
-		++nduplist;
+		/* Store the tag in the argument structure.  */
+		args.d = d;
+
+		if (_dl_catch_error (&errstring, &objname, openaux, &args))
+		  {
+		    /* We are not interested in the error message.  */
+		    assert (errstring != NULL);
+		    free (errstring);
+		  }
+		else
+		  {
+		    /* The auxiliary object is actually available.
+		       Incorporate the map in all the lists.  */
+
+		    /* Allocate new entry.  This always has to be done.  */
+		    struct list *newp = alloca (sizeof (struct list));
+
+		    /* Copy the content of the current entry over.  */
+		    memcpy (newp, orig, sizeof (*newp));
+
+		    /* Initialize new entry.  */
+		    orig->done = 0;
+		    orig->map = args.aux;
+		    orig->dup = newp;
+
+		    /* We must handle two situations here: the map is new,
+		       so we must add it in all three lists.  If the map
+		       is already known, we have two further possibilities:
+		       - if the object is before the current map in the
+		         search list, we do nothing.  It is already found
+			 early
+		       - if the object is after the current one, we must
+		         move it just before the current map to make sure
+			 the symbols are found early enough
+		    */
+		    if (args.aux->l_reserved)
+		      {
+			/* The object is already somewhere in the
+			   list.  Locate it first.  */
+			struct list *late;
+
+			/* This object is already in the search list
+			   we are building.  Don't add a duplicate
+			   pointer.  Release the reference just added
+			   by _dl_map_object.  */
+			--args.aux->l_opencount;
+
+			for (late = orig; late->unique; late = late->unique)
+			  if (late->unique->map == args.aux)
+			    break;
+
+			if (late->unique)
+			  {
+			    /* The object is somewhere behind the current
+			       position in the search path.  We have to
+			       move it to this earlier position.  */
+			    orig->unique = newp;
+
+			    /* Now remove the later entry from the unique
+			       list.  */
+			    late->unique = late->unique->unique;
+
+			    /* We must move the earlier in the chain.  */
+			    if (args.aux->l_prev)
+			      args.aux->l_prev->l_next = args.aux->l_next;
+			    if (args.aux->l_next)
+			      args.aux->l_next->l_prev = args.aux->l_prev;
+
+			    args.aux->l_prev = newp->map->l_prev;
+			    newp->map->l_prev = args.aux;
+			    if (args.aux->l_prev != NULL)
+			      args.aux->l_prev->l_next = args.aux;
+			    args.aux->l_next = newp->map;
+			  }
+			else
+			  {
+			    /* The object must be somewhere earlier in
+			       the list.  That's good, we only have to
+			       insert an entry for the duplicate list.  */
+			    orig->unique = NULL;	/* Never used.  */
+
+			    /* Now we have a problem.  The element pointing
+			       to ORIG in the unique list must point to
+			       NEWP now.  This is the only place where we
+			       need this backreference and this situation
+			       is really not that frequent.  So we don't
+			       use a double-linked list but instead search
+			       for the preceding element.  */
+			    late = head;
+			    while (late->unique != orig)
+			      late = late->unique;
+			    late->unique = newp;
+			  }
+		      }
+		    else
+		      {
+			/* This is easy.  We just add the symbol right
+			   here.  */
+			orig->unique = newp;
+			++nlist;
+			/* Set the mark bit that says it's already in
+			   the list.  */
+			args.aux->l_reserved = 1;
+
+			/* The only problem is that in the double linked
+			   list of all objects we don't have this new
+			   object at the correct place.  Correct this
+			   here.  */
+			if (args.aux->l_prev)
+			  args.aux->l_prev->l_next = args.aux->l_next;
+			if (args.aux->l_next)
+			  args.aux->l_next->l_prev = args.aux->l_prev;
+
+			args.aux->l_prev = newp->map->l_prev;
+			newp->map->l_prev = args.aux;
+			if (args.aux->l_prev != NULL)
+			  args.aux->l_prev->l_next = args.aux;
+			args.aux->l_next = newp->map;
+		      }
+
+		    /* Move the tail pointers if necessary.  */
+		    if (orig == utail)
+		      utail = newp;
+		    if (orig == dtail)
+		      dtail = newp;
+
+		    /* Move on the insert point.  */
+		    orig = newp;
+
+		    /* We always add an entry to the duplicate list.  */
+		    ++nduplist;
+		  }
 	      }
 	}
+      else
+	/* Mark as processed.  */
+	runp->done = 1;
+
+      /* If we have no auxiliary objects just go on to the next map.  */
+      if (runp->done)
+	do
+	  runp = runp->unique;
+	while (runp && runp->done);
     }
 
   /* Store the search list we built in the object.  It will be used for
@@ -192,24 +351,26 @@ _dl_map_object_deps (struct link_map *map,
 		      "cannot allocate symbol search list");
   map->l_nsearchlist = nlist;
 
-  nlist = 0;
-  for (scanp = head; scanp; scanp = scanp->next)
+  for (nlist = 0, runp = head; runp; runp = runp->unique)
     {
-      map->l_searchlist[nlist++] = scanp->map;
+      map->l_searchlist[nlist++] = runp->map;
 
       /* Now clear all the mark bits we set in the objects on the search list
 	 to avoid duplicates, so the next call starts fresh.  */
-      scanp->map->l_reserved = 0;
+      runp->map->l_reserved = 0;
     }
 
-  map->l_dupsearchlist = malloc (nduplist * sizeof (struct link_map *));
-  if (map->l_dupsearchlist == NULL)
-    _dl_signal_error (ENOMEM, map->l_name,
-		      "cannot allocate symbol search list");
   map->l_ndupsearchlist = nduplist;
+  if (nlist == nduplist)
+    map->l_dupsearchlist = map->l_searchlist;
+  else
+    {
+      map->l_dupsearchlist = malloc (nduplist * sizeof (struct link_map *));
+      if (map->l_dupsearchlist == NULL)
+	_dl_signal_error (ENOMEM, map->l_name,
+			  "cannot allocate symbol search list");
 
-  for (nlist = 0; nlist < naux + 1 + npreloads; ++nlist)
-    map->l_dupsearchlist[nlist] = head[nlist].map;
-  for (scanp = duphead.next; scanp; scanp = scanp->next)
-    map->l_dupsearchlist[nlist++] = scanp->map;
+      for (nlist = 0, runp = head; runp; runp = runp->dup)
+	map->l_searchlist[nlist++] = runp->map;
+    }
 }
diff --git a/inet/Makefile b/inet/Makefile
index 47570f131c..0237d0b45d 100644
--- a/inet/Makefile
+++ b/inet/Makefile
@@ -46,6 +46,8 @@ routines := htonl htons		\
 	    getaliasent_r getaliasent getaliasname getaliasname_r \
 	    in6_addr getnameinfo if_index
 
+tests := htontest
+
 # No warnings about losing BSD code.
 CFLAGS-rcmd.c = -w
 CFLAGS-rexec.c = -w
diff --git a/inet/htontest.c b/inet/htontest.c
new file mode 100644
index 0000000000..87167b44a3
--- /dev/null
+++ b/inet/htontest.c
@@ -0,0 +1,70 @@
+/* Test hton/ntoh functions.
+   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 <endian.h>
+#include <stdio.h>
+#include <netinet/in.h>
+
+#if BYTE_ORDER == BIG_ENDIAN
+# define TEST(orig, swapped, fct) \
+  if ((fct (orig)) != (orig)) {						      \
+    printf ("Failed for %s -> %#x\n", #fct "(" #orig ")", fct (orig));	      \
+    result = 1;								      \
+  }
+#elif BYTE_ORDER == LITTLE_ENDIAN
+# define TEST(orig, swapped, fct) \
+  if ((fct (orig)) != (swapped)) {					      \
+    printf ("Failed for %s -> %#x\n", #fct "(" #orig ")", fct (orig));	      \
+    result = 1;								      \
+  }
+#else
+# error "Bah, what kind of system do you use?"
+#endif
+
+u_int32_t lo = 0x67452301;
+u_int16_t foo = 0x1234;
+
+int
+main (void)
+{
+  int result = 0;
+
+  TEST (0x67452301, 0x01234567, htonl);
+  TEST (0x67452301, 0x01234567, (htonl));
+  TEST (0x67452301, 0x01234567, ntohl);
+  TEST (0x67452301, 0x01234567, (ntohl));
+
+  TEST (lo, 0x01234567, htonl);
+  TEST (lo, 0x01234567, (htonl));
+  TEST (lo, 0x01234567, ntohl);
+  TEST (lo, 0x01234567, (ntohl));
+
+  TEST (0x1234, 0x3412, htons);
+  TEST (0x1234, 0x3412, (htons));
+  TEST (0x1234, 0x3412, ntohs);
+  TEST (0x1234, 0x3412, (ntohs));
+
+  TEST (foo, 0x3412, htons);
+  TEST (foo, 0x3412, (htons));
+  TEST (foo, 0x3412, ntohs);
+  TEST (foo, 0x3412, (ntohs));
+
+  return result;
+}
diff --git a/inet/netinet/in.h b/inet/netinet/in.h
index ac0d167287..d2a366b51c 100644
--- a/inet/netinet/in.h
+++ b/inet/netinet/in.h
@@ -185,9 +185,9 @@ struct sockaddr_in
 struct sockaddr_in6
   {
     __SOCKADDR_COMMON (sin6_);
-    u_int16_t		sin6_port;      /* Transport layer port # */
-    u_int32_t		sin6_flowinfo;  /* IPv6 flow information */
-    struct in6_addr	sin6_addr;      /* IPv6 address */
+    u_int16_t sin6_port;	/* Transport layer port # */
+    u_int32_t sin6_flowinfo;	/* IPv6 flow information */
+    struct in6_addr sin6_addr;	/* IPv6 address */
   };
 
 /* IPv6 multicast request.  */
@@ -197,7 +197,7 @@ struct ipv6_mreq
     struct in6_addr ipv6mr_multiaddr;
 
     /* local IPv6 address of interface */
-    int		ipv6mr_ifindex;
+    int ipv6mr_ifindex;
   };
 
 /* Get system-specific definitions.  */
@@ -210,18 +210,17 @@ struct ipv6_mreq
    this was a short-sighted decision since on different systems the types
    may have different representations but the values are always the same.  */
 
-extern u_int32_t __ntohl __P ((u_int32_t __netlong));
 extern u_int32_t ntohl __P ((u_int32_t __netlong));
-extern u_int16_t __ntohs __P ((u_int16_t __netshort));
 extern u_int16_t ntohs __P ((u_int16_t __netshort));
-extern u_int32_t __htonl __P ((u_int32_t __hostlong));
 extern u_int32_t htonl __P ((u_int32_t __hostlong));
-extern u_int16_t __htons __P ((u_int16_t __hostshort));
 extern u_int16_t htons __P ((u_int16_t __hostshort));
 
 #include <endian.h>
 
-#if __BYTE_ORDER == __BIG_ENDIAN
+/* Get machine dependent optimized versions of byte swapping functions.  */
+#include <bits/byteswap.h>
+
+#if __BYTE_ORDER == __BIG_ENDIAN && defined __OPTIMIZE__
 /* The host byte order is the same as network byte order,
    so these functions are all just identity.  */
 # define ntohl(x)	(x)
@@ -230,26 +229,10 @@ extern u_int16_t htons __P ((u_int16_t __hostshort));
 # define htons(x)	(x)
 #else
 # if __BYTE_ORDER == __LITTLE_ENDIAN && defined __OPTIMIZE__
-#  define ntohl(x)	(__builtin_constant_p (x)			  \
-			 ? __constant_htontohl (x) : __ntohl (x))
-#  define ntohs(x)	(__builtin_constant_p (x)			  \
-			 ? __constant_htontohs (x) : __ntohs (x))
-#  define htonl(x)	(__builtin_constant_p (x)			  \
-			 ? __constant_htontohl (x) : __htonl (x))
-#  define htons(x)	(__builtin_constant_p (x)			  \
-			 ? __constant_htontohl (x) : __htonl (x))
-
-#  define __constant_htontohl(x) \
-	((((x) & 0xff000000) >> 24) | \
-	 (((x) & 0x00ff0000) >>  8) | \
-	 (((x) & 0x0000ff00) <<  8) | \
-	 (((x) & 0x000000ff) << 24))
-#  define __constant_htontohs(x) \
-	((((x) & 0x0000ff00) >>  8) | \
-	 (((x) & 0x000000ff) << 8))
-
-/* Now get machine dependent optimized versions for the real work.  */
-#  include <bits/htontoh.h>
+#  define ntohl(x)	__bswap_32 (x)
+#  define ntohs(x)	__bswap_16 (x)
+#  define htonl(x)	__bswap_32 (x)
+#  define htons(x)	__bswap_16 (x)
 # endif
 #endif
 
diff --git a/manual/argp.texi b/manual/argp.texi
index c049d0e1b6..84b131f36a 100644
--- a/manual/argp.texi
+++ b/manual/argp.texi
@@ -271,15 +271,14 @@ group); in this usage, it's conventional to end the string with a
 The group this option is in.
 
 In a long help message, options are sorted alphabetically within each
-group, and the groups presented in the order @math{0, 1, 2,} @dots{},
-@math{@var{n}, -@var{m},} @dots{}, @math{-2, -1}.  Every entry in an
+group, and the groups presented in the order 0, 1, 2, @dots{}, @var{n},
+@minus{}@var{m}, @dots{}, @minus{}2, @minus{}1.  Every entry in an
 options array with this
 field 0 will inherit the group number of the previous entry, or zero if
 it's the first one, unless its a group header (@code{name} and
-@code{key} fields both zero), in which case, the previous entry
-@math{@w{} + 1} is
+@code{key} fields both zero), in which case, the previous entry + 1 is
 the default.  Automagic options such as @samp{--help} are put into group
-@math{-1}.
+@minus{}1.
 
 Note that because of C structure initialization rules, this field
 often need not be specified, because 0 is the right value.
diff --git a/math/test-fenv.c b/math/test-fenv.c
index 9161c3342e..2c3aeb07f9 100644
--- a/math/test-fenv.c
+++ b/math/test-fenv.c
@@ -85,7 +85,8 @@ test_single_exception (short int exception,
 }
 
 static void
-test_exceptions (const char *test_name, short int exception)
+test_exceptions (const char *test_name, short int exception,
+		 int ignore_inexact)
 {
   printf ("Test: %s\n", test_name);
 #ifdef FE_DIVBYZERO
@@ -97,8 +98,9 @@ test_exceptions (const char *test_name, short int exception)
                          "INVALID");
 #endif
 #ifdef FE_INEXACT
-  test_single_exception (exception, INEXACT_EXC, FE_INEXACT,
-                         "INEXACT");
+  if (!ignore_inexact)
+    test_single_exception (exception, INEXACT_EXC, FE_INEXACT,
+			   "INEXACT");
 #endif
 #ifdef FE_UNDERFLOW
   test_single_exception (exception, UNDERFLOW_EXC, FE_UNDERFLOW,
@@ -163,28 +165,32 @@ static void
 set_single_exc (const char *test_name, int fe_exc, fexcept_t exception)
 {
   char str[200];
+  /* The standard allows the inexact exception to be set together with the
+     underflow and overflow exceptions.  So ignore the inexact flag if the
+     others are raised.  */
+  int ignore_inexact = (fe_exc & (UNDERFLOW_EXC | OVERFLOW_EXC)) != 0;
 
   strcpy (str, test_name);
   strcat (str, ": set flag, with rest not set");
   feclearexcept (FE_ALL_EXCEPT);
   feraiseexcept (exception);
-  test_exceptions (str, fe_exc);
+  test_exceptions (str, fe_exc, ignore_inexact);
 
   strcpy (str, test_name);
   strcat (str, ": clear flag, rest also unset");
   feclearexcept (exception);
-  test_exceptions (str, NO_EXC);
+  test_exceptions (str, NO_EXC, ignore_inexact);
 
   strcpy (str, test_name);
   strcat (str, ": set flag, with rest set");
   feraiseexcept (FE_ALL_EXCEPT ^ exception);
   feraiseexcept (exception);
-  test_exceptions (str, ALL_EXC);
+  test_exceptions (str, ALL_EXC, 0);
 
   strcpy (str, test_name);
   strcat (str, ": clear flag, leave rest set");
   feclearexcept (exception);
-  test_exceptions (str, ALL_EXC ^ fe_exc);
+  test_exceptions (str, ALL_EXC ^ fe_exc, 0);
 }
 
 static void
@@ -193,12 +199,12 @@ fe_tests (void)
   /* clear all exceptions and test if all are cleared */
   feclearexcept (FE_ALL_EXCEPT);
   test_exceptions ("feclearexcept (FE_ALL_EXCEPT) clears all exceptions",
-                   NO_EXC);
+                   NO_EXC, 0);
 
   /* raise all exceptions and test if all are raised */
   feraiseexcept (FE_ALL_EXCEPT);
   test_exceptions ("feraiseexcept (FE_ALL_EXCEPT) raises all exceptions",
-                   ALL_EXC);
+                   ALL_EXC, 0);
   feclearexcept (FE_ALL_EXCEPT);
 
 #ifdef FE_DIVBYZERO
@@ -339,7 +345,7 @@ static void
 initial_tests (void)
 {
   test_exceptions ("Initially all exceptions should be cleared",
-                   NO_EXC);
+                   NO_EXC, 0);
   test_rounding ("Rounding direction should be initalized to nearest",
                  FE_TONEAREST);
 }
diff --git a/misc/search.h b/misc/search.h
index ff0672d39d..2b0106463d 100644
--- a/misc/search.h
+++ b/misc/search.h
@@ -20,7 +20,7 @@
 #ifndef _SEARCH_H
 #define	_SEARCH_H 1
 
-#include <sys/cdefs.h>
+#include <features.h>
 
 #define __need_size_t
 #define __need_NULL
@@ -28,7 +28,7 @@
 
 __BEGIN_DECLS
 
-#if defined(__USE_SVID) || defined(__USE_XOPEN_EXTENDED)
+#if defined __USE_SVID || defined __USE_XOPEN_EXTENDED
 /* Prototype structure for a linked-list data structure.
    This is the type used by the `insque' and `remque' functions.  */
 
@@ -50,7 +50,7 @@ extern void remque __P ((void *__elem));
 
 /* For use with hsearch(3).  */
 #ifndef __COMPAR_FN_T
-#define __COMPAR_FN_T
+# define __COMPAR_FN_T
 typedef int (*__compar_fn_t) __P ((__const __ptr_t, __const __ptr_t));
 #endif
 
@@ -72,6 +72,23 @@ ENTRY;
 /* Opaque type for internal use.  */
 struct _ENTRY;
 
+/* Family of hash table handling functions.  The functions also
+   have reentrant counterparts ending with _r.  The non-reentrant
+   functions all work on a signle internal hashing table.  */
+
+/* Search for entry matching ITEM.key in internal hash table.  If
+   ACTION is `FIND' return found entry or signal error by returning
+   NULL.  If ACTION is `ENTER' replace existing data (if any) with
+   ITEM.data.  */
+extern ENTRY *hsearch __P ((ENTRY __item, ACTION __action));
+
+/* Create a new hashing table which will at most contain NEL elements.  */
+extern int hcreate __P ((size_t __nel));
+
+/* Destroy current internal hashing table.  */
+extern void hdestroy __P ((void));
+
+#ifdef __USE_GNU
 /* Data type for reentrant functions.  */
 struct hsearch_data
   {
@@ -80,16 +97,13 @@ struct hsearch_data
     unsigned int filled;
   };
 
-/* Family of hash table handling functions.  The functions also have
-   reentrant counterparts ending with _r.  */
-extern ENTRY *hsearch __P ((ENTRY __item, ACTION __action));
-extern int hcreate __P ((size_t __nel));
-extern void hdestroy __P ((void));
-
+/* Reentrant versions which can handle multiple hashing tables at the
+   same time.  */
 extern int hsearch_r __P ((ENTRY __item, ACTION __action, ENTRY **__retval,
 			   struct hsearch_data *__htab));
 extern int hcreate_r __P ((size_t __nel, struct hsearch_data *htab));
 extern void hdestroy_r __P ((struct hsearch_data *htab));
+#endif
 
 
 /* The tsearch routines are very interesting. They make many
@@ -108,26 +122,26 @@ VISIT;
 
 /* Search for an entry matching the given KEY in the tree pointed to
    by *ROOTP and insert a new element if not found.  */
-extern void *tsearch __P ((__const void * __key, void **__rootp,
+extern void *tsearch __P ((__const void *__key, void **__rootp,
 			   __compar_fn_t compar));
-extern void *__tsearch __P ((__const void * __key, void **__rootp,
+extern void *__tsearch __P ((__const void *__key, void **__rootp,
 			     __compar_fn_t compar));
 
 /* Search for an entry matching the given KEY in the tree pointed to
    by *ROOTP.  If no matching entry is available return NULL.  */
-extern void *tfind __P ((__const void * __key, void *__const * __rootp,
+extern void *tfind __P ((__const void *__key, void *__const *__rootp,
 			 __compar_fn_t compar));
-extern void *__tfind __P ((__const void * __key, void *__const * __rootp,
+extern void *__tfind __P ((__const void *__key, void *__const *__rootp,
 			   __compar_fn_t compar));
 
 /* Remove the element matching KEY from the tree pointed to by *ROOTP.  */
-extern void *tdelete __P ((__const void * __key, void ** __rootp,
+extern void *tdelete __P ((__const void *__key, void **__rootp,
 			   __compar_fn_t compar));
-extern void *__tdelete __P ((__const void * __key, void ** __rootp,
+extern void *__tdelete __P ((__const void *__key, void **__rootp,
 			     __compar_fn_t compar));
 
 #ifndef __ACTION_FN_T
-#define __ACTION_FN_T
+# define __ACTION_FN_T
 typedef void (*__action_fn_t) __P ((__const void *__nodep,
 				    VISIT __value,
 				    int __level));
@@ -135,9 +149,9 @@ typedef void (*__action_fn_t) __P ((__const void *__nodep,
 
 /* Walk through the whole tree and call the ACTION callback for every node
    or leaf.  */
-extern void twalk __P ((__const void * __root, __action_fn_t action));
+extern void twalk __P ((__const void *__root, __action_fn_t action));
 
-extern void __twalk __P ((__const void * __root, __action_fn_t action));
+extern void __twalk __P ((__const void *__root, __action_fn_t action));
 
 #ifdef __USE_GNU
 /* Callback type for function to free a tree node.  If the keys are atomic
@@ -152,14 +166,14 @@ extern void tdestroy __P ((void *__root, __free_fn_t freefct));
 
 /* Perform linear search for KEY by comparing by COMPAR in an array
    [BASE,BASE+NMEMB*SIZE).  */
-extern void * lfind __P ((__const void *__key, __const void *__base,
-			  size_t *__nmemb, size_t __size,
-			  __compar_fn_t __compar));
+extern void *lfind __P ((__const void *__key, __const void *__base,
+			 size_t *__nmemb, size_t __size,
+			 __compar_fn_t __compar));
 
 /* Perform linear search for KEY by comparing by COMPAR function in
    array [BASE,BASE+NMEMB*SIZE) and insert entry if not found.  */
-extern void * lsearch __P ((__const void *__key, void *__base, size_t *__nmemb,
-			    size_t __size, __compar_fn_t __compar));
+extern void *lsearch __P ((__const void *__key, void *__base, size_t *__nmemb,
+			   size_t __size, __compar_fn_t __compar));
 
 __END_DECLS
 
diff --git a/nss/nsswitch.c b/nss/nsswitch.c
index 16cf0e8040..7dd3e0526f 100644
--- a/nss/nsswitch.c
+++ b/nss/nsswitch.c
@@ -426,13 +426,13 @@ nss_lookup_function (service_user *ni, const char *fct_name)
 	    extern void _nss_##h##_get##nm##_r (void);
 # define DEFINE_GETBY(h,nm,ky)						      \
 	    extern void _nss_##h##_get##nm##by##ky##_r (void);
-# include "functions.def"
+# include "function.def"
 # undef DEFINE_ENT
 # undef DEFINE_GET
 # undef DEFINE_GETBY
 # define DEFINE_ENT(h,nm)						      \
-	    { #h"_get"#nm"ent_r", _nss_##h##_get##nm##ent_r },	      \
-	    { #h"_end"#nm"ent", _nss_##h##_end##nm##ent },	      \
+	    { #h"_get"#nm"ent_r", _nss_##h##_get##nm##ent_r },		      \
+	    { #h"_end"#nm"ent", _nss_##h##_end##nm##ent },		      \
 	    { #h"_set"#nm"ent", _nss_##h##_set##nm##ent },
 # define DEFINE_GET(h,nm)						      \
 	    { #h"_get"#nm"_r", _nss_##h##_get##nm##_r },
@@ -440,7 +440,7 @@ nss_lookup_function (service_user *ni, const char *fct_name)
 	    { #h"_get"#nm"by"#ky"_r", _nss_##h##_get##nm##by##ky##_r },
 	    static struct fct_tbl { const char *fname; void *fp; } *tp, tbl[] =
 	      {
-# include "functions.def"
+# include "function.def"
 		{ NULL, NULL }
 	      };
 	    size_t namlen = (5 + strlen (ni->library->name) + 1
diff --git a/resolv/gethnamaddr.c b/resolv/gethnamaddr.c
index f2def79e24..49aea2a719 100644
--- a/resolv/gethnamaddr.c
+++ b/resolv/gethnamaddr.c
@@ -123,6 +123,12 @@ static void addrsort __P((char **, int));
 #define	MAXPACKET	1024
 #endif
 
+/* As per RFC 1034 and 1035 a host name cannot exceed 255 octets in length.  */
+#ifdef MAXHOSTNAMELEN
+# undef MAXHOSTNAMELEN
+#endif
+#define MAXHOSTNAMELEN 256
+
 typedef union {
     HEADER hdr;
     u_char buf[MAXPACKET];
diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
index 19ca33e197..f7721840b7 100644
--- a/resolv/nss_dns/dns-host.c
+++ b/resolv/nss_dns/dns-host.c
@@ -99,6 +99,11 @@
 #else
 # define MAXPACKET	1024
 #endif
+/* As per RFC 1034 and 1035 a host name cannot exceed 255 octets in length.  */
+#ifdef MAXHOSTNAMELEN
+# undef MAXHOSTNAMELEN
+#endif
+#define MAXHOSTNAMELEN 256
 
 static const char AskedForGot[] = "\
 gethostby*.getanswer: asked for \"%s\", got \"%s\"";
diff --git a/string/Makefile b/string/Makefile
index 8eed493a99..3b895dce26 100644
--- a/string/Makefile
+++ b/string/Makefile
@@ -22,7 +22,7 @@
 subdir	:= string
 
 headers	:= string.h strings.h memory.h endian.h bits/endian.h \
-	   argz.h envz.h
+	   argz.h envz.h byteswap.h bits/byteswap.h
 
 routines	:= strcat strchr strcmp strcoll strcpy strcspn		\
 		   strverscmp strdup strndup				\
diff --git a/string/byteswap.h b/string/byteswap.h
new file mode 100644
index 0000000000..4a3e680cc2
--- /dev/null
+++ b/string/byteswap.h
@@ -0,0 +1,40 @@
+/* Copyright (C) 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.  */
+
+#ifndef _BYTESWAP_H
+#define _BYTESWAP_H	1
+
+/* Get the machine specific, optimized definitions.  */
+#include <bits/byteswap.h>
+
+
+/* The following definitions must all be macros since otherwise some
+   of the possible optimizations are not possible.  */
+
+/* Return a value with all bytes in the 16 bit argument swapped.  */
+#define bswap_16(x) __bswap_16 (x)
+
+/* Return a value with all bytes in the 32 bit argument swapped.  */
+#define bswap_32(x) __bswap_32 (x)
+
+#if defined __GNUC__ && __GNUC__ >= 2
+/* Return a value with all bytes in the 64 bit argument swapped.  */
+# define bswap_64(x) __bswap_64 (x)
+#endif
+
+#endif /* byteswap.h */
diff --git a/sunrpc/clnt_udp.c b/sunrpc/clnt_udp.c
index 5faf46caee..a54e1d5665 100644
--- a/sunrpc/clnt_udp.c
+++ b/sunrpc/clnt_udp.c
@@ -231,7 +231,7 @@ clntudp_call (cl, proc, xargs, argsp, xresults, resultsp, utimeout)
 {
   struct cu_data *cu = (struct cu_data *) cl->cl_private;
   XDR *xdrs;
-  int outlen;
+  int outlen = 0;
   int inlen;
   size_t fromlen;
 #ifdef FD_SETSIZE
diff --git a/sysdeps/alpha/htonl.S b/sysdeps/alpha/htonl.S
index c6e09f134f..4308192cbf 100644
--- a/sysdeps/alpha/htonl.S
+++ b/sysdeps/alpha/htonl.S
@@ -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.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -18,7 +18,7 @@
 
 #include <sysdep.h>
 
-ENTRY(__htonl)
+ENTRY(htonl)
 #ifdef PROF
 	ldgp	gp, 0(pv)
 	.set noat
@@ -43,6 +43,4 @@ ENTRY(__htonl)
 
 	END(__htonl)
 
-strong_alias_asm(__htonl, __ntohl)
-weak_alias(__htonl, htonl)
-weak_alias(__htonl, ntohl)
+weak_alias(htonl, ntohl)
diff --git a/sysdeps/alpha/htons.S b/sysdeps/alpha/htons.S
index 8d3aefe149..f65f0e0826 100644
--- a/sysdeps/alpha/htons.S
+++ b/sysdeps/alpha/htons.S
@@ -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.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -18,7 +18,7 @@
 
 #include <sysdep.h>
 
-ENTRY(__htons)
+ENTRY(htons)
 #ifdef PROF
 	ldgp	gp, 0(pv)
 	.set noat
@@ -37,6 +37,4 @@ ENTRY(__htons)
 
 	END(__htons)
 
-strong_alias_asm(__htons, __ntohs)
-weak_alias(__htons, htons)
-weak_alias(__htons, ntohs)
+weak_alias(htons, ntohs)
diff --git a/sysdeps/generic/bits/byteswap.h b/sysdeps/generic/bits/byteswap.h
new file mode 100644
index 0000000000..9404cc452e
--- /dev/null
+++ b/sysdeps/generic/bits/byteswap.h
@@ -0,0 +1,43 @@
+/* Macros to swap the order of bytes in integer values.
+   Copyright (C) 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.  */
+
+#ifndef _BITS_BYTESWAP_H
+#define _BITS_BYTESWAP_H	1
+
+/* Swap bytes in 16 bit value.  */
+#define __bswap_16(x) \
+     ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))
+
+/* Swap bytes in 32 bit value.  */
+#define __bswap_32(x) \
+     ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >>  8) |		      \
+      (((x) & 0x0000ff00) <<  8) | (((x) & 0x000000ff) << 24))
+
+#if defined __GNUC__ && __GNUC__ >= 2
+/* Swap bytes in 64 bit value.  */
+# define __bswap_64(x) \
+     ({ union { unsigned long long int __ll;				      \
+		unsigned long int __l[2]; } __v, __r;			      \
+        __v.__ll = (x);							      \
+	__r.__l[0] = __bswap_32 (__v.__l[1]);				      \
+	__r.__l[1] = __bswap_32 (__v.__l[0]);				      \
+	__r.__ll; })
+#endif
+
+#endif /* bits/byteswap.h */
diff --git a/sysdeps/generic/htonl.c b/sysdeps/generic/htonl.c
index d460d40f89..f433075a0f 100644
--- a/sysdeps/generic/htonl.c
+++ b/sysdeps/generic/htonl.c
@@ -19,17 +19,18 @@
 #include <netinet/in.h>
 
 #undef	htonl
+#undef	ntohl
 
 u_int32_t
-__htonl (x)
+htonl (x)
      u_int32_t x;
 {
-#if BYTE_ORDER == LITTLE_ENDIAN
-  x = (x << 24) | ((x & 0xff00) << 8) | ((x & 0xff0000) >> 8) | (x >> 24);
-#endif
-
+#if BYTE_ORDER == BIG_ENDIAN
   return x;
+#elif BYTE_ORDER == LITTLE_ENDIAN
+  return __bswap_32 (x);
+#else
+# error "What kind of system is this?"
+#endif
 }
-strong_alias (__htonl, __ntohl)
-weak_alias (__htonl, htonl)
-weak_alias (__ntohl, ntohl)
+weak_alias (htonl, ntohl)
diff --git a/sysdeps/generic/htons.c b/sysdeps/generic/htons.c
index a0a0e81adf..8914f74f2e 100644
--- a/sysdeps/generic/htons.c
+++ b/sysdeps/generic/htons.c
@@ -19,17 +19,18 @@
 #include <netinet/in.h>
 
 #undef	htons
+#undef	ntohs
 
 u_int16_t
 __htons (x)
      u_int16_t x;
 {
-#if BYTE_ORDER == LITTLE_ENDIAN
-  x = (x << 8) | (x >> 8);
-#endif
-
+#if BYTE_ORDER == BIG_ENDIAN
   return x;
+#elif BYTE_ORDER == LITTLE_ENDIAN
+  return __bswap_16 (x);
+#else
+# error "What kind of system is this?"
+#endif
 }
-strong_alias (__htons, __ntohs)
-weak_alias (__htons, htons)
-weak_alias (__ntohs, ntohs)
+weak_alias (htons, ntohs)
diff --git a/sysdeps/i386/bits/byteswap.h b/sysdeps/i386/bits/byteswap.h
new file mode 100644
index 0000000000..326962e621
--- /dev/null
+++ b/sysdeps/i386/bits/byteswap.h
@@ -0,0 +1,92 @@
+/* Macros to swap the order of bytes in integer values.
+   Copyright (C) 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.  */
+
+#ifndef _BITS_BYTESWAP_H
+#define _BITS_BYTESWAP_H	1
+
+/* Swap bytes in 16 bit value.  */
+#define __bswap_constant_16(x) \
+     ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))
+
+#if defined __GNUC__ && __GNUC__ >= 2
+# define __bswap_16(x) \
+     ({ register unsigned short int __v;				      \
+	if (__builtin_constant_p (x))					      \
+	  __v = __bswap_constant_16 (x);				      \
+	else								      \
+	  __asm__ __volatile__ ("rorw $8, %w0"				      \
+				: "=q" (__v)				      \
+				: "0" ((unsigned short int) (x))	      \
+				: "cc");				      \
+	__v; })
+#else
+/* This is better than nothing.  */
+# define __bswap_16(x) __bswap_constant_16 (x)
+#endif
+
+
+/* Swap bytes in 32 bit value.  */
+#define __bswap_constant_32(x) \
+     ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >>  8) |		      \
+      (((x) & 0x0000ff00) <<  8) | (((x) & 0x000000ff) << 24))
+
+#if defined __GNUC__ && __GNUC__ >= 2
+/* To swap the bytes in a word the i486 processors and up provide the
+   `bswap' opcode.  On i386 we have to use three instructions.  */
+# if !defined __i486__ && !defined __pentium__ && !defined __pentiumpro__
+#  define __bswap_32(x) \
+     ({ register unsigned int __v;					      \
+	if (__builtin_constant_p (x))					      \
+	  __v = __bswap_constant_32 (x);				      \
+	else								      \
+	  __asm__ __volatile__ ("rorw $8, %w0;"				      \
+				"rorl $16, %0;"				      \
+				"rorw $8, %w0"				      \
+				: "=q" (__v)				      \
+				: "0" ((unsigned int) (x))		      \
+				: "cc");				      \
+	__v; })
+# else
+#  define __bswap_32(x) \
+     ({ register unsigned int __v;					      \
+	if (__builtin_constant_p (x))					      \
+	  __v = __bswap_constant_32 (x);				      \
+	else								      \
+	  __asm__ __volatile__ ("bswap %0"				      \
+				: "=r" (__v)				      \
+				: "0" ((unsigned int) (x)));		      \
+	__v; })
+# endif
+#else
+# define __bswap_32(x) __bswap_constant_32 (x)
+#endif
+
+
+#if defined __GNUC__ && __GNUC__ >= 2
+/* Swap bytes in 64 bit value.  */
+# define __bswap_64(x) \
+     ({ union { unsigned long long int __ll;				      \
+		unsigned long int __l[2]; } __v, __r;			      \
+        __v.__ll = (x);							      \
+	__r.__l[0] = __bswap_32 (__v.__l[1]);				      \
+	__r.__l[1] = __bswap_32 (__v.__l[0]);				      \
+	__r.__ll; })
+#endif
+
+#endif /* bits/byteswap.h */
diff --git a/sysdeps/i386/bits/htontoh.h b/sysdeps/i386/bits/htontoh.h
deleted file mode 100644
index 590b509875..0000000000
--- a/sysdeps/i386/bits/htontoh.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/* Copyright (C) 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.  */
-
-#ifndef _NETINET_IN_H
-# error "Don't include this file directly, use <netinet/in.h>"
-#endif
-
-#if defined __GNUC__ && __GNUC__ >= 2
-/* We can use inline assembler instructions to optimize the code.  */
-
-/* To swap the bytes in a word the i486 processors and up provide the
-   `bswap' opcode.  On i386 we have to use three instructions.  */
-# if !defined __i486__ && !defined __pentium__ && !defined __pentiumpro__
-
-extern __inline u_int32_t
-__ntohl (u_int32_t netlong)
-{
-  register u_int32_t hostlong;
-
-  __asm__ ("rorw $8, %w0; rorl $16, %0; rorw $8, %w0"
-	   : "=r" (hostlong)
-	   : "0" (netlong));
-
-  return hostlong;
-}
-
-# else
-
-extern __inline u_int32_t
-__ntohl (u_int32_t netlong)
-{
-  register u_int32_t hostlong;
-
-  __asm__ ("bswap %0" : "=r" (hostlong) : "0" (netlong));
-
-  return hostlong;
-}
-
-# endif
-
-/* For a short word we have a simple solution.  */
-extern __inline u_int16_t
-__ntohs (u_int16_t netshort)
-{
-  register u_int16_t hostshort;
-
-  __asm__ ("rorw $8, %w0" : "=r" (hostshort) : "0" (netshort));
-}
-
-
-/* The other direction can be handled with the same functions.  */
-extern __inline u_int32_t
-__htonl (u_int32_t hostlong)
-{
-  return __ntohl (hostlong);
-}
-
-extern __inline u_int16_t
-__htons (u_int16_t hostshort)
-{
-  return __ntohs (hostshort);
-}
-
-#endif /* GNU CC */
diff --git a/sysdeps/i386/htonl.S b/sysdeps/i386/htonl.S
index 73dd1e9bea..9c87be6392 100644
--- a/sysdeps/i386/htonl.S
+++ b/sysdeps/i386/htonl.S
@@ -26,14 +26,12 @@
 */
 
 	.text
-ENTRY (__htonl)
+ENTRY (htonl)
 	movl	4(%esp), %eax
 	rorw	$8, %ax
 	rorl	$16, %eax
 	rorw	$8, %ax
 	ret
-END (__htonl)
+END (htonl)
 
-strong_alias (__htonl, __ntohl)
-weak_alias (__htonl, htonl)
-weak_alias (__ntohl, ntohl)
+weak_alias (htonl, ntohl)
diff --git a/sysdeps/i386/htons.S b/sysdeps/i386/htons.S
index 5d0f59c92b..b0539c55cd 100644
--- a/sysdeps/i386/htons.S
+++ b/sysdeps/i386/htons.S
@@ -26,13 +26,11 @@
 */
 
 	.text
-ENTRY (__htons)
+ENTRY (htons)
 	movl	4(%esp), %eax
 	andl	$0xffff, %eax
 	rorw	$8, %ax
 	ret
-END (__htons)
+END (htons)
 
-strong_alias (__htons, __ntohs)
-weak_alias (__htons, htons)
-weak_alias (__ntohs, ntohs)
+weak_alias (htons, ntohs)
diff --git a/sysdeps/i386/i486/htonl.S b/sysdeps/i386/i486/htonl.S
index cf3a94fc76..a61b339b81 100644
--- a/sysdeps/i386/i486/htonl.S
+++ b/sysdeps/i386/i486/htonl.S
@@ -26,12 +26,10 @@
 */
 
 	.text
-ENTRY (__htonl)
+ENTRY (htonl)
 	movl	4(%esp), %eax
 	bswap	%eax
 	ret
-END (__htonl)
+END (htonl)
 
-strong_alias (__htonl, __ntohl)
-weak_alias (__htonl, htonl)
-weak_alias (__ntohl, ntohl)
+weak_alias (htonl, ntohl)
diff --git a/sysdeps/m68k/fpu/fraiseexcpt.c b/sysdeps/m68k/fpu/fraiseexcpt.c
index d509604e28..bc49c9c71f 100644
--- a/sysdeps/m68k/fpu/fraiseexcpt.c
+++ b/sysdeps/m68k/fpu/fraiseexcpt.c
@@ -48,43 +48,17 @@ feraiseexcept (int excepts)
   /* Next: overflow.  */
   if (excepts & FE_OVERFLOW)
     {
-      /* We cannot raise the overflow exception without also setting the
-	 inexact flag.  Restore it after the operation, unless it should
-	 be set anyway.  */
       long double d = LDBL_MAX;
-      fexcept_t fpsr;
 
-      __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (fpsr));
-      __asm__ __volatile__ ("fmul%.x %0,%0" : "=f" (d) : "0" (d));
-      if (!((excepts | fpsr) & FE_INEXACT))
-	{
-	  __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (fpsr));
-	  fpsr &= ~FE_INEXACT;
-	  __asm__ __volatile__ ("fmove%.l %0,%/fpsr" : : "dm" (fpsr));
-	}
-      else
-	__asm__ ("fnop");
+      __asm__ __volatile__ ("fmul%.x %0,%0; fnop" : "=f" (d) : "0" (d));
     }
 
   /* Next: underflow.  */
   if (excepts & FE_UNDERFLOW)
     {
-      /* We cannot raise the underflow exception without also setting the
-	 inexact flag.  Restore it after the operation, unless it should
-	 be set anyway.  */
       long double d = -LDBL_MAX;
-      fexcept_t fpsr;
 
-      __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (fpsr));
-      __asm__ __volatile__ ("fetox%.x %0" : "=f" (d) : "0" (d));
-      if (!((excepts | fpsr) & FE_INEXACT))
-	{
-	  __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (fpsr));
-	  fpsr &= ~FE_INEXACT;
-	  __asm__ __volatile__ ("fmove%.l %0,%/fpsr" : : "dm" (fpsr));
-	}
-      else
-	__asm__ ("fnop");
+      __asm__ __volatile__ ("fetox%.x %0; fnop" : "=f" (d) : "0" (d));
     }
 
   /* Last: inexact.  */
diff --git a/sysdeps/unix/i386/sysdep.h b/sysdeps/unix/i386/sysdep.h
index 08bc0ba51c..97fb1dc4a2 100644
--- a/sysdeps/unix/i386/sysdep.h
+++ b/sysdeps/unix/i386/sysdep.h
@@ -26,9 +26,7 @@
 
 #define DO_CALL(syscall_name, args)					      \
   lea SYS_ify (syscall_name), %eax;					      \
-  /* lcall $7, $0; */							      \
-  /* Above loses; GAS bug.  */						      \
-  .byte 0x9a, 0, 0, 0, 0, 7, 0
+  lcall $7, $0
 
 #define	r0		%eax	/* Normal return-value register.  */
 #define	r1		%edx	/* Secondary return-value register.  */
diff --git a/sysdeps/unix/sysv/linux/Dist b/sysdeps/unix/sysv/linux/Dist
index 9272c06fa4..bdc333a5af 100644
--- a/sysdeps/unix/sysv/linux/Dist
+++ b/sysdeps/unix/sysv/linux/Dist
@@ -30,6 +30,7 @@ netipx/ipx.h
 nfs/nfs.h
 sys/acct.h
 sys/debugreg.h
+sys/fsuid.h
 sys/io.h
 sys/kd.h
 sys/kdaemon.h
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 1c5da4b9bf..ed9ae873fd 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -11,7 +11,7 @@ sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h sys/mtio.h \
 		  sys/module.h sys/io.h sys/klog.h sys/kdaemon.h \
 		  sys/user.h sys/sysmacros.h sys/procfs.h \
 		  sys/debugreg.h sys/kd.h sys/soundcard.h sys/vt.h \
-		  sys/quota.h
+		  sys/quota.h sys/fsuid.h
 
 install-others += $(inst_includedir)/bits/syscall.h
 
diff --git a/sysdeps/generic/bits/htontoh.h b/sysdeps/unix/sysv/linux/sys/fsuid.h
index fa4efed867..8185b95724 100644
--- a/sysdeps/generic/bits/htontoh.h
+++ b/sysdeps/unix/sysv/linux/sys/fsuid.h
@@ -16,8 +16,21 @@
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
-#ifndef _NETINET_IN_H
-# error "Don't include this file directly, use <netinet/in.h>"
-#endif
+#ifndef _SYS_FSUID_H
+#define _SYS_FSUID_H	1
 
-/* We cannot give generic optimized versions here.  */
+#include <features.h>
+#include <gnu/types.h>
+
+__BEGIN_DECLS
+
+/* Change uid used for file access control to UID, without affecting
+   other priveledges (such as who can send signals at the process).  */
+extern int setfsuid __P ((__uid_t __uid));
+
+/* Ditto for group id. */
+extern int setfsgid __P ((__gid_t __gid));
+
+__END_DECLS
+
+#endif /* fsuid.h */
diff --git a/sysdeps/vax/htonl.s b/sysdeps/vax/htonl.s
index 93e13ea9a1..ba399865ec 100644
--- a/sysdeps/vax/htonl.s
+++ b/sysdeps/vax/htonl.s
@@ -23,11 +23,9 @@
 
 #include "DEFS.h"
 
-ENTRY(__htonl, 0)
+ENTRY(htonl, 0)
 	rotl	$-8,4(ap),r0
 	insv	r0,$16,$8,r0
 	movb	7(ap),r0
 	ret
-strong_alias (__htonl, __ntohl)
-weak_alias (__htonl, htonl)
-weak_alias (__ntohl, ntohl)
+weak_alias (htonl, ntohl)
diff --git a/sysdeps/vax/htons.s b/sysdeps/vax/htons.s
index 16964c2861..1e781a17c9 100644
--- a/sysdeps/vax/htons.s
+++ b/sysdeps/vax/htons.s
@@ -28,6 +28,4 @@ ENTRY(htons, 0)
 	movb	5(ap),r0
 	movzwl	r0,r0
 	ret
-strong_alias (__htons, __ntohs)
-weak_alias (__htons, htons)
-weak_alias (__ntohs, ntohs)
+weak_alias (htons, ntohs)