FreeBSD/libexec/rtld-elf/rtld.c
/*
 * Call the initialization functions for each of the objects in
 * "list".  All of the objects are expected to have non-NULL init
 * functions.
 */
Call the initialization functions for each of the objects in
"list".  All of the objects are expected to have non-NULL init
functions.
Call the initialization functions for each of the objects in " list " . All of the objects are expected to have non - NULL init functions .
static void
objlist_call_init(Objlist *list, RtldLockState *lockstate)
{
    Objlist_Entry *elm;
    Obj_Entry *obj;
    char *saved_msg;
    Elf_Addr *init_addr;
    int index;
    TAILQ_FOREACH(obj, &obj_list, next) {
	if (obj->marker)
	    continue;
	obj->init_scanned = false;
    }
    saved_msg = errmsg_save();
    STAILQ_FOREACH(elm, list, link) {
	if (elm->obj->init_done) 
	    continue;
	elm->obj->init_done = true;
	lock_release(rtld_bind_lock, lockstate);
	if (elm->obj->init != (Elf_Addr)NULL) {
	    dbg("calling init function for %s at %p", elm->obj->path,
	        (void *)elm->obj->init);
	    LD_UTRACE(UTRACE_INIT_CALL, elm->obj, (void *)elm->obj->init,
	        0, 0, elm->obj->path);
	    call_initfini_pointer(elm->obj, elm->obj->init);
	}
	init_addr = (Elf_Addr *)elm->obj->init_array;
	if (init_addr != NULL) {
	    for (index = 0; index < elm->obj->init_array_num; index++) {
		if (init_addr[index] != 0 && init_addr[index] != 1) {
		    dbg("calling init function for %s at %p", elm->obj->path,
			(void *)init_addr[index]);
		    LD_UTRACE(UTRACE_INIT_CALL, elm->obj,
			(void *)init_addr[index], 0, 0, elm->obj->path);
		    call_init_pointer(elm->obj, init_addr[index]);
		}
	    }
	}
	wlock_acquire(rtld_bind_lock, lockstate);
    }
    errmsg_restore(saved_msg);
}
static void objlist_call_init ( Objlist * list , RtldLockState * lockstate ) { Objlist_Entry * elm ; Obj_Entry * obj ; char * saved_msg ; Elf_Addr * init_addr ; int index ; TAILQ_FOREACH ( obj , & obj_list , next ) { if ( obj -> marker ) continue ; obj -> init_scanned = false ; } saved_msg = errmsg_save ( ) ; STAILQ_FOREACH ( elm , list , link ) { if ( elm -> obj -> init_done ) continue ; elm -> obj -> init_done = true ; lock_release ( rtld_bind_lock , lockstate ) ; if ( elm -> obj -> init != ( Elf_Addr ) NULL ) { dbg ( " " , elm -> obj -> path , ( void * ) elm -> obj -> init ) ; LD_UTRACE ( UTRACE_INIT_CALL , elm -> obj , ( void * ) elm -> obj -> init , 0 , 0 , elm -> obj -> path ) ; call_initfini_pointer ( elm -> obj , elm -> obj -> init ) ; } init_addr = ( Elf_Addr * ) elm -> obj -> init_array ; if ( init_addr != NULL ) { for ( index = 0 ; index < elm -> obj -> init_array_num ; index ++ ) { if ( init_addr [ index ] != 0 && init_addr [ index ] != 1 ) { dbg ( " " , elm -> obj -> path , ( void * ) init_addr [ index ] ) ; LD_UTRACE ( UTRACE_INIT_CALL , elm -> obj , ( void * ) init_addr [ index ] , 0 , 0 , elm -> obj -> path ) ; call_init_pointer ( elm -> obj , init_addr [ index ] ) ; } } } wlock_acquire ( rtld_bind_lock , lockstate ) ; } errmsg_restore ( saved_msg ) ; }
Call the initialization functions for each of the objects in
 "list".
Call the initialization functions for each of the objects in " list " .
/*
     * Clean init_scanned flag so that objects can be rechecked and
     * possibly initialized earlier if any of vectors called below
     * cause the change by using dlopen.
     */ /*
     * Preserve the current error message since an init function might
     * call into the dynamic linker and overwrite it.
     */ /* Initialized early. */ /*
	 * Race: other thread might try to use this object before current
	 * one completes the initilization. Not much can be done here
	 * without better locking.
	 */ /*
         * It is legal to have both DT_INIT and DT_INIT_ARRAY defined.
         * When this happens, DT_INIT is processed first.
         */