map->l_versyms = ((void *) map->l_addr + map->l_info[VERSTAG (DT_VERSYM)]->d_un.d_ptr);
_dl_check_map_versions (struct link_map *map, int verbose){  int result = 0;  const char *strtab;  /* Pointer to section with needed versions.  */  ElfW(Dyn) *dyn;  /* Pointer to dynamic section with definitions.  */  ElfW(Dyn) *def;  /* We need to find out which is the highest version index used    in a dependecy.  */  unsigned int ndx_high = 0;  /* If we don't have a string table, we must be ok.  */  if (map->l_info[DT_STRTAB] == NULL)    return 0;  strtab = (const char *) (map->l_addr + map->l_info[DT_STRTAB]->d_un.d_ptr);  dyn = map->l_info[VERSTAG (DT_VERNEED)];  def = map->l_info[VERSTAG (DT_VERDEF)];  if (dyn != NULL)    {      /* This file requires special versions from its dependencies.  */      ElfW(Verneed) *ent = (ElfW(Verneed) *) (map->l_addr + dyn->d_un.d_ptr);      /* Currently the version number of the needed entry is 1.	 Make sure all we see is this version.  */      if (ent->vn_version  != 1)	{	  char buf[20];	  buf[sizeof (buf) - 1] = '\0';	  _dl_signal_error (0, (*map->l_name ? map->l_name : _dl_argv[0]),			    make_string ("unsupported version ",					 _itoa_word (ent->vn_version,						     &buf[sizeof (buf) - 1],						     10, 0),					 " of Verneed record\n"));	  return 1;	}      while (1)	{	  ElfW(Vernaux) *aux;	  struct link_map *needed = find_needed (strtab + ent->vn_file, map);	  /* If NEEDED is NULL this means a dependency was not found	     and no stub entry was created.  This should never happen.  */	  assert (needed != NULL);	  /* NEEDED is the map for the file we need.  Now look for the	     dependency symbols.  */	  aux = (ElfW(Vernaux) *) ((char *) ent + ent->vn_aux);	  while (1)	    {	      /* Match the symbol.  */	      result |= match_symbol ((*map->l_name				       ? map->l_name : _dl_argv[0]),				      aux->vna_hash,				      strtab + aux->vna_name,				      needed, verbose,				      aux->vna_flags & VER_FLG_WEAK);	      /* Compare the version index.  */	      if ((unsigned int) (aux->vna_other & 0x7fff) > ndx_high)		ndx_high = aux->vna_other & 0x7fff;	      if (aux->vna_next == 0)		/* No more symbols.  */		break;	      /* Next symbol.  */	      aux = (ElfW(Vernaux) *) ((char *) aux + aux->vna_next);	    }	  if (ent->vn_next == 0)	    /* No more dependencies.  */	    break;	  /* Next dependency.  */	  ent = (ElfW(Verneed) *) ((char *) ent + ent->vn_next);	}    }  /* We also must store the names of the defined versions.  Determine     the maximum index here as well.     XXX We could avoid the loop by just taking the number of definitions     as an upper bound of new indeces.  */  if (def != NULL)    {      ElfW(Verdef) *ent;      ent = (ElfW(Verdef) *) (map->l_addr + def->d_un.d_ptr);      while (1)	{	  if ((unsigned int) (ent->vd_ndx & 0x7fff) > ndx_high)	    ndx_high = ent->vd_ndx & 0x7fff;	  if (ent->vd_next == 0)	    /* No more definitions.  */	    break;	  ent = (ElfW(Verdef) *) ((char *) ent + ent->vd_next);	}    }  if (ndx_high > 0)    {      /* Now we are ready to build the array with the version names	 which can be indexed by the version index in the VERSYM	 section.  */      map->l_versions = (struct r_found_version *)	calloc (ndx_high + 1, sizeof (*map->l_versions));      if (map->l_versions == NULL)	{	  _dl_signal_error (ENOMEM, (*map->l_name ? map->l_name : _dl_argv[0]),			    "cannot allocate version reference table");	  result = 1;	}      else	{	  /* Store the number of available symbols.  */	  map->l_nversions = ndx_high + 1;	  if (dyn != NULL)	    {	      ElfW(Verneed) *ent;	      ent = (ElfW(Verneed) *) (map->l_addr + dyn->d_un.d_ptr);	      while (1)		{		  ElfW(Vernaux) *aux;		  aux = (ElfW(Vernaux) *) ((char *) ent + ent->vn_aux);		  while (1)		    {		      ElfW(Half) ndx = aux->vna_other & 0x7fff;		      map->l_versions[ndx].hash = aux->vna_hash;		      map->l_versions[ndx].hidden = aux->vna_other & 0x8000;		      map->l_versions[ndx].name = &strtab[aux->vna_name];		      map->l_versions[ndx].filename = &strtab[ent->vn_file];		      if (aux->vna_next == 0)			/* No more symbols.  */			break;		      /* Advance to next symbol.  */		      aux = (ElfW(Vernaux) *) ((char *) aux + aux->vna_next);		    }		  if (ent->vn_next == 0)		    /* No more dependencies.  */		    break;		  /* Advance to next dependency.  */		  ent = (ElfW(Verneed) *) ((char *) ent + ent->vn_next);		}	    }	  /* And insert the defined versions.  */	  if (def != NULL)	    {	      ElfW(Verdef) *ent;	      ent = (ElfW(Verdef)  *) (map->l_addr + def->d_un.d_ptr);	      while (1)		{		  ElfW(Verdaux) *aux;		  aux = (ElfW(Verdaux) *) ((char *) ent + ent->vd_aux);		  if ((ent->vd_flags & VER_FLG_BASE) == 0)		    {		      /* The name of the base version should not be			 available for matching a versioned symbol.  */		      ElfW(Half) ndx = ent->vd_ndx & 0x7fff;		      map->l_versions[ndx].hash = ent->vd_hash;		      map->l_versions[ndx].name = &strtab[aux->vda_name];		      map->l_versions[ndx].filename = NULL;		    }		  if (ent->vd_next == 0)		    /* No more definitions.  */		    break;		  ent = (ElfW(Verdef) *) ((char *) ent + ent->vd_next);		}	    }	}    }  return result;}