Exemplo n.º 1
0
void MachOObject::load()
{
	if (isLoaded())
		throw std::logic_error("Module already loaded");
	if (strcmp(m_file->platform(), ARCH_NAME) != 0)
	{
		std::stringstream ss;
		ss << "This version of Darling dyld cannot load binaries for " << m_file->platform() << ".";
		throw std::runtime_error(ss.str());
	}
	
	loadSegments();
	transitionState(dyld_image_state_mapped);
	
	if (m_slide > 0)
		rebase();
	transitionState(dyld_image_state_rebased);
	
	readSymbols();
	readExports();

	MachOMgr::instance()->add(this, isMainModule());

	loadDependencies();
	
	performRelocations();
	performBinds();
	transitionState(dyld_image_state_bound);
	transitionState(dyld_image_state_dependents_initialized);
	
	// registerEHSection();
	
	if (isMainModule())
		fillInProgramVars();
	fillInDyldData();
	
	setInitialSegmentProtection();
	setupTLS();
	
	MachOMgr::instance()->notifyAdd(this);
	runInitializers();

	transitionState(dyld_image_state_initialized);
	
	m_file->closeFd();
	
	if (MachOMgr::instance()->printLibraries())
		std::cerr << "dyld: Loaded " << this->path() << std::endl;
}
Exemplo n.º 2
0
VOID *dlopen(const char *path, int mode)
{
	register ModulePtr mp;
	static void *mainModule;

	/*
	 * Upon the first call register a terminate handler that will
	 * close all libraries. Also get a reference to the main module
	 * for use with loadbind.
	 */
	if (!mainModule) {
		if ((mainModule = findMain()) == NULL)
			return NULL;
		atexit(terminate);
	}
	/*
	 * Scan the list of modules if we have the module already loaded.
	 */
	for (mp = modList; mp; mp = mp->next)
		if (strcmp(mp->name, path) == 0) {
			mp->refCnt++;
			return (VOID *) mp;
		}
	if ((mp = (ModulePtr)calloc(1, sizeof(*mp))) == NULL) {
		errvalid++;
		strcpy(errbuf, "calloc: ");
		strcat(errbuf, strerror(errno));
		return (VOID *) NULL;
	}
	mp->name = malloc((unsigned) (strlen(path) + 1));
	strcpy(mp->name, path);
	/*
	 * load should be declared load(const char *...). Thus we
	 * cast the path to a normal char *. Ugly.
	 */
	if ((mp->entry = (void *)load((char *)path, L_NOAUTODEFER, NULL)) == NULL) {
		free(mp->name);
		free(mp);
		errvalid++;
		strcpy(errbuf, "dlopen: ");
		strcat(errbuf, path);
		strcat(errbuf, ": ");
		/*
		 * If AIX says the file is not executable, the error
		 * can be further described by querying the loader about
		 * the last error.
		 */
		if (errno == ENOEXEC) {
			char *tmp[BUFSIZ/sizeof(char *)];
			if (loadquery(L_GETMESSAGES, tmp, sizeof(tmp)) == -1)
				strcpy(errbuf, strerror(errno));
			else {
				char **p;
				for (p = tmp; *p; p++)
					caterr(*p);
			}
		} else
			strcat(errbuf, strerror(errno));
		return (VOID *) NULL;
	}
	mp->refCnt = 1;
	mp->next = modList;
	modList = mp;
	if (loadbind(0, mainModule, mp->entry) == -1) {
		dlclose(mp);
		errvalid++;
		strcpy(errbuf, "loadbind: ");
		strcat(errbuf, strerror(errno));
		return (VOID *) NULL;
	}
	/*
	 * If the user wants global binding, loadbind against all other
	 * loaded modules.
	 */
	if (mode & RTLD_GLOBAL) {
		register ModulePtr mp1;
		for (mp1 = mp->next; mp1; mp1 = mp1->next)
			if (loadbind(0, mp1->entry, mp->entry) == -1) {
				dlclose(mp);
				errvalid++;
				strcpy(errbuf, "loadbind: ");
				strcat(errbuf, strerror(errno));
				return (VOID *) NULL;
			}
	}
	if (readExports(mp) == -1) {
		dlclose(mp);
		return (VOID *) NULL;
	}
	/*
	 * If there is a dl_info structure, call the init function.
	 */
	if (mp->info = (struct dl_info *)dlsym(mp, "dl_info")) {
		if (mp->info->init)
			(*mp->info->init)();
	} else
		errvalid = 0;
	/*
	 * If the shared object was compiled using xlC we will need
	 * to call static constructors (and later on dlclose destructors).
	 */
	if (mp->cdtors = (CdtorPtr)dlsym(mp, "__cdtors")) {
		while (mp->cdtors->init) {
			(*mp->cdtors->init)();
			mp->cdtors++;
		}
	} else
		errvalid = 0;
	return (VOID *) mp;
}
Exemplo n.º 3
0
ElfFile::ElfFile(const QString& name, QObject *parent) :
    QObject(parent), m_name(name), m_initialized(false)
{
    bfd_init();
    readExports();
}
Exemplo n.º 4
0
bool ElfFile::setFileName(const QString &name)
{
    m_name = name;
    return readExports();
}
Exemplo n.º 5
0
/* ARGSUSED */
void *dlopen(const char *path, int mode)
{
	register ModulePtr mp;
	static void *mainModule;

	/*
	 * Upon the first call register a terminate handler that will
	 * close all libraries. Also get a reference to the main module
	 * for use with loadbind.
	 */
	if (!mainModule) {
		if ((mainModule = findMain()) == NULL)
			return NULL;
		atexit(terminate);
	}
	/*
	 * Scan the list of modules if have the module already loaded.
	 */
	for (mp = modList; mp; mp = mp->next)
		if (strcmp(mp->name, path) == 0) {
			mp->refCnt++;
			return mp;
		}
	if ((mp = (ModulePtr)calloc(1, sizeof(*mp))) == NULL) {
		errvalid++;
		strcpy(errbuf, "calloc: ");
		strcat(errbuf, strerror(errno));
		return NULL;
	}
	if ((mp->name = strdup(path)) == NULL) {
		errvalid++;
		strcpy(errbuf, "strdup: ");
		strcat(errbuf, strerror(errno));
		free(mp);
		return NULL;
	}
	/*
	 * load should be declared load(const char *...). Thus we
	 * cast the path to a normal char *. Ugly.
	 */
	if ((mp->entry = (void *)load((char *)path, L_NOAUTODEFER, NULL)) == NULL) {
		free(mp->name);
		free(mp);
		errvalid++;
		strcpy(errbuf, "dlopen: ");
		strcat(errbuf, path);
		strcat(errbuf, ": ");
		/*
		 * If AIX says the file is not executable, the error
		 * can be further described by querying the loader about
		 * the last error.
		 */
		if (errno == ENOEXEC) {
			char *tmp[BUFSIZ/sizeof(char *)];
			if (loadquery(L_GETMESSAGES, tmp, sizeof(tmp)) == -1)
				strcpy(errbuf, strerror(errno));
			else {
				char **p;
				for (p = tmp; *p; p++)
					caterr(*p);
			}
		} else
			strcat(errbuf, strerror(errno));
		return NULL;
	}
	mp->refCnt = 1;
	mp->next = modList;
	modList = mp;
	if (loadbind(0, mainModule, mp->entry) == -1) {
		dlclose(mp);
		errvalid++;
		strcpy(errbuf, "loadbind: ");
		strcat(errbuf, strerror(errno));
		return NULL;
	}
	if (readExports(mp) == -1) {
		dlclose(mp);
		return NULL;
	}
	/*
	 * If there is a dl_info structure, call the init function.
	 */
	if (mp->info = (struct dl_info *)dlsym(mp, "dl_info")) {
		if (mp->info->init)
			(*mp->info->init)();
	} else
		errvalid = 0;
	return mp;
}