Пример #1
0
int dlclose(void* handle) {
  ScopedPthreadMutexLocker locker(&g_dl_mutex);
  int result = do_dlclose(handle);
  if (result != 0) {
    __bionic_format_dlerror("dlclose failed", linker_get_error_buffer());
  }
  return result;
}
Пример #2
0
libearly_init(void)
{
    char *s;
    int k;

    s = getenv("EARLY");
    if (s == NULL) {
	printf("%s: EARLY = %s\n", __func__, "(not set)");
	return;
    }
    printf("%s: EARLY = %s\n", __func__, s);

    for (k = 0; s[k] != 0; k++) {
	switch (s[k]) {
	case 'C': case 'c':
	    do_dlclose();
	    break;

	case 'E': case 'e':
	    do_exit();
	    break;

	case 'F': case 'f':
	    do_fork();
	    break;

	case 'O': case 'o':
	    do_dlopen();
	    break;

	case 'T': case 't':
	    do_thread();
	    break;

	default:
	    printf("%s: unknown char: %c\n", __func__, s[k]);
	    break;
	}
    }
}
Пример #3
0
int dlclose(void* handle) {
  ScopedPthreadMutexLocker locker(&g_dl_mutex);
  do_dlclose(reinterpret_cast<soinfo*>(handle));
  // dlclose has no defined errors.
  return 0;
}
Пример #4
0
int dlclose(void* handle) {
  ScopedPthreadMutexLocker locker(&gDlMutex);
  return do_dlclose(reinterpret_cast<soinfo*>(handle));
}
Пример #5
0
int _dlclose(void *vhandle)
{
	return do_dlclose(vhandle, 1);
}
Пример #6
0
void *_dlopen(const char *libname, int flag)
{
	struct elf_resolve *tpnt, *tfrom;
	struct dyn_elf *rpnt = NULL;
	struct dyn_elf *dyn_chain;
	struct dyn_elf *dpnt;
	static int dl_init = 0;
	char *from;
	void (*dl_brk) (void);
#ifdef __PIC__
	int (*dl_elf_init) (void);
#endif

	/* A bit of sanity checking... */
	if (!(flag & (RTLD_LAZY|RTLD_NOW))) {
		_dl_error_number = LD_BAD_HANDLE;
		return NULL;
	}

	from = __builtin_return_address(0);

	/* Have the dynamic linker use the regular malloc function now */
	if (!dl_init) {
		dl_init++;
		_dl_malloc_function = malloc;
	}

	/* Cover the trivial case first */
	if (!libname)
		return _dl_symbol_tables;

#ifdef USE_CACHE
	_dl_map_cache();
#endif

	/*
	 * Try and locate the module we were called from - we
	 * need this so that we get the correct RPATH.  Note that
	 * this is the current behavior under Solaris, but the
	 * ABI+ specifies that we should only use the RPATH from
	 * the application.  Thus this may go away at some time
	 * in the future.
	 */
	tfrom = NULL;
	for (dpnt = _dl_symbol_tables; dpnt; dpnt = dpnt->next) {
		tpnt = dpnt->dyn;
		if (tpnt->loadaddr < from
			&& (tfrom == NULL || tfrom->loadaddr < tpnt->loadaddr))
			tfrom = tpnt;
	}

	if (!(tpnt = _dl_load_shared_library(0, &rpnt, tfrom, (char*)libname))) {
#ifdef USE_CACHE
		_dl_unmap_cache();
#endif
		return NULL;
	}
	//tpnt->libtype = loaded_file;

	dyn_chain = rpnt = (struct dyn_elf *) malloc(sizeof(struct dyn_elf));
	_dl_memset(rpnt, 0, sizeof(*rpnt));
	rpnt->dyn = tpnt;
	rpnt->flags = flag;
	if (!tpnt->symbol_scope)
		tpnt->symbol_scope = dyn_chain;

	rpnt->next_handle = _dl_handles;
	_dl_handles = rpnt;

	/*
	 * OK, we have the requested file in memory.  Now check for
	 * any other requested files that may also be required.
	 */
	  {
	    struct elf_resolve *tcurr;
	    struct elf_resolve * tpnt1;
	    Elf32_Dyn * dpnt;
	    char * lpnt;

	    tcurr = tpnt;
	    do{
	      for(dpnt = (Elf32_Dyn *) tcurr->dynamic_addr; dpnt->d_tag; dpnt++)
		{
	  
		  if(dpnt->d_tag == DT_NEEDED)
		    {
		      lpnt = tcurr->loadaddr + tcurr->dynamic_info[DT_STRTAB] + 
			dpnt->d_un.d_val;
		      if(!(tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpnt)))
			goto oops;

		      rpnt->next = (struct dyn_elf *) malloc(sizeof(struct dyn_elf));
		      _dl_memset (rpnt->next, 0, sizeof (*(rpnt->next)));
		      rpnt = rpnt->next;
		      if (!tpnt1->symbol_scope) tpnt1->symbol_scope = dyn_chain;
		      rpnt->dyn = tpnt1;
		    };
		}
	      
	      tcurr = tcurr->next;
	    } while(tcurr);
	  }
	 
	/*
	 * OK, now attach the entire chain at the end
	 */

	rpnt->next = _dl_symbol_tables;

	/*
	 * MIPS is special *sigh*
	 */
#ifdef __mips__
	_dl_perform_mips_global_got_relocations(tpnt);
#endif

	if (do_fixup(tpnt, flag)) {
		_dl_error_number = LD_NO_SYMBOL;
		goto oops;
	}

	if (_dl_debug_addr) {
	    dl_brk = (void (*)(void)) _dl_debug_addr->r_brk;
	    if (dl_brk != NULL) {
		_dl_debug_addr->r_state = RT_ADD;
		(*dl_brk) ();

		_dl_debug_addr->r_state = RT_CONSISTENT;
		(*dl_brk) ();
	    }
	}

#ifdef __PIC__
	for (rpnt = dyn_chain; rpnt; rpnt = rpnt->next) {
		tpnt = rpnt->dyn;
		/* Apparently crt1 for the application is responsible for handling this.
		 * We only need to run the init/fini for shared libraries
		 */
		if (tpnt->libtype == program_interpreter)
			continue;
		if (tpnt->libtype == elf_executable)
			continue;
		if (tpnt->init_flag & INIT_FUNCS_CALLED)
			continue;
		tpnt->init_flag |= INIT_FUNCS_CALLED;

		if (tpnt->dynamic_info[DT_INIT]) {
			dl_elf_init = (int (*)(void)) (tpnt->loadaddr + tpnt->dynamic_info[DT_INIT]);
			(*dl_elf_init) ();
		}
		if (tpnt->dynamic_info[DT_FINI]) {
			atexit((void (*)(void)) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI]));
		}

	}
#endif

#ifdef USE_CACHE
	_dl_unmap_cache();
#endif
	return (void *) dyn_chain;

  oops:
	/* Something went wrong.  Clean up and return NULL. */
#ifdef USE_CACHE
	_dl_unmap_cache();
#endif
	do_dlclose(dyn_chain, 0);
	return NULL;
}