aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog88
-rw-r--r--bits/byteswap.h43
-rw-r--r--elf/dl-deps.c371
-rw-r--r--inet/Makefile2
-rw-r--r--inet/htontest.c70
-rw-r--r--inet/netinet/in.h41
-rw-r--r--manual/argp.texi9
-rw-r--r--math/test-fenv.c26
-rw-r--r--misc/search.h60
-rw-r--r--nss/nsswitch.c8
-rw-r--r--resolv/gethnamaddr.c6
-rw-r--r--resolv/nss_dns/dns-host.c5
-rw-r--r--string/Makefile2
-rw-r--r--string/byteswap.h40
-rw-r--r--sunrpc/clnt_udp.c2
-rw-r--r--sysdeps/alpha/htonl.S8
-rw-r--r--sysdeps/alpha/htons.S8
-rw-r--r--sysdeps/generic/bits/byteswap.h43
-rw-r--r--sysdeps/generic/htonl.c17
-rw-r--r--sysdeps/generic/htons.c15
-rw-r--r--sysdeps/i386/bits/byteswap.h92
-rw-r--r--sysdeps/i386/bits/htontoh.h79
-rw-r--r--sysdeps/i386/htonl.S8
-rw-r--r--sysdeps/i386/htons.S8
-rw-r--r--sysdeps/i386/i486/htonl.S8
-rw-r--r--sysdeps/m68k/fpu/fraiseexcpt.c30
-rw-r--r--sysdeps/unix/i386/sysdep.h4
-rw-r--r--sysdeps/unix/sysv/linux/Dist1
-rw-r--r--sysdeps/unix/sysv/linux/Makefile2
-rw-r--r--sysdeps/unix/sysv/linux/sys/fsuid.h (renamed from sysdeps/generic/bits/htontoh.h)21
-rw-r--r--sysdeps/vax/htonl.s6
-rw-r--r--sysdeps/vax/htons.s4
32 files changed, 787 insertions, 340 deletions
diff --git a/ChangeLog b/ChangeLog
index 0e0750c485..9f3ed378a5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,91 @@
+1997-07-24 03:14 Ulrich Drepper <drepper@cygnus.com>
+
+ * elf/dl-deps.c: Complete rewrite to handle DT_AUXILIARY correctly.
+
+ * inet/Makefile (tests): Add htontest.
+ * inet/htontest.c: New file.
+
+ * inet/netinet/in.h: Cleanup optimization of ntoh/hton functions
+ when they are no noops.
+ * sysdeps/alpha/htonl.S: Don't define __ protected names.
+ * sysdeps/alpha/htons.S: Likewise.
+ * sysdeps/generic/htonl.c: Likewise.
+ * sysdeps/generic/htons.c: Likewise.
+ * sysdeps/i386/htonl.S: Likewise.
+ * sysdeps/i386/htons.S: Likewise.
+ * sysdeps/i386/i486/htonl.S: Likewise.
+ * sysdeps/vax/htonl.s: Likewise.
+ * sysdeps/vax/htons.s: Likewise.
+
+ * string/Makefile (headers): Add byteswap.h and bits/byteswap.h.
+ * string/byteswap.h: New file.
+ * sysdeps/generic/bits/byteswap.h: New file.
+ * sysdeps/i386/bits/byteswap.h: New file.
+ * sysdeps/generic/bits/htontoh.h: Removed.
+ * sysdeps/i386/bits/htontoh.h: Removed.
+
+ * misc/search.h: General cleanup. Don't define reentrant hsearch
+ functions uless __USE_GNU.
+
+ * nss/nsswitch.c: Pretty print.
+
+ * sunrpc/clnt_udp.c (clntudp_call): Initialize outlen to prevent
+ warning.
+
+ * sysdeps/unix/i386/sysdep.h (DO_CALL): Use lcall, binutils have
+ been fixed meanwhile.
+ Reported by Zack Weinberg <zack@rabi.phys.columbia.edu>.
+
+1997-07-24 00:53 Philip Blundell <Philip.Blundell@pobox.com>
+
+ * db/hash/hash.c (init_hash): Only use statbuf.st_blksize if it
+ exists for this port.
+
+1997-07-24 00:12 Philip Blundell <Philip.Blundell@pobox.com>
+
+ * sysdeps/standalone/arm/bits/errno.h (ESTALE): Add.
+
+1997-07-22 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * manual/argp.texi (Argp Option Vectors): Use @minus, not @math,
+ to format a proper minus sign.
+
+1997-07-22 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * sysdeps/m68k/fpu/fraiseexcpt.c: Don't handle FE_INEXACT
+ specially, the standard doesn't require it.
+
+ * math/test-fenv.c (test_exceptions): Add IGNORE_INEXACT argument,
+ if non-zero then don't test inexact flag. Callers changed.
+ (set_single_exc): Ignore inexact flag if underflow or overflow
+ exception is raised.
+
+1997-07-23 05:10 Ulrich Drepper <drepper@cygnus.com>
+
+ * sysdeps/unix/sysv/linux/sys/fsuid.h: New file.
+ Provided by Michael Deutschmann <ldeutsch@mail.netshop.net>.
+ * sysdeps/unix/sysv/linux/Makefile (headers): Add sys/fsuid.h.
+ * sysdeps/unix/sysv/linux/Dist: Add sys/fsuid.h.
+
+1997-07-16 10:09 Fila Kolodny <fila@ibi.com>
+
+ * resolv/gethnamaddr.c: Define MAXHOSTNAMELEN as 256, since RFC 1034
+ and 1035 state that a fully qualified domain name cannot exceed 255
+ octets in length.
+ * resolv/nss_dns/dns-host.c: Likewise.
+
+1997-07-22 09:54 H.J. Lu <hjl@gnu.ai.mit.edu>
+
+ * inet/netinet/in.h (htons): Fix typos.
+
+ * sysdeps/i386/bits/htontoh.h (__ntohs): Return the value.
+
+1997-07-22 11:47 Ulrich Drepper <drepper@cygnus.com>
+
+ * nss/nsswitch.c (nss_lookup_function): Include function.def, not
+ functions.def.
+ Patch by Klaus Espenlaub <kespenla@hydra.informatik.uni-ulm.de>.
+
1997-07-22 01:35 Ulrich Drepper <drepper@cygnus.com>
* Makerules (+make-deps): Use $(CFLAGS) in run of $(+mkdep) so
diff --git a/bits/byteswap.h b/bits/byteswap.h
new file mode 100644
index 0000000000..9404cc452e
--- /dev/null
+++ b/bits/byteswap.h
@@ -0,0 +1,43 @@
+/* Macros to swap the order of bytes in integer values.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#ifndef _BITS_BYTESWAP_H
+#define _BITS_BYTESWAP_H 1
+
+/* Swap bytes in 16 bit value. */
+#define __bswap_16(x) \
+ ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))
+
+/* Swap bytes in 32 bit value. */
+#define __bswap_32(x) \
+ ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
+ (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
+
+#if defined __GNUC__ && __GNUC__ >= 2
+/* Swap bytes in 64 bit value. */
+# define __bswap_64(x) \
+ ({ union { unsigned long long int __ll; \
+ unsigned long int __l[2]; } __v, __r; \
+ __v.__ll = (x); \
+ __r.__l[0] = __bswap_32 (__v.__l[1]); \
+ __r.__l[1] = __bswap_32 (__v.__l[0]); \
+ __r.__ll; })
+#endif
+
+#endif /* bits/byteswap.h */
diff --git a/elf/dl-deps.c b/elf/dl-deps.c
index e2fd340822..36f5ee0606 100644
--- a/elf/dl-deps.c
+++ b/elf/dl-deps.c
@@ -22,17 +22,27 @@
#include <dlfcn.h>
#include <stdlib.h>
+#include <assert.h>
+
+/* Whether an shared object references one or more auxiliary objects
+ is signaled by the AUXTAG entry in l_info. */
+#define AUXTAG (DT_NUM + DT_PROCNUM + DT_VERSIONTAGNUM \
+ + DT_EXTRATAGIDX (DT_AUXILIARY))
+
+
+/* When loading auxiliary objects we must ignore errors. It's ok if
+ an object is missing. */
struct openaux_args
-{
- /* The arguments to openaux. */
- struct link_map *map;
- int trace_mode;
- const char *strtab;
- ElfW(Dyn) *d;
+ {
+ /* The arguments to openaux. */
+ struct link_map *map;
+ int trace_mode;
+ const char *strtab;
+ const ElfW(Dyn) *d;
- /* The return value of openaux. */
- struct link_map *aux;
-};
+ /* The return value of openaux. */
+ struct link_map *aux;
+ };
static void
openaux (void *a)
@@ -45,78 +55,56 @@ openaux (void *a)
args->trace_mode);
}
+
+
+/* We use a very special kind of list to track the three kinds paths
+ through the list of loaded shared objects. We have to
+
+ - go through all objects in the correct order, which includes the
+ possible recursive loading of auxiliary objects and dependencies
+
+ - produce a flat list with unique members of all involved objects
+
+ - produce a flat list of all shared objects.
+*/
+struct list
+ {
+ int done; /* Nonzero if this map was processed. */
+ struct link_map *map; /* The data. */
+
+ struct list *unique; /* Elements for normal list. */
+ struct list *dup; /* Elements in complete list. */
+ };
+
+
void
_dl_map_object_deps (struct link_map *map,
struct link_map **preloads, unsigned int npreloads,
int trace_mode)
{
- struct list
- {
- struct link_map *map;
- struct list *next;
- };
- struct list *head, *tailp, *scanp;
- struct list duphead, *duptailp;
- unsigned int nduplist;
- unsigned int nlist, naux, i;
+ struct list known[1 + npreloads + 1];
+ struct list *runp, *head, *utail, *dtail;
+ unsigned int nlist, nduplist, i;
+
inline void preload (struct link_map *map)
{
- head[nlist].next = &head[nlist + 1];
- head[nlist++].map = map;
+ known[nlist].done = 0;
+ known[nlist].map = map;
+
+ known[nlist].unique = &known[nlist + 1];
+ known[nlist].dup = &known[nlist + 1];
+ ++nlist;
/* We use `l_reserved' as a mark bit to detect objects we have
already put in the search list and avoid adding duplicate
elements later in the list. */
map->l_reserved = 1;
}
- naux = nlist = 0;
-
- /* XXX The AUXILIARY implementation isn't correct in the moment. XXX
- XXX The problem is that we currently do not handle auxiliary XXX
- XXX entries in the loaded objects. XXX */
-
-#define AUXTAG (DT_NUM + DT_PROCNUM + DT_VERSIONTAGNUM \
- + DT_EXTRATAGIDX (DT_AUXILIARY))
-
- /* First determine the number of auxiliary objects we have to load. */
- if (map->l_info[AUXTAG])
- {
- ElfW(Dyn) *d;
- for (d = map->l_ld; d->d_tag != DT_NULL; ++d)
- if (d->d_tag == DT_AUXILIARY)
- ++naux;
- }
-
- /* Now we can allocate the array for the linker maps. */
- head = (struct list *) alloca (sizeof (struct list)
- * (naux + npreloads + 2));
-
- /* Load the auxiliary objects, even before the object itself. */
- if (map->l_info[AUXTAG])
- {
- /* There is at least one auxiliary library specified. We try to
- load it, and if we can, use its symbols in preference to our
- own. But if we can't load it, we just silently ignore it. */
- struct openaux_args args;
- args.strtab
- = ((void *) map->l_addr + map->l_info[DT_STRTAB]->d_un.d_ptr);
- args.map = map;
- args.trace_mode = trace_mode;
-
- for (args.d = map->l_ld; args.d->d_tag != DT_NULL; ++args.d)
- if (args.d->d_tag == DT_AUXILIARY)
- {
- char *errstring;
- const char *objname;
- if (! _dl_catch_error (&errstring, &objname, openaux, &args))
- /* The auxiliary object is actually there. Use it as
- the first search element, even before MAP itself. */
- preload (args.aux);
- }
- }
+ /* No loaded object so far. */
+ nlist = 0;
- /* Next load MAP itself. */
+ /* First load MAP itself. */
preload (map);
/* Add the preloaded items after MAP but before any of its dependencies. */
@@ -124,30 +112,51 @@ _dl_map_object_deps (struct link_map *map,
preload (preloads[i]);
/* Terminate the lists. */
- head[nlist - 1].next = NULL;
- duphead.next = NULL;
+ known[nlist - 1].unique = NULL;
+ known[nlist - 1].dup = NULL;
+
+ /* Pointer to the first member of the unique and duplicate list. */
+ head = known;
- /* Start here for adding dependencies to the list. */
- tailp = &head[nlist - 1];
+ /* Pointer to last unique object. */
+ utail = &known[nlist - 1];
+ /* Pointer to last loaded object. */
+ dtail = &known[nlist - 1];
/* Until now we have the same number of libraries in the normal and
the list with duplicates. */
nduplist = nlist;
- duptailp = &duphead;
- /* Process each element of the search list, loading each of its immediate
- dependencies and appending them to the list as we step through it.
- This produces a flat, ordered list that represents a breadth-first
- search of the dependency tree. */
- for (scanp = head; scanp; scanp = scanp->next)
+ /* Process each element of the search list, loading each of its
+ auxiliary objects and immediate dependencies. Auxiliary objects
+ will be added in the list before the object itself and
+ dependencies will be appended to the list as we step through it.
+ This produces a flat, ordered list that represents a
+ breadth-first search of the dependency tree.
+
+ The whole process is complicated by the fact that we better
+ should use alloca for the temporary list elements. But using
+ alloca means we cannot use recursive function calls. */
+ for (runp = known; runp; )
{
- struct link_map *l = scanp->map;
+ struct link_map *l = runp->map;
- if (l->l_info[DT_NEEDED])
+ if (runp->done == 0 && (l->l_info[AUXTAG] || l->l_info[DT_NEEDED]))
{
- const char *strtab
- = ((void *) l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr);
+ const char *strtab = ((void *) l->l_addr
+ + l->l_info[DT_STRTAB]->d_un.d_ptr);
+ struct openaux_args args;
+ struct list *orig;
const ElfW(Dyn) *d;
+
+ /* Mark map as processed. */
+ runp->done = 1;
+
+ args.strtab = strtab;
+ args.map = l;
+ args.trace_mode = trace_mode;
+ orig = runp;
+
for (d = l->l_ld; d->d_tag != DT_NULL; ++d)
if (d->d_tag == DT_NEEDED)
{
@@ -156,32 +165,182 @@ _dl_map_object_deps (struct link_map *map,
= _dl_map_object (l, strtab + d->d_un.d_val,
l->l_type == lt_executable ? lt_library :
l->l_type, trace_mode);
+ /* Allocate new entry. */
+ struct list *newp = alloca (sizeof (struct list));
+
+ /* Add it in any case to the duplicate list. */
+ newp->map = dep;
+ newp->dup = NULL;
+ dtail->dup = newp;
+ dtail = newp;
+ ++nduplist;
if (dep->l_reserved)
/* This object is already in the search list we are
- building. Don't add a duplicate pointer. Release the
- reference just added by _dl_map_object. */
+ building. Don't add a duplicate pointer.
+ Release the reference just added by
+ _dl_map_object. */
--dep->l_opencount;
else
{
- /* Append DEP to the search list. */
- tailp->next = alloca (sizeof *tailp);
- tailp = tailp->next;
- tailp->map = dep;
- tailp->next = NULL;
+ /* Append DEP to the unique list. */
+ newp->done = 0;
+ newp->unique = NULL;
+ utail->unique = newp;
+ utail = newp;
++nlist;
/* Set the mark bit that says it's already in the list. */
dep->l_reserved = 1;
}
+ }
+ else if (d->d_tag == DT_AUXILIARY)
+ {
+ char *errstring;
+ const char *objname;
- /* In any case append DEP to the duplicates search list. */
- duptailp->next = alloca (sizeof *duptailp);
- duptailp = duptailp->next;
- duptailp->map = dep;
- duptailp->next = NULL;
- ++nduplist;
+ /* Store the tag in the argument structure. */
+ args.d = d;
+
+ if (_dl_catch_error (&errstring, &objname, openaux, &args))
+ {
+ /* We are not interested in the error message. */
+ assert (errstring != NULL);
+ free (errstring);
+ }
+ else
+ {
+ /* The auxiliary object is actually available.
+ Incorporate the map in all the lists. */
+
+ /* Allocate new entry. This always has to be done. */
+ struct list *newp = alloca (sizeof (struct list));
+
+ /* Copy the content of the current entry over. */
+ memcpy (newp, orig, sizeof (*newp));
+
+ /* Initialize new entry. */
+ orig->done = 0;
+ orig->map = args.aux;
+ orig->dup = newp;
+
+ /* We must handle two situations here: the map is new,
+ so we must add it in all three lists. If the map
+ is already known, we have two further possibilities:
+ - if the object is before the current map in the
+ search list, we do nothing. It is already found
+ early
+ - if the object is after the current one, we must
+ move it just before the current map to make sure
+ the symbols are found early enough
+ */
+ if (args.aux->l_reserved)
+ {
+ /* The object is already somewhere in the
+ list. Locate it first. */
+ struct list *late;
+
+ /* This object is already in the search list
+ we are building. Don't add a duplicate
+ pointer. Release the reference just added
+ by _dl_map_object. */
+ --args.aux->l_opencount;
+
+ for (late = orig; late->unique; late = late->unique)
+ if (late->unique->map == args.aux)
+ break;
+
+ if (late->unique)
+ {
+ /* The object is somewhere behind the current
+ position in the search path. We have to
+ move it to this earlier position. */
+ orig->unique = newp;
+
+ /* Now remove the later entry from the unique
+ list. */
+ late->unique = late->unique->unique;
+
+ /* We must move the earlier in the chain. */
+ if (args.aux->l_prev)
+ args.aux->l_prev->l_next = args.aux->l_next;
+ if (args.aux->l_next)
+ args.aux->l_next->l_prev = args.aux->l_prev;
+
+ args.aux->l_prev = newp->map->l_prev;
+ newp->map->l_prev = args.aux;
+ if (args.aux->l_prev != NULL)
+ args.aux->l_prev->l_next = args.aux;
+ args.aux->l_next = newp->map;
+ }
+ else
+ {
+ /* The object must be somewhere earlier in
+ the list. That's good, we only have to
+ insert an entry for the duplicate list. */
+ orig->unique = NULL; /* Never used. */
+
+ /* Now we have a problem. The element pointing
+ to ORIG in the unique list must point to
+ NEWP now. This is the only place where we
+ need this backreference and this situation
+ is really not that frequent. So we don't
+ use a double-linked list but instead search
+ for the preceding element. */
+ late = head;
+ while (late->unique != orig)
+ late = late->unique;
+ late->unique = newp;
+ }
+ }
+ else
+ {
+ /* This is easy. We just add the symbol right
+ here. */
+ orig->unique = newp;
+ ++nlist;
+ /* Set the mark bit that says it's already in
+ the list. */
+ args.aux->l_reserved = 1;
+
+ /* The only problem is that in the double linked
+ list of