File: | src/gnu/usr.bin/binutils/bfd/srec.c |
Warning: | line 550, column 13 Array access (from variable 'data') results in a null pointer dereference |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* BFD back-end for s-record objects. | |||
2 | Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, | |||
3 | 2000, 2001, 2002, 2003 | |||
4 | Free Software Foundation, Inc. | |||
5 | Written by Steve Chamberlain of Cygnus Support <sac@cygnus.com>. | |||
6 | ||||
7 | This file is part of BFD, the Binary File Descriptor library. | |||
8 | ||||
9 | This program is free software; you can redistribute it and/or modify | |||
10 | it under the terms of the GNU General Public License as published by | |||
11 | the Free Software Foundation; either version 2 of the License, or | |||
12 | (at your option) any later version. | |||
13 | ||||
14 | This program is distributed in the hope that it will be useful, | |||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
17 | GNU General Public License for more details. | |||
18 | ||||
19 | You should have received a copy of the GNU General Public License | |||
20 | along with this program; if not, write to the Free Software | |||
21 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | |||
22 | ||||
23 | /* | |||
24 | SUBSECTION | |||
25 | S-Record handling | |||
26 | ||||
27 | DESCRIPTION | |||
28 | ||||
29 | Ordinary S-Records cannot hold anything but addresses and | |||
30 | data, so that's all that we implement. | |||
31 | ||||
32 | The only interesting thing is that S-Records may come out of | |||
33 | order and there is no header, so an initial scan is required | |||
34 | to discover the minimum and maximum addresses used to create | |||
35 | the vma and size of the only section we create. We | |||
36 | arbitrarily call this section ".text". | |||
37 | ||||
38 | When bfd_get_section_contents is called the file is read | |||
39 | again, and this time the data is placed into a bfd_alloc'd | |||
40 | area. | |||
41 | ||||
42 | Any number of sections may be created for output, we save them | |||
43 | up and output them when it's time to close the bfd. | |||
44 | ||||
45 | An s record looks like: | |||
46 | ||||
47 | EXAMPLE | |||
48 | S<type><length><address><data><checksum> | |||
49 | ||||
50 | DESCRIPTION | |||
51 | Where | |||
52 | o length | |||
53 | is the number of bytes following upto the checksum. Note that | |||
54 | this is not the number of chars following, since it takes two | |||
55 | chars to represent a byte. | |||
56 | o type | |||
57 | is one of: | |||
58 | 0) header record | |||
59 | 1) two byte address data record | |||
60 | 2) three byte address data record | |||
61 | 3) four byte address data record | |||
62 | 7) four byte address termination record | |||
63 | 8) three byte address termination record | |||
64 | 9) two byte address termination record | |||
65 | ||||
66 | o address | |||
67 | is the start address of the data following, or in the case of | |||
68 | a termination record, the start address of the image | |||
69 | o data | |||
70 | is the data. | |||
71 | o checksum | |||
72 | is the sum of all the raw byte data in the record, from the length | |||
73 | upwards, modulo 256 and subtracted from 255. | |||
74 | ||||
75 | SUBSECTION | |||
76 | Symbol S-Record handling | |||
77 | ||||
78 | DESCRIPTION | |||
79 | Some ICE equipment understands an addition to the standard | |||
80 | S-Record format; symbols and their addresses can be sent | |||
81 | before the data. | |||
82 | ||||
83 | The format of this is: | |||
84 | ($$ <modulename> | |||
85 | (<space> <symbol> <address>)*) | |||
86 | $$ | |||
87 | ||||
88 | so a short symbol table could look like: | |||
89 | ||||
90 | EXAMPLE | |||
91 | $$ flash.x | |||
92 | $$ flash.c | |||
93 | _port6 $0 | |||
94 | _delay $4 | |||
95 | _start $14 | |||
96 | _etext $8036 | |||
97 | _edata $8036 | |||
98 | _end $8036 | |||
99 | $$ | |||
100 | ||||
101 | DESCRIPTION | |||
102 | We allow symbols to be anywhere in the data stream - the module names | |||
103 | are always ignored. | |||
104 | ||||
105 | */ | |||
106 | ||||
107 | #include "bfd.h" | |||
108 | #include "sysdep.h" | |||
109 | #include "libbfd.h" | |||
110 | #include "libiberty.h" | |||
111 | #include "safe-ctype.h" | |||
112 | ||||
113 | static void srec_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *))(bfd *, asymbol *, symbol_info *); | |||
114 | static void srec_print_symbol | |||
115 | PARAMS ((bfd *, PTR, asymbol *, bfd_print_symbol_type))(bfd *, void *, asymbol *, bfd_print_symbol_type); | |||
116 | static void srec_init PARAMS ((void))(void); | |||
117 | static bfd_boolean srec_mkobject PARAMS ((bfd *))(bfd *); | |||
118 | static int srec_get_byte PARAMS ((bfd *, bfd_boolean *))(bfd *, bfd_boolean *); | |||
119 | static void srec_bad_byte PARAMS ((bfd *, unsigned int, int, bfd_boolean))(bfd *, unsigned int, int, bfd_boolean); | |||
120 | static bfd_boolean srec_scan PARAMS ((bfd *))(bfd *); | |||
121 | static const bfd_target *srec_object_p PARAMS ((bfd *))(bfd *); | |||
122 | static const bfd_target *symbolsrec_object_p PARAMS ((bfd *))(bfd *); | |||
123 | static bfd_boolean srec_read_section PARAMS ((bfd *, asection *, bfd_byte *))(bfd *, asection *, bfd_byte *); | |||
124 | ||||
125 | static bfd_boolean srec_write_record | |||
126 | PARAMS ((bfd *, unsigned int, bfd_vma, const bfd_byte *, const bfd_byte *))(bfd *, unsigned int, bfd_vma, const bfd_byte *, const bfd_byte *); | |||
127 | static bfd_boolean srec_write_header PARAMS ((bfd *))(bfd *); | |||
128 | static bfd_boolean srec_write_symbols PARAMS ((bfd *))(bfd *); | |||
129 | static bfd_boolean srec_new_symbol PARAMS ((bfd *, const char *, bfd_vma))(bfd *, const char *, bfd_vma); | |||
130 | static bfd_boolean srec_get_section_contents | |||
131 | PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type))(bfd *, asection *, void *, file_ptr, bfd_size_type); | |||
132 | static bfd_boolean srec_set_arch_mach | |||
133 | PARAMS ((bfd *, enum bfd_architecture, unsigned long))(bfd *, enum bfd_architecture, unsigned long); | |||
134 | static bfd_boolean srec_set_section_contents | |||
135 | PARAMS ((bfd *, sec_ptr, const PTR, file_ptr, bfd_size_type))(bfd *, sec_ptr, const void *, file_ptr, bfd_size_type); | |||
136 | static bfd_boolean internal_srec_write_object_contents PARAMS ((bfd *, int))(bfd *, int); | |||
137 | static bfd_boolean srec_write_object_contents PARAMS ((bfd *))(bfd *); | |||
138 | static bfd_boolean symbolsrec_write_object_contents PARAMS ((bfd *))(bfd *); | |||
139 | static int srec_sizeof_headers PARAMS ((bfd *, bfd_boolean))(bfd *, bfd_boolean); | |||
140 | static long srec_get_symtab_upper_bound PARAMS ((bfd *))(bfd *); | |||
141 | static long srec_canonicalize_symtab PARAMS ((bfd *, asymbol **))(bfd *, asymbol **); | |||
142 | ||||
143 | /* Macros for converting between hex and binary. */ | |||
144 | ||||
145 | static const char digs[] = "0123456789ABCDEF"; | |||
146 | ||||
147 | #define NIBBLE(x)((unsigned int) _hex_value[(unsigned char) (x)]) hex_value(x)((unsigned int) _hex_value[(unsigned char) (x)]) | |||
148 | #define HEX(buffer)((((unsigned int) _hex_value[(unsigned char) ((buffer)[0])])<< 4) + ((unsigned int) _hex_value[(unsigned char) ((buffer)[1]) ])) ((NIBBLE((buffer)[0])((unsigned int) _hex_value[(unsigned char) ((buffer)[0])])<<4) + NIBBLE((buffer)[1])((unsigned int) _hex_value[(unsigned char) ((buffer)[1])])) | |||
149 | #define TOHEX(d, x, ch)d[1] = digs[(x) & 0xf]; d[0] = digs[((x)>>4)&0xf ]; ch += ((x) & 0xff); \ | |||
150 | d[1] = digs[(x) & 0xf]; \ | |||
151 | d[0] = digs[((x)>>4)&0xf]; \ | |||
152 | ch += ((x) & 0xff); | |||
153 | #define ISHEX(x)(((unsigned int) _hex_value[(unsigned char) (x)]) != 99) hex_p(x)(((unsigned int) _hex_value[(unsigned char) (x)]) != 99) | |||
154 | ||||
155 | /* Initialize by filling in the hex conversion array. */ | |||
156 | ||||
157 | static void | |||
158 | srec_init () | |||
159 | { | |||
160 | static bfd_boolean inited = FALSE0; | |||
161 | ||||
162 | if (! inited) | |||
163 | { | |||
164 | inited = TRUE1; | |||
165 | hex_init (); | |||
166 | } | |||
167 | } | |||
168 | ||||
169 | /* The maximum number of address+data+crc bytes on a line is FF. */ | |||
170 | #define MAXCHUNK0xff 0xff | |||
171 | ||||
172 | /* Default size for a CHUNK. */ | |||
173 | #define DEFAULT_CHUNK16 16 | |||
174 | ||||
175 | /* The number of data bytes we actually fit onto a line on output. | |||
176 | This variable can be modified by objcopy's --srec-len parameter. | |||
177 | For a 0x75 byte record you should set --srec-len=0x70. */ | |||
178 | unsigned int Chunk = DEFAULT_CHUNK16; | |||
179 | ||||
180 | /* The type of srec output (free or forced to S3). | |||
181 | This variable can be modified by objcopy's --srec-forceS3 | |||
182 | parameter. */ | |||
183 | bfd_boolean S3Forced = FALSE0; | |||
184 | ||||
185 | /* When writing an S-record file, the S-records can not be output as | |||
186 | they are seen. This structure is used to hold them in memory. */ | |||
187 | ||||
188 | struct srec_data_list_struct | |||
189 | { | |||
190 | struct srec_data_list_struct *next; | |||
191 | bfd_byte *data; | |||
192 | bfd_vma where; | |||
193 | bfd_size_type size; | |||
194 | }; | |||
195 | ||||
196 | typedef struct srec_data_list_struct srec_data_list_type; | |||
197 | ||||
198 | /* When scanning the S-record file, a linked list of srec_symbol | |||
199 | structures is built to represent the symbol table (if there is | |||
200 | one). */ | |||
201 | ||||
202 | struct srec_symbol | |||
203 | { | |||
204 | struct srec_symbol *next; | |||
205 | const char *name; | |||
206 | bfd_vma val; | |||
207 | }; | |||
208 | ||||
209 | /* The S-record tdata information. */ | |||
210 | ||||
211 | typedef struct srec_data_struct | |||
212 | { | |||
213 | srec_data_list_type *head; | |||
214 | srec_data_list_type *tail; | |||
215 | unsigned int type; | |||
216 | struct srec_symbol *symbols; | |||
217 | struct srec_symbol *symtail; | |||
218 | asymbol *csymbols; | |||
219 | } | |||
220 | tdata_type; | |||
221 | ||||
222 | static bfd_boolean srec_write_section | |||
223 | PARAMS ((bfd *, tdata_type *, srec_data_list_type *))(bfd *, tdata_type *, srec_data_list_type *); | |||
224 | static bfd_boolean srec_write_terminator | |||
225 | PARAMS ((bfd *, tdata_type *))(bfd *, tdata_type *); | |||
226 | ||||
227 | /* Set up the S-record tdata information. */ | |||
228 | ||||
229 | static bfd_boolean | |||
230 | srec_mkobject (abfd) | |||
231 | bfd *abfd; | |||
232 | { | |||
233 | bfd_size_type amt; | |||
234 | tdata_type *tdata; | |||
235 | ||||
236 | srec_init (); | |||
237 | ||||
238 | amt = sizeof (tdata_type); | |||
239 | tdata = (tdata_type *) bfd_alloc (abfd, amt); | |||
240 | if (tdata == NULL((void*)0)) | |||
241 | return FALSE0; | |||
242 | ||||
243 | abfd->tdata.srec_data = tdata; | |||
244 | tdata->type = 1; | |||
245 | tdata->head = NULL((void*)0); | |||
246 | tdata->tail = NULL((void*)0); | |||
247 | tdata->symbols = NULL((void*)0); | |||
248 | tdata->symtail = NULL((void*)0); | |||
249 | tdata->csymbols = NULL((void*)0); | |||
250 | ||||
251 | return TRUE1; | |||
252 | } | |||
253 | ||||
254 | /* Read a byte from an S record file. Set *ERRORPTR if an error | |||
255 | occurred. Return EOF on error or end of file. */ | |||
256 | ||||
257 | static int | |||
258 | srec_get_byte (abfd, errorptr) | |||
259 | bfd *abfd; | |||
260 | bfd_boolean *errorptr; | |||
261 | { | |||
262 | bfd_byte c; | |||
263 | ||||
264 | if (bfd_bread (&c, (bfd_size_type) 1, abfd) != 1) | |||
265 | { | |||
266 | if (bfd_get_error () != bfd_error_file_truncated) | |||
267 | *errorptr = TRUE1; | |||
268 | return EOF(-1); | |||
269 | } | |||
270 | ||||
271 | return (int) (c & 0xff); | |||
272 | } | |||
273 | ||||
274 | /* Report a problem in an S record file. FIXME: This probably should | |||
275 | not call fprintf, but we really do need some mechanism for printing | |||
276 | error messages. */ | |||
277 | ||||
278 | static void | |||
279 | srec_bad_byte (abfd, lineno, c, error) | |||
280 | bfd *abfd; | |||
281 | unsigned int lineno; | |||
282 | int c; | |||
283 | bfd_boolean error; | |||
284 | { | |||
285 | if (c == EOF(-1)) | |||
286 | { | |||
287 | if (! error) | |||
288 | bfd_set_error (bfd_error_file_truncated); | |||
289 | } | |||
290 | else | |||
291 | { | |||
292 | char buf[10]; | |||
293 | ||||
294 | if (! ISPRINT (c)(_sch_istable[(c) & 0xff] & (unsigned short)(_sch_isprint ))) | |||
295 | sprintf (buf, "\\%03o", (unsigned int) c); | |||
296 | else | |||
297 | { | |||
298 | buf[0] = c; | |||
299 | buf[1] = '\0'; | |||
300 | } | |||
301 | (*_bfd_error_handler) | |||
302 | (_("%s:%d: Unexpected character `%s' in S-record file\n")("%s:%d: Unexpected character `%s' in S-record file\n"), | |||
303 | bfd_archive_filename (abfd), lineno, buf); | |||
304 | bfd_set_error (bfd_error_bad_value); | |||
305 | } | |||
306 | } | |||
307 | ||||
308 | /* Add a new symbol found in an S-record file. */ | |||
309 | ||||
310 | static bfd_boolean | |||
311 | srec_new_symbol (abfd, name, val) | |||
312 | bfd *abfd; | |||
313 | const char *name; | |||
314 | bfd_vma val; | |||
315 | { | |||
316 | struct srec_symbol *n; | |||
317 | bfd_size_type amt = sizeof (struct srec_symbol); | |||
318 | ||||
319 | n = (struct srec_symbol *) bfd_alloc (abfd, amt); | |||
320 | if (n == NULL((void*)0)) | |||
321 | return FALSE0; | |||
322 | ||||
323 | n->name = name; | |||
324 | n->val = val; | |||
325 | ||||
326 | if (abfd->tdata.srec_data->symbols == NULL((void*)0)) | |||
327 | abfd->tdata.srec_data->symbols = n; | |||
328 | else | |||
329 | abfd->tdata.srec_data->symtail->next = n; | |||
330 | abfd->tdata.srec_data->symtail = n; | |||
331 | n->next = NULL((void*)0); | |||
332 | ||||
333 | ++abfd->symcount; | |||
334 | ||||
335 | return TRUE1; | |||
336 | } | |||
337 | ||||
338 | /* Read the S record file and turn it into sections. We create a new | |||
339 | section for each contiguous set of bytes. */ | |||
340 | ||||
341 | static bfd_boolean | |||
342 | srec_scan (abfd) | |||
343 | bfd *abfd; | |||
344 | { | |||
345 | int c; | |||
346 | unsigned int lineno = 1; | |||
347 | bfd_boolean error = FALSE0; | |||
348 | bfd_byte *buf = NULL((void*)0); | |||
| ||||
349 | size_t bufsize = 0; | |||
350 | asection *sec = NULL((void*)0); | |||
351 | char *symbuf = NULL((void*)0); | |||
352 | ||||
353 | if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET0) != 0) | |||
354 | goto error_return; | |||
355 | ||||
356 | while ((c = srec_get_byte (abfd, &error)) != EOF(-1)) | |||
357 | { | |||
358 | /* We only build sections from contiguous S-records, so if this | |||
359 | is not an S-record, then stop building a section. */ | |||
360 | if (c != 'S' && c != '\r' && c != '\n') | |||
361 | sec = NULL((void*)0); | |||
362 | ||||
363 | switch (c) | |||
364 | { | |||
365 | default: | |||
366 | srec_bad_byte (abfd, lineno, c, error); | |||
367 | goto error_return; | |||
368 | ||||
369 | case '\n': | |||
370 | ++lineno; | |||
371 | break; | |||
372 | ||||
373 | case '\r': | |||
374 | break; | |||
375 | ||||
376 | case '$': | |||
377 | /* Starting a module name, which we ignore. */ | |||
378 | while ((c = srec_get_byte (abfd, &error)) != '\n' | |||
379 | && c != EOF(-1)) | |||
380 | ; | |||
381 | if (c == EOF(-1)) | |||
382 | { | |||
383 | srec_bad_byte (abfd, lineno, c, error); | |||
384 | goto error_return; | |||
385 | } | |||
386 | ||||
387 | ++lineno; | |||
388 | ||||
389 | break; | |||
390 | ||||
391 | case ' ': | |||
392 | do | |||
393 | { | |||
394 | bfd_size_type alc; | |||
395 | char *p, *symname; | |||
396 | bfd_vma symval; | |||
397 | ||||
398 | /* Starting a symbol definition. */ | |||
399 | while ((c = srec_get_byte (abfd, &error)) != EOF(-1) | |||
400 | && (c == ' ' || c == '\t')) | |||
401 | ; | |||
402 | ||||
403 | if (c == '\n' || c == '\r') | |||
404 | break; | |||
405 | ||||
406 | if (c == EOF(-1)) | |||
407 | { | |||
408 | srec_bad_byte (abfd, lineno, c, error); | |||
409 | goto error_return; | |||
410 | } | |||
411 | ||||
412 | alc = 10; | |||
413 | symbuf = (char *) bfd_malloc (alc + 1); | |||
414 | if (symbuf == NULL((void*)0)) | |||
415 | goto error_return; | |||
416 | ||||
417 | p = symbuf; | |||
418 | ||||
419 | *p++ = c; | |||
420 | while ((c = srec_get_byte (abfd, &error)) != EOF(-1) | |||
421 | && ! ISSPACE (c)(_sch_istable[(c) & 0xff] & (unsigned short)(_sch_isspace ))) | |||
422 | { | |||
423 | if ((bfd_size_type) (p - symbuf) >= alc) | |||
424 | { | |||
425 | char *n; | |||
426 | ||||
427 | alc *= 2; | |||
428 | n = (char *) bfd_realloc (symbuf, alc + 1); | |||
429 | if (n == NULL((void*)0)) | |||
430 | goto error_return; | |||
431 | p = n + (p - symbuf); | |||
432 | symbuf = n; | |||
433 | } | |||
434 | ||||
435 | *p++ = c; | |||
436 | } | |||
437 | ||||
438 | if (c == EOF(-1)) | |||
439 | { | |||
440 | srec_bad_byte (abfd, lineno, c, error); | |||
441 | goto error_return; | |||
442 | } | |||
443 | ||||
444 | *p++ = '\0'; | |||
445 | symname = bfd_alloc (abfd, (bfd_size_type) (p - symbuf)); | |||
446 | if (symname == NULL((void*)0)) | |||
447 | goto error_return; | |||
448 | strcpy (symname, symbuf); | |||
449 | free (symbuf); | |||
450 | symbuf = NULL((void*)0); | |||
451 | ||||
452 | while ((c = srec_get_byte (abfd, &error)) != EOF(-1) | |||
453 | && (c == ' ' || c == '\t')) | |||
454 | ; | |||
455 | if (c == EOF(-1)) | |||
456 | { | |||
457 | srec_bad_byte (abfd, lineno, c, error); | |||
458 | goto error_return; | |||
459 | } | |||
460 | ||||
461 | /* Skip a dollar sign before the hex value. */ | |||
462 | if (c == '$') | |||
463 | { | |||
464 | c = srec_get_byte (abfd, &error); | |||
465 | if (c == EOF(-1)) | |||
466 | { | |||
467 | srec_bad_byte (abfd, lineno, c, error); | |||
468 | goto error_return; | |||
469 | } | |||
470 | } | |||
471 | ||||
472 | symval = 0; | |||
473 | while (ISHEX (c)(((unsigned int) _hex_value[(unsigned char) (c)]) != 99)) | |||
474 | { | |||
475 | symval <<= 4; | |||
476 | symval += NIBBLE (c)((unsigned int) _hex_value[(unsigned char) (c)]); | |||
477 | c = srec_get_byte (abfd, &error); | |||
478 | } | |||
479 | ||||
480 | if (! srec_new_symbol (abfd, symname, symval)) | |||
481 | goto error_return; | |||
482 | } | |||
483 | while (c == ' ' || c == '\t') | |||
484 | ; | |||
485 | ||||
486 | if (c == '\n') | |||
487 | ++lineno; | |||
488 | else if (c != '\r') | |||
489 | { | |||
490 | srec_bad_byte (abfd, lineno, c, error); | |||
491 | goto error_return; | |||
492 | } | |||
493 | ||||
494 | break; | |||
495 | ||||
496 | case 'S': | |||
497 | { | |||
498 | file_ptr pos; | |||
499 | char hdr[3]; | |||
500 | unsigned int bytes; | |||
501 | bfd_vma address; | |||
502 | bfd_byte *data; | |||
503 | ||||
504 | /* Starting an S-record. */ | |||
505 | ||||
506 | pos = bfd_tell (abfd) - 1; | |||
507 | ||||
508 | if (bfd_bread (hdr, (bfd_size_type) 3, abfd) != 3) | |||
509 | goto error_return; | |||
510 | ||||
511 | if (! ISHEX (hdr[1])(((unsigned int) _hex_value[(unsigned char) (hdr[1])]) != 99) || ! ISHEX (hdr[2])(((unsigned int) _hex_value[(unsigned char) (hdr[2])]) != 99)) | |||
512 | { | |||
513 | if (! ISHEX (hdr[1])(((unsigned int) _hex_value[(unsigned char) (hdr[1])]) != 99)) | |||
514 | c = hdr[1]; | |||
515 | else | |||
516 | c = hdr[2]; | |||
517 | srec_bad_byte (abfd, lineno, c, error); | |||
518 | goto error_return; | |||
519 | } | |||
520 | ||||
521 | bytes = HEX (hdr + 1)((((unsigned int) _hex_value[(unsigned char) ((hdr + 1)[0])]) <<4) + ((unsigned int) _hex_value[(unsigned char) ((hdr + 1)[1])])); | |||
522 | if (bytes * 2 > bufsize) | |||
523 | { | |||
524 | if (buf != NULL((void*)0)) | |||
525 | free (buf); | |||
526 | buf = (bfd_byte *) bfd_malloc ((bfd_size_type) bytes * 2); | |||
527 | if (buf == NULL((void*)0)) | |||
528 | goto error_return; | |||
529 | bufsize = bytes * 2; | |||
530 | } | |||
531 | ||||
532 | if (bfd_bread (buf, (bfd_size_type) bytes * 2, abfd) != bytes * 2) | |||
533 | goto error_return; | |||
534 | ||||
535 | /* Ignore the checksum byte. */ | |||
536 | --bytes; | |||
537 | ||||
538 | address = 0; | |||
539 | data = buf; | |||
540 | switch (hdr[0]) | |||
541 | { | |||
542 | case '0': | |||
543 | case '5': | |||
544 | /* Prologue--ignore the file name, but stop building a | |||
545 | section at this point. */ | |||
546 | sec = NULL((void*)0); | |||
547 | break; | |||
548 | ||||
549 | case '3': | |||
550 | address = HEX (data)((((unsigned int) _hex_value[(unsigned char) ((data)[0])])<< 4) + ((unsigned int) _hex_value[(unsigned char) ((data)[1])]) ); | |||
| ||||
551 | data += 2; | |||
552 | --bytes; | |||
553 | /* Fall through. */ | |||
554 | case '2': | |||
555 | address = (address << 8) | HEX (data)((((unsigned int) _hex_value[(unsigned char) ((data)[0])])<< 4) + ((unsigned int) _hex_value[(unsigned char) ((data)[1])]) ); | |||
556 | data += 2; | |||
557 | --bytes; | |||
558 | /* Fall through. */ | |||
559 | case '1': | |||
560 | address = (address << 8) | HEX (data)((((unsigned int) _hex_value[(unsigned char) ((data)[0])])<< 4) + ((unsigned int) _hex_value[(unsigned char) ((data)[1])]) ); | |||
561 | data += 2; | |||
562 | address = (address << 8) | HEX (data)((((unsigned int) _hex_value[(unsigned char) ((data)[0])])<< 4) + ((unsigned int) _hex_value[(unsigned char) ((data)[1])]) ); | |||
563 | data += 2; | |||
564 | bytes -= 2; | |||
565 | ||||
566 | if (sec != NULL((void*)0) | |||
567 | && sec->vma + sec->_raw_size == address) | |||
568 | { | |||
569 | /* This data goes at the end of the section we are | |||
570 | currently building. */ | |||
571 | sec->_raw_size += bytes; | |||
572 | } | |||
573 | else | |||
574 | { | |||
575 | char secbuf[20]; | |||
576 | char *secname; | |||
577 | bfd_size_type amt; | |||
578 | ||||
579 | sprintf (secbuf, ".sec%d", bfd_count_sections (abfd)((abfd)->section_count) + 1); | |||
580 | amt = strlen (secbuf) + 1; | |||
581 | secname = (char *) bfd_alloc (abfd, amt); | |||
582 | strcpy (secname, secbuf); | |||
583 | sec = bfd_make_section (abfd, secname); | |||
584 | if (sec == NULL((void*)0)) | |||
585 | goto error_return; | |||
586 | sec->flags = SEC_HAS_CONTENTS0x200 | SEC_LOAD0x002 | SEC_ALLOC0x001; | |||
587 | sec->vma = address; | |||
588 | sec->lma = address; | |||
589 | sec->_raw_size = bytes; | |||
590 | sec->filepos = pos; | |||
591 | } | |||
592 | ||||
593 | break; | |||
594 | ||||
595 | case '7': | |||
596 | address = HEX (data)((((unsigned int) _hex_value[(unsigned char) ((data)[0])])<< 4) + ((unsigned int) _hex_value[(unsigned char) ((data)[1])]) ); | |||
597 | data += 2; | |||
598 | /* Fall through. */ | |||
599 | case '8': | |||
600 | address = (address << 8) | HEX (data)((((unsigned int) _hex_value[(unsigned char) ((data)[0])])<< 4) + ((unsigned int) _hex_value[(unsigned char) ((data)[1])]) ); | |||
601 | data += 2; | |||
602 | /* Fall through. */ | |||
603 | case '9': | |||
604 | address = (address << 8) | HEX (data)((((unsigned int) _hex_value[(unsigned char) ((data)[0])])<< 4) + ((unsigned int) _hex_value[(unsigned char) ((data)[1])]) ); | |||
605 | data += 2; | |||
606 | address = (address << 8) | HEX (data)((((unsigned int) _hex_value[(unsigned char) ((data)[0])])<< 4) + ((unsigned int) _hex_value[(unsigned char) ((data)[1])]) ); | |||
607 | data += 2; | |||
608 | ||||
609 | /* This is a termination record. */ | |||
610 | abfd->start_address = address; | |||
611 | ||||
612 | if (buf != NULL((void*)0)) | |||
613 | free (buf); | |||
614 | ||||
615 | return TRUE1; | |||
616 | } | |||
617 | } | |||
618 | break; | |||
619 | } | |||
620 | } | |||
621 | ||||
622 | if (error) | |||
623 | goto error_return; | |||
624 | ||||
625 | if (buf != NULL((void*)0)) | |||
626 | free (buf); | |||
627 | ||||
628 | return TRUE1; | |||
629 | ||||
630 | error_return: | |||
631 | if (symbuf != NULL((void*)0)) | |||
632 | free (symbuf); | |||
633 | if (buf != NULL((void*)0)) | |||
634 | free (buf); | |||
635 | return FALSE0; | |||
636 | } | |||
637 | ||||
638 | /* Check whether an existing file is an S-record file. */ | |||
639 | ||||
640 | static const bfd_target * | |||
641 | srec_object_p (abfd) | |||
642 | bfd *abfd; | |||
643 | { | |||
644 | PTRvoid * tdata_save; | |||
645 | bfd_byte b[4]; | |||
646 | ||||
647 | srec_init (); | |||
648 | ||||
649 | if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET0) != 0 | |||
650 | || bfd_bread (b, (bfd_size_type) 4, abfd) != 4) | |||
651 | return NULL((void*)0); | |||
652 | ||||
653 | if (b[0] != 'S' || !ISHEX (b[1])(((unsigned int) _hex_value[(unsigned char) (b[1])]) != 99) || !ISHEX (b[2])(((unsigned int) _hex_value[(unsigned char) (b[2])]) != 99) || !ISHEX (b[3])(((unsigned int) _hex_value[(unsigned char) (b[3])]) != 99)) | |||
654 | { | |||
655 | bfd_set_error (bfd_error_wrong_format); | |||
656 | return NULL((void*)0); | |||
657 | } | |||
658 | ||||
659 | tdata_save = abfd->tdata.any; | |||
660 | if (! srec_mkobject (abfd) || ! srec_scan (abfd)) | |||
661 | { | |||
662 | if (abfd->tdata.any != tdata_save && abfd->tdata.any != NULL((void*)0)) | |||
663 | bfd_release (abfd, abfd->tdata.any); | |||
664 | abfd->tdata.any = tdata_save; | |||
665 | return NULL((void*)0); | |||
666 | } | |||
667 | ||||
668 | if (abfd->symcount > 0) | |||
669 | abfd->flags |= HAS_SYMS0x10; | |||
670 | ||||
671 | return abfd->xvec; | |||
672 | } | |||
673 | ||||
674 | /* Check whether an existing file is an S-record file with symbols. */ | |||
675 | ||||
676 | static const bfd_target * | |||
677 | symbolsrec_object_p (abfd) | |||
678 | bfd *abfd; | |||
679 | { | |||
680 | PTRvoid * tdata_save; | |||
681 | char b[2]; | |||
682 | ||||
683 | srec_init (); | |||
684 | ||||
685 | if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET0) != 0 | |||
686 | || bfd_bread (b, (bfd_size_type) 2, abfd) != 2) | |||
687 | return NULL((void*)0); | |||
688 | ||||
689 | if (b[0] != '$' || b[1] != '$') | |||
690 | { | |||
691 | bfd_set_error (bfd_error_wrong_format); | |||
692 | return NULL((void*)0); | |||
693 | } | |||
694 | ||||
695 | tdata_save = abfd->tdata.any; | |||
696 | if (! srec_mkobject (abfd) || ! srec_scan (abfd)) | |||
697 | { | |||
698 | if (abfd->tdata.any != tdata_save && abfd->tdata.any != NULL((void*)0)) | |||
699 | bfd_release (abfd, abfd->tdata.any); | |||
700 | abfd->tdata.any = tdata_save; | |||
701 | return NULL((void*)0); | |||
702 | } | |||
703 | ||||
704 | if (abfd->symcount > 0) | |||
705 | abfd->flags |= HAS_SYMS0x10; | |||
706 | ||||
707 | return abfd->xvec; | |||
708 | } | |||
709 | ||||
710 | /* Read in the contents of a section in an S-record file. */ | |||
711 | ||||
712 | static bfd_boolean | |||
713 | srec_read_section (abfd, section, contents) | |||
714 | bfd *abfd; | |||
715 | asection *section; | |||
716 | bfd_byte *contents; | |||
717 | { | |||
718 | int c; | |||
719 | bfd_size_type sofar = 0; | |||
720 | bfd_boolean error = FALSE0; | |||
721 | bfd_byte *buf = NULL((void*)0); | |||
722 | size_t bufsize = 0; | |||
723 | ||||
724 | if (bfd_seek (abfd, section->filepos, SEEK_SET0) != 0) | |||
725 | goto error_return; | |||
726 | ||||
727 | while ((c = srec_get_byte (abfd, &error)) != EOF(-1)) | |||
728 | { | |||
729 | bfd_byte hdr[3]; | |||
730 | unsigned int bytes; | |||
731 | bfd_vma address; | |||
732 | bfd_byte *data; | |||
733 | ||||
734 | if (c == '\r' || c == '\n') | |||
735 | continue; | |||
736 | ||||
737 | /* This is called after srec_scan has already been called, so we | |||
738 | ought to know the exact format. */ | |||
739 | BFD_ASSERT (c == 'S'){ if (!(c == 'S')) bfd_assert("/usr/src/gnu/usr.bin/binutils/bfd/srec.c" ,739); }; | |||
740 | ||||
741 | if (bfd_bread (hdr, (bfd_size_type) 3, abfd) != 3) | |||
742 | goto error_return; | |||
743 | ||||
744 | BFD_ASSERT (ISHEX (hdr[1]) && ISHEX (hdr[2])){ if (!((((unsigned int) _hex_value[(unsigned char) (hdr[1])] ) != 99) && (((unsigned int) _hex_value[(unsigned char ) (hdr[2])]) != 99))) bfd_assert("/usr/src/gnu/usr.bin/binutils/bfd/srec.c" ,744); }; | |||
745 | ||||
746 | bytes = HEX (hdr + 1)((((unsigned int) _hex_value[(unsigned char) ((hdr + 1)[0])]) <<4) + ((unsigned int) _hex_value[(unsigned char) ((hdr + 1)[1])])); | |||
747 | ||||
748 | if (bytes * 2 > bufsize) | |||
749 | { | |||
750 | if (buf != NULL((void*)0)) | |||
751 | free (buf); | |||
752 | buf = (bfd_byte *) bfd_malloc ((bfd_size_type) bytes * 2); | |||
753 | if (buf == NULL((void*)0)) | |||
754 | goto error_return; | |||
755 | bufsize = bytes * 2; | |||
756 | } | |||
757 | ||||
758 | if (bfd_bread (buf, (bfd_size_type) bytes * 2, abfd) != bytes * 2) | |||
759 | goto error_return; | |||
760 | ||||
761 | address = 0; | |||
762 | data = buf; | |||
763 | switch (hdr[0]) | |||
764 | { | |||
765 | default: | |||
766 | BFD_ASSERT (sofar == section->_raw_size){ if (!(sofar == section->_raw_size)) bfd_assert("/usr/src/gnu/usr.bin/binutils/bfd/srec.c" ,766); }; | |||
767 | if (buf != NULL((void*)0)) | |||
768 | free (buf); | |||
769 | return TRUE1; | |||
770 | ||||
771 | case '3': | |||
772 | address = HEX (data)((((unsigned int) _hex_value[(unsigned char) ((data)[0])])<< 4) + ((unsigned int) _hex_value[(unsigned char) ((data)[1])]) ); | |||
773 | data += 2; | |||
774 | --bytes; | |||
775 | /* Fall through. */ | |||
776 | case '2': | |||
777 | address = (address << 8) | HEX (data)((((unsigned int) _hex_value[(unsigned char) ((data)[0])])<< 4) + ((unsigned int) _hex_value[(unsigned char) ((data)[1])]) ); | |||
778 | data += 2; | |||
779 | --bytes; | |||
780 | /* Fall through. */ | |||
781 | case '1': | |||
782 | address = (address << 8) | HEX (data)((((unsigned int) _hex_value[(unsigned char) ((data)[0])])<< 4) + ((unsigned int) _hex_value[(unsigned char) ((data)[1])]) ); | |||
783 | data += 2; | |||
784 | address = (address << 8) | HEX (data)((((unsigned int) _hex_value[(unsigned char) ((data)[0])])<< 4) + ((unsigned int) _hex_value[(unsigned char) ((data)[1])]) ); | |||
785 | data += 2; | |||
786 | bytes -= 2; | |||
787 | ||||
788 | if (address != section->vma + sofar) | |||
789 | { | |||
790 | /* We've come to the end of this section. */ | |||
791 | BFD_ASSERT (sofar == section->_raw_size){ if (!(sofar == section->_raw_size)) bfd_assert("/usr/src/gnu/usr.bin/binutils/bfd/srec.c" ,791); }; | |||
792 | if (buf != NULL((void*)0)) | |||
793 | free (buf); | |||
794 | return TRUE1; | |||
795 | } | |||
796 | ||||
797 | /* Don't consider checksum. */ | |||
798 | --bytes; | |||
799 | ||||
800 | while (bytes-- != 0) | |||
801 | { | |||
802 | contents[sofar] = HEX (data)((((unsigned int) _hex_value[(unsigned char) ((data)[0])])<< 4) + ((unsigned int) _hex_value[(unsigned char) ((data)[1])]) ); | |||
803 | data += 2; | |||
804 | ++sofar; | |||
805 | } | |||
806 | ||||
807 | break; | |||
808 | } | |||
809 | } | |||
810 | ||||
811 | if (error) | |||
812 | goto error_return; | |||
813 | ||||
814 | BFD_ASSERT (sofar == section->_raw_size){ if (!(sofar == section->_raw_size)) bfd_assert("/usr/src/gnu/usr.bin/binutils/bfd/srec.c" ,814); }; | |||
815 | ||||
816 | if (buf != NULL((void*)0)) | |||
817 | free (buf); | |||
818 | ||||
819 | return TRUE1; | |||
820 | ||||
821 | error_return: | |||
822 | if (buf != NULL((void*)0)) | |||
823 | free (buf); | |||
824 | return FALSE0; | |||
825 | } | |||
826 | ||||
827 | /* Get the contents of a section in an S-record file. */ | |||
828 | ||||
829 | static bfd_boolean | |||
830 | srec_get_section_contents (abfd, section, location, offset, count) | |||
831 | bfd *abfd; | |||
832 | asection *section; | |||
833 | PTRvoid * location; | |||
834 | file_ptr offset; | |||
835 | bfd_size_type count; | |||
836 | { | |||
837 | if (section->used_by_bfd == NULL((void*)0)) | |||
838 | { | |||
839 | section->used_by_bfd = bfd_alloc (abfd, section->_raw_size); | |||
840 | if (section->used_by_bfd == NULL((void*)0) && section->_raw_size != 0) | |||
841 | return FALSE0; | |||
842 | ||||
843 | if (! srec_read_section (abfd, section, section->used_by_bfd)) | |||
844 | return FALSE0; | |||
845 | } | |||
846 | ||||
847 | memcpy (location, (bfd_byte *) section->used_by_bfd + offset, | |||
848 | (size_t) count); | |||
849 | ||||
850 | return TRUE1; | |||
851 | } | |||
852 | ||||
853 | /* Set the architecture. We accept an unknown architecture here. */ | |||
854 | ||||
855 | static bfd_boolean | |||
856 | srec_set_arch_mach (abfd, arch, mach) | |||
857 | bfd *abfd; | |||
858 | enum bfd_architecture arch; | |||
859 | unsigned long mach; | |||
860 | { | |||
861 | if (arch == bfd_arch_unknown) | |||
862 | { | |||
863 | abfd->arch_info = &bfd_default_arch_struct; | |||
864 | return TRUE1; | |||
865 | } | |||
866 | return bfd_default_set_arch_mach (abfd, arch, mach); | |||
867 | } | |||
868 | ||||
869 | /* We have to save up all the Srecords for a splurge before output. */ | |||
870 | ||||
871 | static bfd_boolean | |||
872 | srec_set_section_contents (abfd, section, location, offset, bytes_to_do) | |||
873 | bfd *abfd; | |||
874 | sec_ptr section; | |||
875 | const PTRvoid * location; | |||
876 | file_ptr offset; | |||
877 | bfd_size_type bytes_to_do; | |||
878 | { | |||
879 | tdata_type *tdata = abfd->tdata.srec_data; | |||
880 | register srec_data_list_type *entry; | |||
881 | ||||
882 | entry = ((srec_data_list_type *) | |||
883 | bfd_alloc (abfd, (bfd_size_type) sizeof (srec_data_list_type))); | |||
884 | if (entry == NULL((void*)0)) | |||
885 | return FALSE0; | |||
886 | ||||
887 | if (bytes_to_do | |||
888 | && (section->flags & SEC_ALLOC0x001) | |||
889 | && (section->flags & SEC_LOAD0x002)) | |||
890 | { | |||
891 | bfd_byte *data; | |||
892 | ||||
893 | data = (bfd_byte *) bfd_alloc (abfd, bytes_to_do); | |||
894 | if (data == NULL((void*)0)) | |||
895 | return FALSE0; | |||
896 | memcpy ((PTRvoid *) data, location, (size_t) bytes_to_do); | |||
897 | ||||
898 | /* Ff S3Forced is TRUE then always select S3 records, | |||
899 | regardless of the siez of the addresses. */ | |||
900 | if (S3Forced) | |||
901 | tdata->type = 3; | |||
902 | else if ((section->lma + offset + bytes_to_do - 1) <= 0xffff) | |||
903 | ; /* The default, S1, is OK. */ | |||
904 | else if ((section->lma + offset + bytes_to_do - 1) <= 0xffffff | |||
905 | && tdata->type <= 2) | |||
906 | tdata->type = 2; | |||
907 | else | |||
908 | tdata->type = 3; | |||
909 | ||||
910 | entry->data = data; | |||
911 | entry->where = section->lma + offset; | |||
912 | entry->size = bytes_to_do; | |||
913 | ||||
914 | /* Sort the records by address. Optimize for the common case of | |||
915 | adding a record to the end of the list. */ | |||
916 | if (tdata->tail != NULL((void*)0) | |||
917 | && entry->where >= tdata->tail->where) | |||
918 | { | |||
919 | tdata->tail->next = entry; | |||
920 | entry->next = NULL((void*)0); | |||
921 | tdata->tail = entry; | |||
922 | } | |||
923 | else | |||
924 | { | |||
925 | register srec_data_list_type **look; | |||
926 | ||||
927 | for (look = &tdata->head; | |||
928 | *look != NULL((void*)0) && (*look)->where < entry->where; | |||
929 | look = &(*look)->next) | |||
930 | ; | |||
931 | entry->next = *look; | |||
932 | *look = entry; | |||
933 | if (entry->next == NULL((void*)0)) | |||
934 | tdata->tail = entry; | |||
935 | } | |||
936 | } | |||
937 | return TRUE1; | |||
938 | } | |||
939 | ||||
940 | /* Write a record of type, of the supplied number of bytes. The | |||
941 | supplied bytes and length don't have a checksum. That's worked out | |||
942 | here. */ | |||
943 | ||||
944 | static bfd_boolean | |||
945 | srec_write_record (abfd, type, address, data, end) | |||
946 | bfd *abfd; | |||
947 | unsigned int type; | |||
948 | bfd_vma address; | |||
949 | const bfd_byte *data; | |||
950 | const bfd_byte *end; | |||
951 | { | |||
952 | char buffer[2 * MAXCHUNK0xff + 6]; | |||
953 | unsigned int check_sum = 0; | |||
954 | const bfd_byte *src = data; | |||
955 | char *dst = buffer; | |||
956 | char *length; | |||
957 | bfd_size_type wrlen; | |||
958 | ||||
959 | *dst++ = 'S'; | |||
960 | *dst++ = '0' + type; | |||
961 | ||||
962 | length = dst; | |||
963 | dst += 2; /* Leave room for dst. */ | |||
964 | ||||
965 | switch (type) | |||
966 | { | |||
967 | case 3: | |||
968 | case 7: | |||
969 | TOHEX (dst, (address >> 24), check_sum)dst[1] = digs[((address >> 24)) & 0xf]; dst[0] = digs [(((address >> 24))>>4)&0xf]; check_sum += (( (address >> 24)) & 0xff);; | |||
970 | dst += 2; | |||
971 | case 8: | |||
972 | case 2: | |||
973 | TOHEX (dst, (address >> 16), check_sum)dst[1] = digs[((address >> 16)) & 0xf]; dst[0] = digs [(((address >> 16))>>4)&0xf]; check_sum += (( (address >> 16)) & 0xff);; | |||
974 | dst += 2; | |||
975 | case 9: | |||
976 | case 1: | |||
977 | case 0: | |||
978 | TOHEX (dst, (address >> 8), check_sum)dst[1] = digs[((address >> 8)) & 0xf]; dst[0] = digs [(((address >> 8))>>4)&0xf]; check_sum += ((( address >> 8)) & 0xff);; | |||
979 | dst += 2; | |||
980 | TOHEX (dst, (address), check_sum)dst[1] = digs[((address)) & 0xf]; dst[0] = digs[(((address ))>>4)&0xf]; check_sum += (((address)) & 0xff);; | |||
981 | dst += 2; | |||
982 | break; | |||
983 | ||||
984 | } | |||
985 | for (src = data; src < end; src++) | |||
986 | { | |||
987 | TOHEX (dst, *src, check_sum)dst[1] = digs[(*src) & 0xf]; dst[0] = digs[((*src)>> 4)&0xf]; check_sum += ((*src) & 0xff);; | |||
988 | dst += 2; | |||
989 | } | |||
990 | ||||
991 | /* Fill in the length. */ | |||
992 | TOHEX (length, (dst - length) / 2, check_sum)length[1] = digs[((dst - length) / 2) & 0xf]; length[0] = digs[(((dst - length) / 2)>>4)&0xf]; check_sum += ( ((dst - length) / 2) & 0xff);; | |||
993 | check_sum &= 0xff; | |||
994 | check_sum = 255 - check_sum; | |||
995 | TOHEX (dst, check_sum, check_sum)dst[1] = digs[(check_sum) & 0xf]; dst[0] = digs[((check_sum )>>4)&0xf]; check_sum += ((check_sum) & 0xff);; | |||
996 | dst += 2; | |||
997 | ||||
998 | *dst++ = '\r'; | |||
999 | *dst++ = '\n'; | |||
1000 | wrlen = dst - buffer; | |||
1001 | if (bfd_bwrite ((PTRvoid *) buffer, wrlen, abfd) != wrlen) | |||
1002 | return FALSE0; | |||
1003 | return TRUE1; | |||
1004 | } | |||
1005 | ||||
1006 | static bfd_boolean | |||
1007 | srec_write_header (abfd) | |||
1008 | bfd *abfd; | |||
1009 | { | |||
1010 | unsigned int len = strlen (abfd->filename); | |||
1011 | ||||
1012 | /* I'll put an arbitrary 40 char limit on header size. */ | |||
1013 | if (len > 40) | |||
1014 | len = 40; | |||
1015 | ||||
1016 | return srec_write_record (abfd, 0, (bfd_vma) 0, | |||
1017 | abfd->filename, abfd->filename + len); | |||
1018 | } | |||
1019 | ||||
1020 | static bfd_boolean | |||
1021 | srec_write_section (abfd, tdata, list) | |||
1022 | bfd *abfd; | |||
1023 | tdata_type *tdata; | |||
1024 | srec_data_list_type *list; | |||
1025 | { | |||
1026 | unsigned int octets_written = 0; | |||
1027 | bfd_byte *location = list->data; | |||
1028 | ||||
1029 | /* Validate number of data bytes to write. The srec length byte | |||
1030 | counts the address, data and crc bytes. S1 (tdata->type == 1) | |||
1031 | records have two address bytes, S2 (tdata->type == 2) records | |||
1032 | have three, and S3 (tdata->type == 3) records have four. | |||
1033 | The total length can't exceed 255, and a zero data length will | |||
1034 | spin for a long time. */ | |||
1035 | if (Chunk == 0) | |||
1036 | Chunk = 1; | |||
1037 | else if (Chunk > MAXCHUNK0xff - tdata->type - 2) | |||
1038 | Chunk = MAXCHUNK0xff - tdata->type - 2; | |||
1039 | ||||
1040 | while (octets_written < list->size) | |||
1041 | { | |||
1042 | bfd_vma address; | |||
1043 | unsigned int octets_this_chunk = list->size - octets_written; | |||
1044 | ||||
1045 | if (octets_this_chunk > Chunk) | |||
1046 | octets_this_chunk = Chunk; | |||
1047 | ||||
1048 | address = list->where + octets_written / bfd_octets_per_byte (abfd); | |||
1049 | ||||
1050 | if (! srec_write_record (abfd, | |||
1051 | tdata->type, | |||
1052 | address, | |||
1053 | location, | |||
1054 | location + octets_this_chunk)) | |||
1055 | return FALSE0; | |||
1056 | ||||
1057 | octets_written += octets_this_chunk; | |||
1058 | location += octets_this_chunk; | |||
1059 | } | |||
1060 | ||||
1061 | return TRUE1; | |||
1062 | } | |||
1063 | ||||
1064 | static bfd_boolean | |||
1065 | srec_write_terminator (abfd, tdata) | |||
1066 | bfd *abfd; | |||
1067 | tdata_type *tdata; | |||
1068 | { | |||
1069 | return srec_write_record (abfd, 10 - tdata->type, | |||
1070 | abfd->start_address, NULL((void*)0), NULL((void*)0)); | |||
1071 | } | |||
1072 | ||||
1073 | static bfd_boolean | |||
1074 | srec_write_symbols (abfd) | |||
1075 | bfd *abfd; | |||
1076 | { | |||
1077 | /* Dump out the symbols of a bfd. */ | |||
1078 | int i; | |||
1079 | int count = bfd_get_symcount (abfd)((abfd)->symcount); | |||
1080 | ||||
1081 | if (count) | |||
1082 | { | |||
1083 | bfd_size_type len; | |||
1084 | asymbol **table = bfd_get_outsymbols (abfd)((abfd)->outsymbols); | |||
1085 | len = strlen (abfd->filename); | |||
1086 | if (bfd_bwrite ("$$ ", (bfd_size_type) 3, abfd) != 3 | |||
1087 | || bfd_bwrite (abfd->filename, len, abfd) != len | |||
1088 | || bfd_bwrite ("\r\n", (bfd_size_type) 2, abfd) != 2) | |||
1089 | return FALSE0; | |||
1090 | ||||
1091 | for (i = 0; i < count; i++) | |||
1092 | { | |||
1093 | asymbol *s = table[i]; | |||
1094 | if (! bfd_is_local_label (abfd, s) | |||
1095 | && (s->flags & BSF_DEBUGGING0x08) == 0) | |||
1096 | { | |||
1097 | /* Just dump out non debug symbols. */ | |||
1098 | char buf[43], *p; | |||
1099 | ||||
1100 | len = strlen (s->name); | |||
1101 | if (bfd_bwrite (" ", (bfd_size_type) 2, abfd) != 2 | |||
1102 | || bfd_bwrite (s->name, len, abfd) != len) | |||
1103 | return FALSE0; | |||
1104 | ||||
1105 | sprintf_vma (buf + 2, (s->valuesprintf (buf + 2, "%016lx", (s->value + s->section-> output_section->lma + s->section->output_offset)) | |||
1106 | + s->section->output_section->lmasprintf (buf + 2, "%016lx", (s->value + s->section-> output_section->lma + s->section->output_offset)) | |||
1107 | + s->section->output_offset))sprintf (buf + 2, "%016lx", (s->value + s->section-> output_section->lma + s->section->output_offset)); | |||
1108 | p = buf + 2; | |||
1109 | while (p[0] == '0' && p[1] != 0) | |||
1110 | p++; | |||
1111 | len = strlen (p); | |||
1112 | p[len] = '\r'; | |||
1113 | p[len + 1] = '\n'; | |||
1114 | *--p = '$'; | |||
1115 | *--p = ' '; | |||
1116 | len += 4; | |||
1117 | if (bfd_bwrite (p, len, abfd) != len) | |||
1118 | return FALSE0; | |||
1119 | } | |||
1120 | } | |||
1121 | if (bfd_bwrite ("$$ \r\n", (bfd_size_type) 5, abfd) != 5) | |||
1122 | return FALSE0; | |||
1123 | } | |||
1124 | ||||
1125 | return TRUE1; | |||
1126 | } | |||
1127 | ||||
1128 | static bfd_boolean | |||
1129 | internal_srec_write_object_contents (abfd, symbols) | |||
1130 | bfd *abfd; | |||
1131 | int symbols; | |||
1132 | { | |||
1133 | tdata_type *tdata = abfd->tdata.srec_data; | |||
1134 | srec_data_list_type *list; | |||
1135 | ||||
1136 | if (symbols) | |||
1137 | { | |||
1138 | if (! srec_write_symbols (abfd)) | |||
1139 | return FALSE0; | |||
1140 | } | |||
1141 | ||||
1142 | if (! srec_write_header (abfd)) | |||
1143 | return FALSE0; | |||
1144 | ||||
1145 | /* Now wander though all the sections provided and output them. */ | |||
1146 | list = tdata->head; | |||
1147 | ||||
1148 | while (list != (srec_data_list_type *) NULL((void*)0)) | |||
1149 | { | |||
1150 | if (! srec_write_section (abfd, tdata, list)) | |||
1151 | return FALSE0; | |||
1152 | list = list->next; | |||
1153 | } | |||
1154 | return srec_write_terminator (abfd, tdata); | |||
1155 | } | |||
1156 | ||||
1157 | static bfd_boolean | |||
1158 | srec_write_object_contents (abfd) | |||
1159 | bfd *abfd; | |||
1160 | { | |||
1161 | return internal_srec_write_object_contents (abfd, 0); | |||
1162 | } | |||
1163 | ||||
1164 | static bfd_boolean | |||
1165 | symbolsrec_write_object_contents (abfd) | |||
1166 | bfd *abfd; | |||
1167 | { | |||
1168 | return internal_srec_write_object_contents (abfd, 1); | |||
1169 | } | |||
1170 | ||||
1171 | static int | |||
1172 | srec_sizeof_headers (abfd, exec) | |||
1173 | bfd *abfd ATTRIBUTE_UNUSED__attribute__ ((__unused__)); | |||
1174 | bfd_boolean exec ATTRIBUTE_UNUSED__attribute__ ((__unused__)); | |||
1175 | { | |||
1176 | return 0; | |||
1177 | } | |||
1178 | ||||
1179 | /* Return the amount of memory needed to read the symbol table. */ | |||
1180 | ||||
1181 | static long | |||
1182 | srec_get_symtab_upper_bound (abfd) | |||
1183 | bfd *abfd; | |||
1184 | { | |||
1185 | return (bfd_get_symcount (abfd)((abfd)->symcount) + 1) * sizeof (asymbol *); | |||
1186 | } | |||
1187 | ||||
1188 | /* Return the symbol table. */ | |||
1189 | ||||
1190 | static long | |||
1191 | srec_canonicalize_symtab (abfd, alocation) | |||
1192 | bfd *abfd; | |||
1193 | asymbol **alocation; | |||
1194 | { | |||
1195 | bfd_size_type symcount = bfd_get_symcount (abfd)((abfd)->symcount); | |||
1196 | asymbol *csymbols; | |||
1197 | unsigned int i; | |||
1198 | ||||
1199 | csymbols = abfd->tdata.srec_data->csymbols; | |||
1200 | if (csymbols == NULL((void*)0)) | |||
1201 | { | |||
1202 | asymbol *c; | |||
1203 | struct srec_symbol *s; | |||
1204 | ||||
1205 | csymbols = (asymbol *) bfd_alloc (abfd, symcount * sizeof (asymbol)); | |||
1206 | if (csymbols == NULL((void*)0) && symcount != 0) | |||
1207 | return 0; | |||
1208 | abfd->tdata.srec_data->csymbols = csymbols; | |||
1209 | ||||
1210 | for (s = abfd->tdata.srec_data->symbols, c = csymbols; | |||
1211 | s != NULL((void*)0); | |||
1212 | s = s->next, ++c) | |||
1213 | { | |||
1214 | c->the_bfd = abfd; | |||
1215 | c->name = s->name; | |||
1216 | c->value = s->val; | |||
1217 | c->flags = BSF_GLOBAL0x02; | |||
1218 | c->section = bfd_abs_section_ptr((asection *) &bfd_abs_section); | |||
1219 | c->udata.p = NULL((void*)0); | |||
1220 | } | |||
1221 | } | |||
1222 | ||||
1223 | for (i = 0; i < symcount; i++) | |||
1224 | *alocation++ = csymbols++; | |||
1225 | *alocation = NULL((void*)0); | |||
1226 | ||||
1227 | return symcount; | |||
1228 | } | |||
1229 | ||||
1230 | static void | |||
1231 | srec_get_symbol_info (ignore_abfd, symbol, ret) | |||
1232 | bfd *ignore_abfd ATTRIBUTE_UNUSED__attribute__ ((__unused__)); | |||
1233 | asymbol *symbol; | |||
1234 | symbol_info *ret; | |||
1235 | { | |||
1236 | bfd_symbol_info (symbol, ret); | |||
1237 | } | |||
1238 | ||||
1239 | static void | |||
1240 | srec_print_symbol (abfd, afile, symbol, how) | |||
1241 | bfd *abfd; | |||
1242 | PTRvoid * afile; | |||
1243 | asymbol *symbol; | |||
1244 | bfd_print_symbol_type how; | |||
1245 | { | |||
1246 | FILE *file = (FILE *) afile; | |||
1247 | switch (how) | |||
1248 | { | |||
1249 | case bfd_print_symbol_name: | |||
1250 | fprintf (file, "%s", symbol->name); | |||
1251 | break; | |||
1252 | default: | |||
1253 | bfd_print_symbol_vandf (abfd, (PTRvoid *) file, symbol); | |||
1254 | fprintf (file, " %-5s %s", | |||
1255 | symbol->section->name, | |||
1256 | symbol->name); | |||
1257 | ||||
1258 | } | |||
1259 | } | |||
1260 | ||||
1261 | #define srec_close_and_cleanupbfd_true _bfd_generic_close_and_cleanupbfd_true | |||
1262 | #define srec_bfd_free_cached_infobfd_true _bfd_generic_bfd_free_cached_infobfd_true | |||
1263 | #define srec_new_section_hook((bfd_boolean (*) (bfd *, asection *)) bfd_true) _bfd_generic_new_section_hook((bfd_boolean (*) (bfd *, asection *)) bfd_true) | |||
1264 | ||||
1265 | #define srec_bfd_is_local_label_namebfd_generic_is_local_label_name bfd_generic_is_local_label_name | |||
1266 | #define srec_get_lineno((alent *(*) (bfd *, asymbol *)) bfd_nullvoidptr) _bfd_nosymbols_get_lineno((alent *(*) (bfd *, asymbol *)) bfd_nullvoidptr) | |||
1267 | #define srec_find_nearest_line((bfd_boolean (*) (bfd *, asection *, asymbol **, bfd_vma, const char **, const char **, unsigned int *)) bfd_false) _bfd_nosymbols_find_nearest_line((bfd_boolean (*) (bfd *, asection *, asymbol **, bfd_vma, const char **, const char **, unsigned int *)) bfd_false) | |||
1268 | #define srec_make_empty_symbol_bfd_generic_make_empty_symbol _bfd_generic_make_empty_symbol | |||
1269 | #define srec_bfd_make_debug_symbol((asymbol *(*) (bfd *, void *, unsigned long)) bfd_nullvoidptr ) _bfd_nosymbols_bfd_make_debug_symbol((asymbol *(*) (bfd *, void *, unsigned long)) bfd_nullvoidptr ) | |||
1270 | #define srec_read_minisymbols_bfd_generic_read_minisymbols _bfd_generic_read_minisymbols | |||
1271 | #define srec_minisymbol_to_symbol_bfd_generic_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol | |||
1272 | ||||
1273 | #define srec_get_reloc_upper_bound((long (*) (bfd *, asection *)) bfd_0l) \ | |||
1274 | ((long (*) PARAMS ((bfd *, asection *))(bfd *, asection *)) bfd_0l) | |||
1275 | #define srec_canonicalize_reloc((long (*) (bfd *, asection *, arelent **, asymbol **)) bfd_0l ) \ | |||
1276 | ((long (*) PARAMS ((bfd *, asection *, arelent **, asymbol **))(bfd *, asection *, arelent **, asymbol **)) bfd_0l) | |||
1277 | #define srec_bfd_reloc_type_lookup((reloc_howto_type *(*) (bfd *, bfd_reloc_code_real_type)) bfd_nullvoidptr ) _bfd_norelocs_bfd_reloc_type_lookup((reloc_howto_type *(*) (bfd *, bfd_reloc_code_real_type)) bfd_nullvoidptr ) | |||
1278 | ||||
1279 | #define srec_get_section_contents_in_window_bfd_generic_get_section_contents_in_window \ | |||
1280 | _bfd_generic_get_section_contents_in_window | |||
1281 | ||||
1282 | #define srec_bfd_get_relocated_section_contentsbfd_generic_get_relocated_section_contents \ | |||
1283 | bfd_generic_get_relocated_section_contents | |||
1284 | #define srec_bfd_relax_sectionbfd_generic_relax_section bfd_generic_relax_section | |||
1285 | #define srec_bfd_gc_sectionsbfd_generic_gc_sections bfd_generic_gc_sections | |||
1286 | #define srec_bfd_merge_sectionsbfd_generic_merge_sections bfd_generic_merge_sections | |||
1287 | #define srec_bfd_discard_groupbfd_generic_discard_group bfd_generic_discard_group | |||
1288 | #define srec_bfd_link_hash_table_create_bfd_generic_link_hash_table_create _bfd_generic_link_hash_table_create | |||
1289 | #define srec_bfd_link_hash_table_free_bfd_generic_link_hash_table_free _bfd_generic_link_hash_table_free | |||
1290 | #define srec_bfd_link_add_symbols_bfd_generic_link_add_symbols _bfd_generic_link_add_symbols | |||
1291 | #define srec_bfd_link_just_syms_bfd_generic_link_just_syms _bfd_generic_link_just_syms | |||
1292 | #define srec_bfd_final_link_bfd_generic_final_link _bfd_generic_final_link | |||
1293 | #define srec_bfd_link_split_section_bfd_generic_link_split_section _bfd_generic_link_split_section | |||
1294 | ||||
1295 | const bfd_target srec_vec = | |||
1296 | { | |||
1297 | "srec", /* name */ | |||
1298 | bfd_target_srec_flavour, | |||
1299 | BFD_ENDIAN_UNKNOWN, /* target byte order */ | |||
1300 | BFD_ENDIAN_UNKNOWN, /* target headers byte order */ | |||
1301 | (HAS_RELOC0x01 | EXEC_P0x02 | /* object flags */ | |||
1302 | HAS_LINENO0x04 | HAS_DEBUG0x08 | | |||
1303 | HAS_SYMS0x10 | HAS_LOCALS0x20 | WP_TEXT0x80 | D_PAGED0x100), | |||
1304 | (SEC_CODE0x020 | SEC_DATA0x040 | SEC_ROM0x080 | SEC_HAS_CONTENTS0x200 | |||
1305 | | SEC_ALLOC0x001 | SEC_LOAD0x002 | SEC_RELOC0x004), /* section flags */ | |||
1306 | 0, /* leading underscore */ | |||
1307 | ' ', /* ar_pad_char */ | |||
1308 | 16, /* ar_max_namelen */ | |||
1309 | bfd_getb64, bfd_getb_signed_64, bfd_putb64, | |||
1310 | bfd_getb32, bfd_getb_signed_32, bfd_putb32, | |||
1311 | bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ | |||
1312 | bfd_getb64, bfd_getb_signed_64, bfd_putb64, | |||
1313 | bfd_getb32, bfd_getb_signed_32, bfd_putb32, | |||
1314 | bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ | |||
1315 | ||||
1316 | { | |||
1317 | _bfd_dummy_target, | |||
1318 | srec_object_p, /* bfd_check_format */ | |||
1319 | _bfd_dummy_target, | |||
1320 | _bfd_dummy_target, | |||
1321 | }, | |||
1322 | { | |||
1323 | bfd_false, | |||
1324 | srec_mkobject, | |||
1325 | _bfd_generic_mkarchive, | |||
1326 | bfd_false, | |||
1327 | }, | |||
1328 | { /* bfd_write_contents */ | |||
1329 | bfd_false, | |||
1330 | srec_write_object_contents, | |||
1331 | _bfd_write_archive_contents, | |||
1332 | bfd_false, | |||
1333 | }, | |||
1334 | ||||
1335 | BFD_JUMP_TABLE_GENERIC (srec)bfd_true, bfd_true, ((bfd_boolean (*) (bfd *, asection *)) bfd_true ), srec_get_section_contents, _bfd_generic_get_section_contents_in_window, | |||
1336 | BFD_JUMP_TABLE_COPY (_bfd_generic)((bfd_boolean (*) (bfd *, bfd *)) bfd_true), ((bfd_boolean (* ) (bfd *, bfd *)) bfd_true), ((bfd_boolean (*) (bfd *, asection *, bfd *, asection *)) bfd_true), ((bfd_boolean (*) (bfd *, asymbol *, bfd *, asymbol *)) bfd_true), ((bfd_boolean (*) (bfd *, flagword )) bfd_true), ((bfd_boolean (*) (bfd *, void *)) bfd_true), | |||
1337 | BFD_JUMP_TABLE_CORE (_bfd_nocore)_bfd_nocore_core_file_failing_command, _bfd_nocore_core_file_failing_signal , _bfd_nocore_core_file_matches_executable_p, | |||
1338 | BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive)bfd_false, bfd_false, ((bfd_boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_false), ((void (*) (bfd *, const char *, char *)) bfd_void), ((bfd_boolean (*) (bfd *, unsigned int , struct orl *, unsigned int, int)) bfd_false), bfd_nullvoidptr , ((bfd *(*) (bfd *, bfd *)) bfd_nullvoidptr), ((bfd *(*) (bfd *, symindex)) bfd_nullvoidptr), bfd_generic_stat_arch_elt, bfd_false, | |||
1339 | BFD_JUMP_TABLE_SYMBOLS (srec)srec_get_symtab_upper_bound, srec_canonicalize_symtab, _bfd_generic_make_empty_symbol , srec_print_symbol, srec_get_symbol_info, bfd_generic_is_local_label_name , ((alent *(*) (bfd *, asymbol *)) bfd_nullvoidptr), ((bfd_boolean (*) (bfd *, asection *, asymbol **, bfd_vma, const char **, const char **, unsigned int *)) bfd_false), ((asymbol *(*) (bfd *, void *, unsigned long)) bfd_nullvoidptr), _bfd_generic_read_minisymbols , _bfd_generic_minisymbol_to_symbol, | |||
1340 | BFD_JUMP_TABLE_RELOCS (srec)((long (*) (bfd *, asection *)) bfd_0l), ((long (*) (bfd *, asection *, arelent **, asymbol **)) bfd_0l), ((reloc_howto_type *(*) (bfd *, bfd_reloc_code_real_type)) bfd_nullvoidptr), | |||
1341 | BFD_JUMP_TABLE_WRITE (srec)srec_set_arch_mach, srec_set_section_contents, | |||
1342 | BFD_JUMP_TABLE_LINK (srec)srec_sizeof_headers, bfd_generic_get_relocated_section_contents , bfd_generic_relax_section, _bfd_generic_link_hash_table_create , _bfd_generic_link_hash_table_free, _bfd_generic_link_add_symbols , _bfd_generic_link_just_syms, _bfd_generic_final_link, _bfd_generic_link_split_section , bfd_generic_gc_sections, bfd_generic_merge_sections, bfd_generic_discard_group, | |||
1343 | BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic)_bfd_n1, ((long (*) (bfd *, asymbol **)) _bfd_n1), _bfd_n1, ( (long (*) (bfd *, arelent **, asymbol **)) _bfd_n1), | |||
1344 | ||||
1345 | NULL((void*)0), | |||
1346 | ||||
1347 | (PTRvoid *) 0 | |||
1348 | }; | |||
1349 | ||||
1350 | const bfd_target symbolsrec_vec = | |||
1351 | { | |||
1352 | "symbolsrec", /* name */ | |||
1353 | bfd_target_srec_flavour, | |||
1354 | BFD_ENDIAN_UNKNOWN, /* target byte order */ | |||
1355 | BFD_ENDIAN_UNKNOWN, /* target headers byte order */ | |||
1356 | (HAS_RELOC0x01 | EXEC_P0x02 | /* object flags */ | |||
1357 | HAS_LINENO0x04 | HAS_DEBUG0x08 | | |||
1358 | HAS_SYMS0x10 | HAS_LOCALS0x20 | WP_TEXT0x80 | D_PAGED0x100), | |||
1359 | (SEC_CODE0x020 | SEC_DATA0x040 | SEC_ROM0x080 | SEC_HAS_CONTENTS0x200 | |||
1360 | | SEC_ALLOC0x001 | SEC_LOAD0x002 | SEC_RELOC0x004), /* section flags */ | |||
1361 | 0, /* leading underscore */ | |||
1362 | ' ', /* ar_pad_char */ | |||
1363 | 16, /* ar_max_namelen */ | |||
1364 | bfd_getb64, bfd_getb_signed_64, bfd_putb64, | |||
1365 | bfd_getb32, bfd_getb_signed_32, bfd_putb32, | |||
1366 | bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ | |||
1367 | bfd_getb64, bfd_getb_signed_64, bfd_putb64, | |||
1368 | bfd_getb32, bfd_getb_signed_32, bfd_putb32, | |||
1369 | bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ | |||
1370 | ||||
1371 | { | |||
1372 | _bfd_dummy_target, | |||
1373 | symbolsrec_object_p, /* bfd_check_format */ | |||
1374 | _bfd_dummy_target, | |||
1375 | _bfd_dummy_target, | |||
1376 | }, | |||
1377 | { | |||
1378 | bfd_false, | |||
1379 | srec_mkobject, | |||
1380 | _bfd_generic_mkarchive, | |||
1381 | bfd_false, | |||
1382 | }, | |||
1383 | { /* bfd_write_contents */ | |||
1384 | bfd_false, | |||
1385 | symbolsrec_write_object_contents, | |||
1386 | _bfd_write_archive_contents, | |||
1387 | bfd_false, | |||
1388 | }, | |||
1389 | ||||
1390 | BFD_JUMP_TABLE_GENERIC (srec)bfd_true, bfd_true, ((bfd_boolean (*) (bfd *, asection *)) bfd_true ), srec_get_section_contents, _bfd_generic_get_section_contents_in_window, | |||
1391 | BFD_JUMP_TABLE_COPY (_bfd_generic)((bfd_boolean (*) (bfd *, bfd *)) bfd_true), ((bfd_boolean (* ) (bfd *, bfd *)) bfd_true), ((bfd_boolean (*) (bfd *, asection *, bfd *, asection *)) bfd_true), ((bfd_boolean (*) (bfd *, asymbol *, bfd *, asymbol *)) bfd_true), ((bfd_boolean (*) (bfd *, flagword )) bfd_true), ((bfd_boolean (*) (bfd *, void *)) bfd_true), | |||
1392 | BFD_JUMP_TABLE_CORE (_bfd_nocore)_bfd_nocore_core_file_failing_command, _bfd_nocore_core_file_failing_signal , _bfd_nocore_core_file_matches_executable_p, | |||
1393 | BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive)bfd_false, bfd_false, ((bfd_boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_false), ((void (*) (bfd *, const char *, char *)) bfd_void), ((bfd_boolean (*) (bfd *, unsigned int , struct orl *, unsigned int, int)) bfd_false), bfd_nullvoidptr , ((bfd *(*) (bfd *, bfd *)) bfd_nullvoidptr), ((bfd *(*) (bfd *, symindex)) bfd_nullvoidptr), bfd_generic_stat_arch_elt, bfd_false, | |||
1394 | BFD_JUMP_TABLE_SYMBOLS (srec)srec_get_symtab_upper_bound, srec_canonicalize_symtab, _bfd_generic_make_empty_symbol , srec_print_symbol, srec_get_symbol_info, bfd_generic_is_local_label_name , ((alent *(*) (bfd *, asymbol *)) bfd_nullvoidptr), ((bfd_boolean (*) (bfd *, asection *, asymbol **, bfd_vma, const char **, const char **, unsigned int *)) bfd_false), ((asymbol *(*) (bfd *, void *, unsigned long)) bfd_nullvoidptr), _bfd_generic_read_minisymbols , _bfd_generic_minisymbol_to_symbol, | |||
1395 | BFD_JUMP_TABLE_RELOCS (srec)((long (*) (bfd *, asection *)) bfd_0l), ((long (*) (bfd *, asection *, arelent **, asymbol **)) bfd_0l), ((reloc_howto_type *(*) (bfd *, bfd_reloc_code_real_type)) bfd_nullvoidptr), | |||
1396 | BFD_JUMP_TABLE_WRITE (srec)srec_set_arch_mach, srec_set_section_contents, | |||
1397 | BFD_JUMP_TABLE_LINK (srec)srec_sizeof_headers, bfd_generic_get_relocated_section_contents , bfd_generic_relax_section, _bfd_generic_link_hash_table_create , _bfd_generic_link_hash_table_free, _bfd_generic_link_add_symbols , _bfd_generic_link_just_syms, _bfd_generic_final_link, _bfd_generic_link_split_section , bfd_generic_gc_sections, bfd_generic_merge_sections, bfd_generic_discard_group, | |||
1398 | BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic)_bfd_n1, ((long (*) (bfd *, asymbol **)) _bfd_n1), _bfd_n1, ( (long (*) (bfd *, arelent **, asymbol **)) _bfd_n1), | |||
1399 | ||||
1400 | NULL((void*)0), | |||
1401 | ||||
1402 | (PTRvoid *) 0 | |||
1403 | }; |