mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-29 11:41:21 +03:00
Update.
1998-08-27 19:42 Ulrich Drepper <drepper@cygnus.com> * elf/Makefile (distribute): Add dl-origin.h. * sysdeps/generic/dl-origin.h: New file. * sysdeps/unix/sysv/linux/dl-origin.h: New file. * elf/link.h (struct link_map): Add l_origin field. * elf/dl-load.c (expand_dynamic_string_token): New function. (decompose_path): Remove WHERE argument, take link map pointer instead. Call expand_dynamic_string_token instead of local_strdup to make copy of rpath. (_dl_init_paths): Call decompose_path with correct argument. (_dl_map_object_from_fd): Define static is EXTERNAL_MAP_FROM_FD is not defined. Check EI_OSABI and EI_ABIVERSION fields in header. (_dl_map_object): Call decompose_path with correct argument. Call expand_dynamic_string_token instead of local_strdup to also expand DST. * elf/dl-object.c (_dl_new_object): Determine l_origin for all maps but the main one. * elf/dl-support.c: Define _dl_origin_path. * elf/rtld.c: Likewise. Set _dl_origin_path based on LD_ORIGIN_PATH. * elf/dl-close (_dl_close): Free l_name and l_origin. * sysdeps/i386/useldt.h (THREAD_GETMEM, THREAD_SETMEM): Use P modifier in asm, not c. * sysdeps/mach/hurd/Makefile [subdirs==elf]: Define CFLAGS-dl-load.c to -DEXTERNAL_MAP_FROM_FD to make _dl_map_object_from_fd extern.
This commit is contained in:
30
ChangeLog
30
ChangeLog
@ -1,3 +1,33 @@
|
|||||||
|
1998-08-27 19:42 Ulrich Drepper <drepper@cygnus.com>
|
||||||
|
|
||||||
|
* elf/Makefile (distribute): Add dl-origin.h.
|
||||||
|
* sysdeps/generic/dl-origin.h: New file.
|
||||||
|
* sysdeps/unix/sysv/linux/dl-origin.h: New file.
|
||||||
|
* elf/link.h (struct link_map): Add l_origin field.
|
||||||
|
* elf/dl-load.c (expand_dynamic_string_token): New function.
|
||||||
|
(decompose_path): Remove WHERE argument, take link map pointer instead.
|
||||||
|
Call expand_dynamic_string_token instead of local_strdup to make copy
|
||||||
|
of rpath.
|
||||||
|
(_dl_init_paths): Call decompose_path with correct argument.
|
||||||
|
(_dl_map_object_from_fd): Define static is EXTERNAL_MAP_FROM_FD is
|
||||||
|
not defined.
|
||||||
|
Check EI_OSABI and EI_ABIVERSION fields in header.
|
||||||
|
(_dl_map_object): Call decompose_path with correct argument.
|
||||||
|
Call expand_dynamic_string_token instead of local_strdup to also
|
||||||
|
expand DST.
|
||||||
|
* elf/dl-object.c (_dl_new_object): Determine l_origin for all maps
|
||||||
|
but the main one.
|
||||||
|
* elf/dl-support.c: Define _dl_origin_path.
|
||||||
|
* elf/rtld.c: Likewise. Set _dl_origin_path based on LD_ORIGIN_PATH.
|
||||||
|
|
||||||
|
* elf/dl-close (_dl_close): Free l_name and l_origin.
|
||||||
|
|
||||||
|
* sysdeps/i386/useldt.h (THREAD_GETMEM, THREAD_SETMEM): Use P
|
||||||
|
modifier in asm, not c.
|
||||||
|
|
||||||
|
* sysdeps/mach/hurd/Makefile [subdirs==elf]: Define CFLAGS-dl-load.c
|
||||||
|
to -DEXTERNAL_MAP_FROM_FD to make _dl_map_object_from_fd extern.
|
||||||
|
|
||||||
1998-08-26 17:48 Ulrich Drepper <drepper@cygnus.com>
|
1998-08-26 17:48 Ulrich Drepper <drepper@cygnus.com>
|
||||||
|
|
||||||
* elf/dl-close.c (_dl_close): Move map->l_nsearchlist value into local
|
* elf/dl-close.c (_dl_close): Move map->l_nsearchlist value into local
|
||||||
|
@ -38,7 +38,7 @@ rtld-routines := rtld $(dl-routines) dl-sysdep dl-environ dl-minimal
|
|||||||
distribute = $(rtld-routines:=.c) dynamic-link.h do-rel.h dl-machine.h \
|
distribute = $(rtld-routines:=.c) dynamic-link.h do-rel.h dl-machine.h \
|
||||||
dl-hash.h soinit.c sofini.c ldd.sh.in ldd.bash.in eval.c \
|
dl-hash.h soinit.c sofini.c ldd.sh.in ldd.bash.in eval.c \
|
||||||
genrtldtbl.awk atomicity.h dl-procinfo.h ldsodefs.h \
|
genrtldtbl.awk atomicity.h dl-procinfo.h ldsodefs.h \
|
||||||
dl-librecon.h interp.c sln.c
|
dl-librecon.h interp.c sln.c dl-origin.h
|
||||||
|
|
||||||
extra-libs = libdl
|
extra-libs = libdl
|
||||||
extra-libs-others = $(extra-libs)
|
extra-libs-others = $(extra-libs)
|
||||||
|
@ -88,6 +88,11 @@ _dl_close (struct link_map *map)
|
|||||||
for (i = 0; i < nsearchlist; ++i)
|
for (i = 0; i < nsearchlist; ++i)
|
||||||
--list[i]->l_opencount;
|
--list[i]->l_opencount;
|
||||||
|
|
||||||
|
if (map->l_origin != NULL)
|
||||||
|
free ((char *) map->l_origin);
|
||||||
|
/* The name always is allocated. */
|
||||||
|
free (map->l_name);
|
||||||
|
|
||||||
/* Check each element of the search list to see if all references to
|
/* Check each element of the search list to see if all references to
|
||||||
it are gone. */
|
it are gone. */
|
||||||
for (i = 0; i < nsearchlist; ++i)
|
for (i = 0; i < nsearchlist; ++i)
|
||||||
|
151
elf/dl-load.c
151
elf/dl-load.c
@ -31,6 +31,8 @@
|
|||||||
#include "dynamic-link.h"
|
#include "dynamic-link.h"
|
||||||
#include <stdio-common/_itoa.h>
|
#include <stdio-common/_itoa.h>
|
||||||
|
|
||||||
|
#include <dl-origin.h>
|
||||||
|
|
||||||
|
|
||||||
/* On some systems, no flag bits are given to specify file mapping. */
|
/* On some systems, no flag bits are given to specify file mapping. */
|
||||||
#ifndef MAP_FILE
|
#ifndef MAP_FILE
|
||||||
@ -124,6 +126,116 @@ local_strdup (const char *s)
|
|||||||
return (char *) memcpy (new, s, len);
|
return (char *) memcpy (new, s, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return copy of argument with all recognized dynamic string tokens
|
||||||
|
($ORIGIN and $PLATFORM for now) replaced. On some platforms it
|
||||||
|
might not be possible to determine the path from which the object
|
||||||
|
belonging to the map is loaded. In this case the path element
|
||||||
|
containing $ORIGIN is left out. */
|
||||||
|
static char *
|
||||||
|
expand_dynamic_string_token (struct link_map *l, const char *s)
|
||||||
|
{
|
||||||
|
/* We make two runs over the string. First we determine how large the
|
||||||
|
resulting string is and then we copy it over. Since this is now
|
||||||
|
frequently executed operation we are looking here not for performance
|
||||||
|
but rather for code size. */
|
||||||
|
const char *st, *sf;
|
||||||
|
size_t cnt = 0;
|
||||||
|
size_t origin_len;
|
||||||
|
size_t total;
|
||||||
|
char *result, *last_elem, *wp;
|
||||||
|
|
||||||
|
st = s;
|
||||||
|
sf = strchr (s, '$');
|
||||||
|
while (sf != NULL)
|
||||||
|
{
|
||||||
|
size_t len = 1;
|
||||||
|
|
||||||
|
if (((strncmp (&sf[1], "ORIGIN", 6) == 0 && (len = 7) != 0)
|
||||||
|
|| (strncmp (&sf[1], "PLATFORM", 8) == 0 && (len = 9) != 0))
|
||||||
|
&& (s[len] == '\0' || s[len] == '/' || s[len] == ':'))
|
||||||
|
++cnt;
|
||||||
|
|
||||||
|
st = sf + len;
|
||||||
|
sf = strchr (st, '$');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we do not have to replace anything simply copy the string. */
|
||||||
|
if (cnt == 0)
|
||||||
|
return local_strdup (s);
|
||||||
|
|
||||||
|
/* Now we make a guess how many extra characters on top of the length
|
||||||
|
of S we need to represent the result. We know that we have CNT
|
||||||
|
replacements. Each at most can use
|
||||||
|
MAX (strlen (ORIGIN), strlen (_dl_platform))
|
||||||
|
minus 7 (which is the length of "$ORIGIN").
|
||||||
|
|
||||||
|
First get the origin string if it is not available yet. This can
|
||||||
|
only happen for the map of the executable. */
|
||||||
|
if (l->l_origin == NULL)
|
||||||
|
{
|
||||||
|
assert (l->l_name[0] == '\0');
|
||||||
|
l->l_origin = get_origin ();
|
||||||
|
origin_len = l->l_origin ? strlen (l->l_origin) : 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
origin_len = l->l_origin == (char *) -1 ? 0 : strlen (l->l_origin);
|
||||||
|
|
||||||
|
total = strlen (s) + cnt * (MAX (origin_len, _dl_platformlen) - 7);
|
||||||
|
result = (char *) malloc (total + 1);
|
||||||
|
if (result == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Now fill the result path. While copying over the string we keep
|
||||||
|
track of the start of the last path element. When we come accross
|
||||||
|
a DST we copy over the value or (if the value is not available)
|
||||||
|
leave the entire path element out. */
|
||||||
|
last_elem = wp = result;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (*s == '$')
|
||||||
|
{
|
||||||
|
const char *repl;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (((strncmp (&s[1], "ORIGIN", 6) == 0 && (len = 7) != 0)
|
||||||
|
|| (strncmp (&s[1], "PLATFORM", 8) == 0 && (len = 9) != 0))
|
||||||
|
&& (s[len] == '\0' || s[len] == '/' || s[len] == ':'))
|
||||||
|
{
|
||||||
|
if ((repl = len == 7 ? l->l_origin : _dl_platform) != NULL
|
||||||
|
&& repl != (const char *) -1)
|
||||||
|
{
|
||||||
|
wp = __stpcpy (wp, repl);
|
||||||
|
s += len;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* We cannot use this path element, the value of the
|
||||||
|
replacement is unknown. */
|
||||||
|
wp = last_elem;
|
||||||
|
s += len;
|
||||||
|
while (*s != '\0' && *s != ':')
|
||||||
|
++s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* No SDK we recognize. */
|
||||||
|
*wp++ = *s++;
|
||||||
|
}
|
||||||
|
else if (*s == ':')
|
||||||
|
{
|
||||||
|
*wp++ = *s++;
|
||||||
|
last_elem = wp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*wp++ = *s++;
|
||||||
|
}
|
||||||
|
while (*s != '\0');
|
||||||
|
|
||||||
|
*wp = '\0';
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/* Add `name' to the list of names for a particular shared object.
|
/* Add `name' to the list of names for a particular shared object.
|
||||||
`name' is expected to have been allocated with malloc and will
|
`name' is expected to have been allocated with malloc and will
|
||||||
be freed if the shared object already has this name.
|
be freed if the shared object already has this name.
|
||||||
@ -286,9 +398,10 @@ 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
|
internal_function
|
||||||
decompose_rpath (const char *rpath, size_t additional_room, const char *where)
|
decompose_rpath (const char *rpath, size_t additional_room, struct link_map *l)
|
||||||
{
|
{
|
||||||
/* Make a copy we can work with. */
|
/* Make a copy we can work with. */
|
||||||
|
const char *where = l->l_name;
|
||||||
char *copy;
|
char *copy;
|
||||||
char *cp;
|
char *cp;
|
||||||
struct r_search_path_elem **result;
|
struct r_search_path_elem **result;
|
||||||
@ -318,8 +431,13 @@ decompose_rpath (const char *rpath, size_t additional_room, const char *where)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Make a writable copy. At the same time expand possible dynamic
|
||||||
|
string tokens. */
|
||||||
|
copy = expand_dynamic_string_token (l, rpath);
|
||||||
|
if (copy == NULL)
|
||||||
|
_dl_signal_error (ENOMEM, NULL, "cannot create RPATH copy");
|
||||||
|
|
||||||
/* Count the number of necessary elements in the result array. */
|
/* Count the number of necessary elements in the result array. */
|
||||||
copy = local_strdup (rpath);
|
|
||||||
nelems = 0;
|
nelems = 0;
|
||||||
for (cp = copy; *cp != '\0'; ++cp)
|
for (cp = copy; *cp != '\0'; ++cp)
|
||||||
if (*cp == ':')
|
if (*cp == ':')
|
||||||
@ -429,7 +547,7 @@ _dl_init_paths (const char *llp)
|
|||||||
decompose_rpath ((const char *)
|
decompose_rpath ((const char *)
|
||||||
(l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr
|
(l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr
|
||||||
+ l->l_info[DT_RPATH]->d_un.d_val),
|
+ l->l_info[DT_RPATH]->d_un.d_val),
|
||||||
nllp, l->l_name);
|
nllp, l);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -497,6 +615,9 @@ _dl_init_paths (const char *llp)
|
|||||||
/* Map in the shared object NAME, actually located in REALNAME, and already
|
/* Map in the shared object NAME, actually located in REALNAME, and already
|
||||||
opened on FD. */
|
opened on FD. */
|
||||||
|
|
||||||
|
#ifndef EXTERNAL_MAP_FROM_FD
|
||||||
|
static
|
||||||
|
#endif
|
||||||
struct link_map *
|
struct link_map *
|
||||||
_dl_map_object_from_fd (char *name, int fd, char *realname,
|
_dl_map_object_from_fd (char *name, int fd, char *realname,
|
||||||
struct link_map *loader, int l_type)
|
struct link_map *loader, int l_type)
|
||||||
@ -591,6 +712,12 @@ _dl_map_object_from_fd (char *name, int fd, char *realname,
|
|||||||
LOSE ("ELF file data encoding not " byteorder_name);
|
LOSE ("ELF file data encoding not " byteorder_name);
|
||||||
if (header->e_ident[EI_VERSION] != EV_CURRENT)
|
if (header->e_ident[EI_VERSION] != EV_CURRENT)
|
||||||
LOSE ("ELF file version ident not " STRING(EV_CURRENT));
|
LOSE ("ELF file version ident not " STRING(EV_CURRENT));
|
||||||
|
/* XXX We should be able so set system specific versions which are
|
||||||
|
allowed here. */
|
||||||
|
if (header->e_ident[EI_OSABI] != ELFOSABI_SYSV)
|
||||||
|
LOSE ("ELF file OS ABI not " STRING(ELFOSABI_SYSV));
|
||||||
|
if (header->e_ident[EI_ABIVERSION] != 0)
|
||||||
|
LOSE ("ELF file ABI version not 0");
|
||||||
if (header->e_version != EV_CURRENT)
|
if (header->e_version != EV_CURRENT)
|
||||||
LOSE ("ELF file version not " STRING(EV_CURRENT));
|
LOSE ("ELF file version not " STRING(EV_CURRENT));
|
||||||
if (! elf_machine_matches_host (header->e_machine))
|
if (! elf_machine_matches_host (header->e_machine))
|
||||||
@ -1076,7 +1203,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
|
|||||||
+ l->l_info[DT_STRTAB]->d_un.d_ptr
|
+ l->l_info[DT_STRTAB]->d_un.d_ptr
|
||||||
+ l->l_info[DT_RPATH]->d_un.d_val);
|
+ l->l_info[DT_RPATH]->d_un.d_val);
|
||||||
l->l_rpath_dirs =
|
l->l_rpath_dirs =
|
||||||
decompose_rpath ((const char *) ptrval, 0, l->l_name);
|
decompose_rpath ((const char *) ptrval, 0, l);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (l->l_rpath_dirs != (struct r_search_path_elem **) -1l)
|
if (l->l_rpath_dirs != (struct r_search_path_elem **) -1l)
|
||||||
@ -1127,15 +1254,17 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fd = __open (name, O_RDONLY);
|
/* The path may contain dynamic string tokens. */
|
||||||
if (fd != -1)
|
realname = (loader
|
||||||
{
|
? expand_dynamic_string_token (loader, name)
|
||||||
realname = local_strdup (name);
|
: local_strdup (name));
|
||||||
if (realname == NULL)
|
if (realname == NULL)
|
||||||
{
|
|
||||||
__close (fd);
|
|
||||||
fd = -1;
|
fd = -1;
|
||||||
}
|
else
|
||||||
|
{
|
||||||
|
fd = __open (realname, O_RDONLY);
|
||||||
|
if (fd == -1)
|
||||||
|
free (realname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include <elf/ldsodefs.h>
|
#include <elf/ldsodefs.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@ -61,5 +62,68 @@ _dl_new_object (char *realname, const char *libname, int type)
|
|||||||
l->l_next = new;
|
l->l_next = new;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The REALNAME is "" for the main link map. This name must be determined
|
||||||
|
specially. */
|
||||||
|
if (realname[0] == '\0')
|
||||||
|
new->l_origin = NULL;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *origin;
|
||||||
|
|
||||||
|
if (realname[0] == '/')
|
||||||
|
{
|
||||||
|
/* It an absolute path. Use it. But we have to make a copy since
|
||||||
|
we strip out the trailing slash. */
|
||||||
|
size_t len = strlen (realname) + 1;
|
||||||
|
origin = malloc (len);
|
||||||
|
if (origin == NULL)
|
||||||
|
origin = (char *) -1;
|
||||||
|
else
|
||||||
|
memcpy (origin, realname, len);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size_t realname_len = strlen (realname) + 1;
|
||||||
|
size_t len = 128 + realname_len;
|
||||||
|
char *result = NULL;
|
||||||
|
|
||||||
|
/* Get the current directory name. */
|
||||||
|
origin = malloc (len);
|
||||||
|
|
||||||
|
while (origin != NULL
|
||||||
|
&& (result = __getcwd (origin, len - realname_len)) == NULL
|
||||||
|
&& errno == ERANGE)
|
||||||
|
{
|
||||||
|
len += 128;
|
||||||
|
origin = (char *) realloc (origin, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result == NULL)
|
||||||
|
{
|
||||||
|
/* We were not able to determine the current directory. */
|
||||||
|
if (origin != NULL)
|
||||||
|
free (origin);
|
||||||
|
origin = (char *) -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Now append the filename. */
|
||||||
|
char *cp = strchr (origin, '\0');
|
||||||
|
|
||||||
|
if (cp [-1] != '/')
|
||||||
|
*cp++ = '/';
|
||||||
|
|
||||||
|
memcpy (cp, realname, realname_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (origin != (char *) -1)
|
||||||
|
/* Now remove the filename and the slash. Do this even if the
|
||||||
|
string is something like "/foo" which leaves an empty string. */
|
||||||
|
*strrchr (origin, '/') = '\0';
|
||||||
|
|
||||||
|
new->l_origin = origin;
|
||||||
|
}
|
||||||
|
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
@ -63,6 +63,9 @@ struct link_map *_dl_profile_map;
|
|||||||
/* This is the address of the last stack address ever used. */
|
/* This is the address of the last stack address ever used. */
|
||||||
void *__libc_stack_end;
|
void *__libc_stack_end;
|
||||||
|
|
||||||
|
/* Path where the binary is found. */
|
||||||
|
const char *_dl_origin_path;
|
||||||
|
|
||||||
|
|
||||||
static void non_dynamic_init (void) __attribute__ ((unused));
|
static void non_dynamic_init (void) __attribute__ ((unused));
|
||||||
|
|
||||||
|
@ -161,6 +161,9 @@ struct link_map
|
|||||||
|
|
||||||
/* Pointer to the version information if available. */
|
/* Pointer to the version information if available. */
|
||||||
ElfW(Half) *l_versyms;
|
ElfW(Half) *l_versyms;
|
||||||
|
|
||||||
|
/* String specifying the path where this object was found. */
|
||||||
|
const char *l_origin;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* link.h */
|
#endif /* link.h */
|
||||||
|
@ -87,6 +87,7 @@ int _dl_debug_reloc;
|
|||||||
int _dl_debug_files;
|
int _dl_debug_files;
|
||||||
const char *_dl_inhibit_rpath; /* RPATH values which should be
|
const char *_dl_inhibit_rpath; /* RPATH values which should be
|
||||||
ignored. */
|
ignored. */
|
||||||
|
const char *_dl_origin_path;
|
||||||
|
|
||||||
/* Set nonzero during loading and initialization of executable and
|
/* Set nonzero during loading and initialization of executable and
|
||||||
libraries, cleared before the executable's entry point runs. This
|
libraries, cleared before the executable's entry point runs. This
|
||||||
@ -1164,6 +1165,12 @@ process_envvars (enum mode *modep, int *lazyp)
|
|||||||
_dl_hwcap_mask = strtoul (&envline[14], NULL, 0);
|
_dl_hwcap_mask = strtoul (&envline[14], NULL, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 11:
|
||||||
|
/* Path where the binary is found. */
|
||||||
|
if (memcmp (&envline[3], "ORIGIN_PATH", 11) == 0)
|
||||||
|
_dl_hwcap_mask = strtoul (&envline[15], 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)
|
||||||
|
@ -82,7 +82,7 @@ extern int __modify_ldt (int, struct modify_ldt_ldt_s *, size_t);
|
|||||||
({ \
|
({ \
|
||||||
__typeof__ (descr->member) __value; \
|
__typeof__ (descr->member) __value; \
|
||||||
if (sizeof (__value) == 1) \
|
if (sizeof (__value) == 1) \
|
||||||
__asm__ __volatile__ ("movb %%gs:%c1,%b0" \
|
__asm__ __volatile__ ("movb %%gs:%P1,%b0" \
|
||||||
: "=r" (__value) \
|
: "=r" (__value) \
|
||||||
: "0" (0), \
|
: "0" (0), \
|
||||||
"i" (offsetof (struct _pthread_descr_struct, \
|
"i" (offsetof (struct _pthread_descr_struct, \
|
||||||
@ -93,7 +93,7 @@ extern int __modify_ldt (int, struct modify_ldt_ldt_s *, size_t);
|
|||||||
/* There should not be any value with a size other than 1 or 4. */ \
|
/* There should not be any value with a size other than 1 or 4. */ \
|
||||||
abort (); \
|
abort (); \
|
||||||
\
|
\
|
||||||
__asm__ __volatile__ ("movl %%gs:%c1,%0" \
|
__asm__ __volatile__ ("movl %%gs:%P1,%0" \
|
||||||
: "=r" (__value) \
|
: "=r" (__value) \
|
||||||
: "i" (offsetof (struct _pthread_descr_struct, \
|
: "i" (offsetof (struct _pthread_descr_struct, \
|
||||||
member))); \
|
member))); \
|
||||||
@ -106,7 +106,7 @@ extern int __modify_ldt (int, struct modify_ldt_ldt_s *, size_t);
|
|||||||
({ \
|
({ \
|
||||||
__typeof__ (descr->member) __value = (value); \
|
__typeof__ (descr->member) __value = (value); \
|
||||||
if (sizeof (__value) == 1) \
|
if (sizeof (__value) == 1) \
|
||||||
__asm__ __volatile__ ("movb %0,%%gs:%c1" : \
|
__asm__ __volatile__ ("movb %0,%%gs:%P1" : \
|
||||||
: "r" (__value), \
|
: "r" (__value), \
|
||||||
"i" (offsetof (struct _pthread_descr_struct, \
|
"i" (offsetof (struct _pthread_descr_struct, \
|
||||||
member))); \
|
member))); \
|
||||||
@ -116,7 +116,7 @@ extern int __modify_ldt (int, struct modify_ldt_ldt_s *, size_t);
|
|||||||
/* There should not be any value with a size other than 1 or 4. */ \
|
/* There should not be any value with a size other than 1 or 4. */ \
|
||||||
abort (); \
|
abort (); \
|
||||||
\
|
\
|
||||||
__asm__ __volatile__ ("movl %0,%%gs:%c1" : \
|
__asm__ __volatile__ ("movl %0,%%gs:%P1" : \
|
||||||
: "r" (__value), \
|
: "r" (__value), \
|
||||||
"i" (offsetof (struct _pthread_descr_struct, \
|
"i" (offsetof (struct _pthread_descr_struct, \
|
||||||
member))); \
|
member))); \
|
||||||
|
47
sysdeps/generic/dl-origin.h
Normal file
47
sysdeps/generic/dl-origin.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/* Find path of executable.
|
||||||
|
Copyright (C) 1998 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
|
||||||
|
|
||||||
|
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. */
|
||||||
|
|
||||||
|
/* Generally it is not possible to implement this. We have to fall
|
||||||
|
back on a solution where the user provides the information. */
|
||||||
|
extern const char *_dl_origin_path;
|
||||||
|
|
||||||
|
static inline const char *
|
||||||
|
get_origin (void)
|
||||||
|
{
|
||||||
|
char *result = (char *) -1;
|
||||||
|
/* We use te environment variable LD_ORIGIN_PATH. If it is set make
|
||||||
|
a copy and strip out trailing slashes. */
|
||||||
|
if (_dl_origin_path != NULL)
|
||||||
|
{
|
||||||
|
size_t len = strlen (_dl_origin_path);
|
||||||
|
result = malloc (len + 1);
|
||||||
|
if (result == NULL)
|
||||||
|
result = (char *) -1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *cp = __mempcpy (result, _dl_origin_path, len);
|
||||||
|
while (cp > result && cp[-1] == '/')
|
||||||
|
--cp;
|
||||||
|
*cp = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
@ -124,6 +124,8 @@ $(inst_libdir)/libc.so: $(rpcuserlibs)
|
|||||||
# objects directly into the shared object.
|
# objects directly into the shared object.
|
||||||
ifeq (elf,$(subdir))
|
ifeq (elf,$(subdir))
|
||||||
$(objpfx)librtld.os: $(rpcuserlibs:.so=_pic.a)
|
$(objpfx)librtld.os: $(rpcuserlibs:.so=_pic.a)
|
||||||
|
|
||||||
|
CFLAGS-dl-load.c = -DEXTERNAL_MAP_FROM_FD
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# We need these libs to link static programs in the libc source tree, too.
|
# We need these libs to link static programs in the libc source tree, too.
|
||||||
|
67
sysdeps/unix/sysv/linux/dl-origin.h
Normal file
67
sysdeps/unix/sysv/linux/dl-origin.h
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/* Find path of executable.
|
||||||
|
Copyright (C) 1998 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
|
||||||
|
|
||||||
|
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. */
|
||||||
|
|
||||||
|
/* On Linux >= 2.1 systems which have the dcache implementation we can get
|
||||||
|
the path of the application from the /proc/self/exe symlink. Try this
|
||||||
|
first and fall back on the generic method if necessary. */
|
||||||
|
extern const char *_dl_origin_path;
|
||||||
|
|
||||||
|
static inline const char *
|
||||||
|
get_origin (void)
|
||||||
|
{
|
||||||
|
char linkval[PATH_MAX];
|
||||||
|
char *result;
|
||||||
|
|
||||||
|
if (readlink ("/proc/self/exe", linkval, PATH_MAX) != -1
|
||||||
|
&& result[0] != '[')
|
||||||
|
{
|
||||||
|
/* We can use this value. */
|
||||||
|
char *last_slash = strrchr (linkval, '/');
|
||||||
|
result = (char *) malloc (linkval - last_slash + 1);
|
||||||
|
if (result == NULL)
|
||||||
|
result = (char *) -1;
|
||||||
|
else
|
||||||
|
*((char *) __mempcpy (result, linkval, linkval - last_slash)) = '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
|
result = (char *) -1;
|
||||||
|
/* We use te environment variable LD_ORIGIN_PATH. If it is set make
|
||||||
|
a copy and strip out trailing slashes. */
|
||||||
|
if (_dl_origin_path != NULL)
|
||||||
|
{
|
||||||
|
size_t len = strlen (_dl_origin_path);
|
||||||
|
result = malloc (len + 1);
|
||||||
|
if (result == NULL)
|
||||||
|
result = (char *) -1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *cp = __mempcpy (result, _dl_origin_path, len);
|
||||||
|
while (cp > result && cp[-1] == '/')
|
||||||
|
--cp;
|
||||||
|
*cp = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
Reference in New Issue
Block a user