X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Fsrec.c;h=1251a7e93c9c353382590203ec8315645c6fe2ea;hb=586d24ef34ba027bccb197f9ffc80ac7cd468b28;hp=5e020a20d3db08f80126231be578b7240fed8b9a;hpb=5e808126677845ec035cc169e41c909be3ec90f4;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/srec.c b/bfd/srec.c index 5e020a20d3..1251a7e93c 100644 --- a/bfd/srec.c +++ b/bfd/srec.c @@ -1,29 +1,32 @@ /* BFD back-end for s-record objects. - Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. + Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, + 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + Free Software Foundation, Inc. Written by Steve Chamberlain of Cygnus Support . -This file is part of BFD, the Binary File Descriptor library. + This file is part of BFD, the Binary File Descriptor library. -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ -/* -SUBSECTION + +/* SUBSECTION S-Record handling -DESCRIPTION - + DESCRIPTION + Ordinary S-Records cannot hold anything but addresses and data, so that's all that we implement. @@ -41,11 +44,11 @@ DESCRIPTION up and output them when it's time to close the bfd. An s record looks like: - -EXAMPLE + + EXAMPLE S
- -DESCRIPTION + + DESCRIPTION Where o length is the number of bytes following upto the checksum. Note that @@ -60,7 +63,7 @@ DESCRIPTION 7) four byte address termination record 8) three byte address termination record 9) two byte address termination record - + o address is the start address of the data following, or in the case of a termination record, the start address of the image @@ -70,11 +73,10 @@ DESCRIPTION is the sum of all the raw byte data in the record, from the length upwards, modulo 256 and subtracted from 255. - -SUBSECTION + SUBSECTION Symbol S-Record handling -DESCRIPTION + DESCRIPTION Some ICE equipment understands an addition to the standard S-Record format; symbols and their addresses can be sent before the data. @@ -86,7 +88,7 @@ DESCRIPTION so a short symbol table could look like: -EXAMPLE + EXAMPLE $$ flash.x $$ flash.c _port6 $0 @@ -97,547 +99,860 @@ EXAMPLE _end $8036 $$ -DESCRIPTION + DESCRIPTION We allow symbols to be anywhere in the data stream - the module names - are always ignored. - -*/ + are always ignored. */ -#include "bfd.h" #include "sysdep.h" +#include "bfd.h" #include "libbfd.h" +#include "libiberty.h" +#include "safe-ctype.h" -/* Macros for converting between hex and binary */ -static CONST char digs[] = "0123456789ABCDEF"; +/* Macros for converting between hex and binary. */ -static char hex_value[1 + (unsigned char) ~0]; +static const char digs[] = "0123456789ABCDEF"; -#define NOT_HEX 20 -#define NIBBLE(x) hex_value[(unsigned char)(x)] -#define HEX(buffer) ((NIBBLE((buffer)[0])<<4) + NIBBLE((buffer)[1])) +#define NIBBLE(x) hex_value(x) +#define HEX(buffer) ((NIBBLE ((buffer)[0])<<4) + NIBBLE ((buffer)[1])) #define TOHEX(d, x, ch) \ d[1] = digs[(x) & 0xf]; \ d[0] = digs[((x)>>4)&0xf]; \ ch += ((x) & 0xff); -#define ISHEX(x) (hex_value[(unsigned char)(x)] != NOT_HEX) - - - -static void -DEFUN_VOID (srec_init) -{ - unsigned int i; - static boolean inited = false; - - if (inited == false) - { +#define ISHEX(x) hex_p(x) - inited = true; +/* The maximum number of address+data+crc bytes on a line is FF. */ +#define MAXCHUNK 0xff - for (i = 0; i < sizeof (hex_value); i++) - { - hex_value[i] = NOT_HEX; - } +/* Default size for a CHUNK. */ +#define DEFAULT_CHUNK 16 - for (i = 0; i < 10; i++) - { - hex_value[i + '0'] = i; +/* The number of data bytes we actually fit onto a line on output. + This variable can be modified by objcopy's --srec-len parameter. + For a 0x75 byte record you should set --srec-len=0x70. */ +unsigned int Chunk = DEFAULT_CHUNK; - } - for (i = 0; i < 6; i++) - { - hex_value[i + 'a'] = i + 10; - hex_value[i + 'A'] = i + 10; - } - } -} - - -/* The maximum number of bytes on a line is FF */ -#define MAXCHUNK 0xff -/* The number of bytes we fit onto a line on output */ -#define CHUNK 21 +/* The type of srec output (free or forced to S3). + This variable can be modified by objcopy's --srec-forceS3 + parameter. */ +bfd_boolean S3Forced = FALSE; -/* We cannot output our srecords as we see them, we have to glue them - together, this is done in this structure : */ +/* When writing an S-record file, the S-records can not be output as + they are seen. This structure is used to hold them in memory. */ struct srec_data_list_struct { - unsigned char *data; + struct srec_data_list_struct *next; + bfd_byte *data; bfd_vma where; bfd_size_type size; - struct srec_data_list_struct *next; +}; +typedef struct srec_data_list_struct srec_data_list_type; + +/* When scanning the S-record file, a linked list of srec_symbol + structures is built to represent the symbol table (if there is + one). */ +struct srec_symbol +{ + struct srec_symbol *next; + const char *name; + bfd_vma val; }; -typedef struct srec_data_list_struct srec_data_list_type; +/* The S-record tdata information. */ typedef struct srec_data_struct { srec_data_list_type *head; + srec_data_list_type *tail; unsigned int type; - - int done_symbol_read; - int count; - asymbol *symbols; - char *strings; - int symbol_idx; - int string_size; - int string_idx; + struct srec_symbol *symbols; + struct srec_symbol *symtail; + asymbol *csymbols; } tdata_type; +/* Initialize by filling in the hex conversion array. */ -/* - called once per input S-Record, used to work out vma and size of data. - */ - -static bfd_vma low, high; - -/*ARGSUSED*/ static void -size_symbols (abfd, buf, len, val) - bfd *abfd; - char *buf; - int len; - int val; +srec_init (void) { - abfd->symcount++; - abfd->tdata.srec_data->string_size += len + 1; -} + static bfd_boolean inited = FALSE; -static void -fillup_symbols (abfd, buf, len, val) - bfd *abfd; - char *buf; - int len; - int val; -{ - if (!abfd->tdata.srec_data->done_symbol_read) + if (! inited) { - asymbol *p; - if (abfd->tdata.srec_data->symbols == 0) - { - abfd->tdata.srec_data->symbols = (asymbol *) bfd_alloc (abfd, abfd->symcount * sizeof (asymbol)); - abfd->tdata.srec_data->strings = (char *) bfd_alloc (abfd, abfd->tdata.srec_data->string_size); - if (!abfd->tdata.srec_data->symbols || !abfd->tdata.srec_data->strings) - { - bfd_set_error (bfd_error_no_memory); - abort (); /* FIXME */ - } - abfd->tdata.srec_data->symbol_idx = 0; - abfd->tdata.srec_data->string_idx = 0; - } - - p = abfd->tdata.srec_data->symbols + abfd->tdata.srec_data->symbol_idx++; - p->the_bfd = abfd; - p->name = abfd->tdata.srec_data->strings + abfd->tdata.srec_data->string_idx; - memcpy ((char *) (p->name), buf, len + 1); - abfd->tdata.srec_data->string_idx += len + 1; - p->value = val; - p->flags = BSF_EXPORT | BSF_GLOBAL; - p->section = &bfd_abs_section; - p->udata = 0; + inited = TRUE; + hex_init (); } } -/*ARGSUSED*/ -static void -DEFUN (size_srec, (abfd, section, address, raw, length), - bfd * abfd AND - asection * section AND - bfd_vma address AND - bfd_byte * raw AND - unsigned int length) + +/* Set up the S-record tdata information. */ + +static bfd_boolean +srec_mkobject (bfd *abfd) { - if (address < low) - low = address; - if (address + length > high) - high = address + length - 1; -} + tdata_type *tdata; + srec_init (); -/* - called once per input S-Record, copies data from input into bfd_alloc'd area - */ + tdata = (tdata_type *) bfd_alloc (abfd, sizeof (tdata_type)); + if (tdata == NULL) + return FALSE; -/*ARGSUSED*/ -static void -DEFUN (fillup, (abfd, section, address, raw, length), - bfd * abfd AND - asection * section AND - bfd_vma address AND - bfd_byte * raw AND - unsigned int length) -{ - unsigned int i; - bfd_byte *dst = - (bfd_byte *) (section->used_by_bfd) + address - section->vma; - /* length -1 because we don't read in the checksum */ - for (i = 0; i < length - 1; i++) - { - *dst = HEX (raw); - dst++; - raw += 2; - } + abfd->tdata.srec_data = tdata; + tdata->type = 1; + tdata->head = NULL; + tdata->tail = NULL; + tdata->symbols = NULL; + tdata->symtail = NULL; + tdata->csymbols = NULL; + + return TRUE; } -/* Pass over an S-Record file, calling one of the above functions on each - record. */ +/* Read a byte from an S record file. Set *ERRORPTR if an error + occurred. Return EOF on error or end of file. */ -static int -white (x) - char x; -{ - return (x == ' ' || x == '\t' || x == '\n' || x == '\r'); -} static int -skipwhite (src, abfd) - char *src; - bfd *abfd; +srec_get_byte (bfd *abfd, bfd_boolean *errorptr) { - int eof = 0; - while (white (*src) && !eof) + bfd_byte c; + + if (bfd_bread (&c, (bfd_size_type) 1, abfd) != 1) { - eof = (boolean) (bfd_read (src, 1, 1, abfd) != 1); + if (bfd_get_error () != bfd_error_file_truncated) + *errorptr = TRUE; + return EOF; } - return eof; + + return (int) (c & 0xff); } -static boolean -DEFUN (srec_mkobject, (abfd), - bfd * abfd) +/* Report a problem in an S record file. FIXME: This probably should + not call fprintf, but we really do need some mechanism for printing + error messages. */ + +static void +srec_bad_byte (bfd *abfd, + unsigned int lineno, + int c, + bfd_boolean error) { - if (abfd->tdata.srec_data == 0) + if (c == EOF) + { + if (! error) + bfd_set_error (bfd_error_file_truncated); + } + else { - tdata_type *tdata = (tdata_type *) bfd_alloc (abfd, sizeof (tdata_type)); - if (!tdata) + char buf[10]; + + if (! ISPRINT (c)) + sprintf (buf, "\\%03o", (unsigned int) c); + else { - bfd_set_error (bfd_error_no_memory); - return false; + buf[0] = c; + buf[1] = '\0'; } - abfd->tdata.srec_data = tdata; - tdata->type = 1; - tdata->head = (srec_data_list_type *) NULL; + (*_bfd_error_handler) + (_("%B:%d: Unexpected character `%s' in S-record file\n"), + abfd, lineno, buf); + bfd_set_error (bfd_error_bad_value); } - return true; - } -static void -pass_over (abfd, func, symbolfunc, section) - bfd *abfd; - void (*func) (); - void (*symbolfunc) (); - asection *section; +/* Add a new symbol found in an S-record file. */ + +static bfd_boolean +srec_new_symbol (bfd *abfd, const char *name, bfd_vma val) { - unsigned int bytes_on_line; - boolean eof = false; + struct srec_symbol *n; + + n = (struct srec_symbol *) bfd_alloc (abfd, sizeof (* n)); + if (n == NULL) + return FALSE; - srec_mkobject (abfd); - /* To the front of the file */ - bfd_seek (abfd, (file_ptr) 0, SEEK_SET); - while (eof == false) + n->name = name; + n->val = val; + + if (abfd->tdata.srec_data->symbols == NULL) + abfd->tdata.srec_data->symbols = n; + else + abfd->tdata.srec_data->symtail->next = n; + abfd->tdata.srec_data->symtail = n; + n->next = NULL; + + ++abfd->symcount; + + return TRUE; +} + +/* Read the S record file and turn it into sections. We create a new + section for each contiguous set of bytes. */ + +static bfd_boolean +srec_scan (bfd *abfd) +{ + int c; + unsigned int lineno = 1; + bfd_boolean error = FALSE; + bfd_byte *buf = NULL; + size_t bufsize = 0; + asection *sec = NULL; + char *symbuf = NULL; + + if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) + goto error_return; + + while ((c = srec_get_byte (abfd, &error)) != EOF) { - char buffer[MAXCHUNK]; - char *src = buffer; - char type; - bfd_vma address = 0; - - /* Find first 'S' or $ */ - eof = (boolean) (bfd_read (src, 1, 1, abfd) != 1); - switch (*src) + /* We only build sections from contiguous S-records, so if this + is not an S-record, then stop building a section. */ + if (c != 'S' && c != '\r' && c != '\n') + sec = NULL; + + switch (c) { default: - if (eof) - return; + srec_bad_byte (abfd, lineno, c, error); + goto error_return; + + case '\n': + ++lineno; + break; + + case '\r': break; case '$': - /* Inside a symbol definition - just ignore the module name */ - while (*src != '\n' && !eof) + /* Starting a module name, which we ignore. */ + while ((c = srec_get_byte (abfd, &error)) != '\n' + && c != EOF) + ; + if (c == EOF) { - eof = (boolean) (bfd_read (src, 1, 1, abfd) != 1); + srec_bad_byte (abfd, lineno, c, error); + goto error_return; } + + ++lineno; break; case ' ': - /* spaces - maybe just before a symbol */ - while (*src != '\n' && *src != '\r' && white (*src)) + do { - eof = skipwhite (src, abfd); + bfd_size_type alc; + char *p, *symname; + bfd_vma symval; + + /* Starting a symbol definition. */ + while ((c = srec_get_byte (abfd, &error)) != EOF + && (c == ' ' || c == '\t')) + ; + + if (c == '\n' || c == '\r') + break; + + if (c == EOF) + { + srec_bad_byte (abfd, lineno, c, error); + goto error_return; + } + + alc = 10; + symbuf = (char *) bfd_malloc (alc + 1); + if (symbuf == NULL) + goto error_return; + + p = symbuf; + + *p++ = c; + while ((c = srec_get_byte (abfd, &error)) != EOF + && ! ISSPACE (c)) + { + if ((bfd_size_type) (p - symbuf) >= alc) + { + char *n; + + alc *= 2; + n = (char *) bfd_realloc (symbuf, alc + 1); + if (n == NULL) + goto error_return; + p = n + (p - symbuf); + symbuf = n; + } + + *p++ = c; + } + + if (c == EOF) + { + srec_bad_byte (abfd, lineno, c, error); + goto error_return; + } + + *p++ = '\0'; + symname = (char *) bfd_alloc (abfd, (bfd_size_type) (p - symbuf)); + if (symname == NULL) + goto error_return; + strcpy (symname, symbuf); + free (symbuf); + symbuf = NULL; + + while ((c = srec_get_byte (abfd, &error)) != EOF + && (c == ' ' || c == '\t')) + ; + if (c == EOF) + { + srec_bad_byte (abfd, lineno, c, error); + goto error_return; + } + + /* Skip a dollar sign before the hex value. */ + if (c == '$') + { + 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 (c == EOF) + { + srec_bad_byte (abfd, lineno, c, error); + goto error_return; + } + } + + 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; + unsigned char check_sum; + + /* Starting an S-record. */ + + pos = bfd_tell (abfd) - 1; + + if (bfd_bread (hdr, (bfd_size_type) 3, abfd) != 3) + goto error_return; + if (! ISHEX (hdr[1]) || ! ISHEX (hdr[2])) { - int val = 0; - int slen = 0; - char symbol[MAXCHUNK]; + if (! ISHEX (hdr[1])) + c = hdr[1]; + else + c = hdr[2]; + srec_bad_byte (abfd, lineno, c, error); + goto error_return; + } + + check_sum = bytes = HEX (hdr + 1); + if (bytes * 2 > bufsize) + { + if (buf != NULL) + free (buf); + buf = (bfd_byte *) bfd_malloc ((bfd_size_type) bytes * 2); + if (buf == NULL) + goto error_return; + bufsize = bytes * 2; + } - /* get the symbol part */ - while (!eof && !white (*src) && slen < MAXCHUNK) + if (bfd_bread (buf, (bfd_size_type) 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': + check_sum += HEX (data); + address = HEX (data); + data += 2; + --bytes; + /* Fall through. */ + case '2': + check_sum += HEX (data); + address = (address << 8) | HEX (data); + data += 2; + --bytes; + /* Fall through. */ + case '1': + check_sum += HEX (data); + address = (address << 8) | HEX (data); + data += 2; + check_sum += HEX (data); + address = (address << 8) | HEX (data); + data += 2; + bytes -= 2; + + if (sec != NULL + && sec->vma + sec->size == address) { - symbol[slen++] = *src; - eof = (boolean) (bfd_read (src, 1, 1, abfd) != 1); + /* This data goes at the end of the section we are + currently building. */ + sec->size += bytes; } - symbol[slen] = 0; - eof = skipwhite (src, abfd); - /* skip the $ for the hex value */ - if (*src == '$') + else { - eof = (boolean) (bfd_read (src, 1, 1, abfd) != 1); + char secbuf[20]; + char *secname; + bfd_size_type amt; + flagword flags; + + sprintf (secbuf, ".sec%d", bfd_count_sections (abfd) + 1); + amt = strlen (secbuf) + 1; + secname = (char *) bfd_alloc (abfd, amt); + strcpy (secname, secbuf); + flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC; + sec = bfd_make_section_with_flags (abfd, secname, flags); + if (sec == NULL) + goto error_return; + sec->vma = address; + sec->lma = address; + sec->size = bytes; + sec->filepos = pos; } - /* Scan off the hex number */ - while (isxdigit (*src)) + while (bytes > 0) { - val *= 16; - if (isdigit (*src)) - val += *src - '0'; - else if (isupper (*src)) - { - val += *src - 'A' + 10; - } - else - { - val += *src - 'a' + 10; - } - eof = (boolean) (bfd_read (src, 1, 1, abfd) != 1); + check_sum += HEX (data); + data += 2; + bytes--; + } + check_sum = 255 - (check_sum & 0xff); + if (check_sum != HEX (data)) + { + (*_bfd_error_handler) + (_("%B:%d: Bad checksum in S-record file\n"), + abfd, lineno); + bfd_set_error (bfd_error_bad_value); + goto error_return; } - symbolfunc (abfd, symbol, slen, val); - } - } - break; - case 'S': - src++; - - /* Fetch the type and the length */ - bfd_read (src, 1, 3, abfd); - type = *src++; + break; + + case '7': + check_sum += HEX (data); + address = HEX (data); + data += 2; + /* Fall through. */ + case '8': + check_sum += HEX (data); + address = (address << 8) | HEX (data); + data += 2; + /* Fall through. */ + case '9': + check_sum += HEX (data); + address = (address << 8) | HEX (data); + data += 2; + check_sum += HEX (data); + address = (address << 8) | HEX (data); + data += 2; + + /* This is a termination record. */ + abfd->start_address = address; + + check_sum = 255 - (check_sum & 0xff); + if (check_sum != HEX (data)) + { + (*_bfd_error_handler) + (_("%B:%d: Bad checksum in S-record file\n"), + abfd, lineno); + bfd_set_error (bfd_error_bad_value); + goto error_return; + } - if (!ISHEX (src[0]) || !ISHEX (src[1])) - break; + if (buf != NULL) + free (buf); - bytes_on_line = HEX (src); + return TRUE; + } + } + break; + } + } - if (bytes_on_line > MAXCHUNK / 2) - break; - src += 2; + if (error) + goto error_return; - bfd_read (src, 1, bytes_on_line * 2, abfd); + if (buf != NULL) + free (buf); - switch (type) - { - case '0': - case '5': - /* Prologue - ignore */ - break; - case '3': - address = HEX (src); - src += 2; - bytes_on_line--; - - case '2': - address = HEX (src) | (address << 8); - src += 2; - bytes_on_line--; - case '1': - address = HEX (src) | (address << 8); - src += 2; - address = HEX (src) | (address << 8); - src += 2; - bytes_on_line -= 2; - func (abfd, section, address, src, bytes_on_line); - break; - default: - return; - } - } - } + return TRUE; + error_return: + if (symbuf != NULL) + free (symbuf); + if (buf != NULL) + free (buf); + return FALSE; } -static bfd_target * -object_p (abfd) - bfd *abfd; -{ - asection *section; - /* We create one section called .text for all the contents, - and allocate enough room for the entire file. */ - - section = bfd_make_section (abfd, ".text"); - section->_raw_size = 0; - section->vma = 0xffffffff; - low = 0xffffffff; - high = 0; - pass_over (abfd, size_srec, size_symbols, section); - section->_raw_size = high - low; - section->vma = low; - section->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC; - - if (abfd->symcount) - abfd->flags |= HAS_SYMS; - return abfd->xvec; -} +/* Check whether an existing file is an S-record file. */ -static bfd_target * -DEFUN (srec_object_p, (abfd), - bfd * abfd) +static const bfd_target * +srec_object_p (bfd *abfd) { - char b[4]; + void * tdata_save; + bfd_byte b[4]; srec_init (); - bfd_seek (abfd, (file_ptr) 0, SEEK_SET); - bfd_read (b, 1, 4, abfd); + if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 + || bfd_bread (b, (bfd_size_type) 4, abfd) != 4) + return NULL; if (b[0] != 'S' || !ISHEX (b[1]) || !ISHEX (b[2]) || !ISHEX (b[3])) - return (bfd_target *) NULL; + { + bfd_set_error (bfd_error_wrong_format); + return NULL; + } - /* We create one section called .text for all the contents, - and allocate enough room for the entire file. */ + tdata_save = abfd->tdata.any; + if (! srec_mkobject (abfd) || ! srec_scan (abfd)) + { + if (abfd->tdata.any != tdata_save && abfd->tdata.any != NULL) + bfd_release (abfd, abfd->tdata.any); + abfd->tdata.any = tdata_save; + return NULL; + } + + if (abfd->symcount > 0) + abfd->flags |= HAS_SYMS; - return object_p (abfd); + return abfd->xvec; } +/* Check whether an existing file is an S-record file with symbols. */ -static bfd_target * -DEFUN (symbolsrec_object_p, (abfd), - bfd * abfd) +static const bfd_target * +symbolsrec_object_p (bfd *abfd) { - char b[4]; + void * tdata_save; + char b[2]; srec_init (); - bfd_seek (abfd, (file_ptr) 0, SEEK_SET); - bfd_read (b, 1, 4, abfd); + if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 + || bfd_bread (b, (bfd_size_type) 2, abfd) != 2) + return NULL; if (b[0] != '$' || b[1] != '$') - return (bfd_target *) NULL; + { + bfd_set_error (bfd_error_wrong_format); + return NULL; + } + + tdata_save = abfd->tdata.any; + if (! srec_mkobject (abfd) || ! srec_scan (abfd)) + { + if (abfd->tdata.any != tdata_save && abfd->tdata.any != NULL) + bfd_release (abfd, abfd->tdata.any); + abfd->tdata.any = tdata_save; + return NULL; + } + + if (abfd->symcount > 0) + abfd->flags |= HAS_SYMS; - return object_p (abfd); + return abfd->xvec; } +/* Read in the contents of a section in an S-record file. */ -static boolean -DEFUN (srec_get_section_contents, (abfd, section, location, offset, count), - bfd * abfd AND - asection * section AND - PTR location AND - file_ptr offset AND - bfd_size_type count) +static bfd_boolean +srec_read_section (bfd *abfd, asection *section, bfd_byte *contents) { - if (section->used_by_bfd == (PTR) NULL) + int c; + bfd_size_type sofar = 0; + bfd_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) { - section->used_by_bfd = (PTR) bfd_alloc (abfd, section->_raw_size); - if (!section->used_by_bfd) + 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_bread (hdr, (bfd_size_type) 3, abfd) != 3) + goto error_return; + + BFD_ASSERT (ISHEX (hdr[1]) && ISHEX (hdr[2])); + + bytes = HEX (hdr + 1); + + if (bytes * 2 > bufsize) { - bfd_set_error (bfd_error_no_memory); - return false; + if (buf != NULL) + free (buf); + buf = (bfd_byte *) bfd_malloc ((bfd_size_type) bytes * 2); + if (buf == NULL) + goto error_return; + bufsize = bytes * 2; } - pass_over (abfd, fillup, fillup_symbols, section); + if (bfd_bread (buf, (bfd_size_type) bytes * 2, abfd) != bytes * 2) + goto error_return; + + address = 0; + data = buf; + switch (hdr[0]) + { + default: + BFD_ASSERT (sofar == section->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->size); + if (buf != NULL) + free (buf); + return TRUE; + } + + /* Don't consider checksum. */ + --bytes; + + while (bytes-- != 0) + { + contents[sofar] = HEX (data); + data += 2; + ++sofar; + } + + break; + } } - memcpy ((PTR) location, - (PTR) ((char *) (section->used_by_bfd) + offset), - count); - return true; -} + if (error) + goto error_return; + + BFD_ASSERT (sofar == section->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. */ -boolean -DEFUN (srec_set_arch_mach, (abfd, arch, machine), - bfd * abfd AND - enum bfd_architecture arch AND - unsigned long machine) +static bfd_boolean +srec_get_section_contents (bfd *abfd, + asection *section, + void * location, + file_ptr offset, + bfd_size_type count) { - return bfd_default_set_arch_mach (abfd, arch, machine); + if (count == 0) + return TRUE; + + if (offset + count < count + || offset + count > section->size) + { + bfd_set_error (bfd_error_invalid_operation); + return FALSE; + } + + if (section->used_by_bfd == NULL) + { + section->used_by_bfd = bfd_alloc (abfd, section->size); + if (section->used_by_bfd == NULL) + return FALSE; + + if (! srec_read_section (abfd, section, + (bfd_byte *) 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 bfd_boolean +srec_set_arch_mach (bfd *abfd, enum bfd_architecture arch, unsigned long mach) +{ + if (arch != bfd_arch_unknown) + return bfd_default_set_arch_mach (abfd, arch, mach); + + abfd->arch_info = & bfd_default_arch_struct; + return TRUE; +} -/* we have to save up all the Srecords for a splurge before output, - also remember */ +/* We have to save up all the Srecords for a splurge before output. */ -static boolean -DEFUN (srec_set_section_contents, (abfd, section, location, offset, bytes_to_do), - bfd * abfd AND - sec_ptr section AND - PTR location AND - file_ptr offset AND - bfd_size_type bytes_to_do) +static bfd_boolean +srec_set_section_contents (bfd *abfd, + sec_ptr section, + const void * location, + file_ptr offset, + bfd_size_type bytes_to_do) { tdata_type *tdata = abfd->tdata.srec_data; - srec_data_list_type *entry = (srec_data_list_type *) - bfd_alloc (abfd, sizeof (srec_data_list_type)); + srec_data_list_type *entry; - if (!entry) - { - bfd_set_error (bfd_error_no_memory); - return false; - } + entry = (srec_data_list_type *) bfd_alloc (abfd, sizeof (* entry)); + if (entry == NULL) + return FALSE; - if ((section->flags & SEC_ALLOC) + if (bytes_to_do + && (section->flags & SEC_ALLOC) && (section->flags & SEC_LOAD)) { - unsigned char *data = (unsigned char *) bfd_alloc (abfd, bytes_to_do); - if (!data) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - memcpy (data, location, bytes_to_do); + bfd_byte *data; + + data = (bfd_byte *) bfd_alloc (abfd, bytes_to_do); + if (data == NULL) + return FALSE; + memcpy ((void *) 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; - if ((section->lma + offset + bytes_to_do) <= 0xffff) - { + entry->data = data; + entry->where = section->lma + offset; + entry->size = bytes_to_do; - } - else if ((section->lma + offset + bytes_to_do) <= 0xffffff - && tdata->type < 2) + /* 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->type = 2; + tdata->tail->next = entry; + entry->next = NULL; + tdata->tail = entry; } else { - tdata->type = 3; + 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; } - - entry->data = data; - entry->where = section->lma + offset; - entry->size = bytes_to_do; - entry->next = tdata->head; - tdata->head = entry; } - return true; + return TRUE; } /* Write a record of type, of the supplied number of bytes. The supplied bytes and length don't have a checksum. That's worked out - here -*/ -static -void -DEFUN (srec_write_record, (abfd, type, address, data, end), - bfd * abfd AND - char type AND - bfd_vma address AND - CONST unsigned char *data AND - CONST unsigned char *end) - + here. */ + +static bfd_boolean +srec_write_record (bfd *abfd, + unsigned int type, + bfd_vma address, + const bfd_byte *data, + const bfd_byte *end) { - char buffer[MAXCHUNK]; - + char buffer[2 * MAXCHUNK + 6]; unsigned int check_sum = 0; - CONST unsigned char *src = data; + const bfd_byte *src = data; char *dst = buffer; char *length; - + bfd_size_type wrlen; *dst++ = 'S'; *dst++ = '0' + type; length = dst; - dst += 2; /* leave room for dst*/ + dst += 2; /* Leave room for dst. */ switch (type) { @@ -665,7 +980,7 @@ DEFUN (srec_write_record, (abfd, type, address, data, end), dst += 2; } - /* Fill in the length */ + /* Fill in the length. */ TOHEX (length, (dst - length) / 2, check_sum); check_sum &= 0xff; check_sum = 255 - check_sum; @@ -674,311 +989,309 @@ DEFUN (srec_write_record, (abfd, type, address, data, end), *dst++ = '\r'; *dst++ = '\n'; - bfd_write ((PTR) buffer, 1, dst - buffer, abfd); -} - + wrlen = dst - buffer; + return bfd_bwrite ((void *) buffer, wrlen, abfd) == wrlen; +} -static void -DEFUN (srec_write_header, (abfd), - bfd * abfd) +static bfd_boolean +srec_write_header (bfd *abfd) { - unsigned char buffer[MAXCHUNK]; - unsigned char *dst = buffer; - unsigned int i; + unsigned int len = strlen (abfd->filename); - /* I'll put an arbitary 40 char limit on header size */ - for (i = 0; i < 40 && abfd->filename[i]; i++) - { - *dst++ = abfd->filename[i]; - } - srec_write_record (abfd, 0, 0, buffer, dst); + /* I'll put an arbitrary 40 char limit on header size. */ + if (len > 40) + len = 40; + + return srec_write_record (abfd, 0, (bfd_vma) 0, + (bfd_byte *) abfd->filename, + (bfd_byte *) abfd->filename + len); } -static void -DEFUN (srec_write_section, (abfd, tdata, list), - bfd * abfd AND - tdata_type * tdata AND - srec_data_list_type * list) +static bfd_boolean +srec_write_section (bfd *abfd, + tdata_type *tdata, + srec_data_list_type *list) { - unsigned int bytes_written = 0; - unsigned char *location = list->data; - - while (bytes_written < list->size) + unsigned int octets_written = 0; + bfd_byte *location = list->data; + + /* Validate number of data bytes to write. The srec length byte + counts the address, data and crc bytes. S1 (tdata->type == 1) + records have two address bytes, S2 (tdata->type == 2) records + have three, and S3 (tdata->type == 3) records have four. + The total length can't exceed 255, and a zero data length will + spin for a long time. */ + if (Chunk == 0) + Chunk = 1; + else if (Chunk > MAXCHUNK - tdata->type - 2) + Chunk = MAXCHUNK - tdata->type - 2; + + while (octets_written < list->size) { bfd_vma address; + unsigned int octets_this_chunk = list->size - octets_written; - unsigned int bytes_this_chunk = list->size - bytes_written; - - if (bytes_this_chunk > CHUNK) - { - bytes_this_chunk = CHUNK; - } + if (octets_this_chunk > Chunk) + octets_this_chunk = Chunk; - address = list->where + bytes_written; + address = list->where + octets_written / bfd_octets_per_byte (abfd); - srec_write_record (abfd, - tdata->type, - address, - location, - location + bytes_this_chunk); + if (! srec_write_record (abfd, + tdata->type, + address, + location, + location + octets_this_chunk)) + return FALSE; - bytes_written += bytes_this_chunk; - location += bytes_this_chunk; + octets_written += octets_this_chunk; + location += octets_this_chunk; } + return TRUE; } -static void -DEFUN (srec_write_terminator, (abfd, tdata), - bfd * abfd AND - tdata_type * tdata) +static bfd_boolean +srec_write_terminator (bfd *abfd, tdata_type *tdata) { - unsigned char buffer[2]; - - srec_write_record (abfd, 10 - tdata->type, - abfd->start_address, buffer, buffer); + return srec_write_record (abfd, 10 - tdata->type, + abfd->start_address, NULL, NULL); } - - -static void -srec_write_symbols (abfd) - bfd *abfd; +static bfd_boolean +srec_write_symbols (bfd *abfd) { - char buffer[MAXCHUNK]; - /* Dump out the symbols of a bfd */ + /* Dump out the symbols of a bfd. */ int i; - int len = bfd_get_symcount (abfd); + int count = bfd_get_symcount (abfd); - if (len) + if (count) { + bfd_size_type len; asymbol **table = bfd_get_outsymbols (abfd); - sprintf (buffer, "$$ %s\r\n", abfd->filename); - bfd_write (buffer, strlen (buffer), 1, abfd); + len = strlen (abfd->filename); + if (bfd_bwrite ("$$ ", (bfd_size_type) 3, abfd) != 3 + || bfd_bwrite (abfd->filename, len, abfd) != len + || bfd_bwrite ("\r\n", (bfd_size_type) 2, abfd) != 2) + return FALSE; - for (i = 0; i < len; i++) + for (i = 0; i < count; i++) { asymbol *s = table[i]; -#if 0 - int len = strlen (s->name); - - /* If this symbol has a .[ocs] in it, it's probably a file name - and we'll output that as the module name */ - - if (len > 3 && s->name[len - 2] == '.') + if (! bfd_is_local_label (abfd, s) + && (s->flags & BSF_DEBUGGING) == 0) { - int l; - sprintf (buffer, "$$ %s\r\n", s->name); - l = strlen (buffer); - bfd_write (buffer, l, 1, abfd); - } - else -#endif - if (s->flags & (BSF_GLOBAL | BSF_LOCAL) - && (s->flags & BSF_DEBUGGING) == 0 - && s->name[0] != '.' - && s->name[0] != 't') - { - /* Just dump out non debug symbols */ - - int l; - char buf2[40], *p; - - sprintf_vma (buf2, - s->value + s->section->output_section->lma - + s->section->output_offset); - p = buf2; + /* Just dump out non debug symbols. */ + char buf[43], *p; + + len = strlen (s->name); + if (bfd_bwrite (" ", (bfd_size_type) 2, abfd) != 2 + || bfd_bwrite (s->name, len, abfd) != len) + return FALSE; + + sprintf_vma (buf + 2, (s->value + + s->section->output_section->lma + + s->section->output_offset)); + p = buf + 2; while (p[0] == '0' && p[1] != 0) p++; - sprintf (buffer, " %s $%s\r\n", s->name, p); - l = strlen (buffer); - bfd_write (buffer, l, 1, abfd); + len = strlen (p); + p[len] = '\r'; + p[len + 1] = '\n'; + *--p = '$'; + *--p = ' '; + len += 4; + if (bfd_bwrite (p, len, abfd) != len) + return FALSE; } } - sprintf (buffer, "$$ \r\n"); - bfd_write (buffer, strlen (buffer), 1, abfd); + if (bfd_bwrite ("$$ \r\n", (bfd_size_type) 5, abfd) != 5) + return FALSE; } + + return TRUE; } -static boolean -internal_srec_write_object_contents (abfd, symbols) - bfd *abfd; - int symbols; +static bfd_boolean +internal_srec_write_object_contents (bfd *abfd, int symbols) { tdata_type *tdata = abfd->tdata.srec_data; srec_data_list_type *list; if (symbols) - srec_write_symbols (abfd); + { + if (! srec_write_symbols (abfd)) + return FALSE; + } - srec_write_header (abfd); + if (! srec_write_header (abfd)) + return FALSE; - /* Now wander though all the sections provided and output them */ + /* Now wander though all the sections provided and output them. */ list = tdata->head; while (list != (srec_data_list_type *) NULL) { - srec_write_section (abfd, tdata, list); + if (! srec_write_section (abfd, tdata, list)) + return FALSE; list = list->next; } - srec_write_terminator (abfd, tdata); - return true; + return srec_write_terminator (abfd, tdata); } -static boolean -srec_write_object_contents (abfd) - bfd *abfd; +static bfd_boolean +srec_write_object_contents (bfd *abfd) { return internal_srec_write_object_contents (abfd, 0); } -static boolean -symbolsrec_write_object_contents (abfd) - bfd *abfd; +static bfd_boolean +symbolsrec_write_object_contents (bfd *abfd) { return internal_srec_write_object_contents (abfd, 1); } -/*ARGSUSED*/ static int -DEFUN (srec_sizeof_headers, (abfd, exec), - bfd * abfd AND - boolean exec) +srec_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED, + struct bfd_link_info *info ATTRIBUTE_UNUSED) { return 0; } -static asymbol * -DEFUN (srec_make_empty_symbol, (abfd), - bfd * abfd) -{ - asymbol *new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol)); - if (new) - new->the_bfd = abfd; - return new; -} +/* Return the amount of memory needed to read the symbol table. */ -static unsigned int -srec_get_symtab_upper_bound (abfd) - bfd *abfd; +static long +srec_get_symtab_upper_bound (bfd *abfd) { - /* Read in all the info */ - srec_get_section_contents (abfd, abfd->sections, 0, 0, 0); - return (bfd_get_symcount (abfd) + 1) * (sizeof (asymbol *)); + return (bfd_get_symcount (abfd) + 1) * sizeof (asymbol *); } -static unsigned int -DEFUN (srec_get_symtab, (abfd, alocation), - bfd * abfd AND - asymbol ** alocation) +/* Return the symbol table. */ + +static long +srec_canonicalize_symtab (bfd *abfd, asymbol **alocation) { - int lim = abfd->symcount; - int i; - for (i = 0; i < lim; i++) + bfd_size_type symcount = bfd_get_symcount (abfd); + asymbol *csymbols; + unsigned int i; + + csymbols = abfd->tdata.srec_data->csymbols; + if (csymbols == NULL && symcount != 0) { - alocation[i] = abfd->tdata.srec_data->symbols + i; + asymbol *c; + struct srec_symbol *s; + + csymbols = (asymbol *) bfd_alloc (abfd, symcount * sizeof (asymbol)); + if (csymbols == NULL) + return -1; + abfd->tdata.srec_data->csymbols = csymbols; + + for (s = abfd->tdata.srec_data->symbols, c = csymbols; + s != NULL; + s = s->next, ++c) + { + c->the_bfd = abfd; + c->name = s->name; + c->value = s->val; + c->flags = BSF_GLOBAL; + c->section = bfd_abs_section_ptr; + c->udata.p = NULL; + } } - alocation[i] = 0; - return lim; + + for (i = 0; i < symcount; i++) + *alocation++ = csymbols++; + *alocation = NULL; + + return symcount; } -/*ARGSUSED*/ -void -DEFUN (srec_get_symbol_info, (ignore_abfd, symbol, ret), - bfd * ignore_abfd AND - asymbol * symbol AND - symbol_info * ret) +static void +srec_get_symbol_info (bfd *ignore_abfd ATTRIBUTE_UNUSED, + asymbol *symbol, + symbol_info *ret) { bfd_symbol_info (symbol, ret); } -/*ARGSUSED*/ -void -DEFUN (srec_print_symbol, (ignore_abfd, afile, symbol, how), - bfd * ignore_abfd AND - PTR afile AND - asymbol * symbol AND - bfd_print_symbol_type how) +static void +srec_print_symbol (bfd *abfd, + void * afile, + asymbol *symbol, + bfd_print_symbol_type how) { FILE *file = (FILE *) afile; + switch (how) { case bfd_print_symbol_name: fprintf (file, "%s", symbol->name); break; default: - bfd_print_symbol_vandf ((PTR) file, symbol); + bfd_print_symbol_vandf (abfd, (void *) file, symbol); fprintf (file, " %-5s %s", symbol->section->name, symbol->name); - } } -#define FOO PROTO -#define srec_new_section_hook (FOO(boolean, (*), (bfd *, asection *)))bfd_true - -#define srec_get_reloc_upper_bound (FOO(unsigned int, (*),(bfd*, asection *)))bfd_false -#define srec_canonicalize_reloc (FOO(unsigned int, (*),(bfd*,asection *, arelent **, asymbol **))) bfd_0 - - - -#define srec_openr_next_archived_file (FOO(bfd *, (*), (bfd*,bfd*))) bfd_nullvoidptr -#define srec_find_nearest_line (FOO(boolean, (*),(bfd*,asection*,asymbol**,bfd_vma, CONST char**, CONST char**, unsigned int *))) bfd_false -#define srec_generic_stat_arch_elt (FOO(int, (*), (bfd *,struct stat *))) bfd_0 - - -#define srec_core_file_failing_command (char *(*)())(bfd_nullvoidptr) -#define srec_core_file_failing_signal (int (*)())bfd_0 -#define srec_core_file_matches_executable_p (FOO(boolean, (*),(bfd*, bfd*)))bfd_false -#define srec_slurp_armap bfd_true -#define srec_slurp_extended_name_table bfd_true -#define srec_truncate_arname (void (*)())bfd_nullvoidptr -#define srec_write_armap (FOO( boolean, (*),(bfd *, unsigned int, struct orl *, unsigned int, int))) bfd_nullvoidptr -#define srec_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr -#define srec_close_and_cleanup bfd_generic_close_and_cleanup -#define srec_bfd_debug_info_start bfd_void -#define srec_bfd_debug_info_end bfd_void -#define srec_bfd_debug_info_accumulate (FOO(void, (*), (bfd *, asection *))) bfd_void -#define srec_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents -#define srec_bfd_relax_section bfd_generic_relax_section -#define srec_bfd_reloc_type_lookup \ - ((CONST struct reloc_howto_struct *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr) -#define srec_bfd_make_debug_symbol \ - ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr) -#define srec_bfd_link_hash_table_create _bfd_generic_link_hash_table_create -#define srec_bfd_link_add_symbols _bfd_generic_link_add_symbols -#define srec_bfd_final_link _bfd_generic_final_link - -bfd_target srec_vec = +#define srec_close_and_cleanup _bfd_generic_close_and_cleanup +#define srec_bfd_free_cached_info _bfd_generic_bfd_free_cached_info +#define srec_new_section_hook _bfd_generic_new_section_hook +#define srec_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false) +#define srec_bfd_is_local_label_name bfd_generic_is_local_label_name +#define srec_get_lineno _bfd_nosymbols_get_lineno +#define srec_find_nearest_line _bfd_nosymbols_find_nearest_line +#define srec_find_inliner_info _bfd_nosymbols_find_inliner_info +#define srec_make_empty_symbol _bfd_generic_make_empty_symbol +#define srec_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol +#define srec_read_minisymbols _bfd_generic_read_minisymbols +#define srec_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol +#define srec_get_section_contents_in_window _bfd_generic_get_section_contents_in_window +#define srec_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents +#define srec_bfd_relax_section bfd_generic_relax_section +#define srec_bfd_gc_sections bfd_generic_gc_sections +#define srec_bfd_merge_sections bfd_generic_merge_sections +#define srec_bfd_is_group_section bfd_generic_is_group_section +#define srec_bfd_discard_group bfd_generic_discard_group +#define srec_section_already_linked _bfd_generic_section_already_linked +#define srec_bfd_define_common_symbol bfd_generic_define_common_symbol +#define srec_bfd_link_hash_table_create _bfd_generic_link_hash_table_create +#define srec_bfd_link_hash_table_free _bfd_generic_link_hash_table_free +#define srec_bfd_link_add_symbols _bfd_generic_link_add_symbols +#define srec_bfd_link_just_syms _bfd_generic_link_just_syms +#define srec_bfd_copy_link_hash_symbol_type \ + _bfd_generic_copy_link_hash_symbol_type +#define srec_bfd_final_link _bfd_generic_final_link +#define srec_bfd_link_split_section _bfd_generic_link_split_section + +const bfd_target srec_vec = { - "srec", /* name */ + "srec", /* Name. */ bfd_target_srec_flavour, - true, /* target byte order */ - true, /* target headers byte order */ - (HAS_RELOC | EXEC_P | /* object flags */ + BFD_ENDIAN_UNKNOWN, /* Target byte order. */ + BFD_ENDIAN_UNKNOWN, /* Target headers byte order. */ + (HAS_RELOC | EXEC_P | /* Object flags. */ HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS - | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* leading underscore */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - 1, /* minimum alignment */ + | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* Section flags. */ + 0, /* Leading underscore. */ + ' ', /* AR_pad_char. */ + 16, /* AR_max_namelen. */ bfd_getb64, bfd_getb_signed_64, bfd_putb64, bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ + bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Data. */ bfd_getb64, bfd_getb_signed_64, bfd_putb64, bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ + bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Hdrs. */ { _bfd_dummy_target, - srec_object_p, /* bfd_check_format */ - (struct bfd_target * (*)()) bfd_nullvoidptr, - (struct bfd_target * (*)()) bfd_nullvoidptr, + srec_object_p, /* bfd_check_format. */ + _bfd_dummy_target, + _bfd_dummy_target, }, { bfd_false, @@ -986,44 +1299,54 @@ bfd_target srec_vec = _bfd_generic_mkarchive, bfd_false, }, - { /* bfd_write_contents */ + { /* bfd_write_contents. */ bfd_false, srec_write_object_contents, _bfd_write_archive_contents, bfd_false, }, - JUMP_TABLE (srec) -}; + BFD_JUMP_TABLE_GENERIC (srec), + BFD_JUMP_TABLE_COPY (_bfd_generic), + BFD_JUMP_TABLE_CORE (_bfd_nocore), + BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), + BFD_JUMP_TABLE_SYMBOLS (srec), + BFD_JUMP_TABLE_RELOCS (_bfd_norelocs), + BFD_JUMP_TABLE_WRITE (srec), + BFD_JUMP_TABLE_LINK (srec), + BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), + NULL, -bfd_target symbolsrec_vec = + NULL +}; + +const bfd_target symbolsrec_vec = { - "symbolsrec", /* name */ + "symbolsrec", /* Name. */ bfd_target_srec_flavour, - true, /* target byte order */ - true, /* target headers byte order */ - (HAS_RELOC | EXEC_P | /* object flags */ + BFD_ENDIAN_UNKNOWN, /* Target byte order. */ + BFD_ENDIAN_UNKNOWN, /* Target headers byte order. */ + (HAS_RELOC | EXEC_P | /* Object flags. */ HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS - | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* leading underscore */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - 1, /* minimum alignment */ + | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* Section flags. */ + 0, /* Leading underscore. */ + ' ', /* AR_pad_char. */ + 16, /* AR_max_namelen. */ bfd_getb64, bfd_getb_signed_64, bfd_putb64, bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ + bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Data. */ bfd_getb64, bfd_getb_signed_64, bfd_putb64, bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ + bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Headers. */ { _bfd_dummy_target, - symbolsrec_object_p, /* bfd_check_format */ - (struct bfd_target * (*)()) bfd_nullvoidptr, - (struct bfd_target * (*)()) bfd_nullvoidptr, + symbolsrec_object_p, /* bfd_check_format. */ + _bfd_dummy_target, + _bfd_dummy_target, }, { bfd_false, @@ -1031,12 +1354,24 @@ bfd_target symbolsrec_vec = _bfd_generic_mkarchive, bfd_false, }, - { /* bfd_write_contents */ + { /* bfd_write_contents. */ bfd_false, symbolsrec_write_object_contents, _bfd_write_archive_contents, bfd_false, }, - JUMP_TABLE (srec), - (PTR) 0 + + BFD_JUMP_TABLE_GENERIC (srec), + BFD_JUMP_TABLE_COPY (_bfd_generic), + BFD_JUMP_TABLE_CORE (_bfd_nocore), + BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), + BFD_JUMP_TABLE_SYMBOLS (srec), + BFD_JUMP_TABLE_RELOCS (_bfd_norelocs), + BFD_JUMP_TABLE_WRITE (srec), + BFD_JUMP_TABLE_LINK (srec), + BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), + + NULL, + + NULL };