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.2 1991/04/03 22:10:51 steve
48 * Revision 1.1.1.1 1991/03/21 21:11:22 gumby
49 * Back from Intel with Steve
51 * Revision 1.1 1991/03/21 21:11:20 gumby
54 * Revision 1.1 1991/03/13 00:22:29 chrisb
57 * Revision 1.3 1991/03/10 19:11:40 rich
59 * bfd.c coff-code.h libbfd.c libbfd.h srec.c sunos.c
61 * Working bugs out of coff support.
63 * Revision 1.2 1991/03/07 02:26:18 sac
64 * Tidied up xfer table
66 * Revision 1.1 1991/03/05 16:28:12 sac
75 static char digs[] = "0123456789ABCDEF";
77 /* Macros for converting between hex and binary */
79 #define NIBBLE(x) ((x >= '0' && x <= '9') ? (x - '0') : (x - 'A' + 10))
80 #define HEX(buffer) ((NIBBLE((buffer)->high) <<4) + NIBBLE((buffer)->low))
82 ((d)->low = digs[(x) & 0xf], (d)->high = digs[((x)>>4)&0xf], x)
87 } byte_as_two_char_type;
89 /* The maximum number of bytes on a line is FF */
91 /* The number of bytes we fit onto a line on output */
94 /* The shape of an srecord .. */
99 byte_as_two_char_type size;
102 byte_as_two_char_type address[4];
103 byte_as_two_char_type data[MAXCHUNK];
104 /* If there isn't MAXCHUNK bytes of data then the checksum will
106 byte_as_two_char_type checksum;
110 byte_as_two_char_type address[4];
111 byte_as_two_char_type data[MAXCHUNK];
112 byte_as_two_char_type checksum;
117 byte_as_two_char_type address[3];
118 byte_as_two_char_type data[MAXCHUNK];
119 byte_as_two_char_type checksum;
124 byte_as_two_char_type address[2];
125 byte_as_two_char_type data[MAXCHUNK];
126 byte_as_two_char_type checksum;
129 byte_as_two_char_type data[MAXCHUNK];
135 called once per input srecord, used to work out vma and size of data.
139 size_srec(abfd, section, address, raw, length)
143 byte_as_two_char_type *raw;
146 if (address < section->vma)
147 section->vma = address;
149 if (address + length > section->vma + section->size)
150 section->size = (address+length) - section->vma;
154 called once per input srecord, copies data from input into malloced area
158 fillup(abfd, section, address, raw, length)
162 byte_as_two_char_type *raw;
166 bfd_byte *dst = (bfd_byte *)(section->used_by_bfd) + address - section->vma;
167 for (i = 0; i < length; i++) {
175 pass over an srecord file calling one of the above functions on each
179 pass_over(abfd, func, section)
184 unsigned int bytes_on_line;
187 /* To the front of the file */
188 bfd_seek(abfd, (file_ptr)0, SEEK_SET);
194 eof = bfd_read(&buffer.S, 1, 1, abfd) != 1;
195 while (buffer.S != 'S' && !eof) {
196 eof = bfd_read(&buffer.S, 1, 1, abfd) != 1;
200 bfd_read(&buffer.type, 1, 3, abfd);
202 bytes_on_line = HEX(&buffer.size);
204 bfd_read(buffer.u.data, 1 , bytes_on_line * 2, abfd);
206 switch (buffer.type) {
208 /* Prologue - ignore */
211 address = (HEX(buffer.u.type_3.address+0) << 24)
212 + (HEX(buffer.u.type_3.address+1) << 16)
213 + (HEX(buffer.u.type_3.address+2) << 8)
214 + (HEX(buffer.u.type_3.address+3));
215 func(abfd,section, address, buffer.u.type_2.data, bytes_on_line -1);
220 address = (HEX(buffer.u.type_2.address+0) << 16)+
221 (HEX(buffer.u.type_2.address+1) << 8) +
222 (HEX(buffer.u.type_2.address+2));
223 func(abfd,section, address, buffer.u.type_2.data, bytes_on_line -1);
228 (HEX(buffer.u.type_1.address+0) << 8)
229 + (HEX(buffer.u.type_1.address+1));
230 func(abfd, section, address, buffer.u.type_1.data, bytes_on_line -1);
244 bfd_seek(abfd, (file_ptr)0, SEEK_SET);
245 bfd_read(&b, 1,1,abfd);
246 if (b != 'S') return (bfd_target*)NULL;
249 We create one section called data for all the contents,
250 and allocate enough room for the entire file
254 section = bfd_make_section(abfd, ".text");
256 section->vma = 0xffffffff;
257 pass_over(abfd, size_srec, section);
270 srec_get_section_contents (abfd, section, location, offset, count)
277 if (section->used_by_bfd == (bfd_byte *)NULL) {
278 section->used_by_bfd = (bfd_byte *)malloc(section->size);
279 pass_over(abfd, fillup, section);
281 (void) memcpy(location, (bfd_byte *)(section->used_by_bfd) + offset, count);
288 srec_set_arch_mach (abfd, arch, machine)
290 enum bfd_architecture arch;
291 unsigned long machine;
293 abfd->obj_arch = arch;
294 abfd->obj_machine = machine;
301 srec_set_section_contents (abfd, section, location, offset, bytes_to_do)
304 unsigned char *location;
315 if (section->size <= 0xffff)
317 else if (section->size <= 0xffffff)
323 buffer.type = '0' + type;
325 while (bytes_written < bytes_to_do) {
327 unsigned int check_sum;
328 byte_as_two_char_type *data;
329 unsigned int bytes_this_chunk = bytes_to_do - bytes_written;
331 if (bytes_this_chunk > CHUNK) {
332 bytes_this_chunk = CHUNK;
335 address = section->vma + offset + bytes_written;
339 check_sum = TOHEX(buffer.u.type_3.address, address >> 24);
340 check_sum += TOHEX(buffer.u.type_3.address+1, address >> 16);
341 check_sum += TOHEX(buffer.u.type_3.address+2, address >> 8);
342 check_sum += TOHEX(buffer.u.type_3.address+3, address >> 0);
343 size = bytes_this_chunk + 5;
344 data = buffer.u.type_3.data;
347 check_sum = TOHEX(buffer.u.type_3.address, address >> 16);
348 check_sum += TOHEX(buffer.u.type_3.address+1, address >> 8);
349 check_sum += TOHEX(buffer.u.type_3.address+2, address >> 0);
350 size = bytes_this_chunk + 4;
351 data = buffer.u.type_2.data;
355 check_sum = TOHEX(buffer.u.type_3.address+0, address >> 8);
356 check_sum += TOHEX(buffer.u.type_3.address+1, address >> 0);
357 size = bytes_this_chunk + 3;
358 data = buffer.u.type_1.data;
361 for (i = 0; i < bytes_this_chunk; i++) {
362 check_sum += TOHEX(data, (location[i]));
366 check_sum += TOHEX(&(buffer.size), size );
367 (void) TOHEX(data, ~check_sum);
370 * ( (char *)(data)) = '\n';
371 bfd_write(&buffer, 1, (char *)data - (char *)&buffer + 1 , abfd);
373 bytes_written += bytes_this_chunk;
374 location += bytes_this_chunk;
383 srec_close_and_cleanup (abfd)
387 if (bfd_read_p (abfd) == false) {
388 switch (abfd->format) {
390 if (!_bfd_write_archive_contents (abfd)) {
395 bfd_write("S9030000FC\n", 1,11,abfd);
398 bfd_error = invalid_operation;
402 for (s = abfd->sections; s != (asection *)NULL;s = s->next) {
403 if (s->used_by_bfd != (void *)NULL) {
404 free(s->used_by_bfd);
411 bfd_target srec_vec =
414 bfd_target_srec_flavour_enum,
415 true, /* target byte order */
416 true, /* target headers byte order */
417 (HAS_RELOC | EXEC_P | /* object flags */
418 HAS_LINENO | HAS_DEBUG |
419 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
420 (SEC_CODE|SEC_DATA|SEC_ROM
421 |SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
422 0, /* valid reloc types */
423 ' ', /* ar_pad_char */
424 16, /* ar_max_namelen */
425 srec_close_and_cleanup, /* _close_and_cleanup */
426 srec_set_section_contents, /* bfd_set_section_contents */
427 srec_get_section_contents,
428 bfd_true, /* new_section_hook */
429 0, /* _core_file_failing_command */
430 0, /* _core_file_failing_signal */
431 0, /* _core_file_matches_ex...p */
433 bfd_false, /* bfd_slurp_armap */
434 bfd_false, /* bfd_slurp_extended_name_table */
435 bfd_void, /* bfd_truncate_arname */
436 bfd_0u, /* get_symtab_upper_bound */
437 bfd_0u, /* canonicalize_symtab */
438 bfd_void, /* bfd_reclaim_symbol_table */
439 bfd_0u, /* get_reloc_upper_bound */
440 bfd_0u, /* bfd_canonicalize_reloc */
441 bfd_void, /* bfd_reclaim_reloc */
442 bfd_0, /* bfd_get_symcount_upper_bound */
443 (symindex (*)())bfd_0, /* bfd_get_first_symbol */
444 (symindex (*)())bfd_0, /* bfd_get_next_symbol */
445 bfd_false, /* bfd_classify_symbol */
446 bfd_false, /* bfd_symbol_hasclass */
447 (char* (*)())bfd_0, /* bfd_symbol_name */
448 bfd_0, /* bfd_symbol_value */
450 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* data */
451 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* hdrs */
454 srec_object_p, /* bfd_check_format */
455 (struct bfd_target *(*)()) bfd_nullvoidptr,
456 (struct bfd_target *(*)()) bfd_nullvoidptr,
460 bfd_true, /* mkobject */
461 _bfd_generic_mkarchive,
464 (asymbol * (*)()) bfd_nullvoidptr, /* bfd_make_empty_symbol */
465 bfd_void, /* bfd_prit_symbol */
466 (alent *(*)())bfd_nullvoidptr, /* srec_get_lineno,*/
467 srec_set_arch_mach, /* bfd_set_arch_mach,*/
468 bfd_false, /* write_armap*/
469 (bfd *(*)())bfd_nullvoidptr, /* openr_next_archived_file */
470 bfd_false, /* bfd_find_nearest_line */