From 4317f9e1377c92493459f2796c37da27c01bccf7 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Tue, 31 Mar 1998 08:36:05 +0000 Subject: Update. * nss/nsswitch.c (__nss_lookup): Adjust comment. --- sysdeps/generic/dl-sysdep.c | 119 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 107 insertions(+), 12 deletions(-) (limited to 'sysdeps') 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; } -- cgit 1.4.1