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

📄 ltdl.c

📁 Small Device C Compiler 面向Inter8051
💻 C
📖 第 1 页 / 共 5 页
字号:
  if (entry)    {      /* Either ARGZ/ARGZ_LEN is empty, or ENTRY points into an address	 within the ARGZ vector.  */      assert ((!argz && !argz_len)	      || ((argz <= entry) && (entry < (argz + argz_len))));      /* Move to the char immediately after the terminating	 '\0' of ENTRY.  */      entry = 1+ strchr (entry, LT_EOS_CHAR);      /* Return either the new ENTRY, or else NULL if ARGZ is	 exhausted.  */      return (entry >= argz + argz_len) ? 0 : (char *) entry;    }  else    {      /* This should probably be flagged as a programmer error,	 since starting an argz_next loop with the iterator set	 to ARGZ is safer.  To preserve semantics, handle the NULL	 case by returning the start of ARGZ (if any).  */      if (argz_len > 0)	return argz;      else	return 0;    }}#endif /* !HAVE_ARGZ_NEXT */#if ! HAVE_ARGZ_STRINGIFY#  define argz_stringify rpl_argz_stringifystatic void argz_stringify LT_PARAMS((char *argz, size_t argz_len,				       int sep));static voidargz_stringify (argz, argz_len, sep)     char *argz;     size_t argz_len;     int sep;{  assert ((argz && argz_len) || (!argz && !argz_len));  if (sep)    {      --argz_len;		/* don't stringify the terminating EOS */      while (--argz_len > 0)	{	  if (argz[argz_len] == LT_EOS_CHAR)	    argz[argz_len] = sep;	}    }}#endif /* !HAVE_ARGZ_STRINGIFY *//* --- TYPE DEFINITIONS -- *//* This type is used for the array of caller data sets in each handler. */typedef struct {  lt_dlcaller_id	key;  lt_ptr		data;} lt_caller_data;/* --- OPAQUE STRUCTURES DECLARED IN LTDL.H --- *//* Extract the diagnostic strings from the error table macro in the same   order as the enumerated indices in ltdl.h. */static const char *lt_dlerror_strings[] =  {#define LT_ERROR(name, diagnostic)	(diagnostic),    lt_dlerror_table#undef LT_ERROR    0  };/* This structure is used for the list of registered loaders. */struct lt_dlloader {  struct lt_dlloader   *next;  const char	       *loader_name;	/* identifying name for each loader */  const char	       *sym_prefix;	/* prefix for symbols */  lt_module_open       *module_open;  lt_module_close      *module_close;  lt_find_sym	       *find_sym;  lt_dlloader_exit     *dlloader_exit;  lt_user_data		dlloader_data;};struct lt_dlhandle_struct {  struct lt_dlhandle_struct   *next;  lt_dlloader	       *loader;		/* dlopening interface */  lt_dlinfo		info;  int			depcount;	/* number of dependencies */  lt_dlhandle	       *deplibs;	/* dependencies */  lt_module		module;		/* system module handle */  lt_ptr		system;		/* system specific data */  lt_caller_data       *caller_data;	/* per caller associated data */  int			flags;		/* various boolean stats */};/* Various boolean flags can be stored in the flags field of an   lt_dlhandle_struct... */#define LT_DLGET_FLAG(handle, flag) (((handle)->flags & (flag)) == (flag))#define LT_DLSET_FLAG(handle, flag) ((handle)->flags |= (flag))#define LT_DLRESIDENT_FLAG	    (0x01 << 0)/* ...add more flags here... */#define LT_DLIS_RESIDENT(handle)    LT_DLGET_FLAG(handle, LT_DLRESIDENT_FLAG)#define LT_DLSTRERROR(name)	lt_dlerror_strings[LT_CONC(LT_ERROR_,name)]static	const char	objdir[]		= LTDL_OBJDIR;static	const char	archive_ext[]		= LTDL_ARCHIVE_EXT;#ifdef	LTDL_SHLIB_EXTstatic	const char	shlib_ext[]		= LTDL_SHLIB_EXT;#endif#ifdef	LTDL_SYSSEARCHPATHstatic	const char	sys_search_path[]	= LTDL_SYSSEARCHPATH;#endif/* --- MUTEX LOCKING --- *//* Macros to make it easier to run the lock functions only if they have   been registered.  The reason for the complicated lock macro is to   ensure that the stored error message from the last error is not   accidentally erased if the current function doesn't generate an   error of its own.  */#define LT_DLMUTEX_LOCK()			LT_STMT_START {	\	if (lt_dlmutex_lock_func) (*lt_dlmutex_lock_func)();	\						} LT_STMT_END#define LT_DLMUTEX_UNLOCK()			LT_STMT_START { \	if (lt_dlmutex_unlock_func) (*lt_dlmutex_unlock_func)();\						} LT_STMT_END#define LT_DLMUTEX_SETERROR(errormsg)		LT_STMT_START {	\	if (lt_dlmutex_seterror_func)				\		(*lt_dlmutex_seterror_func) (errormsg);		\	else 	lt_dllast_error = (errormsg);	} LT_STMT_END#define LT_DLMUTEX_GETERROR(errormsg)		LT_STMT_START {	\	if (lt_dlmutex_seterror_func)				\		(errormsg) = (*lt_dlmutex_geterror_func) ();	\	else	(errormsg) = lt_dllast_error;	} LT_STMT_END/* The mutex functions stored here are global, and are necessarily the   same for all threads that wish to share access to libltdl.  */static	lt_dlmutex_lock	    *lt_dlmutex_lock_func     = 0;static	lt_dlmutex_unlock   *lt_dlmutex_unlock_func   = 0;static	lt_dlmutex_seterror *lt_dlmutex_seterror_func = 0;static	lt_dlmutex_geterror *lt_dlmutex_geterror_func = 0;static	const char	    *lt_dllast_error	      = 0;/* Either set or reset the mutex functions.  Either all the arguments must   be valid functions, or else all can be NULL to turn off locking entirely.   The registered functions should be manipulating a static global lock   from the lock() and unlock() callbacks, which needs to be reentrant.  */intlt_dlmutex_register (lock, unlock, seterror, geterror)     lt_dlmutex_lock *lock;     lt_dlmutex_unlock *unlock;     lt_dlmutex_seterror *seterror;     lt_dlmutex_geterror *geterror;{  lt_dlmutex_unlock *old_unlock = unlock;  int		     errors	= 0;  /* Lock using the old lock() callback, if any.  */  LT_DLMUTEX_LOCK ();  if ((lock && unlock && seterror && geterror)      || !(lock || unlock || seterror || geterror))    {      lt_dlmutex_lock_func     = lock;      lt_dlmutex_unlock_func   = unlock;      lt_dlmutex_geterror_func = geterror;    }  else    {      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_MUTEX_ARGS));      ++errors;    }  /* Use the old unlock() callback we saved earlier, if any.  Otherwise     record any errors using internal storage.  */  if (old_unlock)    (*old_unlock) ();  /* Return the number of errors encountered during the execution of     this function.  */  return errors;}/* --- ERROR HANDLING --- */static	const char    **user_error_strings	= 0;static	int		errorcount		= LT_ERROR_MAX;intlt_dladderror (diagnostic)     const char *diagnostic;{  int		errindex = 0;  int		result	 = -1;  const char  **temp     = (const char **) 0;  assert (diagnostic);  LT_DLMUTEX_LOCK ();  errindex = errorcount - LT_ERROR_MAX;  temp = LT_EREALLOC (const char *, user_error_strings, 1 + errindex);  if (temp)    {      user_error_strings		= temp;      user_error_strings[errindex]	= diagnostic;      result				= errorcount++;    }  LT_DLMUTEX_UNLOCK ();  return result;}intlt_dlseterror (errindex)     int errindex;{  int		errors	 = 0;  LT_DLMUTEX_LOCK ();  if (errindex >= errorcount || errindex < 0)    {      /* Ack!  Error setting the error message! */      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_ERRORCODE));      ++errors;    }  else if (errindex < LT_ERROR_MAX)    {      /* No error setting the error message! */      LT_DLMUTEX_SETERROR (lt_dlerror_strings[errindex]);    }  else    {      /* No error setting the error message! */      LT_DLMUTEX_SETERROR (user_error_strings[errindex - LT_ERROR_MAX]);    }  LT_DLMUTEX_UNLOCK ();  return errors;}static lt_ptrlt_emalloc (size)     size_t size;{  lt_ptr mem = lt_dlmalloc (size);  if (size && !mem)    LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));  return mem;}static lt_ptrlt_erealloc (addr, size)     lt_ptr addr;     size_t size;{  lt_ptr mem = realloc (addr, size);  if (size && !mem)    LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));  return mem;}static char *lt_estrdup (str)     const char *str;{  char *copy = strdup (str);  if (LT_STRLEN (str) && !copy)    LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));  return copy;}/* --- DLOPEN() INTERFACE LOADER --- *//* The Cygwin dlopen implementation prints a spurious error message to   stderr if its call to LoadLibrary() fails for any reason.  We can   mitigate this by not using the Cygwin implementation, and falling   back to our own LoadLibrary() wrapper. */#if HAVE_LIBDL && !defined(__CYGWIN__)/* dynamic linking with dlopen/dlsym */#if HAVE_DLFCN_H#  include <dlfcn.h>#endif#if HAVE_SYS_DL_H#  include <sys/dl.h>#endif#ifdef RTLD_GLOBAL#  define LT_GLOBAL		RTLD_GLOBAL#else#  ifdef DL_GLOBAL#    define LT_GLOBAL		DL_GLOBAL#  endif#endif /* !RTLD_GLOBAL */#ifndef LT_GLOBAL#  define LT_GLOBAL		0#endif /* !LT_GLOBAL *//* We may have to define LT_LAZY_OR_NOW in the command line if we   find out it does not work in some platform. */#ifndef LT_LAZY_OR_NOW#  ifdef RTLD_LAZY#    define LT_LAZY_OR_NOW	RTLD_LAZY#  else#    ifdef DL_LAZY#      define LT_LAZY_OR_NOW	DL_LAZY#    endif#  endif /* !RTLD_LAZY */#endif#ifndef LT_LAZY_OR_NOW#  ifdef RTLD_NOW#    define LT_LAZY_OR_NOW	RTLD_NOW#  else#    ifdef DL_NOW#      define LT_LAZY_OR_NOW	DL_NOW#    endif#  endif /* !RTLD_NOW */#endif#ifndef LT_LAZY_OR_NOW#  define LT_LAZY_OR_NOW	0#endif /* !LT_LAZY_OR_NOW */#if HAVE_DLERROR#  define DLERROR(arg)	dlerror ()#else#  define DLERROR(arg)	LT_DLSTRERROR (arg)#endifstatic lt_modulesys_dl_open (loader_data, filename)     lt_user_data loader_data;     const char *filename;{  lt_module   module   = dlopen (filename, LT_GLOBAL | LT_LAZY_OR_NOW);  if (!module)    {      LT_DLMUTEX_SETERROR (DLERROR (CANNOT_OPEN));    }  return module;}static intsys_dl_close (loader_data, module)     lt_user_data loader_data;     lt_module module;{  int errors = 0;  if (dlclose (module) != 0)    {      LT_DLMUTEX_SETERROR (DLERROR (CANNOT_CLOSE));      ++errors;    }  return errors;}static lt_ptrsys_dl_sym (loader_data, module, symbol)     lt_user_data loader_data;     lt_module module;     const char *symbol;{  lt_ptr address = dlsym (module, symbol);  if (!address)    {      LT_DLMUTEX_SETERROR (DLERROR (SYMBOL_NOT_FOUND));    }  return address;}static struct lt_user_dlloader sys_dl =  {#  ifdef NEED_USCORE    "_",#  else    0,#  endif    sys_dl_open, sys_dl_close, sys_dl_sym, 0, 0 };#endif /* HAVE_LIBDL *//* --- SHL_LOAD() INTERFACE LOADER --- */#if HAVE_SHL_LOAD/* dynamic linking with shl_load (HP-UX) (comments from gmodule) */#ifdef HAVE_DL_H#  include <dl.h>#endif/* some flags are missing on some systems, so we provide * harmless defaults. * * Mandatory: * BIND_IMMEDIATE  - Resolve symbol references when the library is loaded. * BIND_DEFERRED   - Delay code symbol resolution until actual reference. * * Optionally: * BIND_FIRST	   - Place the library at the head of the symbol search * 		     order. * BIND_NONFATAL   - The default BIND_IMMEDIATE behavior is to treat all * 		     unsatisfied symbols as fatal.  This flag allows * 		     binding of unsatisfied code symbols to be deferred * 		     until use. *		     [Perl: For certain libraries, like DCE, deferred *		     binding often causes run time problems. Adding *		     BIND_NONFATAL to BIND_IMMEDIATE still allows *		     unresolved references in situations like this.] * BIND_NOSTART	   - Do not call the initializer for the shared library *		     when the library is loaded, nor on a future call to *		     shl_unload(). * BIND_VERBOSE	   - Print verbose messages concerning possible *		     unsatisfied symbols. * * hp9000s700/hp9000s800: * BIND_RESTRICTED - Restrict symbols visible by the library to those *		     present at library load time. * DYNAMIC_PATH	   - Allow the loader to dynamically search for the *		     library specified by the path argument. */#ifndef	DYNAMIC_PATH#  define DYNAMIC_PATH		0#endif#ifndef	BIND_RESTRICTED#  define BIND_RESTRICTED	0#endif#define	LT_BIND_FLAGS	(BIND_IMMEDIATE | BIND_NONFATAL | DYNAMIC_PATH)static lt_modulesys_shl_open (loader_data, filename)     lt_user_data loader_data;     const char *filename;{  static shl_t self = (shl_t) 0;  lt_module module = shl_load (filename, LT_BIND_FLAGS, 0L);  /* Since searching for a symbol against a NULL module handle will also     look in everything else that was already loaded and exported with     the -E compiler flag, we always cache a handle saved before any     modules are loaded.  */  if (!self)    {      lt_ptr address;      shl_findsym (&self, "main", TYPE_UNDEFINED, &address);    }  if (!filename)    {      module = self;    }  else    {      module = shl_load (filename, LT_BIND_FLAGS, 0L);      if (!module)	{	  LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));	}    }  return module;}static intsys_shl_close (loader_data, module)     lt_user_data loader_data;     lt_module module;{  int errors = 0;  if (module && (shl_unload ((shl_t) (module)) != 0))    {      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));      ++errors;    }  return errors;}static lt_ptrsys_shl_sym (loader_data, module, symbol)     lt_user_data loader_data;     lt_module module;     const char *symbol;{  lt_ptr address = 0;  /* sys_shl_open should never return a NULL module handle */  if (module == (lt_module) 0)  {    LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));  }  else if (!shl_findsym((shl_t*) &module, symbol, TYPE_UNDEFINED, &address))    {      if (!address)	{	  LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));	}    }  return address;}static struct lt_user_dlloader sys_shl = {  0, sys_shl_open, sys_shl_close, sys_shl_sym, 0, 0};#endif /* HAVE_SHL_LOAD *//* --- LOADLIBRARY() INTERFACE LOADER --- */#ifdef __WINDOWS__/* dynamic linking for Win32 */#include <windows.h>/* Forward declaration; required to implement handle search below. */static lt_dlhandle handles;static lt_modulesys_wll_open (loader_data, filename)     lt_user_data loader_data;     const char *filename;{  lt_dlhandle	cur;  lt_module	module	   = 0;  const char   *errormsg   = 0;  char	       *searchname = 0;  char	       *ext;  char		self_name_buf[MAX_PATH];  if (!filename)    {      /* Get the name of main module */      *self_name_buf = 0;      GetModuleFileName (NULL, self_name_buf, sizeof (self_name_buf));      filename = ext = self_name_buf;    }  else    {      ext = strrchr (filename, '.');    }  if (ext)    {      /* FILENAME already has an extension. */      searchname = lt_estrdup (filename);    }  else

⌨️ 快捷键说明

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