From 5353bfc3b42e775870f8a456a8504a69ce8a1450 Mon Sep 17 00:00:00 2001 From: John Polstra Date: Wed, 21 Apr 1999 04:06:57 +0000 Subject: [PATCH] After relocating the main program, but before calling any of the _init() functions, initialize the global variables "__progname" and "environ". This makes it possible for the _init() functions to call things like getenv() and err(). --- libexec/rtld-elf/rtld.c | 40 +++++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index 7196575ddda..5ac7fcdebef 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -22,7 +22,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: rtld.c,v 1.20 1999/04/09 00:28:31 jdp Exp $ + * $Id: rtld.c,v 1.21 1999/04/09 06:42:00 jdp Exp $ */ /* @@ -76,6 +76,7 @@ typedef void (*func_ptr_type)(); /* * Function declarations. */ +static const char *basename(const char *); static void call_fini_functions(Obj_Entry *); static void call_init_functions(Obj_Entry *); static void die(void); @@ -95,16 +96,13 @@ static Obj_Entry *obj_from_addr(const void *); static int relocate_objects(Obj_Entry *, bool); static void rtld_exit(void); static char *search_library_path(const char *, const char *); +static void set_program_var(const char *, const void *); static void unref_object_dag(Obj_Entry *); static void trace_loaded_objects(Obj_Entry *obj); void r_debug_state(void); void xprintf(const char *, ...); -#ifdef DEBUG -static const char *basename(const char *); -#endif - /* * Data declarations. */ @@ -296,6 +294,10 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp) if (do_copy_relocations(obj_main) == -1) die(); + dbg("initializing key program variables"); + set_program_var("__progname", argv[0] != NULL ? basename(argv[0]) : ""); + set_program_var("environ", env); + dbg("calling _init functions"); call_init_functions(obj_main->next); @@ -355,14 +357,12 @@ _rtld_error(const char *fmt, ...) va_end(ap); } -#ifdef DEBUG static const char * basename(const char *name) { const char *p = strrchr(name, '/'); return p != NULL ? p + 1 : name; } -#endif static void call_fini_functions(Obj_Entry *first) @@ -1365,6 +1365,32 @@ r_debug_state(void) { } +/* + * Set a pointer variable in the main program to the given value. This + * is used to set key variables such as "environ" before any of the + * init functions are called. + */ +static void +set_program_var(const char *name, const void *value) +{ + const Obj_Entry *obj; + unsigned long hash; + + hash = elf_hash(name); + for (obj = obj_main; obj != NULL; obj = obj->next) { + const Elf_Sym *def; + + if ((def = symlook_obj(name, hash, obj, false)) != NULL) { + const void **addr; + + addr = (const void **)(obj->relocbase + def->st_value); + dbg("\"%s\": *%p <-- %p", name, addr, value); + *addr = value; + break; + } + } +} + /* * Search the symbol table of a single shared object for a symbol of * the given name. Returns a pointer to the symbol, or NULL if no