⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdl_dlcompat.c

📁 SDL库 在进行视频显示程序spcaview安装时必须的库文件
💻 C
📖 第 1 页 / 共 3 页
字号:
	struct dlstatus *dls = stqueue;	while (dls && status != dls)		dls = dls->next;	if (dls == 0)		error("invalid handle");	else if ((dls->module == 0) || (dls->refs == 0))		error("handle to closed library");	else		return TRUE;	return FALSE;}static inline int isFlagSet(int mode, int flag){	return (mode & flag) == flag;}static struct dlstatus *lookupStatus(const struct stat *sbuf){	struct dlstatus *dls = stqueue;	debug("looking for status");	while (dls && ( /* isFlagSet(dls->mode, RTLD_UNSHARED) */ 0				   || sbuf->st_dev != dls->device || sbuf->st_ino != dls->inode))		dls = dls->next;	return dls;}static void insertStatus(struct dlstatus *dls, const struct stat *sbuf){	debug("inserting status");	dls->inode = sbuf->st_ino;	dls->device = sbuf->st_dev;	dls->refs = 0;	dls->mode = 0;	if ((dls->flags & DL_IN_LIST) == 0)	{		dls->next = stqueue;		stqueue = dls;		dls->flags |= DL_IN_LIST;	}}static struct dlstatus *allocStatus(){	struct dlstatus *dls;#ifdef REUSE_STATUS	dls = stqueue;	while (dls && dls->module)		dls = dls->next;	if (!dls)#endif		dls = SDL_calloc(sizeof(*dls),1);	return dls;}static int promoteLocalToGlobal(struct dlstatus *dls){	static int (*p) (NSModule module) = 0;	debug("promoting");	if (!p)		_dyld_func_lookup("__dyld_NSMakePrivateModulePublic", (void **)&p);	return (dls->module == MAGIC_DYLIB_MOD) || (p && p(dls->module));}static void *reference(struct dlstatus *dls, int mode){	if (dls)	{		if (dls->module == MAGIC_DYLIB_MOD && isFlagSet(mode, RTLD_LOCAL))		{			warning("trying to open a .dylib with RTLD_LOCAL");			error("unable to open a .dylib with RTLD_LOCAL");			return NULL;		}		if (isFlagSet(mode, RTLD_GLOBAL) &&			!isFlagSet(dls->mode, RTLD_GLOBAL) && !promoteLocalToGlobal(dls))		{			error("unable to promote local module to global");			return NULL;		}		dls->mode |= mode;		dls->refs++;	}	else		debug("reference called with NULL argument");	return dls;}static const struct mach_header *my_find_image(const char *name){	const struct mach_header *mh = 0;	const char *id = NULL;	int i = _dyld_image_count();	int j;	mh = (struct mach_header *)		dyld_NSAddImage(name, NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED |						NSADDIMAGE_OPTION_RETURN_ON_ERROR);	if (!mh)	{		for (j = 0; j < i; j++)		{			id = _dyld_get_image_name(j);			if (!SDL_strcmp(id, name))			{				mh = _dyld_get_image_header(j);				break;			}		}	}	return mh;}/* * dyld adds libraries by first adding the directly dependant libraries in link order, and * then adding the dependencies for those libraries, so we should do the same... but we don't * bother adding the extra dependencies, if the symbols are neither in the loaded image nor * any of it's direct dependencies, then it probably isn't there. */static NSSymbol search_linked_libs(const struct mach_header * mh, const char *symbol){	unsigned int n;	struct load_command *lc = 0;	struct mach_header *wh;	NSSymbol nssym = 0;	if (dyld_NSAddImage && dyld_NSIsSymbolNameDefinedInImage && dyld_NSLookupSymbolInImage)	{		lc = (struct load_command *)((char *)mh + sizeof(struct mach_header));		for (n = 0; n < mh->ncmds; n++, lc = (struct load_command *)((char *)lc + lc->cmdsize))		{			if ((LC_LOAD_DYLIB == lc->cmd) || (LC_LOAD_WEAK_DYLIB == lc->cmd))			{				if ((wh = (struct mach_header *)					 my_find_image((char *)(((struct dylib_command *)lc)->dylib.name.offset +											(char *)lc))))				{					if (dyld_NSIsSymbolNameDefinedInImage(wh, symbol))					{						nssym = dyld_NSLookupSymbolInImage(wh,														   symbol,														   NSLOOKUPSYMBOLINIMAGE_OPTION_BIND |														   NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);						break;					}				}			}		}		if ((!nssym) && NSIsSymbolNameDefined(symbol))		{			/* I've never seen this debug message...*/			debug("Symbol \"%s\" is defined but was not found", symbol);		}	}	return nssym;}/* Up to the caller to SDL_free() returned string */static inline char *dyld_error_str(){	NSLinkEditErrors dylder;	int dylderno;	const char *dylderrstr;	const char *dyldfile;	char* retStr = NULL;	NSLinkEditError(&dylder, &dylderno, &dyldfile, &dylderrstr);	if (dylderrstr && *dylderrstr)	{		retStr = SDL_strdup(dylderrstr);	}	return retStr;}static void *dlsymIntern(struct dlstatus *dls, const char *symbol, int canSetError){  NSSymbol nssym = 0;#ifdef __GCC__  	void *caller = __builtin_return_address(1);	/* Be *very* careful about inlining */#else	void *caller = NULL;#endif	const struct mach_header *caller_mh = 0;	char *savedErrorStr = NULL;	resetdlerror();#ifndef RTLD_SELF#define	RTLD_SELF		((void *) -3)#endif	if (NULL == dls)		dls = RTLD_SELF;	if ((RTLD_NEXT == dls) || (RTLD_SELF == dls))	{		if (dyld_NSIsSymbolNameDefinedInImage && dyld_NSLookupSymbolInImage && caller)		  {			caller_mh = image_for_address(caller);			if (RTLD_SELF == dls)			{				/* FIXME: We should be using the NSModule api, if SELF is an MH_BUNDLE				 * But it appears to work anyway, and looking at the code in dyld_libfuncs.c				 * this is acceptable.				 */				if (dyld_NSIsSymbolNameDefinedInImage(caller_mh, symbol))				{					nssym = dyld_NSLookupSymbolInImage(caller_mh,													   symbol,													   NSLOOKUPSYMBOLINIMAGE_OPTION_BIND |													   NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);				}			}			if (!nssym)			{				if (RTLD_SELF == dls)					savedErrorStr = dyld_error_str();				nssym = search_linked_libs(caller_mh, symbol);			}		}		else		{			if (canSetError)				error("RTLD_SELF and RTLD_NEXT are not supported");			return NULL;		}	}	if (!nssym)	{		if (RTLD_DEFAULT == dls)		{			dls = &mainStatus;		}		if (!isValidStatus(dls))			return NULL;		if (dls->module != MAGIC_DYLIB_MOD)		{			nssym = NSLookupSymbolInModule(dls->module, symbol);			if (!nssym && NSIsSymbolNameDefined(symbol))			{				debug("Searching dependencies");				savedErrorStr = dyld_error_str();				nssym = search_linked_libs(get_mach_header_from_NSModule(dls->module), symbol);			}		}		else if (dls->lib && dyld_NSIsSymbolNameDefinedInImage && dyld_NSLookupSymbolInImage)		{			if (dyld_NSIsSymbolNameDefinedInImage(dls->lib, symbol))			{				nssym = dyld_NSLookupSymbolInImage(dls->lib,												   symbol,												   NSLOOKUPSYMBOLINIMAGE_OPTION_BIND |												   NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);			}			else if (NSIsSymbolNameDefined(symbol))			{				debug("Searching dependencies");				savedErrorStr = dyld_error_str();				nssym = search_linked_libs(dls->lib, symbol);			}		}		else if (dls->module == MAGIC_DYLIB_MOD)		{			/* Global context, use NSLookupAndBindSymbol */			if (NSIsSymbolNameDefined(symbol))			{				/* There doesn't seem to be a return on error option for this call???				   this is potentially broken, if binding fails, it will improperly				   exit the application. */				nssym = NSLookupAndBindSymbol(symbol);			}			else			{				if (savedErrorStr)					SDL_free(savedErrorStr);							savedErrorStr = SDL_malloc(256);				SDL_snprintf(savedErrorStr, 256, "Symbol \"%s\" not in global context",symbol);				}		}	}	/* Error reporting */	if (!nssym)	{		if (!savedErrorStr || !SDL_strlen(savedErrorStr))		{			if (savedErrorStr)				SDL_free(savedErrorStr);			savedErrorStr = SDL_malloc(256);			SDL_snprintf(savedErrorStr, 256,"Symbol \"%s\" not found",symbol);		}		if (canSetError)		{			error(savedErrorStr);		}		else		{			debug(savedErrorStr);		}		if (savedErrorStr)			SDL_free(savedErrorStr);		return NULL;	}	return NSAddressOfSymbol(nssym);}static struct dlstatus *loadModule(const char *path, const struct stat *sbuf, int mode){	NSObjectFileImage ofi = 0;	NSObjectFileImageReturnCode ofirc;	struct dlstatus *dls;	NSLinkEditErrors ler;	int lerno;	const char *errstr;	const char *file;	void (*init) (void);	ofirc = NSCreateObjectFileImageFromFile(path, &ofi);	switch (ofirc)	{		case NSObjectFileImageSuccess:			break;		case NSObjectFileImageInappropriateFile:			if (dyld_NSAddImage && dyld_NSIsSymbolNameDefinedInImage && dyld_NSLookupSymbolInImage)			{					if (isFlagSet(mode, RTLD_LOCAL))				{					warning("trying to open a .dylib with RTLD_LOCAL");					error("unable to open this file with RTLD_LOCAL");					return NULL;				}			}			else			{				error("opening this file is unsupported on this system");				return NULL;			}			break;		case NSObjectFileImageFailure:			error("object file setup failure");			return NULL;		case NSObjectFileImageArch:			error("no object for this architecture");			return NULL;		case NSObjectFileImageFormat:			error("bad object file format");			return NULL;		case NSObjectFileImageAccess:			error("can't read object file");			return NULL;		default:			error("unknown error from NSCreateObjectFileImageFromFile()");			return NULL;	}	dls = lookupStatus(sbuf);	if (!dls)	{		dls = allocStatus();	}	if (!dls)	{		error("unable to allocate memory");		return NULL;	}	//	dls->lib = 0;	if (ofirc == NSObjectFileImageInappropriateFile)	{		if ((dls->lib = dyld_NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR)))		{			debug("Dynamic lib loaded at %ld", dls->lib);			ofi = MAGIC_DYLIB_OFI;			dls->module = MAGIC_DYLIB_MOD;			ofirc = NSObjectFileImageSuccess;			/* Although it is possible with a bit of work to modify this so it works and			   functions with RTLD_NOW, I don't deem it necessary at the moment */		}		if (!(dls->module))		{			NSLinkEditError(&ler, &lerno, &file, &errstr);			if (!errstr || (!SDL_strlen(errstr)))				error("Can't open this file type");			else				error(errstr);			if ((dls->flags & DL_IN_LIST) == 0)			{				SDL_free(dls);			}			return NULL;		}	}	else	{		dls->module = NSLinkModule(ofi, path,								   NSLINKMODULE_OPTION_RETURN_ON_ERROR |								   NSLINKMODULE_OPTION_PRIVATE |								   (isFlagSet(mode, RTLD_NOW) ? NSLINKMODULE_OPTION_BINDNOW : 0));		NSDestroyObjectFileImage(ofi);		if (dls->module)		{			dls->lib = get_mach_header_from_NSModule(dls->module);		}	}	if (!dls->module)	{		NSLinkEditError(&ler, &lerno, &file, &errstr);		if ((dls->flags & DL_IN_LIST) == 0)		{			SDL_free(dls);		}		error(errstr);		return NULL;	}	insertStatus(dls, sbuf);	dls = reference(dls, mode);	if ((init = dlsymIntern(dls, "__init", 0)))	{		debug("calling _init()");		init();	}	return dls;}inline static void dlcompat_init_check(void){	static pthread_mutex_t l = PTHREAD_MUTEX_INITIALIZER;	static int init_done = 0;	pthread_mutex_lock(&l);	if (!init_done) {		dlcompat_init_func();		init_done = 1;	}	pthread_mutex_unlock(&l);}static void dlcompat_init_func(void){        _dyld_func_lookup("__dyld_NSAddImage", (void **)&dyld_NSAddImage);	_dyld_func_lookup("__dyld_NSIsSymbolNameDefinedInImage",			  (void **)&dyld_NSIsSymbolNameDefinedInImage);	_dyld_func_lookup("__dyld_NSLookupSymbolInImage", (void **)&dyld_NSLookupSymbolInImage);	if (pthread_mutex_init(&dlcompat_mutex, NULL))	    exit(1);	if (pthread_key_create(&dlerror_key, &dlerrorfree))	    exit(1);}static void resetdlerror(){	struct dlthread *tss;	tss = pthread_getspecific(dlerror_key);	tss->errset = 0;}static void dlerrorfree(void *data){	SDL_free(data);}/* We kind of want a recursive lock here, but meet a little trouble * because they are not available pre OS X 10.2, so we fake it * using thread specific storage to keep a lock count */ static inline void dolock(void){	int err = 0;	struct dlthread *tss;	dlcompat_init_check();	tss = pthread_getspecific(dlerror_key);	if (!tss)	{		tss = SDL_malloc(sizeof(struct dlthread));		tss->lockcnt = 0;		tss->errset = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -