diff options
author | jdp <jdp@FreeBSD.org> | 1999-04-21 04:06:57 +0000 |
---|---|---|
committer | jdp <jdp@FreeBSD.org> | 1999-04-21 04:06:57 +0000 |
commit | d93b4012a3f2c994a992d610c59ffba6fc293de1 (patch) | |
tree | 91b613ff96971306cf9d59fc1a569238d8474bb3 /libexec | |
parent | 9eacfd41889da5cad57e4a8ac677c049983b6e69 (diff) | |
download | FreeBSD-src-d93b4012a3f2c994a992d610c59ffba6fc293de1.zip FreeBSD-src-d93b4012a3f2c994a992d610c59ffba6fc293de1.tar.gz |
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().
Diffstat (limited to 'libexec')
-rw-r--r-- | libexec/rtld-elf/rtld.c | 40 |
1 files changed, 33 insertions, 7 deletions
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index 7196575..5ac7fcd 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) @@ -1366,6 +1366,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 * definition was found. |