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.5 1991/04/23 22:44:14 steve
46 * *** empty log message ***
48 * Revision 1.4 1991/04/23 16:01:02 steve
49 * *** empty log message ***
51 * Revision 1.3 1991/04/08 23:22:31 steve
52 * *** empty log message ***
54 * Revision 1.2 1991/04/03 22:10:51 steve
57 * Revision 1.1.1.1 1991/03/21 21:11:22 gumby
58 * Back from Intel with Steve
60 * Revision 1.1 1991/03/21 21:11:20 gumby
63 * Revision 1.1 1991/03/13 00:22:29 chrisb
66 * Revision 1.3 1991/03/10 19:11:40 rich
68 * bfd.c coff-code.h libbfd.c libbfd.h srec.c sunos.c
70 * Working bugs out of coff support.
72 * Revision 1.2 1991/03/07 02:26:18 sac
73 * Tidied up xfer table
75 * Revision 1.1 1991/03/05 16:28:12 sac
84 static char digs
[] = "0123456789ABCDEF";
86 /* Macros for converting between hex and binary */
88 #define NIBBLE(x) ((x >= '0' && x <= '9') ? (x - '0') : (x - 'A' + 10))
89 #define HEX(buffer) ((NIBBLE((buffer)->high) <<4) + NIBBLE((buffer)->low))
91 ((d)->low = digs[(x) & 0xf], (d)->high = digs[((x)>>4)&0xf], x)
96 } byte_as_two_char_type
;
98 /* The maximum number of bytes on a line is FF */
100 /* The number of bytes we fit onto a line on output */
103 /* The shape of an srecord .. */
108 byte_as_two_char_type size
;
111 byte_as_two_char_type address
[4];
112 byte_as_two_char_type data
[MAXCHUNK
];
113 /* If there isn't MAXCHUNK bytes of data then the checksum will
115 byte_as_two_char_type checksum
;
119 byte_as_two_char_type address
[4];
120 byte_as_two_char_type data
[MAXCHUNK
];
121 byte_as_two_char_type checksum
;
126 byte_as_two_char_type address
[3];
127 byte_as_two_char_type data
[MAXCHUNK
];
128 byte_as_two_char_type checksum
;
133 byte_as_two_char_type address
[2];
134 byte_as_two_char_type data
[MAXCHUNK
];
135 byte_as_two_char_type checksum
;
138 byte_as_two_char_type data
[MAXCHUNK
];
144 called once per input srecord, used to work out vma and size of data.
148 size_srec(abfd
, section
, address
, raw
, length
)
152 byte_as_two_char_type
*raw
;
155 if (address
< section
->vma
)
156 section
->vma
= address
;
158 if (address
+ length
> section
->vma
+ section
->size
)
159 section
->size
= (address
+length
) - section
->vma
;
163 called once per input srecord, copies data from input into malloced area
167 fillup(abfd
, section
, address
, raw
, length
)
171 byte_as_two_char_type
*raw
;
175 bfd_byte
*dst
= (bfd_byte
*)(section
->used_by_bfd
) + address
- section
->vma
;
176 for (i
= 0; i
< length
; i
++) {
184 pass over an srecord file calling one of the above functions on each
188 pass_over(abfd
, func
, section
)
193 unsigned int bytes_on_line
;
196 /* To the front of the file */
197 bfd_seek(abfd
, (file_ptr
)0, SEEK_SET
);
203 eof
= bfd_read(&buffer
.S
, 1, 1, abfd
) != 1;
204 while (buffer
.S
!= 'S' && !eof
) {
205 eof
= bfd_read(&buffer
.S
, 1, 1, abfd
) != 1;
209 bfd_read(&buffer
.type
, 1, 3, abfd
);
211 bytes_on_line
= HEX(&buffer
.size
);
213 bfd_read(buffer
.u
.data
, 1 , bytes_on_line
* 2, abfd
);
215 switch (buffer
.type
) {
217 /* Prologue - ignore */
220 address
= (HEX(buffer
.u
.type_3
.address
+0) << 24)
221 + (HEX(buffer
.u
.type_3
.address
+1) << 16)
222 + (HEX(buffer
.u
.type_3
.address
+2) << 8)
223 + (HEX(buffer
.u
.type_3
.address
+3));
224 func(abfd
,section
, address
, buffer
.u
.type_2
.data
, bytes_on_line
-1);
229 address
= (HEX(buffer
.u
.type_2
.address
+0) << 16)+
230 (HEX(buffer
.u
.type_2
.address
+1) << 8) +
231 (HEX(buffer
.u
.type_2
.address
+2));
232 func(abfd
,section
, address
, buffer
.u
.type_2
.data
, bytes_on_line
-1);
237 (HEX(buffer
.u
.type_1
.address
+0) << 8)
238 + (HEX(buffer
.u
.type_1
.address
+1));
239 func(abfd
, section
, address
, buffer
.u
.type_1
.data
, bytes_on_line
-1);
253 bfd_seek(abfd
, (file_ptr
)0, SEEK_SET
);
254 bfd_read(&b
, 1,1,abfd
);
255 if (b
!= 'S') return (bfd_target
*)NULL
;
258 We create one section called data for all the contents,
259 and allocate enough room for the entire file
263 section
= bfd_make_section(abfd
, ".text");
265 section
->vma
= 0xffffffff;
266 pass_over(abfd
, size_srec
, section
);
279 srec_get_section_contents (abfd
, section
, location
, offset
, count
)
286 if (section
->used_by_bfd
== (bfd_byte
*)NULL
) {
287 section
->used_by_bfd
= (bfd_byte
*)malloc(section
->size
);
288 pass_over(abfd
, fillup
, section
);
290 (void) memcpy(location
, (bfd_byte
*)(section
->used_by_bfd
) + offset
, count
);
297 srec_set_arch_mach (abfd
, arch
, machine
)
299 enum bfd_architecture arch
;
300 unsigned long machine
;
302 abfd
->obj_arch
= arch
;
303 abfd
->obj_machine
= machine
;
310 srec_set_section_contents (abfd
, section
, location
, offset
, bytes_to_do
)
313 unsigned char *location
;
324 if (section
->size
<= 0xffff)
326 else if (section
->size
<= 0xffffff)
332 buffer
.type
= '0' + type
;
334 while (bytes_written
< bytes_to_do
) {
336 unsigned int check_sum
;
337 byte_as_two_char_type
*data
;
338 unsigned int bytes_this_chunk
= bytes_to_do
- bytes_written
;
340 if (bytes_this_chunk
> CHUNK
) {
341 bytes_this_chunk
= CHUNK
;
344 address
= section
->vma
+ offset
+ bytes_written
;
348 check_sum
= TOHEX(buffer
.u
.type_3
.address
, address
>> 24);
349 check_sum
+= TOHEX(buffer
.u
.type_3
.address
+1, address
>> 16);
350 check_sum
+= TOHEX(buffer
.u
.type_3
.address
+2, address
>> 8);
351 check_sum
+= TOHEX(buffer
.u
.type_3
.address
+3, address
>> 0);
352 size
= bytes_this_chunk
+ 5;
353 data
= buffer
.u
.type_3
.data
;
356 check_sum
= TOHEX(buffer
.u
.type_3
.address
, address
>> 16);
357 check_sum
+= TOHEX(buffer
.u
.type_3
.address
+1, address
>> 8);
358 check_sum
+= TOHEX(buffer
.u
.type_3
.address
+2, address
>> 0);
359 size
= bytes_this_chunk
+ 4;
360 data
= buffer
.u
.type_2
.data
;
364 check_sum
= TOHEX(buffer
.u
.type_3
.address
+0, address
>> 8);
365 check_sum
+= TOHEX(buffer
.u
.type_3
.address
+1, address
>> 0);
366 size
= bytes_this_chunk
+ 3;
367 data
= buffer
.u
.type_1
.data
;
370 for (i
= 0; i
< bytes_this_chunk
; i
++) {
371 check_sum
+= TOHEX(data
, (location
[i
]));
375 check_sum
+= TOHEX(&(buffer
.size
), size
);
376 (void) TOHEX(data
, ~check_sum
);
379 * ( (char *)(data
)) = '\n';
380 bfd_write(&buffer
, 1, (char *)data
- (char *)&buffer
+ 1 , abfd
);
382 bytes_written
+= bytes_this_chunk
;
383 location
+= bytes_this_chunk
;
392 srec_close_and_cleanup (abfd
)
396 if (bfd_read_p (abfd
) == false) {
397 switch (abfd
->format
) {
399 if (!_bfd_write_archive_contents (abfd
)) {
404 bfd_write("S9030000FC\n", 1,11,abfd
);
407 bfd_error
= invalid_operation
;
411 for (s
= abfd
->sections
; s
!= (asection
*)NULL
;s
= s
->next
) {
412 if (s
->used_by_bfd
!= (void *)NULL
) {
413 free(s
->used_by_bfd
);
420 DEFUN(srec_sizeof_headers
,(abfd
),
427 #define srec_core_file_failing_command bfd_false
428 #define srec_core_file_failing_signal bfd_false
429 #define srec_core_file_matches_executable_p bfd_false
430 #define srec_slurp_armap bfd_false
431 #define srec_slurp_extended_name_table bfd_false
432 #define srec_truncate_arname bfd_false
433 #define srec_write_armap bfd_false
434 #define srec_new_section_hook bfd_false
435 #define srec_get_symtab_upper_bound bfd_false
436 #define srec_get_symtab bfd_false
437 #define srec_get_reloc_upper_bound bfd_false
438 #define srec_canonicalize_reloc bfd_false
439 #define srec_make_empty_symbol bfd_false
440 #define srec_print_symbol bfd_false
441 #define srec_get_lineno bfd_false
442 #define srec_openr_next_archived_file bfd_false
443 #define srec_find_nearest_line bfd_false
444 #define srec_generic_stat_arch_elt bfd_false
446 bfd_target srec_vec
=
449 bfd_target_srec_flavour_enum
,
450 true, /* target byte order */
451 true, /* target headers byte order */
452 (HAS_RELOC
| EXEC_P
| /* object flags */
453 HAS_LINENO
| HAS_DEBUG
|
454 HAS_SYMS
| HAS_LOCALS
| DYNAMIC
| WP_TEXT
| D_PAGED
),
455 (SEC_CODE
|SEC_DATA
|SEC_ROM
|SEC_HAS_CONTENTS
456 |SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
), /* section flags */
457 ' ', /* ar_pad_char */
458 16, /* ar_max_namelen */
459 _do_getblong
, _do_putblong
, _do_getbshort
, _do_putbshort
, /* data */
460 _do_getblong
, _do_putblong
, _do_getbshort
, _do_putbshort
, /* hdrs */
463 srec_object_p
, /* bfd_check_format */
464 (struct bfd_target
*(*)()) bfd_nullvoidptr
,
465 (struct bfd_target
*(*)()) bfd_nullvoidptr
,
469 bfd_true
, /* mkobject */
470 _bfd_generic_mkarchive
,