aboutsummaryrefslogtreecommitdiff
path: root/elf/dl-sym.c
diff options
context:
space:
mode:
Diffstat (limited to 'elf/dl-sym.c')
-rw-r--r--elf/dl-sym.c274
1 files changed, 0 insertions, 274 deletions
diff --git a/elf/dl-sym.c b/elf/dl-sym.c
deleted file mode 100644
index 7cd6e97643..0000000000
--- a/elf/dl-sym.c
+++ /dev/null
@@ -1,274 +0,0 @@
-/* Look up a symbol in a shared object loaded by `dlopen'.
- Copyright (C) 1999-2017 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
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <http://www.gnu.org/licenses/>. */
-
-#include <assert.h>
-#include <stddef.h>
-#include <setjmp.h>
-#include <stdlib.h>
-#include <libintl.h>
-
-#include <dlfcn.h>
-#include <ldsodefs.h>
-#include <dl-hash.h>
-#include <sysdep-cancel.h>
-#include <dl-tls.h>
-#include <dl-irel.h>
-
-
-#ifdef SHARED
-/* Systems which do not have tls_index also probably have to define
- DONT_USE_TLS_INDEX. */
-
-# ifndef __TLS_GET_ADDR
-# define __TLS_GET_ADDR __tls_get_addr
-# endif
-
-/* Return the symbol address given the map of the module it is in and
- the symbol record. This is used in dl-sym.c. */
-static void *
-internal_function
-_dl_tls_symaddr (struct link_map *map, const ElfW(Sym) *ref)
-{
-# ifndef DONT_USE_TLS_INDEX
- tls_index tmp =
- {
- .ti_module = map->l_tls_modid,
- .ti_offset = ref->st_value
- };
-
- return __TLS_GET_ADDR (&tmp);
-# else
- return __TLS_GET_ADDR (map->l_tls_modid, ref->st_value);
-# endif
-}
-#endif
-
-
-struct call_dl_lookup_args
-{
- /* Arguments to do_dlsym. */
- struct link_map *map;
- const char *name;
- struct r_found_version *vers;
- int flags;
-
- /* Return values of do_dlsym. */
- lookup_t loadbase;
- const ElfW(Sym) **refp;
-};
-
-static void
-call_dl_lookup (void *ptr)
-{
- struct call_dl_lookup_args *args = (struct call_dl_lookup_args *) ptr;
- args->map = GLRO(dl_lookup_symbol_x) (args->name, args->map, args->refp,
- args->map->l_scope, args->vers, 0,
- args->flags, NULL);
-}
-
-
-static void *
-internal_function
-do_sym (void *handle, const char *name, void *who,
- struct r_found_version *vers, int flags)
-{
- const ElfW(Sym) *ref = NULL;
- lookup_t result;
- ElfW(Addr) caller = (ElfW(Addr)) who;
-
- struct link_map *l = _dl_find_dso_for_object (caller);
- /* If the address is not recognized the call comes from the main
- program (we hope). */
- struct link_map *match = l ? l : GL(dl_ns)[LM_ID_BASE]._ns_loaded;
-
- if (handle == RTLD_DEFAULT)
- {
- /* Search the global scope. We have the simple case where
- we look up in the scope of an object which was part of
- the initial binary. And then the more complex part
- where the object is dynamically loaded and the scope
- array can change. */
- if (RTLD_SINGLE_THREAD_P)
- result = GLRO(dl_lookup_symbol_x) (name, match, &ref,
- match->l_scope, vers, 0,
- flags | DL_LOOKUP_ADD_DEPENDENCY,
- NULL);
- else
- {
- struct call_dl_lookup_args args;
- args.name = name;
- args.map = match;
- args.vers = vers;
- args.flags
- = flags | DL_LOOKUP_ADD_DEPENDENCY | DL_LOOKUP_GSCOPE_LOCK;
- args.refp = &ref;
-
- THREAD_GSCOPE_SET_FLAG ();
-
- const char *objname;
- const char *errstring = NULL;
- bool malloced;
- int err = _dl_catch_error (&objname, &errstring, &malloced,
- call_dl_lookup, &args);
-
- THREAD_GSCOPE_RESET_FLAG ();
-
- if (__glibc_unlikely (errstring != NULL))
- {
- /* The lookup was unsuccessful. Rethrow the error. */
- char *errstring_dup = strdupa (errstring);
- char *objname_dup = strdupa (objname);
- if (malloced)
- free ((char *) errstring);
-
- _dl_signal_error (err, objname_dup, NULL, errstring_dup);
- /* NOTREACHED */
- }
-
- result = args.map;
- }
- }
- else if (handle == RTLD_NEXT)
- {
- if (__glibc_unlikely (match == GL(dl_ns)[LM_ID_BASE]._ns_loaded))
- {
- if (match == NULL
- || caller < match->l_map_start
- || caller >= match->l_map_end)
- _dl_signal_error (0, NULL, NULL, N_("\
-RTLD_NEXT used in code not dynamically loaded"));
- }
-
- struct link_map *l = match;
- while (l->l_loader != NULL)
- l = l->l_loader;
-
- result = GLRO(dl_lookup_symbol_x) (name, match, &ref, l->l_local_scope,
- vers, 0, 0, match);
- }
- else
- {
- /* Search the scope of the given object. */
- struct link_map *map = handle;
- result = GLRO(dl_lookup_symbol_x) (name, map, &ref, map->l_local_scope,
- vers, 0, flags, NULL);
- }
-
- if (ref != NULL)
- {
- void *value;
-
-#ifdef SHARED
- if (ELFW(ST_TYPE) (ref->st_info) == STT_TLS)
- /* The found symbol is a thread-local storage variable.
- Return the address for to the current thread. */
- value = _dl_tls_symaddr (result, ref);
- else
-#endif
- value = DL_SYMBOL_ADDRESS (result, ref);
-
- /* Resolve indirect function address. */
- if (__glibc_unlikely (ELFW(ST_TYPE) (ref->st_info) == STT_GNU_IFUNC))
- {
- DL_FIXUP_VALUE_TYPE fixup
- = DL_FIXUP_MAKE_VALUE (result, (ElfW(Addr)) value);
- fixup = elf_ifunc_invoke (DL_FIXUP_VALUE_ADDR (fixup));
- value = (void *) DL_FIXUP_VALUE_CODE_ADDR (fixup);
- }
-
-#ifdef SHARED
- /* Auditing checkpoint: we have a new binding. Provide the
- auditing libraries the possibility to change the value and
- tell us whether further auditing is wanted. */
- if (__glibc_unlikely (GLRO(dl_naudit) > 0))
- {
- const char *strtab = (const char *) D_PTR (result,
- l_info[DT_STRTAB]);
- /* Compute index of the symbol entry in the symbol table of
- the DSO with the definition. */
- unsigned int ndx = (ref - (ElfW(Sym) *) D_PTR (result,
- l_info[DT_SYMTAB]));
-
- if ((match->l_audit_any_plt | result->l_audit_any_plt) != 0)
- {
- unsigned int altvalue = 0;
- struct audit_ifaces *afct = GLRO(dl_audit);
- /* Synthesize a symbol record where the st_value field is
- the result. */
- ElfW(Sym) sym = *ref;
- sym.st_value = (ElfW(Addr)) value;
-
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
- {
- if (afct->symbind != NULL
- && ((match->l_audit[cnt].bindflags & LA_FLG_BINDFROM)
- != 0
- || ((result->l_audit[cnt].bindflags & LA_FLG_BINDTO)
- != 0)))
- {
- unsigned int flags = altvalue | LA_SYMB_DLSYM;
- uintptr_t new_value
- = afct->symbind (&sym, ndx,
- &match->l_audit[cnt].cookie,
- &result->l_audit[cnt].cookie,
- &flags, strtab + ref->st_name);
- if (new_value != (uintptr_t) sym.st_value)
- {
- altvalue = LA_SYMB_ALTVALUE;
- sym.st_value = new_value;
- }
- }
-
- afct = afct->next;
- }
-
- value = (void *) sym.st_value;
- }
- }
-#endif
-
- return value;
- }
-
- return NULL;
-}
-
-
-void *
-internal_function
-_dl_vsym (void *handle, const char *name, const char *version, void *who)
-{
- struct r_found_version vers;
-
- /* Compute hash value to the version string. */
- vers.name = version;
- vers.hidden = 1;
- vers.hash = _dl_elf_hash (version);
- /* We don't have a specific file where the symbol can be found. */
- vers.filename = NULL;
-
- return do_sym (handle, name, who, &vers, 0);
-}
-
-
-void *
-internal_function
-_dl_sym (void *handle, const char *name, void *who)
-{
- return do_sym (handle, name, who, NULL, DL_LOOKUP_RETURN_NEWEST);
-}