/* BFD back-end for s-record objects.
- Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
+ Copyright (C) 1990-2014 Free Software Foundation, Inc.
Written by Steve Chamberlain of Cygnus Support <sac@cygnus.com>.
-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.
up and output them when it's time to close the bfd.
An s record looks like:
-
-EXAMPLE
+
+ EXAMPLE
S<type><length><address><data><checksum>
-
-DESCRIPTION
+
+ DESCRIPTION
Where
o length
is the number of bytes following upto the checksum. Note that
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
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.
so a short symbol table could look like:
-EXAMPLE
+ EXAMPLE
$$ flash.x
$$ flash.c
_port6 $0
_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[40];
+
+ 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;
+ unsigned char hdr[3];
+ unsigned int bytes, min_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);
+ min_bytes = 3;
+ if (hdr[0] == '2' || hdr[0] == '8')
+ min_bytes = 4;
+ else if (hdr[0] == '3' || hdr[0] == '7')
+ min_bytes = 5;
+ if (bytes < min_bytes)
+ {
+ (*_bfd_error_handler) (_("%B:%d: byte count %d too small\n"),
+ abfd, lineno, bytes);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+
+ 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;
+ }
+
+ if (bfd_bread (buf, (bfd_size_type) bytes * 2, abfd) != bytes * 2)
+ goto error_return;
- /* get the symbol part */
- while (!eof && !white (*src) && slen < MAXCHUNK)
+ /* 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;
+ }
+
+ 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;
+ }
- /* We create one section called .text for all the contents,
- and allocate enough room for the entire file. */
+ 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;
+ }
- return object_p (abfd);
+ if (abfd->symcount > 0)
+ abfd->flags |= HAS_SYMS;
+
+ 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;
-boolean
-DEFUN (srec_set_arch_mach, (abfd, arch, machine),
- bfd * abfd AND
- enum bfd_architecture arch AND
- unsigned long machine)
+ error_return:
+ if (buf != NULL)
+ free (buf);
+ return FALSE;
+}
+
+/* Get the contents of a section in an S-record file. */
+
+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)
{
+ int opb = bfd_octets_per_byte (abfd);
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 ((PTR) 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) / opb - 1) <= 0xffff)
+ ; /* The default, S1, is OK. */
+ else if ((section->lma + (offset + bytes_to_do) / opb - 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 / opb;
+ 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)
{
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;
*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_line _bfd_nosymbols_find_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_lookup_section_flags bfd_generic_lookup_section_flags
+#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_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. */
+ 0, /* match priority. */
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,
_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. */
+ 0, /* match priority. */
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,
_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
};