]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/dsrec.c
Update Copyright year range in all files maintained by GDB.
[thirdparty/binutils-gdb.git] / gdb / dsrec.c
CommitLineData
c906108c 1/* S-record download support for GDB, the GNU debugger.
ecd75fc8 2 Copyright (C) 1995-2014 Free Software Foundation, Inc.
c906108c 3
c5aa993b 4 This file is part of GDB.
c906108c 5
c5aa993b
JM
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
a9762ec7 8 the Free Software Foundation; either version 3 of the License, or
c5aa993b 9 (at your option) any later version.
c906108c 10
c5aa993b
JM
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
c906108c 15
c5aa993b 16 You should have received a copy of the GNU General Public License
a9762ec7 17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
18
19#include "defs.h"
20#include "serial.h"
21#include "srec.h"
735522c2 22#include <sys/time.h>
c906108c 23#include <time.h>
44160db3 24#include "gdb_assert.h"
0e9f083f 25#include <string.h>
cbb099e8 26#include "gdb_bfd.h"
c906108c 27
c906108c
SS
28extern int remote_debug;
29
a14ed312
KB
30static int make_srec (char *srec, CORE_ADDR targ_addr, bfd * abfd,
31 asection * sect, int sectoff, int *maxrecsize,
32 int flags);
c906108c
SS
33
34/* Download an executable by converting it to S records. DESC is a
819cc324
AC
35 `struct serial *' to send the data to. FILE is the name of the
36 file to be loaded. LOAD_OFFSET is the offset into memory to load
37 data into. It is usually specified by the user and is useful with
38 the a.out file format. MAXRECSIZE is the length in chars of the
39 largest S-record the host can accomodate. This is measured from
40 the starting `S' to the last char of the checksum. FLAGS is
41 various random flags, and HASHMARK is non-zero to cause a `#' to be
c5aa993b 42 printed out for each record loaded. WAITACK, if non-NULL, is a
819cc324
AC
43 function that waits for an acknowledgement after each S-record, and
44 returns non-zero if the ack is read correctly. */
c906108c
SS
45
46void
819cc324
AC
47load_srec (struct serial *desc, const char *file, bfd_vma load_offset,
48 int maxrecsize,
9df3df99 49 int flags, int hashmark, int (*waitack) (void))
c906108c
SS
50{
51 bfd *abfd;
52 asection *s;
53 char *srec;
54 int i;
55 int reclen;
735522c2 56 struct timeval start_time, end_time;
c906108c 57 unsigned long data_count = 0;
d6ad71ba 58 struct cleanup *cleanup;
c906108c
SS
59
60 srec = (char *) alloca (maxrecsize + 1);
61
1c00ec6b 62 abfd = gdb_bfd_open (file, NULL, -1);
c906108c
SS
63 if (!abfd)
64 {
a3f17187 65 printf_filtered (_("Unable to open file %s\n"), file);
c906108c
SS
66 return;
67 }
68
f9a062ff 69 cleanup = make_cleanup_bfd_unref (abfd);
c906108c
SS
70 if (bfd_check_format (abfd, bfd_object) == 0)
71 {
a3f17187 72 printf_filtered (_("File is not an object file\n"));
d6ad71ba 73 do_cleanups (cleanup);
c906108c
SS
74 return;
75 }
76
735522c2 77 gettimeofday (&start_time, NULL);
c906108c
SS
78
79 /* Write a type 0 header record. no data for a type 0, and there
80 is no data, so len is 0. */
81
82 reclen = maxrecsize;
c5aa993b 83 make_srec (srec, 0, NULL, (asection *) 1, 0, &reclen, flags);
c906108c
SS
84 if (remote_debug)
85 {
86 srec[reclen] = '\0';
87 puts_debug ("sent -->", srec, "<--");
88 }
2cd58942 89 serial_write (desc, srec, reclen);
c906108c
SS
90
91 for (s = abfd->sections; s; s = s->next)
92 if (s->flags & SEC_LOAD)
93 {
94 int numbytes;
9a619af0 95
c906108c 96 bfd_vma addr = bfd_get_section_vma (abfd, s) + load_offset;
2c500098 97 bfd_size_type size = bfd_get_section_size (s);
c5aa993b 98 char *section_name = (char *) bfd_get_section_name (abfd, s);
d4f3574e
SS
99 /* Both GDB and BFD have mechanisms for printing addresses.
100 In the below, GDB's is used so that the address is
101 consistent with the rest of GDB. BFD's printf_vma() could
0963b4bd 102 have also been used. cagney 1999-09-01 */
5af949e3 103 printf_filtered ("%s\t: %s .. %s ",
d4f3574e 104 section_name,
f5656ead
TT
105 paddress (target_gdbarch (), addr),
106 paddress (target_gdbarch (), addr + size));
c906108c
SS
107 gdb_flush (gdb_stdout);
108
109 data_count += size;
110
111 for (i = 0; i < size; i += numbytes)
112 {
113 reclen = maxrecsize;
114 numbytes = make_srec (srec, (CORE_ADDR) (addr + i), abfd, s,
115 i, &reclen, flags);
116
117 if (remote_debug)
118 {
119 srec[reclen] = '\0';
120 puts_debug ("sent -->", srec, "<--");
121 }
122
123 /* Repeatedly send the S-record until a good
124 acknowledgement is sent back. */
125 do
126 {
2cd58942 127 serial_write (desc, srec, reclen);
9a4105ab
AC
128 if (deprecated_ui_load_progress_hook)
129 if (deprecated_ui_load_progress_hook (section_name,
130 (unsigned long) i))
8a3fe4f8 131 error (_("Canceled the download"));
c906108c
SS
132 }
133 while (waitack != NULL && !waitack ());
134
135 if (hashmark)
136 {
137 putchar_unfiltered ('#');
138 gdb_flush (gdb_stdout);
139 }
0963b4bd 140 } /* Per-packet (or S-record) loop. */
c906108c 141
9a4105ab
AC
142 if (deprecated_ui_load_progress_hook)
143 if (deprecated_ui_load_progress_hook (section_name,
144 (unsigned long) i))
8a3fe4f8 145 error (_("Canceled the download"));
c906108c
SS
146 putchar_unfiltered ('\n');
147 }
148
c5aa993b 149 if (hashmark)
c906108c
SS
150 putchar_unfiltered ('\n');
151
735522c2 152 gettimeofday (&end_time, NULL);
c5aa993b 153
c906108c
SS
154 /* Write a terminator record. */
155
156 reclen = maxrecsize;
157 make_srec (srec, abfd->start_address, NULL, NULL, 0, &reclen, flags);
158
159 if (remote_debug)
160 {
161 srec[reclen] = '\0';
162 puts_debug ("sent -->", srec, "<--");
163 }
164
2cd58942 165 serial_write (desc, srec, reclen);
c906108c
SS
166
167 /* Some monitors need these to wake up properly. (Which ones? -sts) */
2cd58942 168 serial_write (desc, "\r\r", 2);
c906108c
SS
169 if (remote_debug)
170 puts_debug ("sent -->", "\r\r", "<---");
171
2cd58942 172 serial_flush_input (desc);
c906108c 173
735522c2
TT
174 print_transfer_performance (gdb_stdout, data_count, 0,
175 &start_time, &end_time);
d6ad71ba 176 do_cleanups (cleanup);
c906108c
SS
177}
178
179/*
0963b4bd 180 * make_srec -- make an srecord. This writes each line, one at a
c5aa993b
JM
181 * time, each with it's own header and trailer line.
182 * An srecord looks like this:
c906108c
SS
183 *
184 * byte count-+ address
185 * start ---+ | | data +- checksum
c5aa993b
JM
186 * | | | |
187 * S01000006F6B692D746573742E73726563E4
188 * S315000448600000000000000000FC00005900000000E9
189 * S31A0004000023C1400037DE00F023604000377B009020825000348D
190 * S30B0004485A0000000000004E
191 * S70500040000F6
c906108c 192 *
c5aa993b 193 * S<type><length><address><data><checksum>
c906108c
SS
194 *
195 * Where
196 * - length
0963b4bd
MS
197 * is the number of bytes following upto the checksum. Note
198 * that this is not the number of chars following, since it
199 * takes two chars to represent a byte.
c906108c
SS
200 * - type
201 * is one of:
202 * 0) header record
203 * 1) two byte address data record
204 * 2) three byte address data record
205 * 3) four byte address data record
206 * 7) four byte address termination record
207 * 8) three byte address termination record
208 * 9) two byte address termination record
209 *
210 * - address
211 * is the start address of the data following, or in the case of
212 * a termination record, the start address of the image
213 * - data
214 * is the data.
215 * - checksum
c5aa993b 216 * is the sum of all the raw byte data in the record, from the length
c906108c
SS
217 * upwards, modulo 256 and subtracted from 255.
218 *
219 * This routine returns the length of the S-record.
220 *
221 */
222
223static int
fba45db2
KB
224make_srec (char *srec, CORE_ADDR targ_addr, bfd *abfd, asection *sect,
225 int sectoff, int *maxrecsize, int flags)
c906108c
SS
226{
227 unsigned char checksum;
228 int tmp;
44d100c3
TT
229 static const char hextab[] = "0123456789ABCDEF";
230 static const char data_code_table[] = "123";
231 static const char term_code_table[] = "987";
232 static const char header_code_table[] = "000";
c906108c
SS
233 char const *code_table;
234 int addr_size;
235 int payload_size;
236 char *binbuf;
237 char *p;
238
239 if (sect)
240 {
241 tmp = flags; /* Data or header record */
242 code_table = abfd ? data_code_table : header_code_table;
c5aa993b 243 binbuf = alloca (*maxrecsize / 2);
c906108c
SS
244 }
245 else
246 {
c5aa993b 247 tmp = flags >> SREC_TERM_SHIFT; /* Term record */
c906108c 248 code_table = term_code_table;
93d56215 249 binbuf = NULL;
c906108c
SS
250 }
251
252 if ((tmp & SREC_2_BYTE_ADDR) && (targ_addr <= 0xffff))
253 addr_size = 2;
254 else if ((tmp & SREC_3_BYTE_ADDR) && (targ_addr <= 0xffffff))
255 addr_size = 3;
256 else if (tmp & SREC_4_BYTE_ADDR)
257 addr_size = 4;
258 else
8e65ff28 259 internal_error (__FILE__, __LINE__,
5af949e3 260 _("make_srec: Bad address (%s), or bad flags (0x%x)."),
f5656ead 261 paddress (target_gdbarch (), targ_addr), flags);
c906108c
SS
262
263 /* Now that we know the address size, we can figure out how much
264 data this record can hold. */
265
266 if (sect && abfd)
267 {
268 payload_size = (*maxrecsize - (1 + 1 + 2 + addr_size * 2 + 2)) / 2;
2c500098 269 payload_size = min (payload_size, bfd_get_section_size (sect) - sectoff);
c906108c
SS
270
271 bfd_get_section_contents (abfd, sect, binbuf, sectoff, payload_size);
272 }
273 else
0963b4bd 274 payload_size = 0; /* Term or header packets have no payload. */
c906108c
SS
275
276 /* Output the header. */
44160db3
AC
277 snprintf (srec, (*maxrecsize) + 1, "S%c%02X%0*X",
278 code_table[addr_size - 2],
279 addr_size + payload_size + 1,
280 addr_size * 2, (int) targ_addr);
c906108c
SS
281
282 /* Note that the checksum is calculated on the raw data, not the
283 hexified data. It includes the length, address and the data
284 portions of the packet. */
285
286 checksum = 0;
c5aa993b 287
c906108c 288 checksum += (payload_size + addr_size + 1 /* Packet length */
0963b4bd 289 + (targ_addr & 0xff) /* Address... */
c5aa993b 290 + ((targ_addr >> 8) & 0xff)
c906108c
SS
291 + ((targ_addr >> 16) & 0xff)
292 + ((targ_addr >> 24) & 0xff));
c5aa993b 293
44160db3
AC
294 /* NOTE: cagney/2003-08-10: The equation is old. Check that the
295 recent snprintf changes match that equation. */
296 gdb_assert (strlen (srec) == 1 + 1 + 2 + addr_size * 2);
c906108c
SS
297 p = srec + 1 + 1 + 2 + addr_size * 2;
298
299 /* Build the Srecord. */
300 for (tmp = 0; tmp < payload_size; tmp++)
301 {
302 unsigned char k;
303
304 k = binbuf[tmp];
c5aa993b
JM
305 *p++ = hextab[k >> 4];
306 *p++ = hextab[k & 0xf];
c906108c
SS
307 checksum += k;
308 }
309
310 checksum = ~checksum;
311
312 *p++ = hextab[checksum >> 4];
313 *p++ = hextab[checksum & 0xf];
314 *p++ = '\r';
315
316 *maxrecsize = p - srec;
317 return payload_size;
318}