FreeBSD/libexec/rtld-elf/rtld.c
/*
 * Load a shared object into memory, if it is not already loaded.  The
 * object may be specified by name or by user-supplied file descriptor
 * fd_u. In the later case, the fd_u descriptor is not closed, but its
 * duplicate is.
 *
 * Returns a pointer to the Obj_Entry for the object.  Returns NULL
 * on failure.
 */
Load a shared object into memory, if it is not already loaded.  The
object may be specified by name or by user-supplied file descriptor
fd_u. In the later case, the fd_u descriptor is not closed, but its
duplicate is.

Returns a pointer to the Obj_Entry for the object.  Returns NULL
on failure.
Load a shared object into memory if it is not already loaded . The object may be specified by name or by user - supplied file descriptor fd_u . In the later case the fd_u descriptor is not closed but its duplicate is . Returns a pointer to the Obj_Entry for the object . Returns NULL on failure .
static Obj_Entry *
load_object(const char *name, int fd_u, const Obj_Entry *refobj, int flags)
{
    Obj_Entry *obj;
    int fd;
    struct stat sb;
    char *path;
    fd = -1;
    if (name != NULL) {
	TAILQ_FOREACH(obj, &obj_list, next) {
	    if (obj->marker)
		continue;
	    if (object_match_name(obj, name))
		return (obj);
	}
	path = find_library(name, refobj, &fd);
	if (path == NULL)
	    return (NULL);
    } else
	path = NULL;
    if (fd >= 0) {
    } else if (fd_u == -1) {
	if ((fd = open(path, O_RDONLY | O_CLOEXEC | O_VERIFY)) == -1) {
	    _rtld_error("Cannot open \"%s\"", path);
	    free(path);
	    return (NULL);
	}
    } else {
	fd = fcntl(fd_u, F_DUPFD_CLOEXEC, 0);
	if (fd == -1) {
	    _rtld_error("Cannot dup fd");
	    free(path);
	    return (NULL);
	}
    }
    if (fstat(fd, &sb) == -1) {
	_rtld_error("Cannot fstat \"%s\"", printable_path(path));
	close(fd);
	free(path);
	return NULL;
    }
    TAILQ_FOREACH(obj, &obj_list, next) {
	if (obj->marker)
	    continue;
	if (obj->ino == sb.st_ino && obj->dev == sb.st_dev)
	    break;
    }
    if (obj != NULL && name != NULL) {
	object_add_name(obj, name);
	free(path);
	close(fd);
	return obj;
    }
    if (flags & RTLD_LO_NOLOAD) {
	free(path);
	close(fd);
	return (NULL);
    }
    obj = do_load_object(fd, name, path, &sb, flags);
    if (obj == NULL)
	free(path);
    close(fd);
    return obj;
}
static Obj_Entry * load_object ( const char * name , int fd_u , const Obj_Entry * refobj , int flags ) { Obj_Entry * obj ; int fd ; struct stat sb ; char * path ; fd = -1 ; if ( name != NULL ) { TAILQ_FOREACH ( obj , & obj_list , next ) { if ( obj -> marker ) continue ; if ( object_match_name ( obj , name ) ) return ( obj ) ; } path = find_library ( name , refobj , & fd ) ; if ( path == NULL ) return ( NULL ) ; } else path = NULL ; if ( fd >= 0 ) { } else if ( fd_u == -1 ) { if ( ( fd = open ( path , O_RDONLY | O_CLOEXEC | O_VERIFY ) ) == -1 ) { _rtld_error ( " \" \" " , path ) ; free ( path ) ; return ( NULL ) ; } } else { fd = fcntl ( fd_u , F_DUPFD_CLOEXEC , 0 ) ; if ( fd == -1 ) { _rtld_error ( " " ) ; free ( path ) ; return ( NULL ) ; } } if ( fstat ( fd , & sb ) == -1 ) { _rtld_error ( " \" \" " , printable_path ( path ) ) ; close ( fd ) ; free ( path ) ; return NULL ; } TAILQ_FOREACH ( obj , & obj_list , next ) { if ( obj -> marker ) continue ; if ( obj -> ino == sb . st_ino && obj -> dev == sb . st_dev ) break ; } if ( obj != NULL && name != NULL ) { object_add_name ( obj , name ) ; free ( path ) ; close ( fd ) ; return obj ; } if ( flags & RTLD_LO_NOLOAD ) { free ( path ) ; close ( fd ) ; return ( NULL ) ; } obj = do_load_object ( fd , name , path , & sb , flags ) ; if ( obj == NULL ) free ( path ) ; close ( fd ) ; return obj ; }
Load a shared object into memory, if it is not already loaded.
Load a shared object into memory if it is not already loaded .
/*
	 * search_library_pathfds() opens a fresh file descriptor for the
	 * library, so there is no need to dup().
	 */ /*
	 * If we didn't find a match by pathname, or the name is not
	 * supplied, open the file and check again by device and inode.
	 * This avoids false mismatches caused by multiple links or ".."
	 * in pathnames.
	 *
	 * To avoid a race, we open the file and use fstat() rather than
	 * using stat().
	 */ /* First use of this object, so we must map it in */