From 3312c6ac985f422a529cf91cfae035f5a3556f8e Mon Sep 17 00:00:00 2001 From: Eric Andersen Date: Thu, 29 Jan 2004 10:44:50 +0000 Subject: Eliminate separate passes for _dl_copy_fixups() and _dl_fixup(), and do both operations in a single pass. --- ldso/include/dl-elf.h | 1 - ldso/include/ld_elf.h | 1 - ldso/ldso/dl-elf.c | 64 +++++++++++++++---------------------------------- ldso/ldso/ldso.c | 15 +++--------- ldso/ldso/readelflib1.c | 64 +++++++++++++++---------------------------------- ldso/libdl/dlib.c | 20 ++++------------ ldso/libdl/libdl.c | 20 ++++------------ 7 files changed, 49 insertions(+), 136 deletions(-) diff --git a/ldso/include/dl-elf.h b/ldso/include/dl-elf.h index 75c7d2761..7ae1591c2 100644 --- a/ldso/include/dl-elf.h +++ b/ldso/include/dl-elf.h @@ -58,7 +58,6 @@ static inline void _dl_unmap_cache(void) { } /* Function prototypes for non-static stuff in readelflib1.c */ -int _dl_copy_fixups(struct dyn_elf * tpnt); extern int _dl_parse_copy_information(struct dyn_elf *rpnt, unsigned long rel_addr, unsigned long rel_size, int type); extern void _dl_parse_lazy_relocation_information(struct elf_resolve *tpnt, diff --git a/ldso/include/ld_elf.h b/ldso/include/ld_elf.h index 75c7d2761..7ae1591c2 100644 --- a/ldso/include/ld_elf.h +++ b/ldso/include/ld_elf.h @@ -58,7 +58,6 @@ static inline void _dl_unmap_cache(void) { } /* Function prototypes for non-static stuff in readelflib1.c */ -int _dl_copy_fixups(struct dyn_elf * tpnt); extern int _dl_parse_copy_information(struct dyn_elf *rpnt, unsigned long rel_addr, unsigned long rel_size, int type); extern void _dl_parse_lazy_relocation_information(struct elf_resolve *tpnt, diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c index 9650b2f53..fb7eacc12 100644 --- a/ldso/ldso/dl-elf.c +++ b/ldso/ldso/dl-elf.c @@ -735,47 +735,6 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure, return tpnt; } -/* Ugly, ugly. Some versions of the SVr4 linker fail to generate COPY - relocations for global variables that are present both in the image and - the shared library. Go through and do it manually. If the images - are guaranteed to be generated by a trustworthy linker, then this - step can be skipped. */ - -int _dl_copy_fixups(struct dyn_elf *rpnt) -{ - int goof = 0; - struct elf_resolve *tpnt; - - if (rpnt->next) - goof += _dl_copy_fixups(rpnt->next); - else - return 0; - - tpnt = rpnt->dyn; - - if (tpnt->init_flag & COPY_RELOCS_DONE) - return goof; - tpnt->init_flag |= COPY_RELOCS_DONE; - -#if defined (__SUPPORT_LD_DEBUG__) - if(_dl_debug) _dl_dprintf(_dl_debug_file,"\nrelocation copy fixups: %s", tpnt->libname); -#endif - -#ifdef ELF_USES_RELOCA - goof += _dl_parse_copy_information(rpnt, - tpnt->dynamic_info[DT_RELA], tpnt->dynamic_info[DT_RELASZ], 0); - -#else - goof += _dl_parse_copy_information(rpnt, tpnt->dynamic_info[DT_REL], - tpnt->dynamic_info[DT_RELSZ], 0); - -#endif -#if defined (__SUPPORT_LD_DEBUG__) - if(_dl_debug) _dl_dprintf(_dl_debug_file,"\nrelocation copy fixups: %s; finished\n\n", tpnt->libname); -#endif - return goof; -} - /* Minimal printf which handles only %s, %d, and %x */ void _dl_dprintf(int fd, const char *fmt, ...) { @@ -905,12 +864,15 @@ void *_dl_malloc(int size) return retval; } -int _dl_fixup(struct elf_resolve *tpnt, int flag) +int _dl_fixup(struct dyn_elf *rpnt, int flag) { int goof = 0; + struct elf_resolve *tpnt; + + if (rpnt->next) + goof += _dl_fixup(rpnt->next, flag); + tpnt = rpnt->dyn; - if (tpnt->next) - goof += _dl_fixup(tpnt->next, flag); #if defined (__SUPPORT_LD_DEBUG__) if(_dl_debug) _dl_dprintf(_dl_debug_file,"\nrelocation processing: %s", tpnt->libname); #endif @@ -961,6 +923,19 @@ int _dl_fixup(struct elf_resolve *tpnt, int flag) tpnt->dynamic_info[DT_PLTRELSZ], 0); } } + if (tpnt->init_flag & COPY_RELOCS_DONE) + return goof; + tpnt->init_flag |= COPY_RELOCS_DONE; +#ifdef ELF_USES_RELOCA + goof += _dl_parse_copy_information(rpnt, + tpnt->dynamic_info[DT_RELA], tpnt->dynamic_info[DT_RELASZ], 0); + +#else + goof += _dl_parse_copy_information(rpnt, tpnt->dynamic_info[DT_REL], + tpnt->dynamic_info[DT_RELSZ], 0); + +#endif + #if defined (__SUPPORT_LD_DEBUG__) if(_dl_debug) { _dl_dprintf(_dl_debug_file,"\nrelocation processing: %s", tpnt->libname); @@ -970,4 +945,3 @@ int _dl_fixup(struct elf_resolve *tpnt, int flag) return goof; } - diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c index 0f89d70e8..8d5d08e1e 100644 --- a/ldso/ldso/ldso.c +++ b/ldso/ldso/ldso.c @@ -145,7 +145,7 @@ static int (*_dl_elf_main) (int, char **, char **); struct r_debug *_dl_debug_addr = NULL; unsigned long *_dl_brkp; unsigned long *_dl_envp; -int _dl_fixup(struct elf_resolve *tpnt, int lazy); +int _dl_fixup(struct dyn_elf *rpnt, int flag); void _dl_debug_state(void); char *_dl_get_last_path_component(char *path); static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *app_tpnt, @@ -1185,18 +1185,9 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a * Now we go through and look for REL and RELA records that indicate fixups * to the GOT tables. We need to do this in reverse order so that COPY * directives work correctly */ - goof = _dl_loaded_modules ? _dl_fixup(_dl_loaded_modules, _dl_be_lazy) : 0; - - - /* Some flavors of SVr4 do not generate the R_*_COPY directive, - and we have to manually search for entries that require fixups. - Solaris gets this one right, from what I understand. */ - -#ifdef __SUPPORT_LD_DEBUG_EARLY__ - _dl_dprintf(_dl_debug_file, "Beginning copy fixups\n"); -#endif if (_dl_symbol_tables) - goof += _dl_copy_fixups(_dl_symbol_tables); + goof += _dl_fixup(_dl_symbol_tables, _dl_be_lazy); + /* OK, at this point things are pretty much ready to run. Now we need to touch up a few items that are required, and then diff --git a/ldso/ldso/readelflib1.c b/ldso/ldso/readelflib1.c index 9650b2f53..fb7eacc12 100644 --- a/ldso/ldso/readelflib1.c +++ b/ldso/ldso/readelflib1.c @@ -735,47 +735,6 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure, return tpnt; } -/* Ugly, ugly. Some versions of the SVr4 linker fail to generate COPY - relocations for global variables that are present both in the image and - the shared library. Go through and do it manually. If the images - are guaranteed to be generated by a trustworthy linker, then this - step can be skipped. */ - -int _dl_copy_fixups(struct dyn_elf *rpnt) -{ - int goof = 0; - struct elf_resolve *tpnt; - - if (rpnt->next) - goof += _dl_copy_fixups(rpnt->next); - else - return 0; - - tpnt = rpnt->dyn; - - if (tpnt->init_flag & COPY_RELOCS_DONE) - return goof; - tpnt->init_flag |= COPY_RELOCS_DONE; - -#if defined (__SUPPORT_LD_DEBUG__) - if(_dl_debug) _dl_dprintf(_dl_debug_file,"\nrelocation copy fixups: %s", tpnt->libname); -#endif - -#ifdef ELF_USES_RELOCA - goof += _dl_parse_copy_information(rpnt, - tpnt->dynamic_info[DT_RELA], tpnt->dynamic_info[DT_RELASZ], 0); - -#else - goof += _dl_parse_copy_information(rpnt, tpnt->dynamic_info[DT_REL], - tpnt->dynamic_info[DT_RELSZ], 0); - -#endif -#if defined (__SUPPORT_LD_DEBUG__) - if(_dl_debug) _dl_dprintf(_dl_debug_file,"\nrelocation copy fixups: %s; finished\n\n", tpnt->libname); -#endif - return goof; -} - /* Minimal printf which handles only %s, %d, and %x */ void _dl_dprintf(int fd, const char *fmt, ...) { @@ -905,12 +864,15 @@ void *_dl_malloc(int size) return retval; } -int _dl_fixup(struct elf_resolve *tpnt, int flag) +int _dl_fixup(struct dyn_elf *rpnt, int flag) { int goof = 0; + struct elf_resolve *tpnt; + + if (rpnt->next) + goof += _dl_fixup(rpnt->next, flag); + tpnt = rpnt->dyn; - if (tpnt->next) - goof += _dl_fixup(tpnt->next, flag); #if defined (__SUPPORT_LD_DEBUG__) if(_dl_debug) _dl_dprintf(_dl_debug_file,"\nrelocation processing: %s", tpnt->libname); #endif @@ -961,6 +923,19 @@ int _dl_fixup(struct elf_resolve *tpnt, int flag) tpnt->dynamic_info[DT_PLTRELSZ], 0); } } + if (tpnt->init_flag & COPY_RELOCS_DONE) + return goof; + tpnt->init_flag |= COPY_RELOCS_DONE; +#ifdef ELF_USES_RELOCA + goof += _dl_parse_copy_information(rpnt, + tpnt->dynamic_info[DT_RELA], tpnt->dynamic_info[DT_RELASZ], 0); + +#else + goof += _dl_parse_copy_information(rpnt, tpnt->dynamic_info[DT_REL], + tpnt->dynamic_info[DT_RELSZ], 0); + +#endif + #if defined (__SUPPORT_LD_DEBUG__) if(_dl_debug) { _dl_dprintf(_dl_debug_file,"\nrelocation processing: %s", tpnt->libname); @@ -970,4 +945,3 @@ int _dl_fixup(struct elf_resolve *tpnt, int flag) return goof; } - diff --git a/ldso/libdl/dlib.c b/ldso/libdl/dlib.c index b116590fe..d09210acc 100644 --- a/ldso/libdl/dlib.c +++ b/ldso/libdl/dlib.c @@ -36,9 +36,7 @@ extern struct elf_resolve * _dl_load_shared_library(int, struct dyn_elf **, stru __attribute__ ((__weak__, __alias__ ("foobar"))); extern struct elf_resolve * _dl_check_if_named_library_is_loaded(const char *full_libname) __attribute__ ((__weak__, __alias__ ("foobar"))); -extern int _dl_fixup(struct elf_resolve *tpnt, int lazy) - __attribute__ ((__weak__, __alias__ ("foobar"))); -extern int _dl_copy_fixups(struct dyn_elf * tpnt) +extern int _dl_fixup(struct dyn_elf *rpnt, int lazy) __attribute__ ((__weak__, __alias__ ("foobar"))); #ifdef __mips__ extern void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt) @@ -87,7 +85,7 @@ static char *_dl_malloc_addr, *_dl_mmap_zero; #define _dl_trace_loaded_objects 0 #include "../ldso/readelflib1.c" void *(*_dl_malloc_function) (size_t size); -int _dl_fixup(struct elf_resolve *tpnt, int lazy); +int _dl_fixup(struct dyn_elf *rpnt, int lazy); #endif static int do_dlclose(void *, int need_fini); @@ -271,21 +269,11 @@ void *_dlopen(const char *libname, int flag) * Now we go through and look for REL and RELA records that indicate fixups * to the GOT tables. We need to do this in reverse order so that COPY * directives work correctly */ - if (_dl_fixup(dyn_chain->dyn, dyn_chain->flags)) + if (_dl_fixup(dyn_chain, dyn_chain->flags)) goto oops; -#ifdef __SUPPORT_LD_DEBUG__ - if(_dl_debug) - _dl_dprintf(_dl_debug_file, "Beginning dlopen copy fixups\n"); -#endif - if (_dl_symbol_tables) { - if (_dl_copy_fixups(dyn_chain)) - goto oops; - } - - /* TODO: Should we set the protections of all pages back to R/O now ? */ - + /* Notify the debugger we have added some objects. */ if (_dl_debug_addr) { diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c index b116590fe..d09210acc 100644 --- a/ldso/libdl/libdl.c +++ b/ldso/libdl/libdl.c @@ -36,9 +36,7 @@ extern struct elf_resolve * _dl_load_shared_library(int, struct dyn_elf **, stru __attribute__ ((__weak__, __alias__ ("foobar"))); extern struct elf_resolve * _dl_check_if_named_library_is_loaded(const char *full_libname) __attribute__ ((__weak__, __alias__ ("foobar"))); -extern int _dl_fixup(struct elf_resolve *tpnt, int lazy) - __attribute__ ((__weak__, __alias__ ("foobar"))); -extern int _dl_copy_fixups(struct dyn_elf * tpnt) +extern int _dl_fixup(struct dyn_elf *rpnt, int lazy) __attribute__ ((__weak__, __alias__ ("foobar"))); #ifdef __mips__ extern void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt) @@ -87,7 +85,7 @@ static char *_dl_malloc_addr, *_dl_mmap_zero; #define _dl_trace_loaded_objects 0 #include "../ldso/readelflib1.c" void *(*_dl_malloc_function) (size_t size); -int _dl_fixup(struct elf_resolve *tpnt, int lazy); +int _dl_fixup(struct dyn_elf *rpnt, int lazy); #endif static int do_dlclose(void *, int need_fini); @@ -271,21 +269,11 @@ void *_dlopen(const char *libname, int flag) * Now we go through and look for REL and RELA records that indicate fixups * to the GOT tables. We need to do this in reverse order so that COPY * directives work correctly */ - if (_dl_fixup(dyn_chain->dyn, dyn_chain->flags)) + if (_dl_fixup(dyn_chain, dyn_chain->flags)) goto oops; -#ifdef __SUPPORT_LD_DEBUG__ - if(_dl_debug) - _dl_dprintf(_dl_debug_file, "Beginning dlopen copy fixups\n"); -#endif - if (_dl_symbol_tables) { - if (_dl_copy_fixups(dyn_chain)) - goto oops; - } - - /* TODO: Should we set the protections of all pages back to R/O now ? */ - + /* Notify the debugger we have added some objects. */ if (_dl_debug_addr) { -- cgit v1.2.3