diff options
32 files changed, 787 insertions, 340 deletions
@@ -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) |