srec.c

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

C
1,379
字号
		{		  c = srec_get_byte (abfd, &error);		  if (c == EOF)		    {		      srec_bad_byte (abfd, lineno, c, error);		      goto error_return;		    }		}	      symval = 0;	      while (ISHEX (c))		{		  symval <<= 4;		  symval += NIBBLE (c);		  c = srec_get_byte (abfd, &error);		}	      if (! srec_new_symbol (abfd, symname, symval))		goto error_return;	    }	  while (c == ' ' || c == '\t')	    ;	  if (c == '\n')	    ++lineno;	  else if (c != '\r')	    {	      srec_bad_byte (abfd, lineno, c, error);	      goto error_return;	    }	  break;	case 'S':	  {	    file_ptr pos;	    char hdr[3];	    unsigned int bytes;	    bfd_vma address;	    bfd_byte *data;	    /* Starting an S-record.  */	    pos = bfd_tell (abfd) - 1;	    if (bfd_read (hdr, 1, 3, abfd) != 3)	      goto error_return;	    if (! ISHEX (hdr[1]) || ! ISHEX (hdr[2]))	      {		if (! ISHEX (hdr[1]))		  c = hdr[1];		else		  c = hdr[2];		srec_bad_byte (abfd, lineno, c, error);		goto error_return;	      }	    bytes = HEX (hdr + 1);	    if (bytes * 2 > bufsize)	      {		if (buf != NULL)		  free (buf);		buf = (bfd_byte *) bfd_malloc (bytes * 2);		if (buf == NULL)		  goto error_return;		bufsize = bytes * 2;	      }	    if (bfd_read (buf, 1, bytes * 2, abfd) != bytes * 2)	      goto error_return;	    /* Ignore the checksum byte.  */	    --bytes;	    address = 0;	    data = buf;	    switch (hdr[0])	      {	      case '0':	      case '5':		/* Prologue--ignore the file name, but stop building a                   section at this point.  */		sec = NULL;		break;	      case '3':		address = HEX (data);		data += 2;		--bytes;		/* Fall through.  */	      case '2':		address = (address << 8) | HEX (data);		data += 2;		--bytes;		/* Fall through.  */	      case '1':		address = (address << 8) | HEX (data);		data += 2;		address = (address << 8) | HEX (data);		data += 2;		bytes -= 2;		if (sec != NULL		    && sec->vma + sec->_raw_size == address)		  {		    /* This data goes at the end of the section we are                       currently building.  */		    sec->_raw_size += bytes;		  }		else		  {		    char secbuf[20];		    char *secname;		    sprintf (secbuf, ".sec%d", bfd_count_sections (abfd) + 1);		    secname = (char *) bfd_alloc (abfd, strlen (secbuf) + 1);		    strcpy (secname, secbuf);		    sec = bfd_make_section (abfd, secname);		    if (sec == NULL)		      goto error_return;		    sec->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC;		    sec->vma = address;		    sec->lma = address;		    sec->_raw_size = bytes;		    sec->filepos = pos;		  }		break;	      case '7':		address = HEX (data);		data += 2;		/* Fall through.  */	      case '8':		address = (address << 8) | HEX (data);		data += 2;		/* Fall through.  */	      case '9':		address = (address << 8) | HEX (data);		data += 2;		address = (address << 8) | HEX (data);		data += 2;		/* This is a termination record.  */		abfd->start_address = address;		if (buf != NULL)		  free (buf);		return true;	      }	  }	  break;	}    }  if (error)    goto error_return;  if (buf != NULL)    free (buf);  return true; error_return:  if (symbuf != NULL)    free (symbuf);  if (buf != NULL)    free (buf);  return false;}/* Check whether an existing file is an S-record file.  */static const bfd_target *srec_object_p (abfd)     bfd *abfd;{  bfd_byte b[4];  srec_init ();  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0      || bfd_read (b, 1, 4, abfd) != 4)    return NULL;  if (b[0] != 'S' || !ISHEX (b[1]) || !ISHEX (b[2]) || !ISHEX (b[3]))    {      bfd_set_error (bfd_error_wrong_format);      return NULL;    }  if (! srec_mkobject (abfd)      || ! srec_scan (abfd))    return NULL;  if (abfd->symcount > 0)    abfd->flags |= HAS_SYMS;  return abfd->xvec;}/* Check whether an existing file is an S-record file with symbols.  */static const bfd_target *symbolsrec_object_p (abfd)     bfd *abfd;{  char b[2];  srec_init ();  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0      || bfd_read (b, 1, 2, abfd) != 2)    return NULL;  if (b[0] != '$' || b[1] != '$')    {      bfd_set_error (bfd_error_wrong_format);      return NULL;    }  if (! srec_mkobject (abfd)      || ! srec_scan (abfd))    return NULL;  if (abfd->symcount > 0)    abfd->flags |= HAS_SYMS;  return abfd->xvec;}/* Read in the contents of a section in an S-record file.  */static booleansrec_read_section (abfd, section, contents)     bfd *abfd;     asection *section;     bfd_byte *contents;{  int c;  bfd_size_type sofar = 0;  boolean error = false;  bfd_byte *buf = NULL;  size_t bufsize = 0;  if (bfd_seek (abfd, section->filepos, SEEK_SET) != 0)    goto error_return;  while ((c = srec_get_byte (abfd, &error)) != EOF)    {      bfd_byte hdr[3];      unsigned int bytes;      bfd_vma address;      bfd_byte *data;      if (c == '\r' || c == '\n')	continue;      /* This is called after srec_scan has already been called, so we         ought to know the exact format.  */      BFD_ASSERT (c == 'S');      if (bfd_read (hdr, 1, 3, abfd) != 3)	goto error_return;      BFD_ASSERT (ISHEX (hdr[1]) && ISHEX (hdr[2]));      bytes = HEX (hdr + 1);      if (bytes * 2 > bufsize)	{	  if (buf != NULL)	    free (buf);	  buf = (bfd_byte *) bfd_malloc (bytes * 2);	  if (buf == NULL)	    goto error_return;	  bufsize = bytes * 2;	}      if (bfd_read (buf, 1, bytes * 2, abfd) != bytes * 2)	goto error_return;      address = 0;      data = buf;      switch (hdr[0])	{	default:	  BFD_ASSERT (sofar == section->_raw_size);	  if (buf != NULL)	    free (buf);	  return true;	case '3':	  address = HEX (data);	  data += 2;	  --bytes;	  /* Fall through.  */	case '2':	  address = (address << 8) | HEX (data);	  data += 2;	  --bytes;	  /* Fall through.  */	case '1':	  address = (address << 8) | HEX (data);	  data += 2;	  address = (address << 8) | HEX (data);	  data += 2;	  bytes -= 2;	  if (address != section->vma + sofar)	    {	      /* We've come to the end of this section.  */	      BFD_ASSERT (sofar == section->_raw_size);	      if (buf != NULL)		free (buf);	      return true;	    }	  /* Don't consider checksum.  */	  --bytes;	  while (bytes-- != 0)	    {	      contents[sofar] = HEX (data);	      data += 2;	      ++sofar;	    }	  break;	}    }  if (error)    goto error_return;  BFD_ASSERT (sofar == section->_raw_size);  if (buf != NULL)    free (buf);  return true; error_return:  if (buf != NULL)    free (buf);  return false;}/* Get the contents of a section in an S-record file.  */static booleansrec_get_section_contents (abfd, section, location, offset, count)     bfd *abfd;     asection *section;     PTR location;     file_ptr offset;     bfd_size_type count;{  if (section->used_by_bfd == NULL)    {      section->used_by_bfd = bfd_alloc (abfd, section->_raw_size);      if (section->used_by_bfd == NULL	  && section->_raw_size != 0)	return false;      if (! srec_read_section (abfd, section, section->used_by_bfd))	return false;    }  memcpy (location, (bfd_byte *) section->used_by_bfd + offset,	  (size_t) count);  return true;}/* Set the architecture.  We accept an unknown architecture here.  */static booleansrec_set_arch_mach (abfd, arch, mach)     bfd *abfd;     enum bfd_architecture arch;     unsigned long mach;{  if (arch == bfd_arch_unknown)    {      abfd->arch_info = &bfd_default_arch_struct;      return true;    }  return bfd_default_set_arch_mach (abfd, arch, mach);}/* We have to save up all the Srecords for a splurge before output.  */static booleansrec_set_section_contents (abfd, section, location, offset, bytes_to_do)     bfd *abfd;     sec_ptr section;     PTR location;     file_ptr offset;     bfd_size_type bytes_to_do;{  tdata_type *tdata = abfd->tdata.srec_data;  register srec_data_list_type *entry;  entry = ((srec_data_list_type *)	   bfd_alloc (abfd, sizeof (srec_data_list_type)));  if (entry == NULL)    return false;  if (bytes_to_do      && (section->flags & SEC_ALLOC)      && (section->flags & SEC_LOAD))    {      bfd_byte *data = (bfd_byte *) bfd_alloc (abfd, bytes_to_do);      if (data == NULL)	return false;      memcpy ((PTR) data, location, (size_t) bytes_to_do);      /* Ff S3Forced is true then always select S3 records,	 regardless of the siez of the addresses.  */      if (S3Forced)	tdata->type = 3;      else if ((section->lma + offset + bytes_to_do - 1) <= 0xffff)	;  /* The default, S1, is OK.  */      else if ((section->lma + offset + bytes_to_do - 1) <= 0xffffff	       && tdata->type <= 2)	tdata->type = 2;      else	tdata->type = 3;      entry->data = data;      entry->where = section->lma + offset;      entry->size = bytes_to_do;      /* Sort the records by address.  Optimize for the common case of         adding a record to the end of the list.  */      if (tdata->tail != NULL	  && entry->where >= tdata->tail->where)	{	  tdata->tail->next = entry;	  entry->next = NULL;	  tdata->tail = entry;	}      else	{	  register srec_data_list_type **look;	  for (look = &tdata->head;	       *look != NULL && (*look)->where < entry->where;	       look = &(*look)->next)	    ;	  entry->next = *look;	  *look = entry;	  if (entry->next == NULL)	    tdata->tail = entry;	}    }  return true;

⌨️ 快捷键说明

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