summary refs log tree commit diff
path: root/sysdeps/generic/dl-sysdep.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1998-03-31 08:36:05 +0000
committerUlrich Drepper <drepper@redhat.com>1998-03-31 08:36:05 +0000
commit4317f9e1377c92493459f2796c37da27c01bccf7 (patch)
tree37f8f4e349b3dfdd41a31ebd0e984e645c698bbc /sysdeps/generic/dl-sysdep.c
parent0491011bdeaa994079912b9955a1fbf7e6fb5c59 (diff)
downloadglibc-4317f9e1377c92493459f2796c37da27c01bccf7.tar.gz
glibc-4317f9e1377c92493459f2796c37da27c01bccf7.tar.xz
glibc-4317f9e1377c92493459f2796c37da27c01bccf7.zip
Update.
	* nss/nsswitch.c (__nss_lookup): Adjust comment.
Diffstat (limited to 'sysdeps/generic/dl-sysdep.c')
-rw-r--r--sysdeps/generic/dl-sysdep.c119
1 files changed, 107 insertions, 12 deletions
diff --git a/sysdeps/generic/dl-sysdep.c b/sysdeps/generic/dl-sysdep.c
index 7f5e32193a..a113c14c42 100644
--- a/sysdeps/generic/dl-sysdep.c
+++ b/sysdeps/generic/dl-sysdep.c
@@ -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;
 }