diff options
author | Filippo Arcidiacono <filippo.arcidiacono@st.com> | 2010-07-29 11:35:05 +0200 |
---|---|---|
committer | Carmelo Amoroso <carmelo.amoroso@st.com> | 2010-09-17 16:07:25 +0200 |
commit | 94cc6edb78a12655c0602a246fa1cbdc8c6d0ad9 (patch) | |
tree | 4dcffeee2396c0cd7d7b30f5a493c31ad7e171ad /ldso/include | |
parent | 637e2b2440f69e22932edd71bd2f0b1210dc32ea (diff) |
ldso: Rework global scope handling and symbol lookup mechanism
Global symbol scope is implemented as a linked list of
local scope, that dynamically grows and shrinks when dlopen/
dlclose are called. Each local scope is implemented as an array
of pointer to struct elf_resolve.
This will help to detect conflict when LD_TRACE_PRELINKING option
will be implemented.
Signed-off-by: Filippo Arcidiacono <filippo.arcidiacono@st.com>
Signed-off-by: Carmelo Amoroso <carmelo.amoroso@st.com>
Diffstat (limited to 'ldso/include')
-rw-r--r-- | ldso/include/dl-defs.h | 2 | ||||
-rw-r--r-- | ldso/include/dl-elf.h | 5 | ||||
-rw-r--r-- | ldso/include/dl-hash.h | 19 | ||||
-rw-r--r-- | ldso/include/ldso.h | 1 |
4 files changed, 20 insertions, 7 deletions
diff --git a/ldso/include/dl-defs.h b/ldso/include/dl-defs.h index 2d6303cfe..cbbaa3cea 100644 --- a/ldso/include/dl-defs.h +++ b/ldso/include/dl-defs.h @@ -225,7 +225,7 @@ typedef struct { /* Similar to DL_LOADADDR_UNMAP, but used for libraries that have been dlopen()ed successfully, when they're dlclose()d. */ #ifndef DL_LIB_UNMAP -# define DL_LIB_UNMAP(LIB, LEN) (DL_LOADADDR_UNMAP ((LIB)->loadaddr, (LEN))) +# define DL_LIB_UNMAP(LIB, LEN) (DL_LOADADDR_UNMAP ((LIB)->mapaddr, (LEN))) #endif /* Define this to verify that a library named LIBNAME, whose ELF diff --git a/ldso/include/dl-elf.h b/ldso/include/dl-elf.h index dc4af7bce..3e8586444 100644 --- a/ldso/include/dl-elf.h +++ b/ldso/include/dl-elf.h @@ -15,6 +15,7 @@ /* Forward declarations for stuff defined in ld_hash.h */ struct dyn_elf; struct elf_resolve; +struct r_scope_elem; #include <dl-defs.h> #ifdef __LDSO_CACHE_SUPPORT__ @@ -30,7 +31,7 @@ static __inline__ void _dl_unmap_cache(void) { } extern void _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt, unsigned long rel_addr, unsigned long rel_size); extern int _dl_parse_relocation_information(struct dyn_elf *rpnt, - unsigned long rel_addr, unsigned long rel_size); + struct r_scope_elem *scope, unsigned long rel_addr, unsigned long rel_size); extern struct elf_resolve * _dl_load_shared_library(int secure, struct dyn_elf **rpnt, struct elf_resolve *tpnt, char *full_libname, int trace_loaded_objects); @@ -39,7 +40,7 @@ extern struct elf_resolve * _dl_load_elf_shared_library(int secure, extern struct elf_resolve *_dl_check_if_named_library_is_loaded(const char *full_libname, int trace_loaded_objects); extern int _dl_linux_resolve(void); -extern int _dl_fixup(struct dyn_elf *rpnt, int flag); +extern int _dl_fixup(struct dyn_elf *rpnt, struct r_scope_elem *scope, int flag); extern void _dl_protect_relro (struct elf_resolve *l); /* diff --git a/ldso/include/dl-hash.h b/ldso/include/dl-hash.h index edef9d81b..f47384c31 100644 --- a/ldso/include/dl-hash.h +++ b/ldso/include/dl-hash.h @@ -25,6 +25,15 @@ struct dyn_elf { struct dyn_elf * prev; }; + +/* Structure to describe a single list of scope elements. The lookup + functions get passed an array of pointers to such structures. */ +struct r_scope_elem { + struct elf_resolve **r_list; /* Array of maps for the scope. */ + unsigned int r_nlist; /* Number of entries in the scope. */ + struct r_scope_elem *next; +}; + struct elf_resolve { /* These entries must be in this order to be compatible with the interface used by gdb to obtain the list of symbols. */ @@ -65,7 +74,8 @@ struct elf_resolve { ElfW(Addr) l_entry; #endif enum {elf_lib, elf_executable,program_interpreter, loaded_file} libtype; - struct dyn_elf * symbol_scope; + /* This is the local scope of the shared object */ + struct r_scope_elem symbol_scope; unsigned short usage_count; unsigned short int init_flag; unsigned long rtld_flags; /* RTLD_GLOBAL, RTLD_NOW etc. */ @@ -132,6 +142,7 @@ struct elf_resolve { #define INIT_FUNCS_CALLED 0x000004 #define FINI_FUNCS_CALLED 0x000008 #define DL_OPENED 0x000010 +#define DL_RESERVED 0x000020 extern struct dyn_elf * _dl_symbol_tables; extern struct elf_resolve * _dl_loaded_modules; @@ -145,15 +156,15 @@ extern struct elf_resolve * _dl_add_elf_hash_table(const char * libname, #if !((defined(USE_TLS) && USE_TLS) || defined __FDPIC__) # define _dl_lookup_hash(n, r, m, c, t) _dl_lookup_hash(n, r, m, c) #endif -extern char *_dl_lookup_hash(const char *name, struct dyn_elf *rpnt, +extern char *_dl_lookup_hash(const char *name, struct r_scope_elem *scope, struct elf_resolve *mytpnt, int type_class, struct elf_resolve **tpntp); -static __always_inline char *_dl_find_hash(const char *name, struct dyn_elf *rpnt, +static __always_inline char *_dl_find_hash(const char *name, struct r_scope_elem *scope, struct elf_resolve *mytpnt, int type_class, struct elf_resolve **tpntp) { - return _dl_lookup_hash(name, rpnt, mytpnt, type_class, tpntp); + return _dl_lookup_hash(name, scope, mytpnt, type_class, tpntp); } extern int _dl_linux_dynamic_link(void); diff --git a/ldso/include/ldso.h b/ldso/include/ldso.h index 120889216..536f7d266 100644 --- a/ldso/include/ldso.h +++ b/ldso/include/ldso.h @@ -27,6 +27,7 @@ /* Pull in compiler and arch stuff */ #include <stdlib.h> #include <stdarg.h> +#include <stddef.h> /* for ptrdiff_t */ #define _FCNTL_H #include <bits/fcntl.h> #include <bits/wordsize.h> |