aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1997-07-24 01:36:01 +0000
committerUlrich Drepper <drepper@redhat.com>1997-07-24 01:36:01 +0000
commit1522c3682ccf373e9d393ca73350be284fcf773b (patch)
treea58f8e8e08b83b3101d235e86f7d869dc880ed4e
parentUpdate. (diff)
downloadglibc-1522c3682ccf373e9d393ca73350be284fcf773b.tar.gz
glibc-1522c3682ccf373e9d393ca73350be284fcf773b.tar.bz2
glibc-1522c3682ccf373e9d393ca73350be284fcf773b.zip
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>.
-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)