/* S-record download support for GDB, the GNU debugger.
- Copyright 1995, 1996, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1997, 1999, 2000, 2001, 2003, 2004, 2007, 2008,
+ 2009 Free Software Foundation, Inc.
This file is part of GDB.
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
+ 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,
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., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
#include "serial.h"
#include "srec.h"
#include <time.h>
+#include "gdb_assert.h"
+#include "gdb_string.h"
-int (*ui_load_progress_hook) PARAMS ((char *, unsigned long));
-extern void report_transfer_performance PARAMS ((unsigned long, time_t, time_t));
+extern void report_transfer_performance (unsigned long, time_t, time_t);
extern int remote_debug;
-static int make_srec PARAMS ((char *srec, CORE_ADDR targ_addr, bfd * abfd,
- asection * sect, int sectoff, int *maxrecsize,
- int flags));
+static int make_srec (char *srec, CORE_ADDR targ_addr, bfd * abfd,
+ asection * sect, int sectoff, int *maxrecsize,
+ int flags);
/* Download an executable by converting it to S records. DESC is a
- serial_t to send the data to. FILE is the name of the file to be
- loaded. LOAD_OFFSET is the offset into memory to load data into.
- It is usually specified by the user and is useful with the a.out
- file format. MAXRECSIZE is the length in chars of the largest
- S-record the host can accomodate. This is measured from the
- starting `S' to the last char of the checksum. FLAGS is various
- random flags, and HASHMARK is non-zero to cause a `#' to be
+ `struct serial *' to send the data to. FILE is the name of the
+ file to be loaded. LOAD_OFFSET is the offset into memory to load
+ data into. It is usually specified by the user and is useful with
+ the a.out file format. MAXRECSIZE is the length in chars of the
+ largest S-record the host can accomodate. This is measured from
+ the starting `S' to the last char of the checksum. FLAGS is
+ various random flags, and HASHMARK is non-zero to cause a `#' to be
printed out for each record loaded. WAITACK, if non-NULL, is a
- function that waits for an acknowledgement after each S-record,
- and returns non-zero if the ack is read correctly. */
+ function that waits for an acknowledgement after each S-record, and
+ returns non-zero if the ack is read correctly. */
void
-load_srec (desc, file, load_offset, maxrecsize, flags, hashmark, waitack)
- serial_t desc;
- const char *file;
- bfd_vma load_offset;
- int maxrecsize;
- int flags;
- int hashmark;
- int (*waitack) PARAMS ((void));
+load_srec (struct serial *desc, const char *file, bfd_vma load_offset,
+ int maxrecsize,
+ int flags, int hashmark, int (*waitack) (void))
{
bfd *abfd;
asection *s;
abfd = bfd_openr (file, 0);
if (!abfd)
{
- printf_filtered ("Unable to open file %s\n", file);
+ printf_filtered (_("Unable to open file %s\n"), file);
return;
}
if (bfd_check_format (abfd, bfd_object) == 0)
{
- printf_filtered ("File is not an object file\n");
+ printf_filtered (_("File is not an object file\n"));
return;
}
srec[reclen] = '\0';
puts_debug ("sent -->", srec, "<--");
}
- SERIAL_WRITE (desc, srec, reclen);
+ serial_write (desc, srec, reclen);
for (s = abfd->sections; s; s = s->next)
if (s->flags & SEC_LOAD)
{
int numbytes;
bfd_vma addr = bfd_get_section_vma (abfd, s) + load_offset;
- bfd_size_type size = bfd_get_section_size_before_reloc (s);
+ bfd_size_type size = bfd_get_section_size (s);
char *section_name = (char *) bfd_get_section_name (abfd, s);
/* Both GDB and BFD have mechanisms for printing addresses.
In the below, GDB's is used so that the address is
acknowledgement is sent back. */
do
{
- SERIAL_WRITE (desc, srec, reclen);
- if (ui_load_progress_hook)
- if (ui_load_progress_hook (section_name, (unsigned long) i))
- error ("Canceled the download");
+ serial_write (desc, srec, reclen);
+ if (deprecated_ui_load_progress_hook)
+ if (deprecated_ui_load_progress_hook (section_name,
+ (unsigned long) i))
+ error (_("Canceled the download"));
}
while (waitack != NULL && !waitack ());
}
} /* Per-packet (or S-record) loop */
- if (ui_load_progress_hook)
- if (ui_load_progress_hook (section_name, (unsigned long) i))
- error ("Canceled the download");
+ if (deprecated_ui_load_progress_hook)
+ if (deprecated_ui_load_progress_hook (section_name,
+ (unsigned long) i))
+ error (_("Canceled the download"));
putchar_unfiltered ('\n');
}
puts_debug ("sent -->", srec, "<--");
}
- SERIAL_WRITE (desc, srec, reclen);
+ serial_write (desc, srec, reclen);
/* Some monitors need these to wake up properly. (Which ones? -sts) */
- SERIAL_WRITE (desc, "\r\r", 2);
+ serial_write (desc, "\r\r", 2);
if (remote_debug)
puts_debug ("sent -->", "\r\r", "<---");
- SERIAL_FLUSH_INPUT (desc);
+ serial_flush_input (desc);
report_transfer_performance (data_count, start_time, end_time);
}
*/
static int
-make_srec (srec, targ_addr, abfd, sect, sectoff, maxrecsize, flags)
- char *srec;
- CORE_ADDR targ_addr;
- bfd *abfd;
- asection *sect;
- int sectoff;
- int *maxrecsize;
- int flags;
+make_srec (char *srec, CORE_ADDR targ_addr, bfd *abfd, asection *sect,
+ int sectoff, int *maxrecsize, int flags)
{
unsigned char checksum;
int tmp;
const static char data_code_table[] = "123";
const static char term_code_table[] = "987";
const static char header_code_table[] = "000";
- const static char *formats[] =
- {"S%c%02X%04X",
- "S%c%02X%06X",
- "S%c%02X%08X"};
char const *code_table;
int addr_size;
int payload_size;
{
tmp = flags >> SREC_TERM_SHIFT; /* Term record */
code_table = term_code_table;
+ binbuf = NULL;
}
if ((tmp & SREC_2_BYTE_ADDR) && (targ_addr <= 0xffff))
else if (tmp & SREC_4_BYTE_ADDR)
addr_size = 4;
else
- internal_error ("make_srec: Bad address (0x%x), or bad flags (0x%x).",
- targ_addr, flags);
+ internal_error (__FILE__, __LINE__,
+ _("make_srec: Bad address (0x%s), or bad flags (0x%x)."),
+ paddr (targ_addr), flags);
/* Now that we know the address size, we can figure out how much
data this record can hold. */
if (sect && abfd)
{
payload_size = (*maxrecsize - (1 + 1 + 2 + addr_size * 2 + 2)) / 2;
- payload_size = min (payload_size, sect->_raw_size - sectoff);
+ payload_size = min (payload_size, bfd_get_section_size (sect) - sectoff);
bfd_get_section_contents (abfd, sect, binbuf, sectoff, payload_size);
}
payload_size = 0; /* Term or header packets have no payload */
/* Output the header. */
-
- sprintf (srec, formats[addr_size - 2], code_table[addr_size - 2],
- addr_size + payload_size + 1, (int) targ_addr);
+ snprintf (srec, (*maxrecsize) + 1, "S%c%02X%0*X",
+ code_table[addr_size - 2],
+ addr_size + payload_size + 1,
+ addr_size * 2, (int) targ_addr);
/* Note that the checksum is calculated on the raw data, not the
hexified data. It includes the length, address and the data
+ ((targ_addr >> 16) & 0xff)
+ ((targ_addr >> 24) & 0xff));
+ /* NOTE: cagney/2003-08-10: The equation is old. Check that the
+ recent snprintf changes match that equation. */
+ gdb_assert (strlen (srec) == 1 + 1 + 2 + addr_size * 2);
p = srec + 1 + 1 + 2 + addr_size * 2;
/* Build the Srecord. */