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

📄 dl-deps.c

📁 Newlib 嵌入式 C库 标准实现代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Load the dependencies of a mapped object.   Copyright (C) 1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc.   This file is part of the GNU C Library.   The GNU C Library is free software; you can redistribute it and/or   modify it under the terms of the GNU Lesser General Public   License as published by the Free Software Foundation; either   version 2.1 of the License, or (at your option) any later version.   The GNU C Library is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   Lesser General Public License for more details.   You should have received a copy of the GNU Lesser General Public   License along with the GNU C Library; if not, write to the Free   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA   02111-1307 USA.  */#include <assert.h>#include <dlfcn.h>#include <errno.h>#include <libintl.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/param.h>#include <ldsodefs.h>#include <dl-dst.h>/* Whether an shared object references one or more auxiliary objects   is signaled by the AUXTAG entry in l_info.  */#define AUXTAG	(DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \		 + DT_EXTRATAGIDX (DT_AUXILIARY))/* Whether an shared object references one or more auxiliary objects   is signaled by the AUXTAG entry in l_info.  */#define FILTERTAG (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \		   + DT_EXTRATAGIDX (DT_FILTER))/* This is zero at program start to signal that the global scope map is   allocated by rtld.  Later it keeps the size of the map.  It might be   reset if in _dl_close if the last global object is removed.  */size_t _dl_global_scope_alloc;extern size_t _dl_platformlen;/* When loading auxiliary objects we must ignore errors.  It's ok if   an object is missing.  */struct openaux_args  {    /* The arguments to openaux.  */    struct link_map *map;    int trace_mode;    const char *strtab;    const char *name;    /* The return value of openaux.  */    struct link_map *aux;  };static voidopenaux (void *a){  struct openaux_args *args = (struct openaux_args *) a;  args->aux = _dl_map_object (args->map, args->name, 0,			      (args->map->l_type == lt_executable			       ? lt_library : args->map->l_type),			      args->trace_mode, 0);}/* We use a very special kind of list to track the path   through the list of loaded shared objects.  We have to   produce a flat list with unique members of all involved objects.*/struct list  {    int done;			/* Nonzero if this map was processed.  */    struct link_map *map;	/* The data.  */    struct list *next;	/* Elements for normal list.  */  };/* Macro to expand DST.  It is an macro since we use `alloca'.  */#define expand_dst(l, str, fatal) \  ({									      \    const char *__str = (str);						      \    const char *__result = __str;					      \    size_t __cnt = DL_DST_COUNT(__str, 0);				      \									      \    if (__cnt != 0)							      \      {									      \	char *__newp;							      \									      \	__newp = (char *) alloca (DL_DST_REQUIRED (l, __str, strlen (__str),  \						   __cnt));		      \									      \	__result = DL_DST_SUBSTITUTE (l, __str, __newp, 0);		      \									      \	if (*__result == '\0')						      \	  {								      \	    /* The replacement for the DST is not known.  We can't	      \	       processed.  */						      \	    if (fatal)							      \	      _dl_signal_error (0, __str, NULL, N_("\empty dynamics string token substitution"));				      \	    else							      \	      {								      \		/* This is for DT_AUXILIARY.  */			      \		if (__builtin_expect (_dl_debug_mask & DL_DEBUG_LIBS, 0))     \		  _dl_debug_printf ("cannot load auxiliary `%s' because of"   \				    "empty dynamic string token "	      \				    "substitution\n", __str);		      \		continue;						      \	      }								      \	  }								      \      }									      \									      \    __result; })voidinternal_function_dl_map_object_deps (struct link_map *map,		     struct link_map **preloads, unsigned int npreloads,		     int trace_mode){  struct list known[1 + npreloads + 1];  struct list *runp, *tail;  unsigned int nlist, i;  /* Object name.  */  const char *name;  int errno_saved;  int errno_reason;  const char *errstring;  const char *objname;  auto inline void preload (struct link_map *map);  inline void preload (struct link_map *map)    {      known[nlist].done = 0;      known[nlist].map = map;      known[nlist].next = &known[nlist + 1];      ++nlist;      /* We use `l_reserved' as a mark bit to detect objects we have	 already put in the search list and avoid adding duplicate	 elements later in the list.  */      map->l_reserved = 1;    }  /* No loaded object so far.  */  nlist = 0;  /* First load MAP itself.  */  preload (map);  /* Add the preloaded items after MAP but before any of its dependencies.  */  for (i = 0; i < npreloads; ++i)    preload (preloads[i]);  /* Terminate the lists.  */  known[nlist - 1].next = NULL;  /* Pointer to last unique object.  */  tail = &known[nlist - 1];  /* Process each element of the search list, loading each of its     auxiliary objects and immediate dependencies.  Auxiliary objects     will be added in the list before the object itself and     dependencies will be appended to the list as we step through it.     This produces a flat, ordered list that represents a     breadth-first search of the dependency tree.     The whole process is complicated by the fact that we better     should use alloca for the temporary list elements.  But using     alloca means we cannot use recursive function calls.  */  errno_saved = errno;  errno_reason = 0;  errstring = NULL;  errno = 0;  name = NULL;  for (runp = known; runp; )    {      struct link_map *l = runp->map;      struct link_map **needed = NULL;      unsigned int nneeded = 0;      /* Unless otherwise stated, this object is handled.  */      runp->done = 1;      /* Allocate a temporary record to contain the references to the	 dependencies of this object.  */      if (l->l_searchlist.r_list == NULL && l->l_initfini == NULL	  && l != map && l->l_ldnum > 0)	needed = (struct link_map **) alloca (l->l_ldnum					      * sizeof (struct link_map *));      if (l->l_info[DT_NEEDED] || l->l_info[AUXTAG] || l->l_info[FILTERTAG])	{	  const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]);	  struct openaux_args args;	  struct list *orig;	  const ElfW(Dyn) *d;	  args.strtab = strtab;	  args.map = l;	  args.trace_mode = trace_mode;	  orig = runp;	  for (d = l->l_ld; d->d_tag != DT_NULL; ++d)	    if (__builtin_expect (d->d_tag, DT_NEEDED) == DT_NEEDED)	      {		/* Map in the needed object.  */		struct link_map *dep;		int err;		/* Recognize DSTs.  */		name = expand_dst (l, strtab + d->d_un.d_val, 0);		/* Store the tag in the argument structure.  */		args.name = name;		err = _dl_catch_error (&objname, &errstring, openaux, &args);		if (__builtin_expect (errstring != NULL, 0))		  {		    if (err)		      errno_reason = err;		    else		      errno_reason = -1;		    goto out;		  }		else		  dep = args.aux;		if (! dep->l_reserved)		  {		    /* Allocate new entry.  */		    struct list *newp;		    newp = alloca (sizeof (struct list));		    /* Append DEP to the list.  */		    newp->map = dep;		    newp->done = 0;		    newp->next = NULL;		    tail->next = newp;		    tail = newp;		    ++nlist;		    /* Set the mark bit that says it's already in the list.  */		    dep->l_reserved = 1;		  }		/* Remember this dependency.  */		if (needed != NULL)		  needed[nneeded++] = dep;	      }	    else if (d->d_tag == DT_AUXILIARY || d->d_tag == DT_FILTER)	      {		struct list *newp;		/* Recognize DSTs.  */		name = expand_dst (l, strtab + d->d_un.d_val,				   d->d_tag == DT_AUXILIARY);		/* Store the tag in the argument structure.  */		args.name = name;		if (d->d_tag == DT_AUXILIARY)		  {		    int err;		    /* Say that we are about to load an auxiliary library.  */		    if (__builtin_expect (_dl_debug_mask & DL_DEBUG_LIBS, 0))		      _dl_debug_printf ("load auxiliary object=%s"					" requested by file=%s\n", name,					l->l_name[0]					? l->l_name : _dl_argv[0]);

⌨️ 快捷键说明

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