Update.
authorUlrich Drepper <drepper@redhat.com>
Tue, 31 Mar 1998 08:36:05 +0000 (08:36 +0000)
committerUlrich Drepper <drepper@redhat.com>
Tue, 31 Mar 1998 08:36:05 +0000 (08:36 +0000)
* nss/nsswitch.c (__nss_lookup): Adjust comment.

ChangeLog
elf/dl-load.c
elf/ldsodefs.h
elf/link.h
nss/nsswitch.c
resolv/netdb.h
sysdeps/generic/dl-sysdep.c

index 5400d1a..7b28c90 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,7 @@
 1998-03-30  Ulrich Drepper  <drepper@cygnus.com>
 
+       * nss/nsswitch.c (__nss_lookup): Adjust comment.
+
        * sysdeps/generic/dl-sysdep.c (_dl_important_hwcaps): New
        function.
 
index c75a913..212b223 100644 (file)
@@ -331,6 +331,10 @@ _dl_init_paths (const char *llp)
      variable.  */
   struct link_map *l;
 
+  /* Names of important hardware capabilities.  */
+  char **hwcap_names;
+  size_t nhwcap_names;
+
   /* Number of elements in the library path.  */
   size_t nllp;
 
@@ -347,6 +351,10 @@ _dl_init_paths (const char *llp)
   else
     nllp = 0;
 
+  /* Get the capabilities.  */
+  hwcap_names = _dl_important_hwcaps (&nhwcap_names,
+                                     _dl_platform, _dl_platformlen);
+
   l = _dl_loaded;
   if (l != NULL)
     {
index 3154bf2..578e085 100644 (file)
@@ -53,20 +53,22 @@ enum r_dir_status { unknown, nonexisting, existing };
 
 struct r_search_path_elem
   {
-    const char *dirname;
-
-    size_t dirnamelen;
-    enum r_dir_status dirstatus;
-
-    size_t machdirnamelen;
-    enum r_dir_status machdirstatus;
+    /* This link is only used in the `all_dirs' member of `r_search_path'.  */
+    struct r_search_path_elem *next;
 
     /* Strings saying where the definition came from.  */
     const char *what;
     const char *where;
 
-    /* This link is only used in the `all_dirs' member of `r_search_path'.  */
-    struct r_search_path_elem *next;
+    const char *dirname;
+
+    enum r_dir_status exists[0];
+  };
+
+struct r_strlenpair
+  {
+    const char *str;
+    size_t len;
   };
 
 
@@ -383,6 +385,9 @@ extern void _dl_show_auxv (void);
    other.  */
 extern char *_dl_next_ld_env_entry (char ***position);
 
+/* Return an array with the names of the important hardware capabilities.  */
+extern char **_dl_important_hwcap (size_t *sz);
+
 __END_DECLS
 
 #endif /* ldsodefs.h */
index 30efa0e..edf1303 100644 (file)
@@ -156,6 +156,10 @@ struct link_map
     /* Collected information about own RPATH directories.  */
     struct r_search_path_elem **l_rpath_dirs;
 
+    /* Directory names composed from capability names.  */
+    struct r_strlenpair *l_capstrs;
+    size_t l_ncapstrs;
+
     /* Collected results of relocation while profiling.  */
     ElfW(Addr) *l_reloc_result;
 
index ab0f850..c968502 100644 (file)
@@ -135,7 +135,7 @@ __nss_database_lookup (const char *database, const char *alternate_name,
 
 
 /* -1 == not found
-    0 == adjusted for next function
+    0 == function found
     1 == finished */
 int
 __nss_lookup (service_user **ni, const char *fct_name, void **fctp)
index fdfc056..9282be3 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it
@@ -49,13 +49,11 @@ extern int h_errno;
 extern int *__h_errno_location __P ((void)) __attribute__ ((__const__));
 
 #ifdef _LIBC
-/* Retain some binary compatibility with old libraries by having both the
-   global variable and the per-thread variable set on error.  */
 # ifdef _LIBC_REENTRANT
 static inline int
 __set_h_errno (int __err)
 {
-  return *__h_errno_location () = h_errno = __err;
+  return *__h_errno_location () = __err;
 }
 # else
 #  define __set_h_errno(x) (h_errno = (x))
index 7f5e321..a113c14 100644 (file)
@@ -272,28 +272,123 @@ _dl_next_ld_env_entry (char ***position)
 }
 
 /* Return an array of useful/necessary hardware capability names.  */
-char **
-_dl_important_hwcaps (size_t *sz)
+const struct r_strlenpair *
+_dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz)
 {
   /* Determine how many important bits are set.  */
   unsigned long int important = hwcap & HWCAP_IMPORTANT;
-  size_t cnt = 0;
-  size_t n;
-  char **result;
+  size_t cnt = platform != NULL;
+  size_t n, m;
+  size_t total;
+  struct r_strlenpair *temp;
+  struct r_strlenpair *result;
 
   for (n = 0; (~((1UL << n) - 1) & important) != 0; ++n)
     if ((important & (1UL << n)) != 0)
       ++cnt;
 
-  *sz = 0;
   if (cnt == 0)
-    return NULL;
+    {
+      /* If we have platform name and no important capability we only have
+        the base directory to search.  */
+      result = (struct r_strlenpair *) malloc (sizeof (*result));
+      if (result == NULL)
+       {
+       no_memory:
+         _dl_signal_error (ENOMEM, NULL, "cannot create capability list");
+       }
+
+      result[0]->str = (char *) result;        /* Does not really matter.  */
+      result[0]->len = 0;
+
+      *sz = 1;
+      return &only_base;
+    }
+
+  /* Create temporary data structure to generate result table.  */
+  temp = (struct r_strlenpair *) alloca (cnt * sizeof (*temp));
+  m = 0;
+  for (n = 0; (~((1UL << n) - 1) & important) != 0; ++n)
+    if ((important & (1UL << n)) != 0)
+      {
+       temp[m].str = _dl_hwcap_string (n);
+       temp[m].len = strlen (temp[m].str);
+       ++m
+      }
+  if (platform != NULL)
+    {
+      temp[m].str = platform;
+      temp[m].len = platform_len;
+      ++m;
+    }
+
+  if (cnt == 1)
+    {
+      result = (struct r_strlenpair *) malloc (2 * sizeof (*result)
+                                              + temp[0].len + 1);
+      if (result == NULL)
+       goto no_memory;
+
+      result[0].str = (char *) (result + 1);
+      result[0].len = len;
+      result[1].str = (char *) (result + 1);
+      result[1].len = 0;
+      result[0].str[0] = '/';
+      memcpy (&result[0].str[1], temp[0].str, temp[0].len);
+      *sz = 2;
+
+      return result;
+    }
+
+  /* Determine the total size of all strings together.  */
+  total = cnt * (temp[0].len + temp[cnt - 1].len + 2);
+  for (n = 1; n + 1 < cnt; ++n)
+    total += 2 * (temp[n].len + 1);
+
+  /* The result structure: we use a very compressed way to store the
+     various combinations of capability names.  */
+  result = (struct r_strlenpair *) malloc (1 << (cnt - 2) * sizeof (*result)
+                                          + total);
+  if (result == NULL)
+    goto no_memory;
+
+  /* Fill in the information.  This follows the following scheme
+     (indeces from TEMP for four strings):
+       entry #0: 0, 1, 2, 3    binary: 1111
+             #1: 0, 1, 3               1101
+             #2: 0, 2, 3               1011
+             #3: 0, 3                  1001
+     This allows to represent all possible combinations of capability
+     names in the string.  First generate the strings.  */
+  n = 1 << cnt;
+  cp = result[0].str = (char *) (result + 1 << (cnt - 2));
+  do
+    {
+#define add(idx) \
+      cp = __mempcpy (__mempcpy (cp, "/", 1), temp[idx].str, temp[idx].len)
+
+      n -= 2;
+
+      /* We always add the last string.  */
+      add (cnt - 1);
+
+      /* Add the strings which have the bit set in N.  */
+      for (m = cnt - 2; cnt > 0; --cnt)
+       if ((n & (1 << m)) != 0)
+         add (m);
+
+      /* Always add the first string.  */
+      add (0);
+    }
+  while (n != 0);
+
+  /* Now we are ready to install the string pointers and length.
+     The first string contains all strings.  */
+  result[0].len = 0;
+  for (n = 0; n < cnt; ++n)
+    result[0].len += temp[n].len;
 
-  result = (char **) malloc (cnt * sizeof (char *));
-  if (result != NULL)
-    for (n = 0; (~((1UL << n) - 1) & important) != 0; ++n)
-      if ((important & (1UL << n)) != 0)
-       result[*sz++] = _dl_hwcap_string (n);
+  I KNOW THIS DOES NOT YET WORK --drepper
 
   return result;
 }