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().
This commit is contained in:
parent
f998a53420
commit
5353bfc3b4
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=45890
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user