1 /* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
3 This file is part of BFD, the Binary File Diddler.
5 BFD is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 1, or (at your option)
10 BFD is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with BFD; see the file COPYING. If not, write to
17 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
21 bfd backend for srecord objects.
23 Srecords cannot hold anything but addresses and data, so that's all
26 The only interesting thing is that srecords may come out of order and
27 there is no header, so an initial scan is required to discover the
28 minimum and maximum addresses used to create the vma and size of the
29 only section we create. We arbitarily call this section ".text".
31 When bfd_get_section_contents is called the file is read again, and
32 this time the data is placed into a malloced area.
34 Any number of sections may be created for output, we just output them
35 in the order provided to bfd_set_section_contents.
38 Steve Chamberlain steve@cygnus.com
45 * Revision 1.6 1991/04/25 04:06:21 gnu
46 * Fix minor pointer type problems that "cc" complains about.
48 * Revision 1.5 1991/04/23 22:44:14 steve
49 * *** empty log message ***
51 * Revision 1.4 1991/04/23 16:01:02 steve
52 * *** empty log message ***
54 * Revision 1.3 1991/04/08 23:22:31 steve
55 * *** empty log message ***
57 * Revision 1.2 1991/04/03 22:10:51 steve
60 * Revision 1.1.1.1 1991/03/21 21:11:22 gumby
61 * Back from Intel with Steve
63 * Revision 1.1 1991/03/21 21:11:20 gumby
66 * Revision 1.1 1991/03/13 00:22:29 chrisb
69 * Revision 1.3 1991/03/10 19:11:40 rich
71 * bfd.c coff-code.h libbfd.c libbfd.h srec.c sunos.c
73 * Working bugs out of coff support.
75 * Revision 1.2 1991/03/07 02:26:18 sac
76 * Tidied up xfer table
78 * Revision 1.1 1991/03/05 16:28:12 sac
87 static char digs[] = "0123456789ABCDEF";
89 /* Macros for converting between hex and binary */
91 #define NIBBLE(x) ((x >= '0' && x <= '9') ? (x - '0') : (x - 'A' + 10))
92 #define HEX(buffer) ((NIBBLE((buffer)->high) <<4) + NIBBLE((buffer)->low))
94 ((d)->low = digs[(x) & 0xf], (d)->high = digs[((x)>>4)&0xf], x)
99 } byte_as_two_char_type;
101 /* The maximum number of bytes on a line is FF */
102 #define MAXCHUNK 0xff
103 /* The number of bytes we fit onto a line on output */
106 /* The shape of an srecord .. */
111 byte_as_two_char_type size;
114 byte_as_two_char_type address[4];
115 byte_as_two_char_type data[MAXCHUNK];
116 /* If there isn't MAXCHUNK bytes of data then the checksum will
118 byte_as_two_char_type checksum;
122 byte_as_two_char_type address[4];
123 byte_as_two_char_type data[MAXCHUNK];
124 byte_as_two_char_type checksum;
129 byte_as_two_char_type address[3];
130 byte_as_two_char_type data[MAXCHUNK];
131 byte_as_two_char_type checksum;
136 byte_as_two_char_type address[2];
137 byte_as_two_char_type data[MAXCHUNK];
138 byte_as_two_char_type checksum;
141 byte_as_two_char_type data[MAXCHUNK];
147 called once per input srecord, used to work out vma and size of data.
151 size_srec(abfd, section, address, raw, length)
155 byte_as_two_char_type *raw;
158 if (address < section->vma)
159 section->vma = address;
161 if (address + length > section->vma + section->size)
162 section->size = (address+length) - section->vma;
166 called once per input srecord, copies data from input into malloced area
170 fillup(abfd, section, address, raw, length)
174 byte_as_two_char_type *raw;
178 bfd_byte *dst = (bfd_byte *)(section->used_by_bfd) + address - section->vma;
179 for (i = 0; i < length; i++) {
187 pass over an srecord file calling one of the above functions on each
191 pass_over(abfd, func, section)
196 unsigned int bytes_on_line;
199 /* To the front of the file */
200 bfd_seek(abfd, (file_ptr)0, SEEK_SET);
206 eof = bfd_read(&buffer.S, 1, 1, abfd) != 1;
207 while (buffer.S != 'S' && !eof) {
208 eof = bfd_read(&buffer.S, 1, 1, abfd) != 1;
212 bfd_read(&buffer.type, 1, 3, abfd);
214 bytes_on_line = HEX(&buffer.size);
216 bfd_read(buffer.u.data, 1 , bytes_on_line * 2, abfd);
218 switch (buffer.type) {
220 /* Prologue - ignore */
223 address = (HEX(buffer.u.type_3.address+0) << 24)
224 + (HEX(buffer.u.type_3.address+1) << 16)
225 + (HEX(buffer.u.type_3.address+2) << 8)
226 + (HEX(buffer.u.type_3.address+3));
227 func(abfd,section, address, buffer.u.type_2.data, bytes_on_line -1);
232 address = (HEX(buffer.u.type_2.address+0) << 16)+
233 (HEX(buffer.u.type_2.address+1) << 8) +
234 (HEX(buffer.u.type_2.address+2));
235 func(abfd,section, address, buffer.u.type_2.data, bytes_on_line -1);
240 (HEX(buffer.u.type_1.address+0) << 8)
241 + (HEX(buffer.u.type_1.address+1));
242 func(abfd, section, address, buffer.u.type_1.data, bytes_on_line -1);
256 bfd_seek(abfd, (file_ptr)0, SEEK_SET);
257 bfd_read(&b, 1,1,abfd);
258 if (b != 'S') return (bfd_target*)NULL;
261 We create one section called data for all the contents,
262 and allocate enough room for the entire file
266 section = bfd_make_section(abfd, ".text");
268 section->vma = 0xffffffff;
269 pass_over(abfd, size_srec, section);
282 srec_get_section_contents (abfd, section, location, offset, count)
289 if (section->used_by_bfd == (PTR)NULL) {
290 section->used_by_bfd = (PTR)malloc(section->size);
291 pass_over(abfd, fillup, section);
293 (void) memcpy(location, (bfd_byte *)(section->used_by_bfd) + offset, count);
300 srec_set_arch_mach (abfd, arch, machine)
302 enum bfd_architecture arch;
303 unsigned long machine;
305 abfd->obj_arch = arch;
306 abfd->obj_machine = machine;
313 srec_set_section_contents (abfd, section, location, offset, bytes_to_do)
316 unsigned char *location;
327 if (section->size <= 0xffff)
329 else if (section->size <= 0xffffff)
335 buffer.type = '0' + type;
337 while (bytes_written < bytes_to_do) {
339 unsigned int check_sum;
340 byte_as_two_char_type *data;
341 unsigned int bytes_this_chunk = bytes_to_do - bytes_written;
343 if (bytes_this_chunk > CHUNK) {
344 bytes_this_chunk = CHUNK;
347 address = section->vma + offset + bytes_written;
351 check_sum = TOHEX(buffer.u.type_3.address, address >> 24);
352 check_sum += TOHEX(buffer.u.type_3.address+1, address >> 16);
353 check_sum += TOHEX(buffer.u.type_3.address+2, address >> 8);
354 check_sum += TOHEX(buffer.u.type_3.address+3, address >> 0);
355 size = bytes_this_chunk + 5;
356 data = buffer.u.type_3.data;
359 check_sum = TOHEX(buffer.u.type_3.address, address >> 16);
360 check_sum += TOHEX(buffer.u.type_3.address+1, address >> 8);
361 check_sum += TOHEX(buffer.u.type_3.address+2, address >> 0);
362 size = bytes_this_chunk + 4;
363 data = buffer.u.type_2.data;
367 check_sum = TOHEX(buffer.u.type_3.address+0, address >> 8);
368 check_sum += TOHEX(buffer.u.type_3.address+1, address >> 0);
369 size = bytes_this_chunk + 3;
370 data = buffer.u.type_1.data;
373 for (i = 0; i < bytes_this_chunk; i++) {
374 check_sum += TOHEX(data, (location[i]));
378 check_sum += TOHEX(&(buffer.size), size );
379 (void) TOHEX(data, ~check_sum);
382 * ( (char *)(data)) = '\n';
383 bfd_write(&buffer, 1, (char *)data - (char *)&buffer + 1 , abfd);
385 bytes_written += bytes_this_chunk;
386 location += bytes_this_chunk;
395 srec_close_and_cleanup (abfd)
399 if (bfd_read_p (abfd) == false) {
400 switch (abfd->format) {
402 if (!_bfd_write_archive_contents (abfd)) {
407 bfd_write("S9030000FC\n", 1,11,abfd);
410 bfd_error = invalid_operation;
414 for (s = abfd->sections; s != (asection *)NULL;s = s->next) {
415 if (s->used_by_bfd != (void *)NULL) {
416 free(s->used_by_bfd);
423 DEFUN(srec_sizeof_headers,(abfd),
430 #define srec_core_file_failing_command bfd_false
431 #define srec_core_file_failing_signal bfd_false
432 #define srec_core_file_matches_executable_p bfd_false
433 #define srec_slurp_armap bfd_false
434 #define srec_slurp_extended_name_table bfd_false
435 #define srec_truncate_arname bfd_false
436 #define srec_write_armap bfd_false
437 #define srec_new_section_hook bfd_false
438 #define srec_get_symtab_upper_bound bfd_false
439 #define srec_get_symtab bfd_false
440 #define srec_get_reloc_upper_bound bfd_false
441 #define srec_canonicalize_reloc bfd_false
442 #define srec_make_empty_symbol bfd_false
443 #define srec_print_symbol bfd_false
444 #define srec_get_lineno bfd_false
445 #define srec_openr_next_archived_file bfd_false
446 #define srec_find_nearest_line bfd_false
447 #define srec_generic_stat_arch_elt bfd_false
449 bfd_target srec_vec =
452 bfd_target_srec_flavour_enum,
453 true, /* target byte order */
454 true, /* target headers byte order */
455 (HAS_RELOC | EXEC_P | /* object flags */
456 HAS_LINENO | HAS_DEBUG |
457 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
458 (SEC_CODE|SEC_DATA|SEC_ROM|SEC_HAS_CONTENTS
459 |SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
460 ' ', /* ar_pad_char */
461 16, /* ar_max_namelen */
462 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* data */
463 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* hdrs */
466 srec_object_p, /* bfd_check_format */
467 (struct bfd_target *(*)()) bfd_nullvoidptr,
468 (struct bfd_target *(*)()) bfd_nullvoidptr,
472 bfd_true, /* mkobject */
473 _bfd_generic_mkarchive,