mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-30 22:43:12 +03:00
Update.
1998-03-31 18:11 Ulrich Drepper <drepper@cygnus.com> * include/mntent.h: New file. * elf/Makefile (trusted-dirs.h): Append slash to filename. * elf/dl-load.c: Rewrite search path handling. * elf/ldsodefs.h (struct r_search_path_elem): Change for rewrite. * elf/rtld.c (process_envvars): Recognize LD_HWCAP_MASK. * sysdeps/generic/dl-sysdep.h (_dl_important_hwcap): New function. * elf/ldsodefs.h: Add prototype.
This commit is contained in:
11
ChangeLog
11
ChangeLog
@ -1,3 +1,14 @@
|
|||||||
|
1998-03-31 18:11 Ulrich Drepper <drepper@cygnus.com>
|
||||||
|
|
||||||
|
* include/mntent.h: New file.
|
||||||
|
|
||||||
|
* elf/Makefile (trusted-dirs.h): Append slash to filename.
|
||||||
|
* elf/dl-load.c: Rewrite search path handling.
|
||||||
|
* elf/ldsodefs.h (struct r_search_path_elem): Change for rewrite.
|
||||||
|
* elf/rtld.c (process_envvars): Recognize LD_HWCAP_MASK.
|
||||||
|
* sysdeps/generic/dl-sysdep.h (_dl_important_hwcap): New function.
|
||||||
|
* elf/ldsodefs.h: Add prototype.
|
||||||
|
|
||||||
1998-03-30 Ulrich Drepper <drepper@cygnus.com>
|
1998-03-30 Ulrich Drepper <drepper@cygnus.com>
|
||||||
|
|
||||||
* nss/nsswitch.c (__nss_lookup): Adjust comment.
|
* nss/nsswitch.c (__nss_lookup): Adjust comment.
|
||||||
|
@ -141,7 +141,7 @@ $(objpfx)trusted-dirs.h: Makefile $(..)Makeconfig
|
|||||||
$(make-target-directory)
|
$(make-target-directory)
|
||||||
(for dir in `echo "$(default-rpath) $(user-defined-trusted-dirs)" | \
|
(for dir in `echo "$(default-rpath) $(user-defined-trusted-dirs)" | \
|
||||||
sed 's/:/ /g'`; do \
|
sed 's/:/ /g'`; do \
|
||||||
echo " \"$$dir\","; \
|
echo " \"$$dir/\","; \
|
||||||
done;) > $@T
|
done;) > $@T
|
||||||
mv -f $@T $@
|
mv -f $@T $@
|
||||||
$(objpfx)rtldtbl.h: Makefile $(..)Makeconfig genrtldtbl.awk
|
$(objpfx)rtldtbl.h: Makefile $(..)Makeconfig genrtldtbl.awk
|
||||||
|
311
elf/dl-load.c
311
elf/dl-load.c
@ -100,6 +100,11 @@ extern size_t _dl_platformlen;
|
|||||||
binaries. */
|
binaries. */
|
||||||
static struct r_search_path_elem **fake_path_list;
|
static struct r_search_path_elem **fake_path_list;
|
||||||
|
|
||||||
|
/* List of the hardware capabilities we might end up using. */
|
||||||
|
static const struct r_strlenpair *capstr;
|
||||||
|
static size_t ncapstr;
|
||||||
|
static size_t max_capstrlen;
|
||||||
|
|
||||||
|
|
||||||
/* Local version of `strdup' function. */
|
/* Local version of `strdup' function. */
|
||||||
static inline char *
|
static inline char *
|
||||||
@ -119,6 +124,7 @@ local_strdup (const char *s)
|
|||||||
be freed if the shared object already has this name.
|
be freed if the shared object already has this name.
|
||||||
Returns false if the object already had this name. */
|
Returns false if the object already had this name. */
|
||||||
static int
|
static int
|
||||||
|
internal_function
|
||||||
add_name_to_object (struct link_map *l, char *name)
|
add_name_to_object (struct link_map *l, char *name)
|
||||||
{
|
{
|
||||||
struct libname_list *lnp, *lastp;
|
struct libname_list *lnp, *lastp;
|
||||||
@ -156,9 +162,11 @@ add_name_to_object (struct link_map *l, char *name)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* All known directories in sorted order. */
|
||||||
|
static struct r_search_path_elem *all_dirs;
|
||||||
|
|
||||||
/* Implement cache for search path lookup. */
|
/* Standard search directories. */
|
||||||
#include "rtldtbl.h"
|
static struct r_search_path_elem **rtld_search_dirs;
|
||||||
|
|
||||||
static size_t max_dirnamelen;
|
static size_t max_dirnamelen;
|
||||||
|
|
||||||
@ -173,6 +181,11 @@ fillin_rpath (char *rpath, struct r_search_path_elem **result, const char *sep,
|
|||||||
{
|
{
|
||||||
struct r_search_path_elem *dirp;
|
struct r_search_path_elem *dirp;
|
||||||
size_t len = strlen (cp);
|
size_t len = strlen (cp);
|
||||||
|
|
||||||
|
/* `strsep' can pass an empty string. */
|
||||||
|
if (len == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
/* Remove trailing slashes. */
|
/* Remove trailing slashes. */
|
||||||
while (len > 1 && cp[len - 1] == '/')
|
while (len > 1 && cp[len - 1] == '/')
|
||||||
--len;
|
--len;
|
||||||
@ -187,7 +200,8 @@ fillin_rpath (char *rpath, struct r_search_path_elem **result, const char *sep,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
while (*trun != NULL
|
while (*trun != NULL
|
||||||
&& (memcmp (*trun, cp, len) != 0 || (*trun)[len] != '\0'))
|
&& (memcmp (*trun, cp, len) != 0
|
||||||
|
|| ((*trun)[len] != '/' && (*trun)[len + 1] != '\0')))
|
||||||
++trun;
|
++trun;
|
||||||
|
|
||||||
if (*trun == NULL)
|
if (*trun == NULL)
|
||||||
@ -201,12 +215,12 @@ fillin_rpath (char *rpath, struct r_search_path_elem **result, const char *sep,
|
|||||||
|
|
||||||
/* See if this directory is already known. */
|
/* See if this directory is already known. */
|
||||||
for (dirp = all_dirs; dirp != NULL; dirp = dirp->next)
|
for (dirp = all_dirs; dirp != NULL; dirp = dirp->next)
|
||||||
if (dirp->dirnamelen == len && strcmp (cp, dirp->dirname) == 0)
|
if (dirp->dirnamelen == len && memcmp (cp, dirp->dirname, len) == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (dirp != NULL)
|
if (dirp != NULL)
|
||||||
{
|
{
|
||||||
/* It is available, see whether it's in our own list. */
|
/* It is available, see whether it's on our own list. */
|
||||||
size_t cnt;
|
size_t cnt;
|
||||||
for (cnt = 0; cnt < nelems; ++cnt)
|
for (cnt = 0; cnt < nelems; ++cnt)
|
||||||
if (result[cnt] == dirp)
|
if (result[cnt] == dirp)
|
||||||
@ -217,57 +231,30 @@ fillin_rpath (char *rpath, struct r_search_path_elem **result, const char *sep,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
size_t cnt;
|
||||||
|
|
||||||
/* It's a new directory. Create an entry and add it. */
|
/* It's a new directory. Create an entry and add it. */
|
||||||
dirp = (struct r_search_path_elem *) malloc (sizeof (*dirp));
|
dirp = (struct r_search_path_elem *)
|
||||||
|
malloc (sizeof (*dirp) + ncapstr * sizeof (enum r_dir_status));
|
||||||
if (dirp == NULL)
|
if (dirp == NULL)
|
||||||
_dl_signal_error (ENOMEM, NULL,
|
_dl_signal_error (ENOMEM, NULL,
|
||||||
"cannot create cache for search path");
|
"cannot create cache for search path");
|
||||||
|
|
||||||
|
dirp->dirname = cp;
|
||||||
dirp->dirnamelen = len;
|
dirp->dirnamelen = len;
|
||||||
|
|
||||||
|
if (len > max_dirnamelen)
|
||||||
|
max_dirnamelen = len;
|
||||||
|
|
||||||
/* We have to make sure all the relative directories are never
|
/* We have to make sure all the relative directories are never
|
||||||
ignored. The current directory might change and all our
|
ignored. The current directory might change and all our
|
||||||
saved information would be void. */
|
saved information would be void. */
|
||||||
dirp->dirstatus = cp[0] != '/' ? existing : unknown;
|
if (cp[0] != '/')
|
||||||
|
for (cnt = 0; cnt < ncapstr; ++cnt)
|
||||||
/* Add the name of the machine dependent directory if a machine
|
dirp->status[cnt] = existing;
|
||||||
is defined. */
|
|
||||||
if (_dl_platform != NULL)
|
|
||||||
{
|
|
||||||
char *tmp;
|
|
||||||
|
|
||||||
dirp->machdirnamelen = len + _dl_platformlen + 1;
|
|
||||||
tmp = (char *) malloc (len + _dl_platformlen + 2);
|
|
||||||
if (tmp == NULL)
|
|
||||||
_dl_signal_error (ENOMEM, NULL,
|
|
||||||
"cannot create cache for search path");
|
|
||||||
dirp->dirname = tmp;
|
|
||||||
tmp = __mempcpy (tmp, cp, len);
|
|
||||||
tmp = __mempcpy (tmp, _dl_platform, _dl_platformlen);
|
|
||||||
*tmp++ = '/';
|
|
||||||
*tmp = '\0';
|
|
||||||
|
|
||||||
dirp->machdirstatus = dirp->dirstatus;
|
|
||||||
|
|
||||||
if (max_dirnamelen < dirp->machdirnamelen)
|
|
||||||
max_dirnamelen = dirp->machdirnamelen;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
for (cnt = 0; cnt < ncapstr; ++cnt)
|
||||||
char *tmp;
|
dirp->status[cnt] = unknown;
|
||||||
|
|
||||||
dirp->machdirnamelen = len;
|
|
||||||
dirp->machdirstatus = nonexisting;
|
|
||||||
|
|
||||||
tmp = (char *) malloc (len + 1);
|
|
||||||
if (tmp == NULL)
|
|
||||||
_dl_signal_error (ENOMEM, NULL,
|
|
||||||
"cannot create cache for search path");
|
|
||||||
dirp->dirname = tmp;
|
|
||||||
*((char *) __mempcpy (tmp, cp, len)) = '\0';
|
|
||||||
|
|
||||||
if (max_dirnamelen < dirp->dirnamelen)
|
|
||||||
max_dirnamelen = dirp->dirnamelen;
|
|
||||||
}
|
|
||||||
|
|
||||||
dirp->what = what;
|
dirp->what = what;
|
||||||
dirp->where = where;
|
dirp->where = where;
|
||||||
@ -288,6 +275,7 @@ fillin_rpath (char *rpath, struct r_search_path_elem **result, const char *sep,
|
|||||||
|
|
||||||
|
|
||||||
static struct r_search_path_elem **
|
static struct r_search_path_elem **
|
||||||
|
internal_function
|
||||||
decompose_rpath (const char *rpath, size_t additional_room,
|
decompose_rpath (const char *rpath, size_t additional_room,
|
||||||
const char *what, const char *where)
|
const char *what, const char *where)
|
||||||
{
|
{
|
||||||
@ -317,13 +305,14 @@ decompose_rpath (const char *rpath, size_t additional_room,
|
|||||||
void
|
void
|
||||||
_dl_init_paths (const char *llp)
|
_dl_init_paths (const char *llp)
|
||||||
{
|
{
|
||||||
static const char *trusted_dirs[] =
|
static const char *system_dirs[] =
|
||||||
{
|
{
|
||||||
#include "trusted-dirs.h"
|
#include "trusted-dirs.h"
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
const char **strp;
|
||||||
struct r_search_path_elem **pelem;
|
struct r_search_path_elem *pelem, **aelem;
|
||||||
|
size_t round_size;
|
||||||
|
|
||||||
/* We have in `search_path' the information about the RPATH of the
|
/* We have in `search_path' the information about the RPATH of the
|
||||||
dynamic loader. Now fill in the information about the applications
|
dynamic loader. Now fill in the information about the applications
|
||||||
@ -331,10 +320,6 @@ _dl_init_paths (const char *llp)
|
|||||||
variable. */
|
variable. */
|
||||||
struct link_map *l;
|
struct link_map *l;
|
||||||
|
|
||||||
/* Names of important hardware capabilities. */
|
|
||||||
char **hwcap_names;
|
|
||||||
size_t nhwcap_names;
|
|
||||||
|
|
||||||
/* Number of elements in the library path. */
|
/* Number of elements in the library path. */
|
||||||
size_t nllp;
|
size_t nllp;
|
||||||
|
|
||||||
@ -352,8 +337,47 @@ _dl_init_paths (const char *llp)
|
|||||||
nllp = 0;
|
nllp = 0;
|
||||||
|
|
||||||
/* Get the capabilities. */
|
/* Get the capabilities. */
|
||||||
hwcap_names = _dl_important_hwcaps (&nhwcap_names,
|
capstr = _dl_important_hwcaps (_dl_platform, _dl_platformlen,
|
||||||
_dl_platform, _dl_platformlen);
|
&ncapstr, &max_capstrlen);
|
||||||
|
|
||||||
|
/* First set up the rest of the default search directory entries. */
|
||||||
|
aelem = rtld_search_dirs = (struct r_search_path_elem **)
|
||||||
|
malloc ((ncapstr + 1) * sizeof (struct r_search_path_elem *));
|
||||||
|
|
||||||
|
round_size = ((2 * sizeof (struct r_search_path_elem) - 1
|
||||||
|
+ ncapstr * sizeof (enum r_dir_status))
|
||||||
|
/ sizeof (struct r_search_path_elem));
|
||||||
|
|
||||||
|
rtld_search_dirs[0] = (struct r_search_path_elem *)
|
||||||
|
malloc ((sizeof (system_dirs) / sizeof (system_dirs[0]) - 1)
|
||||||
|
* round_size * sizeof (struct r_search_path_elem));
|
||||||
|
if (rtld_search_dirs[0] == NULL)
|
||||||
|
_dl_signal_error (ENOMEM, NULL, "cannot create cache for search path");
|
||||||
|
|
||||||
|
pelem = all_dirs= rtld_search_dirs[0];
|
||||||
|
for (strp = system_dirs; *strp != NULL; ++strp, pelem += round_size)
|
||||||
|
{
|
||||||
|
size_t cnt;
|
||||||
|
|
||||||
|
*aelem++ = pelem;
|
||||||
|
|
||||||
|
pelem->next = *(strp + 1) == NULL ? NULL : (pelem + round_size);
|
||||||
|
|
||||||
|
pelem->what = "system search path";
|
||||||
|
pelem->where = NULL;
|
||||||
|
|
||||||
|
pelem->dirnamelen = strlen (pelem->dirname = *strp);
|
||||||
|
if (pelem->dirnamelen > max_dirnamelen)
|
||||||
|
max_dirnamelen = pelem->dirnamelen;
|
||||||
|
|
||||||
|
if (pelem->dirname[0] != '/')
|
||||||
|
for (cnt = 0; cnt < ncapstr; ++cnt)
|
||||||
|
pelem->status[cnt] = existing;
|
||||||
|
else
|
||||||
|
for (cnt = 0; cnt < ncapstr; ++cnt)
|
||||||
|
pelem->status[cnt] = unknown;
|
||||||
|
}
|
||||||
|
*aelem = NULL;
|
||||||
|
|
||||||
l = _dl_loaded;
|
l = _dl_loaded;
|
||||||
if (l != NULL)
|
if (l != NULL)
|
||||||
@ -391,7 +415,7 @@ _dl_init_paths (const char *llp)
|
|||||||
|
|
||||||
if (nllp > 0)
|
if (nllp > 0)
|
||||||
{
|
{
|
||||||
char *copy = strdupa (llp);
|
char *copy = local_strdup (llp);
|
||||||
|
|
||||||
/* Decompose the LD_LIBRARY_PATH and fill in the result.
|
/* Decompose the LD_LIBRARY_PATH and fill in the result.
|
||||||
First search for the next place to enter elements. */
|
First search for the next place to enter elements. */
|
||||||
@ -402,7 +426,7 @@ _dl_init_paths (const char *llp)
|
|||||||
/* We need to take care that the LD_LIBRARY_PATH environment
|
/* We need to take care that the LD_LIBRARY_PATH environment
|
||||||
variable can contain a semicolon. */
|
variable can contain a semicolon. */
|
||||||
(void) fillin_rpath (copy, result, ":;",
|
(void) fillin_rpath (copy, result, ":;",
|
||||||
__libc_enable_secure ? trusted_dirs : NULL,
|
__libc_enable_secure ? system_dirs : NULL,
|
||||||
"LD_LIBRARY_PATH", NULL);
|
"LD_LIBRARY_PATH", NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -424,50 +448,10 @@ _dl_init_paths (const char *llp)
|
|||||||
"cannot create cache for search path");
|
"cannot create cache for search path");
|
||||||
|
|
||||||
(void) fillin_rpath (local_strdup (llp), fake_path_list, ":;",
|
(void) fillin_rpath (local_strdup (llp), fake_path_list, ":;",
|
||||||
__libc_enable_secure ? trusted_dirs : NULL,
|
__libc_enable_secure ? system_dirs : NULL,
|
||||||
"LD_LIBRARY_PATH", NULL);
|
"LD_LIBRARY_PATH", NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now set up the rest of the rtld_search_dirs. */
|
|
||||||
for (pelem = rtld_search_dirs; *pelem != NULL; ++pelem)
|
|
||||||
{
|
|
||||||
struct r_search_path_elem *relem = *pelem;
|
|
||||||
|
|
||||||
if (_dl_platform != NULL)
|
|
||||||
{
|
|
||||||
char *tmp, *orig;
|
|
||||||
|
|
||||||
relem->machdirnamelen = relem->dirnamelen + _dl_platformlen + 1;
|
|
||||||
tmp = (char *) malloc (relem->machdirnamelen + 1);
|
|
||||||
if (tmp == NULL)
|
|
||||||
_dl_signal_error (ENOMEM, NULL,
|
|
||||||
"cannot create cache for search path");
|
|
||||||
|
|
||||||
orig = tmp;
|
|
||||||
tmp = __mempcpy (tmp, relem->dirname, relem->dirnamelen);
|
|
||||||
tmp = __mempcpy (tmp, _dl_platform, _dl_platformlen);
|
|
||||||
*tmp++ = '/';
|
|
||||||
*tmp = '\0';
|
|
||||||
relem->dirname = orig;
|
|
||||||
|
|
||||||
relem->machdirstatus = unknown;
|
|
||||||
|
|
||||||
if (max_dirnamelen < relem->machdirnamelen)
|
|
||||||
max_dirnamelen = relem->machdirnamelen;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
relem->machdirnamelen = relem->dirnamelen;
|
|
||||||
relem->machdirstatus = nonexisting;
|
|
||||||
|
|
||||||
if (max_dirnamelen < relem->dirnamelen)
|
|
||||||
max_dirnamelen = relem->dirnamelen;
|
|
||||||
}
|
|
||||||
|
|
||||||
relem->what = "system search path";
|
|
||||||
relem->where = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -844,26 +828,26 @@ static void
|
|||||||
print_search_path (struct r_search_path_elem **list,
|
print_search_path (struct r_search_path_elem **list,
|
||||||
const char *what, const char *name)
|
const char *what, const char *name)
|
||||||
{
|
{
|
||||||
|
char buf[max_dirnamelen + max_capstrlen];
|
||||||
|
char *endp;
|
||||||
int first = 1;
|
int first = 1;
|
||||||
|
|
||||||
_dl_debug_message (1, " search path=", NULL);
|
_dl_debug_message (1, " search path=", NULL);
|
||||||
|
|
||||||
while (*list != NULL && (*list)->what == what) /* Yes, ==. */
|
while (*list != NULL && (*list)->what == what) /* Yes, ==. */
|
||||||
{
|
{
|
||||||
char *buf = strdupa ((*list)->dirname);
|
char *endp = __mempcpy (buf, (*list)->dirname, (*list)->dirnamelen);
|
||||||
|
size_t cnt;
|
||||||
|
|
||||||
|
for (cnt = 0; cnt < ncapstr; ++cnt)
|
||||||
|
if ((*list)->status[cnt] != nonexisting)
|
||||||
|
{
|
||||||
|
char *cp = __mempcpy (endp, capstr[cnt].str, capstr[cnt].len);
|
||||||
|
cp[-1] = '\0';
|
||||||
|
_dl_debug_message (0, first ? "" : ":", buf, NULL);
|
||||||
|
first = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if ((*list)->machdirstatus != nonexisting)
|
|
||||||
{
|
|
||||||
buf[(*list)->machdirnamelen - 1] = '\0';
|
|
||||||
_dl_debug_message (0, first ? "" : ":", buf, NULL);
|
|
||||||
first = 0;
|
|
||||||
}
|
|
||||||
if ((*list)->dirstatus != nonexisting)
|
|
||||||
{
|
|
||||||
buf[(*list)->dirnamelen - 1] = '\0';
|
|
||||||
_dl_debug_message (0, first ? "" : ":", buf, NULL);
|
|
||||||
first = 0;
|
|
||||||
}
|
|
||||||
++list;
|
++list;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -893,11 +877,12 @@ open_path (const char *name, size_t namelen, int preloaded,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = __alloca (max_dirnamelen + namelen);
|
buf = __alloca (max_dirnamelen + max_capstrlen + namelen + 1);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
struct r_search_path_elem *this_dir = *dirs;
|
struct r_search_path_elem *this_dir = *dirs;
|
||||||
size_t buflen = 0;
|
size_t buflen = 0;
|
||||||
|
size_t cnt;
|
||||||
|
|
||||||
/* If we are debugging the search for libraries print the path
|
/* If we are debugging the search for libraries print the path
|
||||||
now if it hasn't happened now. */
|
now if it hasn't happened now. */
|
||||||
@ -907,95 +892,43 @@ open_path (const char *name, size_t namelen, int preloaded,
|
|||||||
print_search_path (dirs, current_what, this_dir->where);
|
print_search_path (dirs, current_what, this_dir->where);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this_dir->machdirstatus != nonexisting)
|
for (cnt = 0; fd == -1 && cnt < ncapstr; ++cnt)
|
||||||
{
|
{
|
||||||
/* Construct the pathname to try. */
|
/* Skip this directory if we know it does not exist. */
|
||||||
buflen = ((char *) __mempcpy (__mempcpy (buf, this_dir->dirname,
|
if (this_dir->status[cnt] == nonexisting)
|
||||||
this_dir->machdirnamelen),
|
continue;
|
||||||
name, namelen)
|
|
||||||
- buf);
|
|
||||||
|
|
||||||
/* Print name we try if this is wanted. */
|
buflen =
|
||||||
if (_dl_debug_libs)
|
((char *) __mempcpy (__mempcpy (__mempcpy (buf, this_dir->dirname,
|
||||||
_dl_debug_message (1, " trying file=", buf, "\n", NULL);
|
this_dir->dirnamelen),
|
||||||
|
capstr[cnt].str, capstr[cnt].len),
|
||||||
fd = __open (buf, O_RDONLY);
|
name, namelen)
|
||||||
if (this_dir->machdirstatus == unknown)
|
- buf);
|
||||||
if (fd != -1)
|
|
||||||
this_dir->machdirstatus = existing;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* We failed to open machine dependent library. Let's
|
|
||||||
test whether there is any directory at all. */
|
|
||||||
struct stat st;
|
|
||||||
|
|
||||||
buf[this_dir->machdirnamelen - 1] = '\0';
|
|
||||||
|
|
||||||
if (__xstat (_STAT_VER, buf, &st) != 0
|
|
||||||
|| ! S_ISDIR (st.st_mode))
|
|
||||||
/* The directory does not exist ot it is no directory. */
|
|
||||||
this_dir->machdirstatus = nonexisting;
|
|
||||||
else
|
|
||||||
this_dir->machdirstatus = existing;
|
|
||||||
}
|
|
||||||
if (fd != -1 && preloaded && __libc_enable_secure)
|
|
||||||
{
|
|
||||||
/* This is an extra security effort to make sure nobody can
|
|
||||||
preload broken shared objects which are in the trusted
|
|
||||||
directories and so exploit the bugs. */
|
|
||||||
struct stat st;
|
|
||||||
|
|
||||||
if (__fxstat (_STAT_VER, fd, &st) != 0
|
|
||||||
|| (st.st_mode & S_ISUID) == 0)
|
|
||||||
{
|
|
||||||
/* The shared object cannot be tested for being SUID
|
|
||||||
or this bit is not set. In this case we must not
|
|
||||||
use this object. */
|
|
||||||
__close (fd);
|
|
||||||
fd = -1;
|
|
||||||
/* We simply ignore the file, signal this by setting
|
|
||||||
the error value which would have been set by `open'. */
|
|
||||||
errno = ENOENT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
errno = ENOENT;
|
|
||||||
|
|
||||||
if (fd == -1 && errno == ENOENT && this_dir->dirstatus != nonexisting)
|
|
||||||
{
|
|
||||||
/* Construct the pathname to try. */
|
|
||||||
buflen = ((char *) __mempcpy (__mempcpy (buf, this_dir->dirname,
|
|
||||||
this_dir->dirnamelen),
|
|
||||||
name, namelen)
|
|
||||||
- buf);
|
|
||||||
|
|
||||||
/* Print name we try if this is wanted. */
|
/* Print name we try if this is wanted. */
|
||||||
if (_dl_debug_libs)
|
if (_dl_debug_libs)
|
||||||
_dl_debug_message (1, " trying file=", buf, "\n", NULL);
|
_dl_debug_message (1, " trying file=", buf, "\n", NULL);
|
||||||
|
|
||||||
fd = __open (buf, O_RDONLY);
|
fd = __open (buf, O_RDONLY);
|
||||||
if (this_dir->dirstatus == unknown)
|
if (this_dir->status[cnt] == unknown)
|
||||||
if (fd != -1)
|
if (fd != -1)
|
||||||
this_dir->dirstatus = existing;
|
this_dir->status[cnt] = existing;
|
||||||
else
|
else
|
||||||
/* We failed to open library. Let's test whether there
|
{
|
||||||
is any directory at all. */
|
/* We failed to open machine dependent library. Let's
|
||||||
if (this_dir->dirnamelen <= 1)
|
test whether there is any directory at all. */
|
||||||
this_dir->dirstatus = existing;
|
struct stat st;
|
||||||
else
|
|
||||||
{
|
|
||||||
struct stat st;
|
|
||||||
|
|
||||||
buf[this_dir->dirnamelen - 1] = '\0';
|
buf[this_dir->dirnamelen + capstr[cnt].len] = '\0';
|
||||||
|
|
||||||
|
if (__xstat (_STAT_VER, buf, &st) != 0
|
||||||
|
|| ! S_ISDIR (st.st_mode))
|
||||||
|
/* The directory does not exist ot it is no directory. */
|
||||||
|
this_dir->status[cnt] = nonexisting;
|
||||||
|
else
|
||||||
|
this_dir->status[cnt] = existing;
|
||||||
|
}
|
||||||
|
|
||||||
if (__xstat (_STAT_VER, buf, &st) != 0
|
|
||||||
|| ! S_ISDIR (st.st_mode))
|
|
||||||
/* The directory does not exist ot it is no directory. */
|
|
||||||
this_dir->dirstatus = nonexisting;
|
|
||||||
else
|
|
||||||
this_dir->dirstatus = existing;
|
|
||||||
}
|
|
||||||
if (fd != -1 && preloaded && __libc_enable_secure)
|
if (fd != -1 && preloaded && __libc_enable_secure)
|
||||||
{
|
{
|
||||||
/* This is an extra security effort to make sure nobody can
|
/* This is an extra security effort to make sure nobody can
|
||||||
|
@ -60,9 +60,12 @@ struct r_search_path_elem
|
|||||||
const char *what;
|
const char *what;
|
||||||
const char *where;
|
const char *where;
|
||||||
|
|
||||||
|
/* Basename for this search path element. The string must end with
|
||||||
|
a slash character. */
|
||||||
const char *dirname;
|
const char *dirname;
|
||||||
|
size_t dirnamelen;
|
||||||
|
|
||||||
enum r_dir_status exists[0];
|
enum r_dir_status status[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct r_strlenpair
|
struct r_strlenpair
|
||||||
@ -137,6 +140,9 @@ extern int _dl_debug_files;
|
|||||||
/* Expect cache ID. */
|
/* Expect cache ID. */
|
||||||
extern int _dl_correct_cache_id;
|
extern int _dl_correct_cache_id;
|
||||||
|
|
||||||
|
/* Mask for important hardware capabilities we honour. */
|
||||||
|
extern unsigned long int _dl_hwcap_mask;
|
||||||
|
|
||||||
/* File deccriptor to write debug messages to. */
|
/* File deccriptor to write debug messages to. */
|
||||||
extern int _dl_debug_fd;
|
extern int _dl_debug_fd;
|
||||||
|
|
||||||
@ -386,7 +392,10 @@ extern void _dl_show_auxv (void);
|
|||||||
extern char *_dl_next_ld_env_entry (char ***position);
|
extern char *_dl_next_ld_env_entry (char ***position);
|
||||||
|
|
||||||
/* Return an array with the names of the important hardware capabilities. */
|
/* Return an array with the names of the important hardware capabilities. */
|
||||||
extern char **_dl_important_hwcap (size_t *sz);
|
extern const struct r_strlenpair *_dl_important_hwcaps (const char *platform,
|
||||||
|
size_t paltform_len,
|
||||||
|
size_t *sz,
|
||||||
|
size_t *max_capstrlen);
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|
||||||
|
@ -156,10 +156,6 @@ struct link_map
|
|||||||
/* Collected information about own RPATH directories. */
|
/* Collected information about own RPATH directories. */
|
||||||
struct r_search_path_elem **l_rpath_dirs;
|
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. */
|
/* Collected results of relocation while profiling. */
|
||||||
ElfW(Addr) *l_reloc_result;
|
ElfW(Addr) *l_reloc_result;
|
||||||
|
|
||||||
|
@ -1112,6 +1112,12 @@ process_envvars (enum mode *modep, int *lazyp)
|
|||||||
_dl_show_auxv ();
|
_dl_show_auxv ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 10:
|
||||||
|
/* mask for the important hardware capabilities. */
|
||||||
|
if (memcmp (&envline[3], "HWCAP_MASK", 10) == 0)
|
||||||
|
_dl_hwcap_mask = strtoul (&envline[14], NULL, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
case 12:
|
case 12:
|
||||||
/* Where to place the profiling data file. */
|
/* Where to place the profiling data file. */
|
||||||
if (memcmp (&envline[3], "DEBUG_OUTPUT", 12) == 0)
|
if (memcmp (&envline[3], "DEBUG_OUTPUT", 12) == 0)
|
||||||
|
1
include/mntent.h
Normal file
1
include/mntent.h
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include <misc/mntent.h>
|
@ -18,7 +18,10 @@
|
|||||||
Boston, MA 02111-1307, USA. */
|
Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
#include <elf.h>
|
#include <elf.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
@ -45,7 +48,8 @@ int __libc_enable_secure;
|
|||||||
int __libc_multiple_libcs; /* Defining this here avoids the inclusion
|
int __libc_multiple_libcs; /* Defining this here avoids the inclusion
|
||||||
of init-first. */
|
of init-first. */
|
||||||
static ElfW(auxv_t) *_dl_auxv;
|
static ElfW(auxv_t) *_dl_auxv;
|
||||||
static unsigned long hwcap;
|
static unsigned long int hwcap;
|
||||||
|
unsigned long int _dl_hwcap_mask = HWCAP_IMPORTANT;
|
||||||
|
|
||||||
|
|
||||||
#ifndef DL_FIND_ARG_COMPONENTS
|
#ifndef DL_FIND_ARG_COMPONENTS
|
||||||
@ -273,18 +277,21 @@ _dl_next_ld_env_entry (char ***position)
|
|||||||
|
|
||||||
/* Return an array of useful/necessary hardware capability names. */
|
/* Return an array of useful/necessary hardware capability names. */
|
||||||
const struct r_strlenpair *
|
const struct r_strlenpair *
|
||||||
_dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz)
|
_dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz,
|
||||||
|
size_t *max_capstrlen)
|
||||||
{
|
{
|
||||||
/* Determine how many important bits are set. */
|
/* Determine how many important bits are set. */
|
||||||
unsigned long int important = hwcap & HWCAP_IMPORTANT;
|
unsigned long int mask = _dl_hwcap_mask;
|
||||||
size_t cnt = platform != NULL;
|
size_t cnt = platform != NULL;
|
||||||
size_t n, m;
|
size_t n, m;
|
||||||
size_t total;
|
size_t total;
|
||||||
struct r_strlenpair *temp;
|
struct r_strlenpair *temp;
|
||||||
struct r_strlenpair *result;
|
struct r_strlenpair *result;
|
||||||
|
struct r_strlenpair *rp;
|
||||||
|
char *cp;
|
||||||
|
|
||||||
for (n = 0; (~((1UL << n) - 1) & important) != 0; ++n)
|
for (n = 0; (~((1UL << n) - 1) & mask) != 0; ++n)
|
||||||
if ((important & (1UL << n)) != 0)
|
if ((mask & (1UL << n)) != 0)
|
||||||
++cnt;
|
++cnt;
|
||||||
|
|
||||||
if (cnt == 0)
|
if (cnt == 0)
|
||||||
@ -298,22 +305,23 @@ _dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz)
|
|||||||
_dl_signal_error (ENOMEM, NULL, "cannot create capability list");
|
_dl_signal_error (ENOMEM, NULL, "cannot create capability list");
|
||||||
}
|
}
|
||||||
|
|
||||||
result[0]->str = (char *) result; /* Does not really matter. */
|
result[0].str = (char *) result; /* Does not really matter. */
|
||||||
result[0]->len = 0;
|
result[0].len = 0;
|
||||||
|
|
||||||
*sz = 1;
|
*sz = 1;
|
||||||
return &only_base;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create temporary data structure to generate result table. */
|
/* Create temporary data structure to generate result table. */
|
||||||
temp = (struct r_strlenpair *) alloca (cnt * sizeof (*temp));
|
temp = (struct r_strlenpair *) alloca (cnt * sizeof (*temp));
|
||||||
m = 0;
|
m = 0;
|
||||||
for (n = 0; (~((1UL << n) - 1) & important) != 0; ++n)
|
for (n = 0; mask != 0; ++n)
|
||||||
if ((important & (1UL << n)) != 0)
|
if ((mask & (1UL << n)) != 0)
|
||||||
{
|
{
|
||||||
temp[m].str = _dl_hwcap_string (n);
|
temp[m].str = _dl_hwcap_string (n);
|
||||||
temp[m].len = strlen (temp[m].str);
|
temp[m].len = strlen (temp[m].str);
|
||||||
++m
|
mask ^= 1UL << n;
|
||||||
|
++m;
|
||||||
}
|
}
|
||||||
if (platform != NULL)
|
if (platform != NULL)
|
||||||
{
|
{
|
||||||
@ -322,36 +330,37 @@ _dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz)
|
|||||||
++m;
|
++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. */
|
/* Determine the total size of all strings together. */
|
||||||
total = cnt * (temp[0].len + temp[cnt - 1].len + 2);
|
if (cnt == 1)
|
||||||
for (n = 1; n + 1 < cnt; ++n)
|
total = temp[0].len;
|
||||||
total += 2 * (temp[n].len + 1);
|
else
|
||||||
|
{
|
||||||
|
total = (1 << (cnt - 2)) * (temp[0].len = temp[cnt - 1].len + 2);
|
||||||
|
for (n = 1; n + 1 < cnt; ++n)
|
||||||
|
total += (1 << (cnt - 3)) * (temp[n].len + 1);
|
||||||
|
}
|
||||||
|
|
||||||
/* The result structure: we use a very compressed way to store the
|
/* The result structure: we use a very compressed way to store the
|
||||||
various combinations of capability names. */
|
various combinations of capability names. */
|
||||||
result = (struct r_strlenpair *) malloc (1 << (cnt - 2) * sizeof (*result)
|
*sz = 1 << cnt;
|
||||||
+ total);
|
result = (struct r_strlenpair *) malloc (*sz * sizeof (*result) + total);
|
||||||
if (result == NULL)
|
if (result == NULL)
|
||||||
goto no_memory;
|
goto no_memory;
|
||||||
|
|
||||||
|
if (cnt == 1)
|
||||||
|
{
|
||||||
|
result[0].str = (char *) (result + *sz);
|
||||||
|
result[0].len = temp[0].len + 1;
|
||||||
|
result[1].str = (char *) (result + *sz);
|
||||||
|
result[1].len = 0;
|
||||||
|
cp = __mempcpy ((char *) (result + *sz), temp[0].str, temp[0].len);
|
||||||
|
*cp = '/';
|
||||||
|
*sz = 2;
|
||||||
|
*max_capstrlen = result[0].len;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/* Fill in the information. This follows the following scheme
|
/* Fill in the information. This follows the following scheme
|
||||||
(indeces from TEMP for four strings):
|
(indeces from TEMP for four strings):
|
||||||
entry #0: 0, 1, 2, 3 binary: 1111
|
entry #0: 0, 1, 2, 3 binary: 1111
|
||||||
@ -360,35 +369,75 @@ _dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz)
|
|||||||
#3: 0, 3 1001
|
#3: 0, 3 1001
|
||||||
This allows to represent all possible combinations of capability
|
This allows to represent all possible combinations of capability
|
||||||
names in the string. First generate the strings. */
|
names in the string. First generate the strings. */
|
||||||
n = 1 << cnt;
|
result[1].str = result[0].str = cp = (char *) (result + *sz);
|
||||||
cp = result[0].str = (char *) (result + 1 << (cnt - 2));
|
#define add(idx) \
|
||||||
|
cp = __mempcpy (__mempcpy (cp, temp[idx].str, temp[idx].len), "/", 1);
|
||||||
|
if (cnt == 2)
|
||||||
|
{
|
||||||
|
add (1);
|
||||||
|
add (0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
n = 1 << cnt;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
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; m > 0; --m)
|
||||||
|
if ((n & (1 << m)) != 0)
|
||||||
|
add (m);
|
||||||
|
|
||||||
|
/* Always add the first string. */
|
||||||
|
add (0);
|
||||||
|
}
|
||||||
|
while (n != 0);
|
||||||
|
}
|
||||||
|
#undef add
|
||||||
|
|
||||||
|
/* Now we are ready to install the string pointers and length. */
|
||||||
|
for (n = 0; n < (1 << cnt); ++n)
|
||||||
|
result[n].len = 0;
|
||||||
|
n = cnt;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
#define add(idx) \
|
size_t mask = 1 << --n;
|
||||||
cp = __mempcpy (__mempcpy (cp, "/", 1), temp[idx].str, temp[idx].len)
|
|
||||||
|
|
||||||
n -= 2;
|
rp = result;
|
||||||
|
for (m = 1 << cnt; m > 0; ++rp)
|
||||||
/* We always add the last string. */
|
if ((--m & mask) != 0)
|
||||||
add (cnt - 1);
|
rp->len += temp[n].len + 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);
|
while (n != 0);
|
||||||
|
|
||||||
/* Now we are ready to install the string pointers and length.
|
/* The first half of the strings all include the first string. */
|
||||||
The first string contains all strings. */
|
n = (1 << cnt) - 2;
|
||||||
result[0].len = 0;
|
rp = &result[2];
|
||||||
for (n = 0; n < cnt; ++n)
|
while (n != (1 << (cnt - 1)))
|
||||||
result[0].len += temp[n].len;
|
{
|
||||||
|
if ((n & 1) != 0)
|
||||||
|
rp[0].str = rp[-2].str + rp[-2].len;
|
||||||
|
else
|
||||||
|
rp[0].str = rp[-1].str;
|
||||||
|
++rp;
|
||||||
|
--n;
|
||||||
|
}
|
||||||
|
|
||||||
I KNOW THIS DOES NOT YET WORK --drepper
|
/* The second have starts right after the first part of the string of
|
||||||
|
corresponding entry in the first half. */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
rp[0].str = rp[-(1 << (cnt - 1))].str + temp[cnt - 1].len + 1;
|
||||||
|
++rp;
|
||||||
|
}
|
||||||
|
while (--n != 0);
|
||||||
|
|
||||||
|
/* The maximum string length. */
|
||||||
|
*max_capstrlen = result[0].len;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user