diff options
Diffstat (limited to 'elf/dl-reloc.c')
-rw-r--r-- | elf/dl-reloc.c | 74 |
1 files changed, 37 insertions, 37 deletions
diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c index 117410e..4004316 100644 --- a/elf/dl-reloc.c +++ b/elf/dl-reloc.c @@ -1,5 +1,5 @@ /* Relocate a shared object and resolve its references to other loaded objects. - Copyright (C) 1995-2004, 2005 Free Software Foundation, Inc. + Copyright (C) 1995-2002, 2003, 2004 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 @@ -48,6 +48,8 @@ void internal_function __attribute_noinline__ _dl_allocate_static_tls (struct link_map *map) { + size_t offset; + /* If the alignment requirements are too high fail. */ if (map->l_tls_align > GL(dl_tls_static_align)) { @@ -69,15 +71,15 @@ cannot allocate memory in static TLS block")); n = (freebytes - blsize) / map->l_tls_align; - size_t offset = GL(dl_tls_static_used) + (freebytes - n * map->l_tls_align - - map->l_tls_firstbyte_offset); + offset = GL(dl_tls_static_used) + (freebytes - n * map->l_tls_align + - map->l_tls_firstbyte_offset); map->l_tls_offset = GL(dl_tls_static_used) = offset; # elif TLS_DTV_AT_TP size_t used; size_t check; - size_t offset = roundup (GL(dl_tls_static_used), map->l_tls_align); + offset = roundup (GL(dl_tls_static_used), map->l_tls_align); used = offset + map->l_tls_blocksize; check = used; /* dl_tls_static_used includes the TCB at the beginning. */ @@ -91,20 +93,8 @@ cannot allocate memory in static TLS block")); # error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined" # endif - /* If the object is not yet relocated we cannot initialize the - static TLS region. Delay it. */ - if (map->l_real->l_relocated) - { -#ifdef SHARED - if (__builtin_expect (THREAD_DTV()[0].counter != GL(dl_tls_generation), - 0)) - /* Update the slot information data for at least the generation of - the DSO we are allocating data for. */ - (void) _dl_update_slotinfo (map->l_tls_modid); -#endif - - GL(dl_init_static_tls) (map); - } + if (map->l_relocated) + GL(dl_init_static_tls) (map); else map->l_need_tls_init = 1; } @@ -124,10 +114,7 @@ _dl_nothread_init_static_tls (struct link_map *map) # endif /* Fill in the DTV slot so that a later LD/GD access will find it. */ - dtv_t *dtv = THREAD_DTV (); - assert (map->l_tls_modid <= dtv[-1].counter); - dtv[map->l_tls_modid].pointer.val = dest; - dtv[map->l_tls_modid].pointer.is_static = true; + THREAD_DTV ()[map->l_tls_modid].pointer = dest; /* Initialize the memory. */ memset (__mempcpy (dest, map->l_tls_initimage, map->l_tls_initimage_size), @@ -150,20 +137,11 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], /* Initialize it to make the compiler happy. */ const char *errstring = NULL; -#ifdef SHARED - /* If we are auditing, install the same handlers we need for profiling. */ - consider_profiling |= GLRO(dl_audit) != NULL; -#elif defined PROF - /* Never use dynamic linker profiling for gprof profiling code. */ -# define consider_profiling 0 -#endif - if (l->l_relocated) return; /* If DT_BIND_NOW is set relocate all references in this object. We do not do this if we are profiling, of course. */ - // XXX Correct for auditing? if (!consider_profiling && __builtin_expect (l->l_info[DT_BIND_NOW] != NULL, 0)) lazy = 0; @@ -247,6 +225,29 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], l->l_lookup_cache.ret = (*ref); \ l->l_lookup_cache.value = _lr; })) \ : l) +#define RESOLVE(ref, version, r_type) \ + (ELFW(ST_BIND) ((*ref)->st_info) != STB_LOCAL \ + ? ((__builtin_expect ((*ref) == l->l_lookup_cache.sym, 0) \ + && elf_machine_type_class (r_type) == l->l_lookup_cache.type_class) \ + ? (bump_num_cache_relocations (), \ + (*ref) = l->l_lookup_cache.ret, \ + l->l_lookup_cache.value) \ + : ({ lookup_t _lr; \ + int _tc = elf_machine_type_class (r_type); \ + l->l_lookup_cache.type_class = _tc; \ + l->l_lookup_cache.sym = (*ref); \ + const struct r_found_version *v = NULL; \ + int flags = DL_LOOKUP_ADD_DEPENDENCY; \ + if ((version) != NULL && (version)->hash != 0) \ + { \ + v = (version); \ + flags = 0; \ + } \ + _lr = _dl_lookup_symbol_x (strtab + (*ref)->st_name, l, (ref), \ + scope, v, _tc, flags, NULL); \ + l->l_lookup_cache.ret = (*ref); \ + l->l_lookup_cache.value = _lr; })) \ + : l->l_addr) /* This macro is used as a callback from elf_machine_rel{a,} when a static TLS reloc is about to be performed. Since (in dl-load.c) we @@ -267,7 +268,6 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], ELF_DYNAMIC_RELOCATE (l, lazy, consider_profiling); -#ifndef PROF if (__builtin_expect (consider_profiling, 0)) { /* Allocate the array which will contain the already found @@ -276,23 +276,23 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], will be NULL. */ if (l->l_info[DT_PLTRELSZ] == NULL) { - errstring = N_("%s: no PLTREL found in object %s\n"); + errstring = N_("%s: profiler found no PLTREL in object %s\n"); fatal: _dl_fatal_printf (errstring, rtld_progname ?: "<program name unknown>", l->l_name); } - l->l_reloc_result = calloc (sizeof (l->l_reloc_result[0]), - l->l_info[DT_PLTRELSZ]->d_un.d_val); + l->l_reloc_result = + (ElfW(Addr) *) calloc (sizeof (ElfW(Addr)), + l->l_info[DT_PLTRELSZ]->d_un.d_val); if (l->l_reloc_result == NULL) { errstring = N_("\ -%s: out of memory to store relocation results for %s\n"); +%s: profiler out of memory shadowing PLTREL of %s\n"); goto fatal; } } -#endif } /* Mark the object so we know this work has been done. */ |