Exemplo n.º 1
0
bool
rtems_rtl_obj_load (rtems_rtl_obj_t* obj)
{
  int fd;

  if (!rtems_rtl_obj_fname_valid (obj))
  {
    rtems_rtl_set_error (ENOMEM, "invalid object file name path");
    return false;
  }

  fd = open (rtems_rtl_obj_fname (obj), O_RDONLY);
  if (fd < 0)
  {
    rtems_rtl_set_error (ENOMEM, "opening for object file");
    return false;
  }

  /*
   * Find the object file in the archive if it is an archive that
   * has been opened.
   */
  if (rtems_rtl_obj_aname_valid (obj))
  {
    if (!rtems_rtl_obj_archive_find (obj, fd))
    {
      rtems_rtl_obj_caches_flush ();
      close (fd);
      return false;
    }
  }

  /*
   * Call the format specific loader. Currently this is a call to the ELF
   * loader. This call could be changed to allow probes then calls if more than
   * one format is supported.
   */
  if (!rtems_rtl_obj_file_load (obj, fd))
  {
    rtems_rtl_obj_caches_flush ();
    close (fd);
    return false;
  }

  if (!_rtld_linkmap_add (obj)) /* For GDB */
  {
    close (fd);
    return false;
  }

  rtems_rtl_obj_caches_flush ();

  close (fd);

  return true;
}
Exemplo n.º 2
0
Arquivo: load.c Projeto: Ga-vin/MINIX3
/*
 * Load a shared object into memory, if it is not already loaded.
 *
 * Returns a pointer to the Obj_Entry for the object.  Returns NULL
 * on failure.
 */
Obj_Entry *
_rtld_load_object(const char *filepath, int flags)
{
	Obj_Entry *obj;
	int fd = -1;
	struct stat sb;
	size_t pathlen = strlen(filepath);

	for (obj = _rtld_objlist->next; obj != NULL; obj = obj->next)
		if (pathlen == obj->pathlen && !strcmp(obj->path, filepath)) 
			break;

	/*
	 * If we didn't find a match by pathname, 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().
	 */
	if (obj == NULL) {
		if ((fd = open(filepath, O_RDONLY)) == -1) {
			_rtld_error("Cannot open \"%s\"", filepath);
			return NULL;
		}
		if (fstat(fd, &sb) == -1) {
			_rtld_error("Cannot fstat \"%s\"", filepath);
			close(fd);
			return NULL;
		}
		for (obj = _rtld_objlist->next; obj != NULL; obj = obj->next) {
			if (obj->ino == sb.st_ino && obj->dev == sb.st_dev) {
				close(fd);
				break;
			}
		}
	}

	if (obj == NULL) { /* First use of this object, so we must map it in */
		obj = _rtld_map_object(filepath, fd, &sb);
		(void)close(fd);
		if (obj == NULL)
			return NULL;
		_rtld_digest_dynamic(filepath, obj);

		if (flags & _RTLD_DLOPEN) {
			if (obj->z_noopen || (flags & _RTLD_NOLOAD)) {
				dbg(("refusing to load non-loadable \"%s\"",
				    obj->path));
				_rtld_error("Cannot dlopen non-loadable %s",
				    obj->path);
				munmap(obj->mapbase, obj->mapsize);
				_rtld_obj_free(obj);
				return OBJ_ERR;
			}
		}

		*_rtld_objtail = obj;
		_rtld_objtail = &obj->next;
		_rtld_objcount++;
		_rtld_objloads++;
#ifdef RTLD_LOADER
		_rtld_linkmap_add(obj);	/* for GDB */
#endif
		dbg(("  %p .. %p: %s", obj->mapbase,
		    obj->mapbase + obj->mapsize - 1, obj->path));
		if (obj->textrel)
			dbg(("  WARNING: %s has impure text", obj->path));
	}

	++obj->refcount;
#ifdef RTLD_LOADER
	if (flags & _RTLD_MAIN && !obj->mainref) {
		obj->mainref = 1;
		dbg(("adding %p (%s) to _rtld_list_main", obj, obj->path));
		_rtld_objlist_push_tail(&_rtld_list_main, obj);
	}
	if (flags & _RTLD_GLOBAL && !obj->globalref) {
		obj->globalref = 1;
		dbg(("adding %p (%s) to _rtld_list_global", obj, obj->path));
		_rtld_objlist_push_tail(&_rtld_list_global, obj);
	}
#endif
	return obj;
}