mirror of
git://sourceware.org/git/glibc.git
synced 2025-04-24 14:41:06 +08:00
Update.
* posix/unistd.h: Move declaration of __libc_enable_secure to... * include/unistd.h: ...here. * elf/dl-open.c (dl_open_worker): If DST is used in SUID program punt. * elf/dl-deps.c (expand_dst): Likewise. * elf/dynamic-link.h: Set DT_SYMBOLIC, DT_TEXTREL, and DT_BIND_NOW based on DT_FLAGS value. * elf/do-lookup.h: Remove reference_name parameter, add undef_map. Add test for symbols marked STV_HIDDEN. * elf/dl-lookup.c (_dl_lookup_symbol): Remove reference_name parameter, add undef_map. Compute reference_name locally. Update call to do_lookup. (_dl_lookup_symbol_skip): Likewise. (_dl_lookup_versioned_symbol): Likewise. (_dl_lookup_versioned_symbol_skip): Likewise. * elf/dl-libc.c: Update call to _dl_lookup_*symbol. * elf/dl-runtime.c: Likewise. * elf/dl-sym.c: Likewise. * elf/dl-symbol.c: Likewise. * elf/ldsodefs.h: Adjust prototypes. * elf/dl-reloc.c (RESOLV): Add test for STV_PROTECTED flag set and handle appropriately. Add comment about DT_TEXTREL. * elf/dl-runtime.c: Likewise.
This commit is contained in:
parent
fc9cfb28c0
commit
06535ae948
27
ChangeLog
27
ChangeLog
@ -13,6 +13,33 @@
|
||||
DT_PREINIT_ARRAY, DT_PREINIT_ARRAYSZ.
|
||||
Add DF_ORIGIN, DF_SYMBOLIC, DF_TEXTREL, and DF_BIND_NOW.
|
||||
|
||||
* posix/unistd.h: Move declaration of __libc_enable_secure to...
|
||||
* include/unistd.h: ...here.
|
||||
|
||||
* elf/dl-open.c (dl_open_worker): If DST is used in SUID program punt.
|
||||
* elf/dl-deps.c (expand_dst): Likewise.
|
||||
|
||||
* elf/dynamic-link.h: Set DT_SYMBOLIC, DT_TEXTREL, and DT_BIND_NOW
|
||||
based on DT_FLAGS value.
|
||||
|
||||
* elf/do-lookup.h: Remove reference_name parameter, add undef_map.
|
||||
Add test for symbols marked STV_HIDDEN.
|
||||
* elf/dl-lookup.c (_dl_lookup_symbol): Remove reference_name parameter,
|
||||
add undef_map. Compute reference_name locally. Update call to
|
||||
do_lookup.
|
||||
(_dl_lookup_symbol_skip): Likewise.
|
||||
(_dl_lookup_versioned_symbol): Likewise.
|
||||
(_dl_lookup_versioned_symbol_skip): Likewise.
|
||||
* elf/dl-libc.c: Update call to _dl_lookup_*symbol.
|
||||
* elf/dl-runtime.c: Likewise.
|
||||
* elf/dl-sym.c: Likewise.
|
||||
* elf/dl-symbol.c: Likewise.
|
||||
* elf/ldsodefs.h: Adjust prototypes.
|
||||
|
||||
* elf/dl-reloc.c (RESOLV): Add test for STV_PROTECTED flag set and
|
||||
handle appropriately. Add comment about DT_TEXTREL.
|
||||
* elf/dl-runtime.c: Likewise.
|
||||
|
||||
1999-07-21 Roland McGrath <roland@baalperazim.frob.com>
|
||||
|
||||
* elf/dl-reloc.c (_dl_reloc_bad_type): New function.
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/param.h>
|
||||
#include <elf/ldsodefs.h>
|
||||
|
||||
@ -96,9 +97,15 @@ struct list
|
||||
\
|
||||
if (__cnt != 0) \
|
||||
{ \
|
||||
char *__newp = (char *) alloca (DL_DST_REQUIRED (l, __str, \
|
||||
strlen (__str), \
|
||||
__cnt)); \
|
||||
char *__newp; \
|
||||
\
|
||||
/* DST must not appear in SUID/SGID programs. */ \
|
||||
if (__libc_enable_secure) \
|
||||
_dl_signal_error (0, __str, \
|
||||
"DST not allowed in SUID/SGID programs"); \
|
||||
\
|
||||
__newp = (char *) alloca (DL_DST_REQUIRED (l, __str, strlen (__str), \
|
||||
__cnt)); \
|
||||
\
|
||||
__result = DL_DST_SUBSTITUTE (l, __str, __newp, 0); \
|
||||
\
|
||||
|
@ -82,9 +82,8 @@ do_dlsym (void *ptr)
|
||||
{
|
||||
struct do_dlsym_args *args = (struct do_dlsym_args *) ptr;
|
||||
args->ref = NULL;
|
||||
args->loadbase = _dl_lookup_symbol (args->name, &args->ref,
|
||||
args->map->l_local_scope,
|
||||
args->map->l_name, 0);
|
||||
args->loadbase = _dl_lookup_symbol (args->name, args->map, &args->ref,
|
||||
args->map->l_local_scope, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -75,11 +75,11 @@ unsigned long int _dl_num_relocations;
|
||||
|
||||
ElfW(Addr)
|
||||
internal_function
|
||||
_dl_lookup_symbol (const char *undef_name, const ElfW(Sym) **ref,
|
||||
struct r_scope_elem *symbol_scope[],
|
||||
const char *reference_name,
|
||||
_dl_lookup_symbol (const char *undef_name, struct link_map *undef_map,
|
||||
const ElfW(Sym) **ref, struct r_scope_elem *symbol_scope[],
|
||||
int reloc_type)
|
||||
{
|
||||
const char *reference_name = undef_map ? undef_map->l_name : NULL;
|
||||
const unsigned long int hash = _dl_elf_hash (undef_name);
|
||||
struct sym_val current_value = { NULL, NULL };
|
||||
struct r_scope_elem **scope;
|
||||
@ -88,8 +88,8 @@ _dl_lookup_symbol (const char *undef_name, const ElfW(Sym) **ref,
|
||||
|
||||
/* Search the relevant loaded objects for a definition. */
|
||||
for (scope = symbol_scope; *scope; ++scope)
|
||||
if (do_lookup (undef_name, hash, *ref, ¤t_value,
|
||||
*scope, 0, reference_name, NULL, reloc_type))
|
||||
if (do_lookup (undef_name, undef_map, hash, *ref, ¤t_value,
|
||||
*scope, 0, NULL, reloc_type))
|
||||
break;
|
||||
|
||||
if (current_value.s == NULL)
|
||||
@ -125,11 +125,12 @@ _dl_lookup_symbol (const char *undef_name, const ElfW(Sym) **ref,
|
||||
SKIP_MAP is only skipped. */
|
||||
ElfW(Addr)
|
||||
internal_function
|
||||
_dl_lookup_symbol_skip (const char *undef_name, const ElfW(Sym) **ref,
|
||||
_dl_lookup_symbol_skip (const char *undef_name,
|
||||
struct link_map *undef_map, const ElfW(Sym) **ref,
|
||||
struct r_scope_elem *symbol_scope[],
|
||||
const char *reference_name,
|
||||
struct link_map *skip_map)
|
||||
{
|
||||
const char *reference_name = undef_map ? undef_map->l_name : NULL;
|
||||
const unsigned long int hash = _dl_elf_hash (undef_name);
|
||||
struct sym_val current_value = { NULL, NULL };
|
||||
struct r_scope_elem **scope;
|
||||
@ -143,11 +144,11 @@ _dl_lookup_symbol_skip (const char *undef_name, const ElfW(Sym) **ref,
|
||||
assert (i < (*scope)->r_nduplist);
|
||||
|
||||
if (i >= (*scope)->r_nlist
|
||||
|| ! do_lookup (undef_name, hash, *ref, ¤t_value,
|
||||
*scope, i, reference_name, skip_map, 0))
|
||||
|| ! do_lookup (undef_name, undef_map, hash, *ref, ¤t_value,
|
||||
*scope, i, skip_map, 0))
|
||||
while (*++scope)
|
||||
if (do_lookup (undef_name, hash, *ref, ¤t_value,
|
||||
*scope, 0, reference_name, skip_map, 0))
|
||||
if (do_lookup (undef_name, undef_map, hash, *ref, ¤t_value,
|
||||
*scope, 0, skip_map, 0))
|
||||
break;
|
||||
|
||||
if (current_value.s == NULL)
|
||||
@ -177,12 +178,13 @@ _dl_lookup_symbol_skip (const char *undef_name, const ElfW(Sym) **ref,
|
||||
XXX We'll see whether we need this separate function. */
|
||||
ElfW(Addr)
|
||||
internal_function
|
||||
_dl_lookup_versioned_symbol (const char *undef_name, const ElfW(Sym) **ref,
|
||||
_dl_lookup_versioned_symbol (const char *undef_name,
|
||||
struct link_map *undef_map, const ElfW(Sym) **ref,
|
||||
struct r_scope_elem *symbol_scope[],
|
||||
const char *reference_name,
|
||||
const struct r_found_version *version,
|
||||
int reloc_type)
|
||||
{
|
||||
const char *reference_name = undef_map ? undef_map->l_name : NULL;
|
||||
const unsigned long int hash = _dl_elf_hash (undef_name);
|
||||
struct sym_val current_value = { NULL, NULL };
|
||||
struct r_scope_elem **scope;
|
||||
@ -192,8 +194,8 @@ _dl_lookup_versioned_symbol (const char *undef_name, const ElfW(Sym) **ref,
|
||||
/* Search the relevant loaded objects for a definition. */
|
||||
for (scope = symbol_scope; *scope; ++scope)
|
||||
{
|
||||
int res = do_lookup_versioned (undef_name, hash, *ref, ¤t_value,
|
||||
*scope, 0, reference_name, version, NULL,
|
||||
int res = do_lookup_versioned (undef_name, undef_map, hash, *ref,
|
||||
¤t_value, *scope, 0, version, NULL,
|
||||
reloc_type);
|
||||
if (res > 0)
|
||||
break;
|
||||
@ -250,12 +252,13 @@ _dl_lookup_versioned_symbol (const char *undef_name, const ElfW(Sym) **ref,
|
||||
ElfW(Addr)
|
||||
internal_function
|
||||
_dl_lookup_versioned_symbol_skip (const char *undef_name,
|
||||
struct link_map *undef_map,
|
||||
const ElfW(Sym) **ref,
|
||||
struct r_scope_elem *symbol_scope[],
|
||||
const char *reference_name,
|
||||
const struct r_found_version *version,
|
||||
struct link_map *skip_map)
|
||||
{
|
||||
const char *reference_name = undef_map ? undef_map->l_name : NULL;
|
||||
const unsigned long int hash = _dl_elf_hash (undef_name);
|
||||
struct sym_val current_value = { NULL, NULL };
|
||||
struct r_scope_elem **scope;
|
||||
@ -269,11 +272,13 @@ _dl_lookup_versioned_symbol_skip (const char *undef_name,
|
||||
assert (i < (*scope)->r_nduplist);
|
||||
|
||||
if (i >= (*scope)->r_nlist
|
||||
|| ! do_lookup_versioned (undef_name, hash, *ref, ¤t_value, *scope,
|
||||
i, reference_name, version, skip_map, 0))
|
||||
|| ! do_lookup_versioned (undef_name, undef_map, hash, *ref,
|
||||
¤t_value, *scope, i, version, skip_map,
|
||||
0))
|
||||
while (*++scope)
|
||||
if (do_lookup_versioned (undef_name, hash, *ref, ¤t_value, *scope,
|
||||
0, reference_name, version, skip_map, 0))
|
||||
if (do_lookup_versioned (undef_name, undef_map, hash, *ref,
|
||||
¤t_value, *scope, 0, version, skip_map,
|
||||
0))
|
||||
break;
|
||||
|
||||
if (current_value.s == NULL)
|
||||
|
@ -20,9 +20,10 @@
|
||||
#include <assert.h>
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <libintl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <libintl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h> /* Check whether MAP_COPY is defined. */
|
||||
#include <sys/param.h>
|
||||
#include <bits/libc-lock.h>
|
||||
@ -100,6 +101,12 @@ dl_open_worker (void *a)
|
||||
struct link_map *call_map;
|
||||
char *new_file;
|
||||
|
||||
/* DSTs must not appear in SUID/SGID programs. */
|
||||
if (__libc_enable_secure)
|
||||
/* This is an error. */
|
||||
_dl_signal_error (0, "dlopen",
|
||||
"DST not allowed in SUID/SGID programs");
|
||||
|
||||
/* We have to find out from which object the caller is calling.
|
||||
Find the highest-addressed object that ADDRESS is not below. */
|
||||
call_map = NULL;
|
||||
|
@ -71,11 +71,13 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
|
||||
|
||||
/* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code. */
|
||||
#define RESOLVE(ref, version, flags) \
|
||||
((version) != NULL && (version)->hash != 0 \
|
||||
? _dl_lookup_versioned_symbol (strtab + (*ref)->st_name, (ref), scope, \
|
||||
l->l_name, (version), (flags)) \
|
||||
: _dl_lookup_symbol (strtab + (*ref)->st_name, (ref), scope, \
|
||||
l->l_name, (flags)))
|
||||
(ELFW(ST_VISIBILITY) ((*ref)->st_other) != STV_PROTECTED \
|
||||
? ((version) != NULL && (version)->hash != 0 \
|
||||
? _dl_lookup_versioned_symbol (strtab + (*ref)->st_name, l, (ref), \
|
||||
scope, (version), (flags)) \
|
||||
: _dl_lookup_symbol (strtab + (*ref)->st_name, l, (ref), scope, \
|
||||
(flags))) \
|
||||
: l->l_addr)
|
||||
|
||||
#include "dynamic-link.h"
|
||||
ELF_DYNAMIC_RELOCATE (l, lazy, consider_profiling);
|
||||
@ -96,6 +98,9 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
|
||||
/* Mark the object so we know this work has been done. */
|
||||
l->l_relocated = 1;
|
||||
|
||||
/* DT_TEXTREL is now in level 2 and might phase out at some time.
|
||||
But we rewrite the DT_FLAGS entry to make testing easier and
|
||||
therefore it will be available at all time. */
|
||||
if (l->l_info[DT_TEXTREL])
|
||||
{
|
||||
/* Undo the protection change we made before relocating. */
|
||||
|
110
elf/dl-runtime.c
110
elf/dl-runtime.c
@ -66,32 +66,40 @@ fixup (
|
||||
/* Sanity check that we're really looking at a PLT relocation. */
|
||||
assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT);
|
||||
|
||||
/* Look up the target symbol. */
|
||||
switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
|
||||
/* Look up the target symbol. If the symbol is marked STV_PROTEXTED
|
||||
don't look in the global scope. */
|
||||
if (ELFW(ST_VISIBILITY) (sym->st_other) != STV_PROTECTED)
|
||||
{
|
||||
default:
|
||||
{
|
||||
const ElfW(Half) *vernum =
|
||||
(const void *) l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr;
|
||||
ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)];
|
||||
const struct r_found_version *version = &l->l_versions[ndx];
|
||||
|
||||
if (version->hash != 0)
|
||||
switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
|
||||
{
|
||||
default:
|
||||
{
|
||||
value = _dl_lookup_versioned_symbol(strtab + sym->st_name,
|
||||
&sym, l->l_scope, l->l_name,
|
||||
version, ELF_MACHINE_JMP_SLOT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
case 0:
|
||||
value = _dl_lookup_symbol (strtab + sym->st_name, &sym, l->l_scope,
|
||||
l->l_name, ELF_MACHINE_JMP_SLOT);
|
||||
}
|
||||
const ElfW(Half) *vernum =
|
||||
(const void *) l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr;
|
||||
ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)];
|
||||
const struct r_found_version *version = &l->l_versions[ndx];
|
||||
|
||||
/* Currently value contains the base load address of the object
|
||||
that defines sym. Now add in the symbol offset. */
|
||||
value = (sym ? value + sym->st_value : 0);
|
||||
if (version->hash != 0)
|
||||
{
|
||||
value = _dl_lookup_versioned_symbol(strtab + sym->st_name, l,
|
||||
&sym, l->l_scope, version,
|
||||
ELF_MACHINE_JMP_SLOT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
case 0:
|
||||
value = _dl_lookup_symbol (strtab + sym->st_name, l, &sym,
|
||||
l->l_scope, ELF_MACHINE_JMP_SLOT);
|
||||
}
|
||||
|
||||
/* Currently value contains the base load address of the object
|
||||
that defines sym. Now add in the symbol offset. */
|
||||
value = (sym ? value + sym->st_value : 0);
|
||||
}
|
||||
else
|
||||
/* We already found the symbol. The module (and therefore its load
|
||||
address) is also known. */
|
||||
value = l->l_addr + sym->st_value;
|
||||
|
||||
/* And now perhaps the relocation addend. */
|
||||
value = elf_machine_plt_value (l, reloc, value);
|
||||
@ -141,33 +149,41 @@ profile_fixup (
|
||||
/* Sanity check that we're really looking at a PLT relocation. */
|
||||
assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT);
|
||||
|
||||
/* Look up the target symbol. */
|
||||
switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
|
||||
/* Look up the target symbol. If the symbol is marked STV_PROTEXTED
|
||||
don't look in the global scope. */
|
||||
if (ELFW(ST_VISIBILITY) (sym->st_other) != STV_PROTECTED)
|
||||
{
|
||||
default:
|
||||
{
|
||||
const ElfW(Half) *vernum =
|
||||
(const void *) l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr;
|
||||
ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)];
|
||||
const struct r_found_version *version = &l->l_versions[ndx];
|
||||
|
||||
if (version->hash != 0)
|
||||
switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
|
||||
{
|
||||
default:
|
||||
{
|
||||
value = _dl_lookup_versioned_symbol(strtab + sym->st_name,
|
||||
&sym, l->l_scope,
|
||||
l->l_name, version,
|
||||
ELF_MACHINE_JMP_SLOT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
case 0:
|
||||
value = _dl_lookup_symbol (strtab + sym->st_name, &sym, l->l_scope,
|
||||
l->l_name, ELF_MACHINE_JMP_SLOT);
|
||||
}
|
||||
const ElfW(Half) *vernum =
|
||||
(const void *) l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr;
|
||||
ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)];
|
||||
const struct r_found_version *version = &l->l_versions[ndx];
|
||||
|
||||
/* Currently value contains the base load address of the object
|
||||
that defines sym. Now add in the symbol offset. */
|
||||
value = (sym ? value + sym->st_value : 0);
|
||||
if (version->hash != 0)
|
||||
{
|
||||
value = _dl_lookup_versioned_symbol(strtab + sym->st_name,
|
||||
l, &sym, l->l_scope,
|
||||
version,
|
||||
ELF_MACHINE_JMP_SLOT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
case 0:
|
||||
value = _dl_lookup_symbol (strtab + sym->st_name, l, &sym,
|
||||
l->l_scope, ELF_MACHINE_JMP_SLOT);
|
||||
}
|
||||
|
||||
/* Currently value contains the base load address of the object
|
||||
that defines sym. Now add in the symbol offset. */
|
||||
value = (sym ? value + sym->st_value : 0);
|
||||
}
|
||||
else
|
||||
/* We already found the symbol. The module (and therefore its load
|
||||
address) is also known. */
|
||||
value = l->l_addr + sym->st_value;
|
||||
|
||||
/* And now perhaps the relocation addend. */
|
||||
value = elf_machine_plt_value (l, reloc, value);
|
||||
|
22
elf/dl-sym.c
22
elf/dl-sym.c
@ -34,7 +34,7 @@ _dl_sym (void *handle, const char *name, void *who)
|
||||
|
||||
if (handle == RTLD_DEFAULT)
|
||||
/* Search the global scope. */
|
||||
loadbase = _dl_lookup_symbol (name, &ref, _dl_global_scope, NULL, 0);
|
||||
loadbase = _dl_lookup_symbol (name, NULL, &ref, _dl_global_scope, 0);
|
||||
else if (handle == RTLD_NEXT)
|
||||
{
|
||||
struct link_map *l, *match;
|
||||
@ -54,15 +54,14 @@ RTLD_NEXT used in code not dynamically loaded"));
|
||||
while (l->l_loader)
|
||||
l = l->l_loader;
|
||||
|
||||
loadbase = _dl_lookup_symbol_skip (name, &ref, l->l_local_scope,
|
||||
NULL, match);
|
||||
loadbase = _dl_lookup_symbol_skip (name, l, &ref, l->l_local_scope,
|
||||
match);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Search the scope of the given object. */
|
||||
struct link_map *map = handle;
|
||||
loadbase = _dl_lookup_symbol (name, &ref, map->l_local_scope,
|
||||
map->l_name, 0);
|
||||
loadbase = _dl_lookup_symbol (name, map, &ref, map->l_local_scope, 0);
|
||||
}
|
||||
|
||||
if (loadbase)
|
||||
@ -88,8 +87,8 @@ _dl_vsym (void *handle, const char *name, const char *version, void *who)
|
||||
|
||||
if (handle == RTLD_DEFAULT)
|
||||
/* Search the global scope. */
|
||||
loadbase = _dl_lookup_versioned_symbol (name, &ref, _dl_global_scope,
|
||||
NULL, &vers, 0);
|
||||
loadbase = _dl_lookup_versioned_symbol (name, NULL, &ref, _dl_global_scope,
|
||||
&vers, 0);
|
||||
else if (handle == RTLD_NEXT)
|
||||
{
|
||||
struct link_map *l, *match;
|
||||
@ -109,17 +108,16 @@ RTLD_NEXT used in code not dynamically loaded"));
|
||||
while (l->l_loader)
|
||||
l = l->l_loader;
|
||||
|
||||
loadbase = _dl_lookup_versioned_symbol_skip (name, &ref,
|
||||
loadbase = _dl_lookup_versioned_symbol_skip (name, l, &ref,
|
||||
l->l_local_scope,
|
||||
NULL, &vers, match);
|
||||
&vers, match);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Search the scope of the given object. */
|
||||
struct link_map *map = handle;
|
||||
loadbase = _dl_lookup_versioned_symbol (name, &ref,
|
||||
map->l_local_scope,
|
||||
map->l_name, &vers, 0);
|
||||
loadbase = _dl_lookup_versioned_symbol (name, map, &ref,
|
||||
map->l_local_scope, &vers, 0);
|
||||
}
|
||||
|
||||
if (loadbase)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Look up a symbol's run-time value in the scope of a loaded object.
|
||||
Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995, 1996, 1998, 1999 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@ -28,7 +28,6 @@ _dl_symbol_value (struct link_map *map, const char *name)
|
||||
{
|
||||
ElfW(Addr) loadbase;
|
||||
const ElfW(Sym) *ref = NULL;
|
||||
loadbase = _dl_lookup_symbol (name, &ref, map->l_local_scope, map->l_name,
|
||||
0);
|
||||
loadbase = _dl_lookup_symbol (name, map, &ref, map->l_local_scope, 0);
|
||||
return loadbase + ref->st_value;
|
||||
}
|
||||
|
@ -29,10 +29,10 @@
|
||||
found the symbol, the value 0 if nothing is found and < 0 if
|
||||
something bad happened. */
|
||||
static inline int
|
||||
FCT (const char *undef_name, unsigned long int hash,
|
||||
const ElfW(Sym) *ref, struct sym_val *result,
|
||||
struct r_scope_elem *scope, size_t i, const char *reference_name,
|
||||
ARG struct link_map *skip, int reloc_type)
|
||||
FCT (const char *undef_name, struct link_map *undef_map,
|
||||
unsigned long int hash, const ElfW(Sym) *ref, struct sym_val *result,
|
||||
struct r_scope_elem *scope, size_t i, ARG struct link_map *skip,
|
||||
int reloc_type)
|
||||
{
|
||||
struct link_map **list = scope->r_list;
|
||||
size_t n = scope->r_nlist;
|
||||
@ -154,7 +154,12 @@ FCT (const char *undef_name, unsigned long int hash,
|
||||
sym = num_versions == 1 ? versioned_sym : NULL;
|
||||
#endif
|
||||
|
||||
if (sym != NULL)
|
||||
if (sym != NULL
|
||||
/* Don't allow binding if the symbol is hidden. When processor
|
||||
specific definitions for STV_INTERNAL are defined we might
|
||||
have to extend this conditional. */
|
||||
&& (ELFW(ST_VISIBILITY) (sym->st_other) != STV_HIDDEN
|
||||
|| map == undef_map))
|
||||
{
|
||||
found_it:
|
||||
switch (ELFW(ST_BIND) (sym->st_info))
|
||||
|
@ -93,6 +93,19 @@ elf_get_dynamic_info (ElfW(Dyn) *dyn, ElfW(Addr) l_addr,
|
||||
info[DT_JMPREL]->d_un.d_ptr += l_addr;
|
||||
if (info[VERSYMIDX (DT_VERSYM)] != NULL)
|
||||
info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr += l_addr;
|
||||
if (info[DT_FLAGS] != NULL)
|
||||
{
|
||||
/* Flags are used. Translate to the old form where available.
|
||||
Since these l_info entries are only tested for NULL pointers it
|
||||
is ok if they point to the DT_FLAGS entry. */
|
||||
ElfW(Word) flags = info[DT_FLAGS]->d_un.d_val;
|
||||
if (flags & DF_SYMBOLIC)
|
||||
info[DT_SYMBOLIC] = info[DT_FLAGS];
|
||||
if (flags & DF_TEXTREL)
|
||||
info[DT_TEXTREL] = info[DT_FLAGS];
|
||||
if (flags & DF_BIND_NOW)
|
||||
info[DT_BIND_NOW] = info[DT_FLAGS];
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef RESOLVE
|
||||
|
@ -260,35 +260,35 @@ extern void _dl_setup_hash (struct link_map *map) internal_function;
|
||||
the `elf_machine_lookup_*_p' macros in dl-machine.h to affect which
|
||||
symbols can be chosen. */
|
||||
extern ElfW(Addr) _dl_lookup_symbol (const char *undef,
|
||||
struct link_map *undef_map,
|
||||
const ElfW(Sym) **sym,
|
||||
struct r_scope_elem *symbol_scope[],
|
||||
const char *reference_name,
|
||||
int reloc_type)
|
||||
internal_function;
|
||||
|
||||
/* Lookup versioned symbol. */
|
||||
extern ElfW(Addr) _dl_lookup_versioned_symbol (const char *undef,
|
||||
struct link_map *undef_map,
|
||||
const ElfW(Sym) **sym,
|
||||
struct r_scope_elem *symbol_scope[],
|
||||
const char *reference_name,
|
||||
const struct r_found_version *version,
|
||||
int reloc_type)
|
||||
internal_function;
|
||||
|
||||
/* For handling RTLD_NEXT we must be able to skip shared objects. */
|
||||
extern ElfW(Addr) _dl_lookup_symbol_skip (const char *undef,
|
||||
struct link_map *undef_map,
|
||||
const ElfW(Sym) **sym,
|
||||
struct r_scope_elem *symbol_scope[],
|
||||
const char *reference_name,
|
||||
struct link_map *skip_this)
|
||||
internal_function;
|
||||
|
||||
/* For handling RTLD_NEXT with versioned symbols we must be able to
|
||||
skip shared objects. */
|
||||
extern ElfW(Addr) _dl_lookup_versioned_symbol_skip (const char *undef,
|
||||
struct link_map *undef_map,
|
||||
const ElfW(Sym) **sym,
|
||||
struct r_scope_elem *symbol_scope[],
|
||||
const char *reference_name,
|
||||
const struct r_found_version *version,
|
||||
struct link_map *skip_this)
|
||||
internal_function;
|
||||
|
@ -63,4 +63,13 @@ extern int __profil __P ((unsigned short int *__sample_buffer, size_t __size,
|
||||
size_t __offset, unsigned int __scale));
|
||||
extern int __getdtablesize __P ((void));
|
||||
extern int __brk __P ((__ptr_t __addr));
|
||||
|
||||
|
||||
/* This variable is set nonzero at startup if the process's effective
|
||||
IDs differ from its real IDs, or it is otherwise indicated that
|
||||
extra security should be used. When this is set the dynamic linker
|
||||
and some functions contained in the C library ignore various
|
||||
environment variables that normally affect them. */
|
||||
extern int __libc_enable_secure;
|
||||
|
||||
#endif
|
||||
|
@ -927,16 +927,7 @@ extern int lockf64 __P ((int __fd, int __cmd, __off64_t __len));
|
||||
({ long int __result; \
|
||||
do __result = (long int) (expression); \
|
||||
while (__result == -1L && errno == EINTR); \
|
||||
__result; })) \
|
||||
|
||||
|
||||
/* This variable is set nonzero at startup if the process's effective
|
||||
IDs differ from its real IDs, or it is otherwise indicated that
|
||||
extra security should be used. When this is set the dynamic linker
|
||||
and some functions contained in the C library ignore various
|
||||
environment variables that normally affect them. */
|
||||
extern int __libc_enable_secure;
|
||||
|
||||
__result; }))
|
||||
#endif
|
||||
|
||||
#if defined __USE_POSIX199309 || defined __USE_UNIX98
|
||||
|
Loading…
x
Reference in New Issue
Block a user