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.4 1991/04/23 16:01:02 steve
46 * *** empty log message ***
48 * Revision 1.3 1991/04/08 23:22:31 steve
49 * *** empty log message ***
51 * Revision 1.2 1991/04/03 22:10:51 steve
54 * Revision 1.1.1.1 1991/03/21 21:11:22 gumby
55 * Back from Intel with Steve
57 * Revision 1.1 1991/03/21 21:11:20 gumby
60 * Revision 1.1 1991/03/13 00:22:29 chrisb
63 * Revision 1.3 1991/03/10 19:11:40 rich
65 * bfd.c coff-code.h libbfd.c libbfd.h srec.c sunos.c
67 * Working bugs out of coff support.
69 * Revision 1.2 1991/03/07 02:26:18 sac
70 * Tidied up xfer table
72 * Revision 1.1 1991/03/05 16:28:12 sac
81 static char digs
[] = "0123456789ABCDEF";
83 /* Macros for converting between hex and binary */
85 #define NIBBLE(x) ((x >= '0' && x <= '9') ? (x - '0') : (x - 'A' + 10))
86 #define HEX(buffer) ((NIBBLE((buffer)->high) <<4) + NIBBLE((buffer)->low))
88 ((d)->low = digs[(x) & 0xf], (d)->high = digs[((x)>>4)&0xf], x)
93 } byte_as_two_char_type
;
95 /* The maximum number of bytes on a line is FF */
97 /* The number of bytes we fit onto a line on output */
100 /* The shape of an srecord .. */
105 byte_as_two_char_type size
;
108 byte_as_two_char_type address
[4];
109 byte_as_two_char_type data
[MAXCHUNK
];
110 /* If there isn't MAXCHUNK bytes of data then the checksum will
112 byte_as_two_char_type checksum
;
116 byte_as_two_char_type address
[4];
117 byte_as_two_char_type data
[MAXCHUNK
];
118 byte_as_two_char_type checksum
;
123 byte_as_two_char_type address
[3];
124 byte_as_two_char_type data
[MAXCHUNK
];
125 byte_as_two_char_type checksum
;
130 byte_as_two_char_type address
[2];
131 byte_as_two_char_type data
[MAXCHUNK
];
132 byte_as_two_char_type checksum
;
135 byte_as_two_char_type data
[MAXCHUNK
];
141 called once per input srecord, used to work out vma and size of data.
145 size_srec(abfd
, section
, address
, raw
, length
)
149 byte_as_two_char_type
*raw
;
152 if (address
< section
->vma
)
153 section
->vma
= address
;
155 if (address
+ length
> section
->vma
+ section
->size
)
156 section
->size
= (address
+length
) - section
->vma
;
160 called once per input srecord, copies data from input into malloced area
164 fillup(abfd
, section
, address
, raw
, length
)
168 byte_as_two_char_type
*raw
;
172 bfd_byte
*dst
= (bfd_byte
*)(section
->used_by_bfd
) + address
- section
->vma
;
173 for (i
= 0; i
< length
; i
++) {
181 pass over an srecord file calling one of the above functions on each
185 pass_over(abfd
, func
, section
)
190 unsigned int bytes_on_line
;
193 /* To the front of the file */
194 bfd_seek(abfd
, (file_ptr
)0, SEEK_SET
);
200 eof
= bfd_read(&buffer
.S
, 1, 1, abfd
) != 1;
201 while (buffer
.S
!= 'S' && !eof
) {
202 eof
= bfd_read(&buffer
.S
, 1, 1, abfd
) != 1;
206 bfd_read(&buffer
.type
, 1, 3, abfd
);
208 bytes_on_line
= HEX(&buffer
.size
);
210 bfd_read(buffer
.u
.data
, 1 , bytes_on_line
* 2, abfd
);
212 switch (buffer
.type
) {
214 /* Prologue - ignore */
217 address
= (HEX(buffer
.u
.type_3
.address
+0) << 24)
218 + (HEX(buffer
.u
.type_3
.address
+1) << 16)
219 + (HEX(buffer
.u
.type_3
.address
+2) << 8)
220 + (HEX(buffer
.u
.type_3
.address
+3));
221 func(abfd
,section
, address
, buffer
.u
.type_2
.data
, bytes_on_line
-1);
226 address
= (HEX(buffer
.u
.type_2
.address
+0) << 16)+
227 (HEX(buffer
.u
.type_2
.address
+1) << 8) +
228 (HEX(buffer
.u
.type_2
.address
+2));
229 func(abfd
,section
, address
, buffer
.u
.type_2
.data
, bytes_on_line
-1);
234 (HEX(buffer
.u
.type_1
.address
+0) << 8)
235 + (HEX(buffer
.u
.type_1
.address
+1));
236 func(abfd
, section
, address
, buffer
.u
.type_1
.data
, bytes_on_line
-1);
250 bfd_seek(abfd
, (file_ptr
)0, SEEK_SET
);
251 bfd_read(&b
, 1,1,abfd
);
252 if (b
!= 'S') return (bfd_target
*)NULL
;
255 We create one section called data for all the contents,
256 and allocate enough room for the entire file
260 section
= bfd_make_section(abfd
, ".text");
262 section
->vma
= 0xffffffff;
263 pass_over(abfd
, size_srec
, section
);
276 srec_get_section_contents (abfd
, section
, location
, offset
, count
)
283 if (section
->used_by_bfd
== (bfd_byte
*)NULL
) {
284 section
->used_by_bfd
= (bfd_byte
*)malloc(section
->size
);
285 pass_over(abfd
, fillup
, section
);
287 (void) memcpy(location
, (bfd_byte
*)(section
->used_by_bfd
) + offset
, count
);
294 srec_set_arch_mach (abfd
, arch
, machine
)
296 enum bfd_architecture arch
;
297 unsigned long machine
;
299 abfd
->obj_arch
= arch
;
300 abfd
->obj_machine
= machine
;
307 srec_set_section_contents (abfd
, section
, location
, offset
, bytes_to_do
)
310 unsigned char *location
;
321 if (section
->size
<= 0xffff)
323 else if (section
->size
<= 0xffffff)
329 buffer
.type
= '0' + type
;
331 while (bytes_written
< bytes_to_do
) {
333 unsigned int check_sum
;
334 byte_as_two_char_type
*data
;
335 unsigned int bytes_this_chunk
= bytes_to_do
- bytes_written
;
337 if (bytes_this_chunk
> CHUNK
) {
338 bytes_this_chunk
= CHUNK
;
341 address
= section
->vma
+ offset
+ bytes_written
;
345 check_sum
= TOHEX(buffer
.u
.type_3
.address
, address
>> 24);
346 check_sum
+= TOHEX(buffer
.u
.type_3
.address
+1, address
>> 16);
347 check_sum
+= TOHEX(buffer
.u
.type_3
.address
+2, address
>> 8);
348 check_sum
+= TOHEX(buffer
.u
.type_3
.address
+3, address
>> 0);
349 size
= bytes_this_chunk
+ 5;
350 data
= buffer
.u
.type_3
.data
;
353 check_sum
= TOHEX(buffer
.u
.type_3
.address
, address
>> 16);
354 check_sum
+= TOHEX(buffer
.u
.type_3
.address
+1, address
>> 8);
355 check_sum
+= TOHEX(buffer
.u
.type_3
.address
+2, address
>> 0);
356 size
= bytes_this_chunk
+ 4;
357 data
= buffer
.u
.type_2
.data
;
361 check_sum
= TOHEX(buffer
.u
.type_3
.address
+0, address
>> 8);
362 check_sum
+= TOHEX(buffer
.u
.type_3
.address
+1, address
>> 0);
363 size
= bytes_this_chunk
+ 3;
364 data
= buffer
.u
.type_1
.data
;
367 for (i
= 0; i
< bytes_this_chunk
; i
++) {
368 check_sum
+= TOHEX(data
, (location
[i
]));
372 check_sum
+= TOHEX(&(buffer
.size
), size
);
373 (void) TOHEX(data
, ~check_sum
);
376 * ( (char *)(data
)) = '\n';
377 bfd_write(&buffer
, 1, (char *)data
- (char *)&buffer
+ 1 , abfd
);
379 bytes_written
+= bytes_this_chunk
;
380 location
+= bytes_this_chunk
;
389 srec_close_and_cleanup (abfd
)
393 if (bfd_read_p (abfd
) == false) {
394 switch (abfd
->format
) {
396 if (!_bfd_write_archive_contents (abfd
)) {
401 bfd_write("S9030000FC\n", 1,11,abfd
);
404 bfd_error
= invalid_operation
;
408 for (s
= abfd
->sections
; s
!= (asection
*)NULL
;s
= s
->next
) {
409 if (s
->used_by_bfd
!= (void *)NULL
) {
410 free(s
->used_by_bfd
);
417 #define srec_core_file_failing_command bfd_false
418 #define srec_core_file_failing_signal bfd_false
419 #define srec_core_file_matches_executable_p bfd_false
420 #define srec_slurp_armap bfd_false
421 #define srec_slurp_extended_name_table bfd_false
422 #define srec_truncate_arname bfd_false
423 #define srec_write_armap bfd_false
424 #define srec_new_section_hook bfd_false
425 #define srec_get_symtab_upper_bound bfd_false
426 #define srec_get_symtab bfd_false
427 #define srec_get_reloc_upper_bound bfd_false
428 #define srec_canonicalize_reloc bfd_false
429 #define srec_make_empty_symbol bfd_false
430 #define srec_print_symbol bfd_false
431 #define srec_get_lineno bfd_false
432 #define srec_openr_next_archived_file bfd_false
433 #define srec_find_nearest_line bfd_false
434 #define srec_generic_stat_arch_elt bfd_false
436 bfd_target srec_vec
=
439 bfd_target_srec_flavour_enum
,
440 true, /* target byte order */
441 true, /* target headers byte order */
442 (HAS_RELOC
| EXEC_P
| /* object flags */
443 HAS_LINENO
| HAS_DEBUG
|
444 HAS_SYMS
| HAS_LOCALS
| DYNAMIC
| WP_TEXT
| D_PAGED
),
445 (SEC_CODE
|SEC_DATA
|SEC_ROM
|SEC_HAS_CONTENTS
446 |SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
), /* section flags */
447 ' ', /* ar_pad_char */
448 16, /* ar_max_namelen */
449 _do_getblong
, _do_putblong
, _do_getbshort
, _do_putbshort
, /* data */
450 _do_getblong
, _do_putblong
, _do_getbshort
, _do_putbshort
, /* hdrs */
453 srec_object_p
, /* bfd_check_format */
454 (struct bfd_target
*(*)()) bfd_nullvoidptr
,
455 (struct bfd_target
*(*)()) bfd_nullvoidptr
,
459 bfd_true
, /* mkobject */
460 _bfd_generic_mkarchive
,