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

📄 dl-lookup.c

📁 用于嵌入式Linux系统的标准C的库函数
💻 C
📖 第 1 页 / 共 2 页
字号:
  if (! _dl_do_lookup (undef_name, hash, *ref, &current_value, *scope, i,		       skip_map, 0))    while (*++scope)      if (_dl_do_lookup (undef_name, hash, *ref, &current_value, *scope, 0,			 skip_map, 0))	break;  if (__builtin_expect (current_value.s == NULL, 0))    {      *ref = NULL;      return 0;    }  protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;  if (__builtin_expect (_dl_debug_mask & DL_DEBUG_BINDINGS, 0))    _dl_debug_printf ("binding file %s to %s: %s symbol `%s'\n",		       (reference_name && reference_name[0]			? reference_name : (_dl_argv[0] ?: "<main program>")),		       current_value.m->l_name[0]		       ? current_value.m->l_name : _dl_argv[0],		       protected ? "protected" : "normal", undef_name);  if (__builtin_expect (protected == 0, 1))    {      *ref = current_value.s;      return LOOKUP_VALUE (current_value.m);    }  else    {      /* It is very tricky.  We need to figure out what value to         return for the protected symbol.  */      struct sym_val protected_value = { NULL, NULL };      if (i >= (*scope)->r_nlist	  || !_dl_do_lookup (undef_name, hash, *ref, &protected_value, *scope,			     i, skip_map, ELF_RTYPE_CLASS_PLT))	while (*++scope)	  if (_dl_do_lookup (undef_name, hash, *ref, &protected_value, *scope,			     0, skip_map, ELF_RTYPE_CLASS_PLT))	    break;      if (protected_value.s == NULL || protected_value.m == undef_map)	{	  *ref = current_value.s;	  return LOOKUP_VALUE (current_value.m);	}      return LOOKUP_VALUE (undef_map);    }}/* This function works like _dl_lookup_symbol but it takes an   additional arguement with the version number of the requested   symbol.   XXX We'll see whether we need this separate function.  */lookup_tinternal_function_dl_lookup_versioned_symbol (const char *undef_name,			     struct link_map *undef_map, const ElfW(Sym) **ref,			     struct r_scope_elem *symbol_scope[],			     const struct r_found_version *version,			     int type_class, int explicit){  unsigned long int hash = _dl_elf_hash (undef_name);  struct sym_val current_value = { NULL, NULL };  struct r_scope_elem **scope;  int protected;  ++_dl_num_relocations;  /* Search the relevant loaded objects for a definition.  */  for (scope = symbol_scope; *scope; ++scope)    {      int res = do_lookup_versioned (undef_name, hash, *ref, &current_value,				     *scope, 0, version, NULL, type_class);      if (res > 0)	{	  /* We have to check whether this would bind UNDEF_MAP to an object	     in the global scope which was dynamically loaded.  In this case	     we have to prevent the latter from being unloaded unless the	     UNDEF_MAP object is also unloaded.  */	  if (__builtin_expect (current_value.m->l_type == lt_loaded, 0)	      /* Don't do this for explicit lookups as opposed to implicit		 runtime lookups.  */	      && ! explicit	      /* Add UNDEF_MAP to the dependencies.  */	      && add_dependency (undef_map, current_value.m) < 0)	    /* Something went wrong.  Perhaps the object we tried to reference	       was just removed.  Try finding another definition.  */	    return _dl_lookup_versioned_symbol (undef_name, undef_map, ref,						symbol_scope, version,						type_class, 0);	  break;	}      if (__builtin_expect (res, 0) < 0)	{	  /* Oh, oh.  The file named in the relocation entry does not	     contain the needed symbol.  */	  const char *reference_name = undef_map ? undef_map->l_name : NULL;	  /* XXX We cannot translate the message.  */	  _dl_signal_cerror (0, (reference_name && reference_name[0]				 ? reference_name				 : (_dl_argv[0] ?: "<main program>")),			     N_("relocation error"),			     make_string ("symbol ", undef_name, ", version ",					  version->name,					  " not defined in file ",					  version->filename,					  " with link time reference",					  res == -2					  ? " (no version symbols)" : ""));	  *ref = NULL;	  return 0;	}    }  if (__builtin_expect (current_value.s == NULL, 0))    {      if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)	{	  /* We could find no value for a strong reference.  */	  const char *reference_name = undef_map ? undef_map->l_name : NULL;	  /* XXX We cannot translate the message.  */	  _dl_signal_cerror (0, (reference_name && reference_name[0]				 ? reference_name				 : (_dl_argv[0] ?: "<main program>")), NULL,			     make_string (undefined_msg, undef_name,					  ", version ",					  version->name ?: NULL));	}      *ref = NULL;      return 0;    }  protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;  if (__builtin_expect (_dl_debug_mask & DL_DEBUG_BINDINGS, 0))    {      const char *reference_name = undef_map ? undef_map->l_name : NULL;      _dl_debug_printf ("binding file %s to %s: %s symbol `%s' [%s]\n",			(reference_name && reference_name[0]			 ? reference_name : (_dl_argv[0] ?: "<main program>")),			current_value.m->l_name[0]			? current_value.m->l_name : _dl_argv[0],			protected ? "protected" : "normal",			undef_name, version->name);    }  if (__builtin_expect (protected == 0, 1))    {      *ref = current_value.s;      return LOOKUP_VALUE (current_value.m);    }  else    {      /* It is very tricky. We need to figure out what value to         return for the protected symbol */      struct sym_val protected_value = { NULL, NULL };      for (scope = symbol_scope; *scope; ++scope)	if (_dl_do_lookup_versioned (undef_name, hash, *ref, &protected_value,				     *scope, 0, version, NULL,				     ELF_RTYPE_CLASS_PLT))	  break;      if (protected_value.s == NULL || protected_value.m == undef_map)	{	  *ref = current_value.s;	  return LOOKUP_VALUE (current_value.m);	}      return LOOKUP_VALUE (undef_map);    }}/* Similar to _dl_lookup_symbol_skip but takes an additional argument   with the version we are looking for.  */lookup_tinternal_function_dl_lookup_versioned_symbol_skip (const char *undef_name,				  struct link_map *undef_map,				  const ElfW(Sym) **ref,				  struct r_scope_elem *symbol_scope[],				  const struct r_found_version *version,				  struct link_map *skip_map){  const char *reference_name = undef_map ? undef_map->l_name : NULL;  const unsigned long int hash = _dl_elf_hash (undef_name);  struct sym_val current_value = { NULL, NULL };  struct r_scope_elem **scope;  size_t i;  int protected;  ++_dl_num_relocations;  /* Search the relevant loaded objects for a definition.  */  scope = symbol_scope;  for (i = 0; (*scope)->r_list[i] != skip_map; ++i)    assert (i < (*scope)->r_nlist);  if (! _dl_do_lookup_versioned (undef_name, hash, *ref, &current_value,				 *scope, i, version, skip_map, 0))    while (*++scope)      if (_dl_do_lookup_versioned (undef_name, hash, *ref, &current_value,				   *scope, 0, version, skip_map, 0))	break;  if (__builtin_expect (current_value.s == NULL, 0))    {      if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)	{	  /* We could find no value for a strong reference.  */	  const size_t len = strlen (undef_name);	  char buf[sizeof undefined_msg + len];          char *tmp;          tmp = memcpy (buf, undefined_msg, sizeof undefined_msg - 1);          tmp += (sizeof undefined_msg - 1);	  memcpy (tmp, undef_name, len + 1);	  /* XXX We cannot translate the messages.  */	  _dl_signal_cerror (0, (reference_name && reference_name[0]				 ? reference_name				 : (_dl_argv[0] ?: "<main program>")),			     NULL, buf);	}      *ref = NULL;      return 0;    }  protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;  if (__builtin_expect (_dl_debug_mask & DL_DEBUG_BINDINGS, 0))    _dl_debug_printf ("binding file %s to %s: %s symbol `%s' [%s]\n",		      (reference_name && reference_name[0]		       ? reference_name : (_dl_argv[0] ?: "<main program>")),		      current_value.m->l_name[0]		      ? current_value.m->l_name : _dl_argv[0],		      protected ? "protected" : "normal",		      undef_name, version->name);  if (__builtin_expect (protected == 0, 1))    {      *ref = current_value.s;      return LOOKUP_VALUE (current_value.m);    }  else    {      /* It is very tricky. We need to figure out what value to         return for the protected symbol */      struct sym_val protected_value = { NULL, NULL };      if (i >= (*scope)->r_nlist	  || !_dl_do_lookup_versioned (undef_name, hash, *ref,				       &protected_value, *scope, i, version,				       skip_map, ELF_RTYPE_CLASS_PLT))	while (*++scope)	  if (_dl_do_lookup_versioned (undef_name, hash, *ref,				       &protected_value, *scope, 0, version,				       skip_map, ELF_RTYPE_CLASS_PLT))	    break;      if (protected_value.s == NULL || protected_value.m == undef_map)	{	  *ref = current_value.s;	  return LOOKUP_VALUE (current_value.m);	}      return LOOKUP_VALUE (undef_map);    }}/* Cache the location of MAP's hash table.  */voidinternal_function_dl_setup_hash (struct link_map *map){  Elf_Symndx *hash;  Elf_Symndx nchain;  if (!map->l_info[DT_HASH])    return;  hash = (void *)(map->l_addr + map->l_info[DT_HASH]->d_un.d_ptr);  map->l_nbuckets = *hash++;  nchain = *hash++;  map->l_buckets = hash;  hash += map->l_nbuckets;  map->l_chain = hash;}/* These are here so that we only inline do_lookup{,_versioned} in the common   case, not everywhere.  */static intinternal_function_dl_do_lookup (const char *undef_name, unsigned long int hash,	       const ElfW(Sym) *ref, struct sym_val *result,	       struct r_scope_elem *scope, size_t i,	       struct link_map *skip, int type_class){  return do_lookup (undef_name, hash, ref, result, scope, i, skip,		    type_class);}static intinternal_function_dl_do_lookup_versioned (const char *undef_name, unsigned long int hash,			 const ElfW(Sym) *ref, struct sym_val *result,			 struct r_scope_elem *scope, size_t i,			 const struct r_found_version *const version,			 struct link_map *skip, int type_class){  return do_lookup_versioned (undef_name, hash, ref, result, scope, i,			      version, skip, type_class);}

⌨️ 快捷键说明

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