diff options
author | Salvatore Cro <salvatore.cro@st.com> | 2011-01-12 10:27:16 +0100 |
---|---|---|
committer | Carmelo Amoroso <carmelo.amoroso@st.com> | 2011-01-20 14:51:42 +0100 |
commit | aaf4cbd98fda76af93ebea5241f65291ff6bcaac (patch) | |
tree | e74a6dfb7639f30be2a8c723fc44e92b63b84538 /ldso/libdl/libdl.c | |
parent | c70ac1d9b290e70cbc789b0abb47337f8aa9faef (diff) |
Add protected symbols support for all architectures
Protected symbols are global symbols for which interposition is not allowed.
We manage them in generic _dl_lookup_hash function. To handle protected symbols
we need to get a reference to the module that defines the symbol itself.
So we pass a new parameter 'struct symbol_ref' to the __dl_lookup_hash
that is defined as below:
struct symbol_ref {
const ElfW(Sym) *sym;
struct elf_resolve *tpnt;
};
The tpnt field is used as an ouput parameter and refers to the module which defines
the protected symbol.
Further it can be used as output parameter for TLS relocations and FDPIC case.
The sym field is instead used as an input parameter to detect the visibility of the
symbol we are looking-up.
In this way we get rid of different signatures for _dl_lookup_hash, allowing to remove
the _dl_find_hash wrapper.
This new structure is also suitable for prelink integration.
Signed-off-by: Salvatore Cro <salvatore.cro@st.com>
Signed-off-by: Carmelo Amoroso <carmelo.amoroso@st.com>
Diffstat (limited to 'ldso/libdl/libdl.c')
-rw-r--r-- | ldso/libdl/libdl.c | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c index 3957e846f..b88bc4819 100644 --- a/ldso/libdl/libdl.c +++ b/ldso/libdl/libdl.c @@ -613,6 +613,7 @@ void *dlsym(void *vhandle, const char *name) struct dyn_elf *rpnt; void *ret; struct elf_resolve *tls_tpnt = NULL; + struct symbol_ref sym_ref = { NULL, NULL }; /* Nastiness to support underscore prefixes. */ #ifdef __UCLIBC_UNDERSCORES__ char tmp_buf[80]; @@ -667,13 +668,13 @@ void *dlsym(void *vhandle, const char *name) tpnt = NULL; if (handle == _dl_symbol_tables) tpnt = handle->dyn; /* Only search RTLD_GLOBAL objs if global object */ - ret = _dl_find_hash(name2, handle, NULL, 0, &tls_tpnt); + ret = _dl_find_hash(name2, handle, tpnt, 0, &sym_ref); #if defined(USE_TLS) && USE_TLS && defined SHARED - if (tls_tpnt) { + if (sym_ref.tpnt) { /* The found symbol is a thread-local storage variable. Return the address for to the current thread. */ - ret = _dl_tls_symaddr ((struct link_map *)tls_tpnt, (Elf32_Addr)ret); + ret = _dl_tls_symaddr ((struct link_map *)sym_ref.tpnt, (Elf32_Addr)ret); } #endif |