summaryrefslogtreecommitdiffstats
path: root/libexec
diff options
context:
space:
mode:
authorjdp <jdp@FreeBSD.org>1999-04-21 04:06:57 +0000
committerjdp <jdp@FreeBSD.org>1999-04-21 04:06:57 +0000
commitd93b4012a3f2c994a992d610c59ffba6fc293de1 (patch)
tree91b613ff96971306cf9d59fc1a569238d8474bb3 /libexec
parent9eacfd41889da5cad57e4a8ac677c049983b6e69 (diff)
downloadFreeBSD-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.c40
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.
OpenPOWER on IntegriCloud