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 bfd_alloc'd 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.8 1991/05/11 00:38:46 gnu
46 * Cleanups of interface, including close_and_cleanup and write_contents
47 * transfer vector changes. See ChangeLog.
49 * Revision 1.7 1991/05/08 19:21:47 steve
50 * Various portability lints.
51 * Fixed reloc bug in ieee and oasys.
53 * Revision 1.6 1991/04/25 04:06:21 gnu
54 * Fix minor pointer type problems that "cc" complains about.
56 * Revision 1.5 1991/04/23 22:44:14 steve
57 * *** empty log message ***
59 * Revision 1.4 1991/04/23 16:01:02 steve
60 * *** empty log message ***
62 * Revision 1.3 1991/04/08 23:22:31 steve
63 * *** empty log message ***
65 * Revision 1.2 1991/04/03 22:10:51 steve
68 * Revision 1.1.1.1 1991/03/21 21:11:22 gumby
69 * Back from Intel with Steve
71 * Revision 1.1 1991/03/21 21:11:20 gumby
74 * Revision 1.1 1991/03/13 00:22:29 chrisb
77 * Revision 1.3 1991/03/10 19:11:40 rich
79 * bfd.c coff-code.h libbfd.c libbfd.h srec.c sunos.c
81 * Working bugs out of coff support.
83 * Revision 1.2 1991/03/07 02:26:18 sac
84 * Tidied up xfer table
86 * Revision 1.1 1991/03/05 16:28:12 sac
95 static char digs
[] = "0123456789ABCDEF";
97 /* Macros for converting between hex and binary */
99 #define NIBBLE(x) ((x >= '0' && x <= '9') ? (x - '0') : (x - 'A' + 10))
100 #define HEX(buffer) ((NIBBLE((buffer)->high) <<4) + NIBBLE((buffer)->low))
102 ((d)->low = digs[(x) & 0xf], (d)->high = digs[((x)>>4)&0xf], x)
107 } byte_as_two_char_type
;
109 /* The maximum number of bytes on a line is FF */
110 #define MAXCHUNK 0xff
111 /* The number of bytes we fit onto a line on output */
114 /* The shape of an srecord .. */
119 byte_as_two_char_type size
;
122 byte_as_two_char_type address
[4];
123 byte_as_two_char_type data
[MAXCHUNK
];
124 /* If there isn't MAXCHUNK bytes of data then the checksum will
126 byte_as_two_char_type checksum
;
130 byte_as_two_char_type address
[4];
131 byte_as_two_char_type data
[MAXCHUNK
];
132 byte_as_two_char_type checksum
;
137 byte_as_two_char_type address
[3];
138 byte_as_two_char_type data
[MAXCHUNK
];
139 byte_as_two_char_type checksum
;
144 byte_as_two_char_type address
[2];
145 byte_as_two_char_type data
[MAXCHUNK
];
146 byte_as_two_char_type checksum
;
149 byte_as_two_char_type data
[MAXCHUNK
];
155 called once per input srecord, used to work out vma and size of data.
159 size_srec(abfd
, section
, address
, raw
, length
)
163 byte_as_two_char_type
*raw
;
166 if (address
< section
->vma
)
167 section
->vma
= address
;
169 if (address
+ length
> section
->vma
+ section
->size
)
170 section
->size
= (address
+length
) - section
->vma
;
174 called once per input srecord, copies data from input into bfd_alloc'd area
178 fillup(abfd
, section
, address
, raw
, length
)
182 byte_as_two_char_type
*raw
;
186 bfd_byte
*dst
= (bfd_byte
*)(section
->used_by_bfd
) + address
- section
->vma
;
187 for (i
= 0; i
< length
; i
++) {
195 pass over an srecord file calling one of the above functions on each
199 pass_over(abfd
, func
, section
)
204 unsigned int bytes_on_line
;
207 /* To the front of the file */
208 bfd_seek(abfd
, (file_ptr
)0, SEEK_SET
);
214 eof
= bfd_read(&buffer
.S
, 1, 1, abfd
) != 1;
215 while (buffer
.S
!= 'S' && !eof
) {
216 eof
= bfd_read(&buffer
.S
, 1, 1, abfd
) != 1;
220 bfd_read(&buffer
.type
, 1, 3, abfd
);
222 bytes_on_line
= HEX(&buffer
.size
);
224 bfd_read((PTR
)buffer
.u
.data
, 1 , bytes_on_line
* 2, abfd
);
226 switch (buffer
.type
) {
228 /* Prologue - ignore */
231 address
= (HEX(buffer
.u
.type_3
.address
+0) << 24)
232 + (HEX(buffer
.u
.type_3
.address
+1) << 16)
233 + (HEX(buffer
.u
.type_3
.address
+2) << 8)
234 + (HEX(buffer
.u
.type_3
.address
+3));
235 func(abfd
,section
, address
, buffer
.u
.type_2
.data
, bytes_on_line
-1);
240 address
= (HEX(buffer
.u
.type_2
.address
+0) << 16)+
241 (HEX(buffer
.u
.type_2
.address
+1) << 8) +
242 (HEX(buffer
.u
.type_2
.address
+2));
243 func(abfd
,section
, address
, buffer
.u
.type_2
.data
, bytes_on_line
-1);
248 (HEX(buffer
.u
.type_1
.address
+0) << 8)
249 + (HEX(buffer
.u
.type_1
.address
+1));
250 func(abfd
, section
, address
, buffer
.u
.type_1
.data
, bytes_on_line
-1);
264 bfd_seek(abfd
, (file_ptr
)0, SEEK_SET
);
265 bfd_read(&b
, 1,1,abfd
);
266 if (b
!= 'S') return (bfd_target
*)NULL
;
269 We create one section called data for all the contents,
270 and allocate enough room for the entire file
274 section
= bfd_make_section(abfd
, ".text");
276 section
->vma
= 0xffffffff;
277 pass_over(abfd
, size_srec
, section
);
290 srec_get_section_contents (abfd
, section
, location
, offset
, count
)
297 if (section
->used_by_bfd
== (PTR
)NULL
) {
298 section
->used_by_bfd
= (PTR
)bfd_alloc (abfd
, section
->size
);
299 pass_over(abfd
, fillup
, section
);
301 (void) memcpy(location
, (bfd_byte
*)(section
->used_by_bfd
) + offset
, count
);
308 srec_set_arch_mach (abfd
, arch
, machine
)
310 enum bfd_architecture arch
;
311 unsigned long machine
;
313 abfd
->obj_arch
= arch
;
314 abfd
->obj_machine
= machine
;
321 srec_set_section_contents (abfd
, section
, location
, offset
, bytes_to_do
)
324 unsigned char *location
;
335 if (section
->size
<= 0xffff)
337 else if (section
->size
<= 0xffffff)
343 buffer
.type
= '0' + type
;
345 while (bytes_written
< bytes_to_do
) {
347 unsigned int check_sum
;
348 byte_as_two_char_type
*data
;
349 unsigned int bytes_this_chunk
= bytes_to_do
- bytes_written
;
351 if (bytes_this_chunk
> CHUNK
) {
352 bytes_this_chunk
= CHUNK
;
355 address
= section
->vma
+ offset
+ bytes_written
;
359 check_sum
= TOHEX(buffer
.u
.type_3
.address
, address
>> 24);
360 check_sum
+= TOHEX(buffer
.u
.type_3
.address
+1, address
>> 16);
361 check_sum
+= TOHEX(buffer
.u
.type_3
.address
+2, address
>> 8);
362 check_sum
+= TOHEX(buffer
.u
.type_3
.address
+3, address
>> 0);
363 size
= bytes_this_chunk
+ 5;
364 data
= buffer
.u
.type_3
.data
;
367 check_sum
= TOHEX(buffer
.u
.type_3
.address
, address
>> 16);
368 check_sum
+= TOHEX(buffer
.u
.type_3
.address
+1, address
>> 8);
369 check_sum
+= TOHEX(buffer
.u
.type_3
.address
+2, address
>> 0);
370 size
= bytes_this_chunk
+ 4;
371 data
= buffer
.u
.type_2
.data
;
375 check_sum
= TOHEX(buffer
.u
.type_3
.address
+0, address
>> 8);
376 check_sum
+= TOHEX(buffer
.u
.type_3
.address
+1, address
>> 0);
377 size
= bytes_this_chunk
+ 3;
378 data
= buffer
.u
.type_1
.data
;
381 for (i
= 0; i
< bytes_this_chunk
; i
++) {
382 check_sum
+= TOHEX(data
, (location
[i
]));
386 check_sum
+= TOHEX(&(buffer
.size
), size
);
387 (void) TOHEX(data
, ~check_sum
);
390 * ( (char *)(data
)) = '\n';
391 bfd_write((PTR
)&buffer
, 1, (char *)data
- (char *)&buffer
+ 1 , abfd
);
393 bytes_written
+= bytes_this_chunk
;
394 location
+= bytes_this_chunk
;
402 srec_write_object_contents (abfd
)
405 bfd_write("S9030000FC\n", 1,11,abfd
);
409 DEFUN(srec_sizeof_headers
,(abfd
),
417 #define srec_new_section_hook bfd_false
418 #define srec_get_symtab_upper_bound bfd_false
419 #define srec_get_symtab bfd_false
420 #define srec_get_reloc_upper_bound bfd_false
421 #define srec_canonicalize_reloc bfd_false
422 #define srec_make_empty_symbol bfd_false
423 #define srec_print_symbol bfd_false
425 #define srec_openr_next_archived_file bfd_false
426 #define srec_find_nearest_line bfd_false
427 #define srec_generic_stat_arch_elt bfd_false
430 #define srec_core_file_failing_command (char *(*)())(bfd_nullvoidptr)
431 #define srec_core_file_failing_signal (int (*)())bfd_0
432 #define srec_core_file_matches_executable_p (PROTO(boolean, (*),(bfd*, bfd*)))bfd_false
433 #define srec_slurp_armap bfd_true
434 #define srec_slurp_extended_name_table bfd_true
435 #define srec_truncate_arname (void (*)())bfd_nullvoidptr
436 #define srec_write_armap (PROTO( boolean, (*),(bfd *, unsigned int, struct orl *, int, int))) bfd_nullvoidptr
437 #define srec_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
439 #define srec_close_and_cleanup bfd_generic_close_and_cleanup
442 bfd_target srec_vec
=
445 bfd_target_srec_flavour_enum
,
446 true, /* target byte order */
447 true, /* target headers byte order */
448 (HAS_RELOC
| EXEC_P
| /* object flags */
449 HAS_LINENO
| HAS_DEBUG
|
450 HAS_SYMS
| HAS_LOCALS
| DYNAMIC
| WP_TEXT
| D_PAGED
),
451 (SEC_CODE
|SEC_DATA
|SEC_ROM
|SEC_HAS_CONTENTS
452 |SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
), /* section flags */
453 ' ', /* ar_pad_char */
454 16, /* ar_max_namelen */
455 _do_getblong
, _do_putblong
, _do_getbshort
, _do_putbshort
, /* data */
456 _do_getblong
, _do_putblong
, _do_getbshort
, _do_putbshort
, /* hdrs */
459 srec_object_p
, /* bfd_check_format */
460 (struct bfd_target
*(*)()) bfd_nullvoidptr
,
461 (struct bfd_target
*(*)()) bfd_nullvoidptr
,
465 bfd_true
, /* mkobject */
466 _bfd_generic_mkarchive
,
469 { /* bfd_write_contents */
471 srec_write_object_contents
,
472 _bfd_write_archive_contents
,