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