archive.c

来自「基于4个mips核的noc设计」· C语言 代码 · 共 2,234 行 · 第 1/5 页

C
2,234
字号
	if (tmp->arch_header[0] == '/'	    && tmp->arch_header[1] == ' ')	  {	    ardata->first_file_filepos +=	      (tmp->parsed_size + sizeof (struct ar_hdr) + 1) & ~1;	  }	bfd_release (abfd, tmp);      }  }  return true;release_raw_armap:  bfd_release (abfd, (PTR) raw_armap);release_symdefs:  bfd_release (abfd, (PTR) (ardata)->symdefs);  return false;}/* This routine can handle either coff-style or bsd-style armaps.   Returns false on error, true otherwise */booleanbfd_slurp_armap (abfd)     bfd *abfd;{  char nextname[17];  int i = bfd_read ((PTR) nextname, 1, 16, abfd);  if (i == 0)    return true;  if (i != 16)    return false;  if (bfd_seek (abfd, (file_ptr) - 16, SEEK_CUR) != 0)    return false;  if (!strncmp (nextname, "__.SYMDEF       ", 16)      || !strncmp (nextname, "__.SYMDEF/      ", 16)) /* old Linux archives */    return do_slurp_bsd_armap (abfd);  else if (!strncmp (nextname, "/               ", 16))    return do_slurp_coff_armap (abfd);  else if (!strncmp (nextname, "/SYM64/         ", 16))    {      /* Irix 6 archive--must be recognized by code in elf64-mips.c.  */      bfd_set_error (bfd_error_wrong_format);      return false;    }  bfd_has_map (abfd) = false;  return true;}/* Returns false on error, true otherwise *//* flavor 2 of a bsd armap, similar to bfd_slurp_bsd_armap except the   header is in a slightly different order and the map name is '/'.   This flavour is used by hp300hpux.  */#define HPUX_SYMDEF_COUNT_SIZE 2booleanbfd_slurp_bsd_armap_f2 (abfd)     bfd *abfd;{  struct areltdata *mapdata;  char nextname[17];  unsigned int counter;  bfd_byte *raw_armap, *rbase;  struct artdata *ardata = bfd_ardata (abfd);  char *stringbase;  unsigned int stringsize;  carsym *set;  int i = bfd_read ((PTR) nextname, 1, 16, abfd);  if (i == 0)    return true;  if (i != 16)    return false;  /* The archive has at least 16 bytes in it.  */  if (bfd_seek (abfd, -16L, SEEK_CUR) != 0)    return false;  if (!strncmp (nextname, "__.SYMDEF       ", 16)      || !strncmp (nextname, "__.SYMDEF/      ", 16)) /* old Linux archives */    return do_slurp_bsd_armap (abfd);  if (strncmp (nextname, "/               ", 16))    {      bfd_has_map (abfd) = false;      return true;    }  mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd);  if (mapdata == NULL)    return false;  raw_armap = (bfd_byte *) bfd_zalloc (abfd, mapdata->parsed_size);  if (raw_armap == NULL)    {    byebye:      bfd_release (abfd, (PTR) mapdata);      return false;    }  if (bfd_read ((PTR) raw_armap, 1, mapdata->parsed_size, abfd) !=      mapdata->parsed_size)    {      if (bfd_get_error () != bfd_error_system_call)	bfd_set_error (bfd_error_malformed_archive);    byebyebye:      bfd_release (abfd, (PTR) raw_armap);      goto byebye;    }  ardata->symdef_count = bfd_h_get_16 (abfd, (PTR) raw_armap);  if (ardata->symdef_count * BSD_SYMDEF_SIZE      > mapdata->parsed_size - HPUX_SYMDEF_COUNT_SIZE)    {      /* Probably we're using the wrong byte ordering.  */      bfd_set_error (bfd_error_wrong_format);      goto byebyebye;    }  ardata->cache = 0;  stringsize = bfd_h_get_32 (abfd, raw_armap + HPUX_SYMDEF_COUNT_SIZE);  /* Skip sym count and string sz.  */  stringbase = ((char *) raw_armap		+ HPUX_SYMDEF_COUNT_SIZE		+ BSD_STRING_COUNT_SIZE);  rbase = (bfd_byte *) stringbase + stringsize;  ardata->symdefs = (carsym *) bfd_alloc (abfd,					  (ardata->symdef_count					   * BSD_SYMDEF_SIZE));  if (!ardata->symdefs)    return false;  for (counter = 0, set = ardata->symdefs;       counter < ardata->symdef_count;       counter++, set++, rbase += BSD_SYMDEF_SIZE)    {      set->name = bfd_h_get_32 (abfd, rbase) + stringbase;      set->file_offset = bfd_h_get_32 (abfd, rbase + BSD_SYMDEF_OFFSET_SIZE);    }  ardata->first_file_filepos = bfd_tell (abfd);  /* Pad to an even boundary if you have to.  */  ardata->first_file_filepos += (ardata->first_file_filepos) % 2;  /* FIXME, we should provide some way to free raw_ardata when     we are done using the strings from it.  For now, it seems     to be allocated on an objalloc anyway...  */  bfd_has_map (abfd) = true;  return true;}/** Extended name table.  Normally archives support only 14-character filenames.  Intel has extended the format: longer names are stored in a special  element (the first in the archive, or second if there is an armap);  the name in the ar_hdr is replaced by <space><index into filename  element>.  Index is the P.R. of an int (decimal).  Data General have  extended the format by using the prefix // for the special element.  *//* Returns false on error, true otherwise.  */boolean_bfd_slurp_extended_name_table (abfd)     bfd *abfd;{  char nextname[17];  struct areltdata *namedata;  /* FIXME:  Formatting sucks here, and in case of failure of BFD_READ,     we probably don't want to return true.  */  bfd_seek (abfd, bfd_ardata (abfd)->first_file_filepos, SEEK_SET);  if (bfd_read ((PTR) nextname, 1, 16, abfd) == 16)    {      if (bfd_seek (abfd, (file_ptr) - 16, SEEK_CUR) != 0)	return false;      if (strncmp (nextname, "ARFILENAMES/    ", 16) != 0 &&	  strncmp (nextname, "//              ", 16) != 0)	{	  bfd_ardata (abfd)->extended_names = NULL;	  return true;	}      namedata = (struct areltdata *) _bfd_read_ar_hdr (abfd);      if (namedata == NULL)	return false;      bfd_ardata (abfd)->extended_names =	bfd_zalloc (abfd, namedata->parsed_size);      if (bfd_ardata (abfd)->extended_names == NULL)	{	byebye:	  bfd_release (abfd, (PTR) namedata);	  return false;	}      if (bfd_read ((PTR) bfd_ardata (abfd)->extended_names, 1,		    namedata->parsed_size, abfd) != namedata->parsed_size)	{	  if (bfd_get_error () != bfd_error_system_call)	    bfd_set_error (bfd_error_malformed_archive);	  bfd_release (abfd, (PTR) (bfd_ardata (abfd)->extended_names));	  bfd_ardata (abfd)->extended_names = NULL;	  goto byebye;	}      /* Since the archive is supposed to be printable if it contains	 text, the entries in the list are newline-padded, not null	 padded. In SVR4-style archives, the names also have a	 trailing '/'.  DOS/NT created archive often have \ in them	 We'll fix all problems here..  */      {	char *temp = bfd_ardata (abfd)->extended_names;	char *limit = temp + namedata->parsed_size;	for (; temp < limit; ++temp)	  {	    if (*temp == '\012')	      temp[temp[-1] == '/' ? -1 : 0] = '\0';	    if (*temp == '\\')	      *temp = '/';	  }      }      /* Pad to an even boundary if you have to.  */      bfd_ardata (abfd)->first_file_filepos = bfd_tell (abfd);      bfd_ardata (abfd)->first_file_filepos +=	(bfd_ardata (abfd)->first_file_filepos) % 2;      /* FIXME, we can't release namedata here because it was allocated	 below extended_names on the objalloc...  */#if 0      bfd_release (abfd, namedata);#endif    }  return true;}#ifdef VMS/* Return a copy of the stuff in the filename between any :]> and a   semicolon.  */static const char *normalize (abfd, file)     bfd *abfd;     const char *file;{  CONST char *first;  CONST char *last;  char *copy;  first = file + strlen (file) - 1;  last = first + 1;  while (first != file)    {      if (*first == ';')	last = first;      if (*first == ':' || *first == ']' || *first == '>')	{	  first++;	  break;	}      first--;    }  copy = (char *) bfd_alloc (abfd, last - first + 1);  if (copy == NULL)    return NULL;  memcpy (copy, first, last - first);  copy[last - first] = 0;  return copy;}#elsestatic const char *normalize (abfd, file)     bfd *abfd ATTRIBUTE_UNUSED;     const char *file;{  const char *filename = strrchr (file, '/');#ifdef HAVE_DOS_BASED_FILE_SYSTEM  {    /* We could have foo/bar\\baz, or foo\\bar, or d:bar.  */    char *bslash = strrchr (file, '\\');    if (filename == NULL || (bslash != NULL && bslash > filename))      filename = bslash;    if (filename == NULL && file[0] != '\0' && file[1] == ':')      filename = file + 1;  }#endif  if (filename != (char *) NULL)    filename++;  else    filename = file;  return filename;}#endif/* Build a BFD style extended name table.  */boolean_bfd_archive_bsd_construct_extended_name_table (abfd, tabloc, tablen, name)     bfd *abfd;     char **tabloc;     bfd_size_type *tablen;     const char **name;{  *name = "ARFILENAMES/";  return _bfd_construct_extended_name_table (abfd, false, tabloc, tablen);}/* Build an SVR4 style extended name table.  */boolean_bfd_archive_coff_construct_extended_name_table (abfd, tabloc, tablen, name)     bfd *abfd;     char **tabloc;     bfd_size_type *tablen;     const char **name;{  *name = "//";  return _bfd_construct_extended_name_table (abfd, true, tabloc, tablen);}/* Follows archive_head and produces an extended name table if   necessary.  Returns (in tabloc) a pointer to an extended name   table, and in tablen the length of the table.  If it makes an entry   it clobbers the filename so that the element may be written without   further massage.  Returns true if it ran successfully, false if   something went wrong.  A successful return may still involve a   zero-length tablen!  */boolean_bfd_construct_extended_name_table (abfd, trailing_slash, tabloc, tablen)     bfd *abfd;     boolean trailing_slash;     char **tabloc;     bfd_size_type *tablen;{  unsigned int maxname = abfd->xvec->ar_max_namelen;  unsigned int total_namelen = 0;  bfd *current;  char *strptr;  *tablen = 0;  /* Figure out how long the table should be.  */  for (current = abfd->archive_head; current != NULL; current = current->next)    {      const char *normal;      unsigned int thislen;      normal = normalize (current, current->filename);      if (normal == NULL)	return false;      thislen = strlen (normal);      if (thislen > maxname	  && (bfd_get_file_flags (abfd) & BFD_TRADITIONAL_FORMAT) != 0)	thislen = maxname;      if (thislen > maxname)	{	  /* Add one to leave room for \n.  */	  total_namelen += thislen + 1;	  if (trailing_slash)	    {	      /* Leave room for trailing slash.  */	      ++total_namelen;	    }	}      else	{	  struct ar_hdr *hdr = arch_hdr (current);	  if (strncmp (normal, hdr->ar_name, thislen) != 0	      || (thislen < sizeof hdr->ar_name		  && hdr->ar_name[thislen] != ar_padchar (current)))	    {	      /* Must have been using extended format even though it	         didn't need to.  Fix it to use normal format.  */	      memcpy (hdr->ar_name, normal, thislen);	      if (thislen < maxname		  || (thislen == maxname && thislen < sizeof hdr->ar_name))		hdr->ar_name[thislen] = ar_padchar (current);	    }	}    }  if (total_namelen == 0)    return true;  *tabloc = bfd_zalloc (abfd, total_namelen);  if (*tabloc == NULL)    return false;  *tablen = total_namelen;  strptr = *tabloc;  for (current = abfd->archive_head; current != NULL; current =       current->next)    {      const char *normal;      unsigned int thislen;      normal = normalize (current, current->filename);      if (normal == NULL)	return false;      thislen = strlen (normal);      if (thislen > maxname)	{	  /* Works for now; may need to be re-engineered if we	     encounter an oddball archive format and want to	     generalise this hack.  */	  struct ar_hdr *hdr = arch_hdr (current);	  strcpy (strptr, normal);	  if (! trailing_slash)	    strptr[thislen] = '\012';	  else	    {	      strptr[thislen] = '/';	      strptr[thislen + 1] = '\012';	    }	  hdr->ar_name[0] = ar_padchar (current);	  /* We know there will always be enough room (one of the few	     cases where you may safely use sprintf).  */	  sprintf ((hdr->ar_name) + 1, "%-d", (unsigned) (strptr - *tabloc));	  /* Kinda Kludgy.  We should just use the returned value of	     sprintf but not all implementations get this right.  */	  {	    char *temp = hdr->ar_name + 2;	    for (; temp < hdr->ar_name + maxname; temp++)	      if (*temp == '\0')		*temp = ' ';

⌨️ 快捷键说明

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