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 + -
显示快捷键?