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.7 1991/05/08 19:21:47 steve
46 * Various portability lints.
47 * Fixed reloc bug in ieee and oasys.
49 * Revision 1.6 1991/04/25 04:06:21 gnu
50 * Fix minor pointer type problems that "cc" complains about.
52 * Revision 1.5 1991/04/23 22:44:14 steve
53 * *** empty log message ***
55 * Revision 1.4 1991/04/23 16:01:02 steve
56 * *** empty log message ***
58 * Revision 1.3 1991/04/08 23:22:31 steve
59 * *** empty log message ***
61 * Revision 1.2 1991/04/03 22:10:51 steve
64 * Revision 1.1.1.1 1991/03/21 21:11:22 gumby
65 * Back from Intel with Steve
67 * Revision 1.1 1991/03/21 21:11:20 gumby
70 * Revision 1.1 1991/03/13 00:22:29 chrisb
73 * Revision 1.3 1991/03/10 19:11:40 rich
75 * bfd.c coff-code.h libbfd.c libbfd.h srec.c sunos.c
77 * Working bugs out of coff support.
79 * Revision 1.2 1991/03/07 02:26:18 sac
80 * Tidied up xfer table
82 * Revision 1.1 1991/03/05 16:28:12 sac
91 static char digs
[] = "0123456789ABCDEF";
93 /* Macros for converting between hex and binary */
95 #define NIBBLE(x) ((x >= '0' && x <= '9') ? (x - '0') : (x - 'A' + 10))
96 #define HEX(buffer) ((NIBBLE((buffer)->high) <<4) + NIBBLE((buffer)->low))
98 ((d)->low = digs[(x) & 0xf], (d)->high = digs[((x)>>4)&0xf], x)
103 } byte_as_two_char_type
;
105 /* The maximum number of bytes on a line is FF */
106 #define MAXCHUNK 0xff
107 /* The number of bytes we fit onto a line on output */
110 /* The shape of an srecord .. */
115 byte_as_two_char_type size
;
118 byte_as_two_char_type address
[4];
119 byte_as_two_char_type data
[MAXCHUNK
];
120 /* If there isn't MAXCHUNK bytes of data then the checksum will
122 byte_as_two_char_type checksum
;
126 byte_as_two_char_type address
[4];
127 byte_as_two_char_type data
[MAXCHUNK
];
128 byte_as_two_char_type checksum
;
133 byte_as_two_char_type address
[3];
134 byte_as_two_char_type data
[MAXCHUNK
];
135 byte_as_two_char_type checksum
;
140 byte_as_two_char_type address
[2];
141 byte_as_two_char_type data
[MAXCHUNK
];
142 byte_as_two_char_type checksum
;
145 byte_as_two_char_type data
[MAXCHUNK
];
151 called once per input srecord, used to work out vma and size of data.
155 size_srec(abfd
, section
, address
, raw
, length
)
159 byte_as_two_char_type
*raw
;
162 if (address
< section
->vma
)
163 section
->vma
= address
;
165 if (address
+ length
> section
->vma
+ section
->size
)
166 section
->size
= (address
+length
) - section
->vma
;
170 called once per input srecord, copies data from input into malloced area
174 fillup(abfd
, section
, address
, raw
, length
)
178 byte_as_two_char_type
*raw
;
182 bfd_byte
*dst
= (bfd_byte
*)(section
->used_by_bfd
) + address
- section
->vma
;
183 for (i
= 0; i
< length
; i
++) {
191 pass over an srecord file calling one of the above functions on each
195 pass_over(abfd
, func
, section
)
200 unsigned int bytes_on_line
;
203 /* To the front of the file */
204 bfd_seek(abfd
, (file_ptr
)0, SEEK_SET
);
210 eof
= bfd_read(&buffer
.S
, 1, 1, abfd
) != 1;
211 while (buffer
.S
!= 'S' && !eof
) {
212 eof
= bfd_read(&buffer
.S
, 1, 1, abfd
) != 1;
216 bfd_read(&buffer
.type
, 1, 3, abfd
);
218 bytes_on_line
= HEX(&buffer
.size
);
220 bfd_read((PTR
)buffer
.u
.data
, 1 , bytes_on_line
* 2, abfd
);
222 switch (buffer
.type
) {
224 /* Prologue - ignore */
227 address
= (HEX(buffer
.u
.type_3
.address
+0) << 24)
228 + (HEX(buffer
.u
.type_3
.address
+1) << 16)
229 + (HEX(buffer
.u
.type_3
.address
+2) << 8)
230 + (HEX(buffer
.u
.type_3
.address
+3));
231 func(abfd
,section
, address
, buffer
.u
.type_2
.data
, bytes_on_line
-1);
236 address
= (HEX(buffer
.u
.type_2
.address
+0) << 16)+
237 (HEX(buffer
.u
.type_2
.address
+1) << 8) +
238 (HEX(buffer
.u
.type_2
.address
+2));
239 func(abfd
,section
, address
, buffer
.u
.type_2
.data
, bytes_on_line
-1);
244 (HEX(buffer
.u
.type_1
.address
+0) << 8)
245 + (HEX(buffer
.u
.type_1
.address
+1));
246 func(abfd
, section
, address
, buffer
.u
.type_1
.data
, bytes_on_line
-1);
260 bfd_seek(abfd
, (file_ptr
)0, SEEK_SET
);
261 bfd_read(&b
, 1,1,abfd
);
262 if (b
!= 'S') return (bfd_target
*)NULL
;
265 We create one section called data for all the contents,
266 and allocate enough room for the entire file
270 section
= bfd_make_section(abfd
, ".text");
272 section
->vma
= 0xffffffff;
273 pass_over(abfd
, size_srec
, section
);
286 srec_get_section_contents (abfd
, section
, location
, offset
, count
)
293 if (section
->used_by_bfd
== (PTR
)NULL
) {
294 section
->used_by_bfd
= (PTR
)malloc(section
->size
);
295 pass_over(abfd
, fillup
, section
);
297 (void) memcpy(location
, (bfd_byte
*)(section
->used_by_bfd
) + offset
, count
);
304 srec_set_arch_mach (abfd
, arch
, machine
)
306 enum bfd_architecture arch
;
307 unsigned long machine
;
309 abfd
->obj_arch
= arch
;
310 abfd
->obj_machine
= machine
;
317 srec_set_section_contents (abfd
, section
, location
, offset
, bytes_to_do
)
320 unsigned char *location
;
331 if (section
->size
<= 0xffff)
333 else if (section
->size
<= 0xffffff)
339 buffer
.type
= '0' + type
;
341 while (bytes_written
< bytes_to_do
) {
343 unsigned int check_sum
;
344 byte_as_two_char_type
*data
;
345 unsigned int bytes_this_chunk
= bytes_to_do
- bytes_written
;
347 if (bytes_this_chunk
> CHUNK
) {
348 bytes_this_chunk
= CHUNK
;
351 address
= section
->vma
+ offset
+ bytes_written
;
355 check_sum
= TOHEX(buffer
.u
.type_3
.address
, address
>> 24);
356 check_sum
+= TOHEX(buffer
.u
.type_3
.address
+1, address
>> 16);
357 check_sum
+= TOHEX(buffer
.u
.type_3
.address
+2, address
>> 8);
358 check_sum
+= TOHEX(buffer
.u
.type_3
.address
+3, address
>> 0);
359 size
= bytes_this_chunk
+ 5;
360 data
= buffer
.u
.type_3
.data
;
363 check_sum
= TOHEX(buffer
.u
.type_3
.address
, address
>> 16);
364 check_sum
+= TOHEX(buffer
.u
.type_3
.address
+1, address
>> 8);
365 check_sum
+= TOHEX(buffer
.u
.type_3
.address
+2, address
>> 0);
366 size
= bytes_this_chunk
+ 4;
367 data
= buffer
.u
.type_2
.data
;
371 check_sum
= TOHEX(buffer
.u
.type_3
.address
+0, address
>> 8);
372 check_sum
+= TOHEX(buffer
.u
.type_3
.address
+1, address
>> 0);
373 size
= bytes_this_chunk
+ 3;
374 data
= buffer
.u
.type_1
.data
;
377 for (i
= 0; i
< bytes_this_chunk
; i
++) {
378 check_sum
+= TOHEX(data
, (location
[i
]));
382 check_sum
+= TOHEX(&(buffer
.size
), size
);
383 (void) TOHEX(data
, ~check_sum
);
386 * ( (char *)(data
)) = '\n';
387 bfd_write((PTR
)&buffer
, 1, (char *)data
- (char *)&buffer
+ 1 , abfd
);
389 bytes_written
+= bytes_this_chunk
;
390 location
+= bytes_this_chunk
;
399 srec_close_and_cleanup (abfd
)
403 if (bfd_read_p (abfd
) == false) {
404 switch (abfd
->format
) {
406 if (!_bfd_write_archive_contents (abfd
)) {
411 bfd_write("S9030000FC\n", 1,11,abfd
);
414 bfd_error
= invalid_operation
;
418 for (s
= abfd
->sections
; s
!= (asection
*)NULL
;s
= s
->next
) {
419 if (s
->used_by_bfd
!= (void *)NULL
) {
420 free(s
->used_by_bfd
);
427 DEFUN(srec_sizeof_headers
,(abfd
),
435 #define srec_new_section_hook bfd_false
436 #define srec_get_symtab_upper_bound bfd_false
437 #define srec_get_symtab bfd_false
438 #define srec_get_reloc_upper_bound bfd_false
439 #define srec_canonicalize_reloc bfd_false
440 #define srec_make_empty_symbol bfd_false
441 #define srec_print_symbol bfd_false
443 #define srec_openr_next_archived_file bfd_false
444 #define srec_find_nearest_line bfd_false
445 #define srec_generic_stat_arch_elt bfd_false
448 #define srec_core_file_failing_command (char *(*)())(bfd_nullvoidptr)
449 #define srec_core_file_failing_signal (int (*)())bfd_0
450 #define srec_core_file_matches_executable_p (PROTO(boolean, (*),(bfd*, bfd*)))bfd_false
451 #define srec_slurp_armap bfd_true
452 #define srec_slurp_extended_name_table bfd_true
453 #define srec_truncate_arname (void (*)())bfd_nullvoidptr
454 #define srec_write_armap (PROTO( boolean, (*),(bfd *, unsigned int, struct orl *, int, int))) bfd_nullvoidptr
455 #define srec_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
458 bfd_target srec_vec
=
461 bfd_target_srec_flavour_enum
,
462 true, /* target byte order */
463 true, /* target headers byte order */
464 (HAS_RELOC
| EXEC_P
| /* object flags */
465 HAS_LINENO
| HAS_DEBUG
|
466 HAS_SYMS
| HAS_LOCALS
| DYNAMIC
| WP_TEXT
| D_PAGED
),
467 (SEC_CODE
|SEC_DATA
|SEC_ROM
|SEC_HAS_CONTENTS
468 |SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
), /* section flags */
469 ' ', /* ar_pad_char */
470 16, /* ar_max_namelen */
471 _do_getblong
, _do_putblong
, _do_getbshort
, _do_putbshort
, /* data */
472 _do_getblong
, _do_putblong
, _do_getbshort
, _do_putbshort
, /* hdrs */
475 srec_object_p
, /* bfd_check_format */
476 (struct bfd_target
*(*)()) bfd_nullvoidptr
,
477 (struct bfd_target
*(*)()) bfd_nullvoidptr
,
481 bfd_true
, /* mkobject */
482 _bfd_generic_mkarchive
,