* Makefile.am (libbfd.h): Add "Extracted from.." comment.
[deliverable/binutils-gdb.git] / bfd / srec.c
index 54706acb8c58e1867ec37e4568ce08b7a2e232e5..b556f267379d958874116b6b1fa855e7a9e4856f 100644 (file)
@@ -1,6 +1,6 @@
 /* BFD back-end for s-record objects.
    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001
+   2000, 2001, 2002
    Free Software Foundation, Inc.
    Written by Steve Chamberlain of Cygnus Support <sac@cygnus.com>.
 
@@ -138,7 +138,6 @@ static boolean internal_srec_write_object_contents PARAMS ((bfd *, int));
 static boolean srec_write_object_contents PARAMS ((bfd *));
 static boolean symbolsrec_write_object_contents PARAMS ((bfd *));
 static int srec_sizeof_headers PARAMS ((bfd *, boolean));
-static asymbol *srec_make_empty_symbol PARAMS ((bfd *));
 static long srec_get_symtab_upper_bound PARAMS ((bfd *));
 static long srec_get_symtab PARAMS ((bfd *, asymbol **));
 
@@ -168,13 +167,13 @@ srec_init ()
     }
 }
 
-/* The maximum number of bytes on a line is FF.  */
+/* The maximum number of address+data+crc bytes on a line is FF.  */
 #define MAXCHUNK 0xff
 
 /* Default size for a CHUNK.  */
 #define DEFAULT_CHUNK 16
 
-/* The number of bytes we actually fit onto a line on output.
+/* 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;
@@ -300,7 +299,7 @@ srec_bad_byte (abfd, lineno, c, error)
        }
       (*_bfd_error_handler)
        (_("%s:%d: Unexpected character `%s' in S-record file\n"),
-        bfd_get_filename (abfd), lineno, buf);
+        bfd_archive_filename (abfd), lineno, buf);
       bfd_set_error (bfd_error_bad_value);
     }
 }
@@ -937,7 +936,7 @@ srec_write_record (abfd, type, address, data, end)
      const bfd_byte *data;
      const bfd_byte *end;
 {
-  char buffer[MAXCHUNK];
+  char buffer[2 * MAXCHUNK + 6];
   unsigned int check_sum = 0;
   const bfd_byte *src = data;
   char *dst = buffer;
@@ -995,15 +994,14 @@ static boolean
 srec_write_header (abfd)
      bfd *abfd;
 {
-  bfd_byte buffer[MAXCHUNK];
-  bfd_byte *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];
+  if (len > 40)
+    len = 40;
 
-  return srec_write_record (abfd, 0, (bfd_vma) 0, buffer, dst);
+  return srec_write_record (abfd, 0, (bfd_vma) 0,
+                           abfd->filename, abfd->filename + len);
 }
 
 static boolean
@@ -1015,6 +1013,17 @@ srec_write_section (abfd, tdata, list)
   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;
@@ -1044,17 +1053,14 @@ srec_write_terminator (abfd, tdata)
      bfd *abfd;
      tdata_type *tdata;
 {
-  bfd_byte buffer[2];
-
   return srec_write_record (abfd, 10 - tdata->type,
-                           abfd->start_address, buffer, buffer);
+                           abfd->start_address, NULL, NULL);
 }
 
 static boolean
 srec_write_symbols (abfd)
      bfd *abfd;
 {
-  char buffer[MAXCHUNK];
   /* Dump out the symbols of a bfd.  */
   int i;
   int count = bfd_get_symcount (abfd);
@@ -1063,10 +1069,10 @@ srec_write_symbols (abfd)
     {
       bfd_size_type len;
       asymbol **table = bfd_get_outsymbols (abfd);
-      sprintf (buffer, "$$ %s\r\n", abfd->filename);
-
-      len = strlen (buffer);
-      if (bfd_bwrite (buffer, len, abfd) != len)
+      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 < count; i++)
@@ -1076,23 +1082,29 @@ srec_write_symbols (abfd)
              && (s->flags & BSF_DEBUGGING) == 0)
            {
              /* Just dump out non debug symbols.  */
-             char buf2[40], *p;
+             char buf[42], *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 (buf2,
-                          s->value + s->section->output_section->lma
-                          + s->section->output_offset);
-             p = buf2;
+             sprintf_vma (buf + 1, (s->value
+                                    + s->section->output_section->lma
+                                    + s->section->output_offset));
+             p = buf + 1;
              while (p[0] == '0' && p[1] != 0)
                p++;
-             sprintf (buffer, "  %s $%s\r\n", s->name, p);
-             len = strlen (buffer);
-             if (bfd_bwrite (buffer, len, abfd) != len)
+             len = strlen (p);
+             p[len] = '\r';
+             p[len + 1] = '\n';
+             *--p = ' ';
+             len += 3;
+             if (bfd_bwrite (p, len, abfd) != len)
                return false;
            }
        }
-      sprintf (buffer, "$$ \r\n");
-      len = strlen (buffer);
-      if (bfd_bwrite (buffer, len, abfd) != len)
+      if (bfd_bwrite ("$$ \r\n", (bfd_size_type) 5, abfd) != 5)
        return false;
     }
 
@@ -1150,18 +1162,6 @@ srec_sizeof_headers (abfd, exec)
   return 0;
 }
 
-static asymbol *
-srec_make_empty_symbol (abfd)
-     bfd *abfd;
-{
-  asymbol *new;
-
-  new = (asymbol *) bfd_zalloc (abfd, (bfd_size_type) sizeof (asymbol));
-  if (new)
-    new->the_bfd = abfd;
-  return new;
-}
-
 /* Return the amount of memory needed to read the symbol table.  */
 
 static long
@@ -1251,6 +1251,7 @@ srec_print_symbol (abfd, afile, symbol, how)
 #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_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
@@ -1270,7 +1271,9 @@ srec_print_symbol (abfd, afile, symbol, how)
 #define srec_bfd_gc_sections bfd_generic_gc_sections
 #define srec_bfd_merge_sections bfd_generic_merge_sections
 #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_final_link _bfd_generic_final_link
 #define srec_bfd_link_split_section _bfd_generic_link_split_section
 
This page took 0.025949 seconds and 4 git commands to generate.