1 /* BFD back-end for oasys objects. 2 Copyright (C) 1990-2016 Free Software Foundation, Inc. 3 Written by Steve Chamberlain of Cygnus Support, <sac (at) cygnus.com>. 4 5 This file is part of BFD, the Binary File Descriptor library. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 20 MA 02110-1301, USA. */ 21 22 #define UNDERSCORE_HACK 1 23 #include "sysdep.h" 24 #include "bfd.h" 25 #include "safe-ctype.h" 26 #include "libbfd.h" 27 #include "oasys.h" 28 #include "liboasys.h" 29 #include "libiberty.h" 30 31 /* Read in all the section data and relocation stuff too. */ 32 33 static bfd_boolean 34 oasys_read_record (bfd *abfd, oasys_record_union_type *record) 35 { 36 bfd_size_type amt = sizeof (record->header); 37 38 if (bfd_bread ((void *) record, amt, abfd) != amt) 39 return FALSE; 40 41 amt = record->header.length - sizeof (record->header); 42 if ((long) amt <= 0) 43 return TRUE; 44 if (bfd_bread ((void *) ((char *) record + sizeof (record->header)), amt, abfd) 45 != amt) 46 return FALSE; 47 return TRUE; 48 } 49 50 static size_t 51 oasys_string_length (oasys_record_union_type *record) 52 { 53 return record->header.length 54 - ((char *) record->symbol.name - (char *) record); 55 } 56 57 /* Slurp the symbol table by reading in all the records at the start file 58 till we get to the first section record. 59 60 We'll sort the symbolss into two lists, defined and undefined. The 61 undefined symbols will be placed into the table according to their 62 refno. 63 64 We do this by placing all undefined symbols at the front of the table 65 moving in, and the defined symbols at the end of the table moving back. */ 66 67 static bfd_boolean 68 oasys_slurp_symbol_table (bfd *const abfd) 69 { 70 oasys_record_union_type record; 71 oasys_data_type *data = OASYS_DATA (abfd); 72 bfd_boolean loop = TRUE; 73 asymbol *dest_defined; 74 asymbol *dest; 75 char *string_ptr; 76 bfd_size_type amt; 77 78 if (data->symbols != NULL) 79 return TRUE; 80 81 /* Buy enough memory for all the symbols and all the names. */ 82 amt = abfd->symcount; 83 amt *= sizeof (asymbol); 84 data->symbols = bfd_alloc (abfd, amt); 85 86 amt = data->symbol_string_length; 87 #ifdef UNDERSCORE_HACK 88 /* Buy 1 more char for each symbol to keep the underscore in. */ 89 amt += abfd->symcount; 90 #endif 91 data->strings = bfd_alloc (abfd, amt); 92 93 if (!data->symbols || !data->strings) 94 return FALSE; 95 96 dest_defined = data->symbols + abfd->symcount - 1; 97 98 string_ptr = data->strings; 99 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) 100 return FALSE; 101 while (loop) 102 { 103 if (! oasys_read_record (abfd, &record)) 104 return FALSE; 105 106 switch (record.header.type) 107 { 108 case oasys_record_is_header_enum: 109 break; 110 case oasys_record_is_local_enum: 111 case oasys_record_is_symbol_enum: 112 { 113 int flag = record.header.type == (int) oasys_record_is_local_enum ? 114 (BSF_LOCAL) : (BSF_GLOBAL | BSF_EXPORT); 115 116 size_t length = oasys_string_length (&record); 117 switch (record.symbol.relb & RELOCATION_TYPE_BITS) 118 { 119 case RELOCATION_TYPE_ABS: 120 dest = dest_defined--; 121 dest->section = bfd_abs_section_ptr; 122 dest->flags = 0; 123 124 break; 125 case RELOCATION_TYPE_REL: 126 dest = dest_defined--; 127 dest->section = 128 OASYS_DATA (abfd)->sections[record.symbol.relb & 129 RELOCATION_SECT_BITS]; 130 if (record.header.type == (int) oasys_record_is_local_enum) 131 { 132 dest->flags = BSF_LOCAL; 133 if (dest->section == (asection *) (~0)) 134 { 135 /* It seems that sometimes internal symbols are tied up, but 136 still get output, even though there is no 137 section */ 138 dest->section = 0; 139 } 140 } 141 else 142 dest->flags = flag; 143 break; 144 case RELOCATION_TYPE_UND: 145 dest = data->symbols + H_GET_16 (abfd, record.symbol.refno); 146 dest->section = bfd_und_section_ptr; 147 break; 148 case RELOCATION_TYPE_COM: 149 dest = dest_defined--; 150 dest->name = string_ptr; 151 dest->the_bfd = abfd; 152 dest->section = bfd_com_section_ptr; 153 break; 154 default: 155 dest = dest_defined--; 156 BFD_ASSERT (FALSE); 157 break; 158 } 159 dest->name = string_ptr; 160 dest->the_bfd = abfd; 161 dest->udata.p = NULL; 162 dest->value = H_GET_32 (abfd, record.symbol.value); 163 164 #ifdef UNDERSCORE_HACK 165 if (record.symbol.name[0] != '_') 166 { 167 string_ptr[0] = '_'; 168 string_ptr++; 169 } 170 #endif 171 memcpy (string_ptr, record.symbol.name, length); 172 173 string_ptr[length] = 0; 174 string_ptr += length + 1; 175 } 176 break; 177 default: 178 loop = FALSE; 179 } 180 } 181 return TRUE; 182 } 183 184 static long 185 oasys_get_symtab_upper_bound (bfd *const abfd) 186 { 187 if (! oasys_slurp_symbol_table (abfd)) 188 return -1; 189 190 return (abfd->symcount + 1) * (sizeof (oasys_symbol_type *)); 191 } 192 193 extern const bfd_target oasys_vec; 194 195 static long 196 oasys_canonicalize_symtab (bfd *abfd, asymbol **location) 197 { 198 asymbol *symbase; 199 unsigned int counter; 200 201 if (! oasys_slurp_symbol_table (abfd)) 202 return -1; 203 204 symbase = OASYS_DATA (abfd)->symbols; 205 for (counter = 0; counter < abfd->symcount; counter++) 206 *(location++) = symbase++; 207 208 *location = 0; 209 return abfd->symcount; 210 } 211 212 /* Archive stuff. */ 213 214 static const bfd_target * 215 oasys_archive_p (bfd *abfd) 216 { 217 oasys_archive_header_type header; 218 oasys_extarchive_header_type header_ext; 219 unsigned int i; 220 file_ptr filepos; 221 bfd_size_type amt; 222 223 amt = sizeof (header_ext); 224 if (bfd_seek (abfd, (file_ptr) 0, 0) != 0 225 || bfd_bread ((void *) &header_ext, amt, abfd) != amt) 226 { 227 if (bfd_get_error () != bfd_error_system_call) 228 bfd_set_error (bfd_error_wrong_format); 229 return NULL; 230 } 231 232 header.version = H_GET_32 (abfd, header_ext.version); 233 header.mod_count = H_GET_32 (abfd, header_ext.mod_count); 234 header.mod_tbl_offset = H_GET_32 (abfd, header_ext.mod_tbl_offset); 235 header.sym_tbl_size = H_GET_32 (abfd, header_ext.sym_tbl_size); 236 header.sym_count = H_GET_32 (abfd, header_ext.sym_count); 237 header.sym_tbl_offset = H_GET_32 (abfd, header_ext.sym_tbl_offset); 238 header.xref_count = H_GET_32 (abfd, header_ext.xref_count); 239 header.xref_lst_offset = H_GET_32 (abfd, header_ext.xref_lst_offset); 240 241 /* There isn't a magic number in an Oasys archive, so the best we 242 can do to verify reasonableness is to make sure that the values in 243 the header are too weird. */ 244 245 if (header.version > 10000 246 || header.mod_count > 10000 247 || header.sym_count > 100000 248 || header.xref_count > 100000) 249 return NULL; 250 251 /* That all worked, let's buy the space for the header and read in 252 the headers. */ 253 { 254 oasys_ar_data_type *ar; 255 oasys_module_info_type *module; 256 oasys_module_table_type record; 257 258 amt = sizeof (oasys_ar_data_type); 259 ar = bfd_alloc (abfd, amt); 260 261 amt = header.mod_count; 262 amt *= sizeof (oasys_module_info_type); 263 module = bfd_alloc (abfd, amt); 264 265 if (!ar || !module) 266 return NULL; 267 268 abfd->tdata.oasys_ar_data = ar; 269 ar->module = module; 270 ar->module_count = header.mod_count; 271 272 filepos = header.mod_tbl_offset; 273 for (i = 0; i < header.mod_count; i++) 274 { 275 oasys_extmodule_table_type_b_type record_ext; 276 277 if (bfd_seek (abfd, filepos, SEEK_SET) != 0) 278 return NULL; 279 280 /* There are two ways of specifying the archive header. */ 281 amt = sizeof (record_ext); 282 if (bfd_bread ((void *) &record_ext, amt, abfd) != amt) 283 return NULL; 284 285 record.mod_size = H_GET_32 (abfd, record_ext.mod_size); 286 record.file_offset = H_GET_32 (abfd, record_ext.file_offset); 287 288 record.dep_count = H_GET_32 (abfd, record_ext.dep_count); 289 record.depee_count = H_GET_32 (abfd, record_ext.depee_count); 290 record.sect_count = H_GET_32 (abfd, record_ext.sect_count); 291 record.module_name_size = H_GET_32 (abfd, 292 record_ext.mod_name_length); 293 294 amt = record.module_name_size; 295 module[i].name = bfd_alloc (abfd, amt + 1); 296 if (!module[i].name) 297 return NULL; 298 if (bfd_bread ((void *) module[i].name, amt, abfd) != amt) 299 return NULL; 300 module[i].name[record.module_name_size] = 0; 301 filepos += (sizeof (record_ext) 302 + record.dep_count * 4 303 + record.module_name_size + 1); 304 305 module[i].size = record.mod_size; 306 module[i].pos = record.file_offset; 307 module[i].abfd = 0; 308 } 309 } 310 return abfd->xvec; 311 } 312 313 static bfd_boolean 314 oasys_mkobject (bfd *abfd) 315 { 316 bfd_size_type amt = sizeof (oasys_data_type); 317 318 abfd->tdata.oasys_obj_data = bfd_alloc (abfd, amt); 319 320 return abfd->tdata.oasys_obj_data != NULL; 321 } 322 323 /* The howto table is build using the top two bits of a reloc byte to 324 index into it. The bits are PCREL,WORD/LONG. */ 325 326 static reloc_howto_type howto_table[] = 327 { 328 329 HOWTO (0, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, 0, "abs16", TRUE, 0x0000ffff, 0x0000ffff, FALSE), 330 HOWTO (0, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, 0, "abs32", TRUE, 0xffffffff, 0xffffffff, FALSE), 331 HOWTO (0, 0, 1, 16, TRUE, 0, complain_overflow_signed, 0, "pcrel16", TRUE, 0x0000ffff, 0x0000ffff, FALSE), 332 HOWTO (0, 0, 2, 32, TRUE, 0, complain_overflow_signed, 0, "pcrel32", TRUE, 0xffffffff, 0xffffffff, FALSE) 333 }; 334 335 /* Read in all the section data and relocation stuff too. */ 336 337 static bfd_boolean 338 oasys_slurp_section_data (bfd *const abfd) 339 { 340 oasys_record_union_type record; 341 oasys_data_type *data = OASYS_DATA (abfd); 342 bfd_boolean loop = TRUE; 343 oasys_per_section_type *per; 344 asection *s; 345 bfd_size_type amt; 346 347 /* See if the data has been slurped already. */ 348 for (s = abfd->sections; s != NULL; s = s->next) 349 { 350 per = oasys_per_section (s); 351 if (per->initialized) 352 return TRUE; 353 } 354 355 if (data->first_data_record == 0) 356 return TRUE; 357 358 if (bfd_seek (abfd, data->first_data_record, SEEK_SET) != 0) 359 return FALSE; 360 361 while (loop) 362 { 363 if (! oasys_read_record (abfd, &record)) 364 return FALSE; 365 366 switch (record.header.type) 367 { 368 case oasys_record_is_header_enum: 369 break; 370 case oasys_record_is_data_enum: 371 { 372 bfd_byte *src = record.data.data; 373 bfd_byte *end_src = ((bfd_byte *) & record) + record.header.length; 374 bfd_byte *dst_ptr; 375 bfd_byte *dst_base_ptr; 376 unsigned int relbit; 377 unsigned int count; 378 asection *section = 379 data->sections[record.data.relb & RELOCATION_SECT_BITS]; 380 bfd_vma dst_offset; 381 382 per = oasys_per_section (section); 383 384 if (! per->initialized) 385 { 386 arelent **relpp; 387 388 per->data = bfd_zalloc (abfd, section->size); 389 if (!per->data) 390 return FALSE; 391 relpp = §ion->relocation; 392 per->reloc_tail_ptr = (oasys_reloc_type **) relpp; 393 per->had_vma = FALSE; 394 per->initialized = TRUE; 395 section->reloc_count = 0; 396 section->flags = SEC_ALLOC; 397 } 398 399 dst_offset = H_GET_32 (abfd, record.data.addr); 400 if (! per->had_vma) 401 { 402 /* Take the first vma we see as the base. */ 403 section->vma = dst_offset; 404 per->had_vma = TRUE; 405 } 406 407 dst_offset -= section->vma; 408 409 dst_base_ptr = oasys_per_section (section)->data; 410 dst_ptr = oasys_per_section (section)->data + 411 dst_offset; 412 413 if (src < end_src) 414 section->flags |= SEC_LOAD | SEC_HAS_CONTENTS; 415 416 while (src < end_src) 417 { 418 unsigned char mod_byte = *src++; 419 size_t gap = end_src - src; 420 421 count = 8; 422 if (mod_byte == 0 && gap >= 8) 423 { 424 dst_ptr[0] = src[0]; 425 dst_ptr[1] = src[1]; 426 dst_ptr[2] = src[2]; 427 dst_ptr[3] = src[3]; 428 dst_ptr[4] = src[4]; 429 dst_ptr[5] = src[5]; 430 dst_ptr[6] = src[6]; 431 dst_ptr[7] = src[7]; 432 dst_ptr += 8; 433 src += 8; 434 } 435 else 436 { 437 for (relbit = 1; count-- != 0 && src < end_src; relbit <<= 1) 438 { 439 if (relbit & mod_byte) 440 { 441 unsigned char reloc = *src; 442 /* This item needs to be relocated. */ 443 switch (reloc & RELOCATION_TYPE_BITS) 444 { 445 case RELOCATION_TYPE_ABS: 446 break; 447 448 case RELOCATION_TYPE_REL: 449 { 450 /* Relocate the item relative to the section. */ 451 oasys_reloc_type *r; 452 453 amt = sizeof (oasys_reloc_type); 454 r = bfd_alloc (abfd, amt); 455 if (!r) 456 return FALSE; 457 *(per->reloc_tail_ptr) = r; 458 per->reloc_tail_ptr = &r->next; 459 r->next = NULL; 460 /* Reference to undefined symbol. */ 461 src++; 462 /* There is no symbol. */ 463 r->symbol = 0; 464 /* Work out the howto. */ 465 abort (); 466 r->relent.address = dst_ptr - dst_base_ptr; 467 r->relent.howto = &howto_table[reloc >> 6]; 468 r->relent.sym_ptr_ptr = NULL; 469 section->reloc_count++; 470 471 /* Fake up the data to look like 472 it's got the -ve pc in it, this 473 makes it much easier to convert 474 into other formats. This is done 475 by hitting the addend. */ 476 if (r->relent.howto->pc_relative) 477 r->relent.addend -= dst_ptr - dst_base_ptr; 478 } 479 break; 480 481 case RELOCATION_TYPE_UND: 482 { 483 oasys_reloc_type *r; 484 485 amt = sizeof (oasys_reloc_type); 486 r = bfd_alloc (abfd, amt); 487 if (!r) 488 return FALSE; 489 *(per->reloc_tail_ptr) = r; 490 per->reloc_tail_ptr = &r->next; 491 r->next = NULL; 492 /* Reference to undefined symbol. */ 493 src++; 494 /* Get symbol number. */ 495 r->symbol = (src[0] << 8) | src[1]; 496 /* Work out the howto. */ 497 abort (); 498 499 r->relent.addend = 0; 500 r->relent.address = dst_ptr - dst_base_ptr; 501 r->relent.howto = &howto_table[reloc >> 6]; 502 r->relent.sym_ptr_ptr = NULL; 503 section->reloc_count++; 504 505 src += 2; 506 /* Fake up the data to look like 507 it's got the -ve pc in it, this 508 makes it much easier to convert 509 into other formats. This is done 510 by hitting the addend. */ 511 if (r->relent.howto->pc_relative) 512 r->relent.addend -= dst_ptr - dst_base_ptr; 513 } 514 break; 515 case RELOCATION_TYPE_COM: 516 BFD_FAIL (); 517 } 518 } 519 *dst_ptr++ = *src++; 520 } 521 } 522 } 523 } 524 break; 525 case oasys_record_is_local_enum: 526 case oasys_record_is_symbol_enum: 527 case oasys_record_is_section_enum: 528 break; 529 default: 530 loop = FALSE; 531 } 532 } 533 534 return TRUE; 535 536 } 537 538 #define MAX_SECS 16 539 540 static const bfd_target * 541 oasys_object_p (bfd *abfd) 542 { 543 oasys_data_type *oasys; 544 oasys_data_type *save = OASYS_DATA (abfd); 545 bfd_boolean loop = TRUE; 546 bfd_boolean had_usefull = FALSE; 547 548 abfd->tdata.oasys_obj_data = 0; 549 oasys_mkobject (abfd); 550 oasys = OASYS_DATA (abfd); 551 memset ((void *) oasys->sections, 0xff, sizeof (oasys->sections)); 552 553 /* Point to the start of the file. */ 554 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) 555 goto fail; 556 oasys->symbol_string_length = 0; 557 558 /* Inspect the records, but only keep the section info - 559 remember the size of the symbols. */ 560 oasys->first_data_record = 0; 561 while (loop) 562 { 563 oasys_record_union_type record; 564 if (! oasys_read_record (abfd, &record)) 565 goto fail; 566 if ((size_t) record.header.length < (size_t) sizeof (record.header)) 567 goto fail; 568 569 switch ((oasys_record_enum_type) (record.header.type)) 570 { 571 case oasys_record_is_header_enum: 572 had_usefull = TRUE; 573 break; 574 case oasys_record_is_symbol_enum: 575 case oasys_record_is_local_enum: 576 /* Count symbols and remember their size for a future malloc. */ 577 abfd->symcount++; 578 oasys->symbol_string_length += 1 + oasys_string_length (&record); 579 had_usefull = TRUE; 580 break; 581 case oasys_record_is_section_enum: 582 { 583 asection *s; 584 char *buffer; 585 unsigned int section_number; 586 587 if (record.section.header.length != sizeof (record.section)) 588 goto fail; 589 590 buffer = bfd_alloc (abfd, (bfd_size_type) 3); 591 if (!buffer) 592 goto fail; 593 section_number = record.section.relb & RELOCATION_SECT_BITS; 594 sprintf (buffer, "%u", section_number); 595 s = bfd_make_section (abfd, buffer); 596 oasys->sections[section_number] = s; 597 switch (record.section.relb & RELOCATION_TYPE_BITS) 598 { 599 case RELOCATION_TYPE_ABS: 600 case RELOCATION_TYPE_REL: 601 break; 602 case RELOCATION_TYPE_UND: 603 case RELOCATION_TYPE_COM: 604 BFD_FAIL (); 605 } 606 607 s->size = H_GET_32 (abfd, record.section.value); 608 s->vma = H_GET_32 (abfd, record.section.vma); 609 s->flags = 0; 610 had_usefull = TRUE; 611 } 612 break; 613 case oasys_record_is_data_enum: 614 oasys->first_data_record = bfd_tell (abfd) - record.header.length; 615 case oasys_record_is_debug_enum: 616 case oasys_record_is_module_enum: 617 case oasys_record_is_named_section_enum: 618 case oasys_record_is_end_enum: 619 if (! had_usefull) 620 goto fail; 621 loop = FALSE; 622 break; 623 default: 624 goto fail; 625 } 626 } 627 oasys->symbols = NULL; 628 629 /* Oasys support several architectures, but I can't see a simple way 630 to discover which one is in a particular file - we'll guess. */ 631 bfd_default_set_arch_mach (abfd, bfd_arch_m68k, 0); 632 if (abfd->symcount != 0) 633 abfd->flags |= HAS_SYMS; 634 635 /* We don't know if a section has data until we've read it. */ 636 oasys_slurp_section_data (abfd); 637 638 return abfd->xvec; 639 640 fail: 641 (void) bfd_release (abfd, oasys); 642 abfd->tdata.oasys_obj_data = save; 643 return NULL; 644 } 645 646 647 static void 648 oasys_get_symbol_info (bfd *ignore_abfd ATTRIBUTE_UNUSED, 649 asymbol *symbol, 650 symbol_info *ret) 651 { 652 bfd_symbol_info (symbol, ret); 653 654 if (!symbol->section) 655 ret->type = (symbol->flags & BSF_LOCAL) ? 'a' : 'A'; 656 } 657 658 static void 659 oasys_print_symbol (bfd *abfd, void * afile, asymbol *symbol, bfd_print_symbol_type how) 660 { 661 FILE *file = (FILE *) afile; 662 663 switch (how) 664 { 665 case bfd_print_symbol_name: 666 case bfd_print_symbol_more: 667 fprintf (file, "%s", symbol->name); 668 break; 669 case bfd_print_symbol_all: 670 { 671 const char *section_name = symbol->section == NULL ? 672 (const char *) "*abs" : symbol->section->name; 673 674 bfd_print_symbol_vandf (abfd, (void *) file, symbol); 675 676 fprintf (file, " %-5s %s", 677 section_name, 678 symbol->name); 679 } 680 break; 681 } 682 } 683 684 static bfd_boolean 685 oasys_new_section_hook (bfd *abfd, asection *newsect) 686 { 687 if (!newsect->used_by_bfd) 688 { 689 newsect->used_by_bfd 690 = bfd_alloc (abfd, (bfd_size_type) sizeof (oasys_per_section_type)); 691 if (!newsect->used_by_bfd) 692 return FALSE; 693 } 694 oasys_per_section (newsect)->data = NULL; 695 oasys_per_section (newsect)->section = newsect; 696 oasys_per_section (newsect)->offset = 0; 697 oasys_per_section (newsect)->initialized = FALSE; 698 newsect->alignment_power = 1; 699 700 /* Turn the section string into an index. */ 701 sscanf (newsect->name, "%u", &newsect->target_index); 702 703 return _bfd_generic_new_section_hook (abfd, newsect); 704 } 705 706 707 static long 708 oasys_get_reloc_upper_bound (bfd *abfd, sec_ptr asect) 709 { 710 if (! oasys_slurp_section_data (abfd)) 711 return -1; 712 return (asect->reloc_count + 1) * sizeof (arelent *); 713 } 714 715 static bfd_boolean 716 oasys_get_section_contents (bfd *abfd, 717 sec_ptr section, 718 void * location, 719 file_ptr offset, 720 bfd_size_type count) 721 { 722 oasys_per_section_type *p = oasys_per_section (section); 723 724 oasys_slurp_section_data (abfd); 725 726 if (! p->initialized) 727 (void) memset (location, 0, (size_t) count); 728 else 729 (void) memcpy (location, (void *) (p->data + offset), (size_t) count); 730 731 return TRUE; 732 } 733 734 static long 735 oasys_canonicalize_reloc (bfd *ignore_abfd ATTRIBUTE_UNUSED, 736 sec_ptr section, 737 arelent **relptr, 738 asymbol **symbols ATTRIBUTE_UNUSED) 739 { 740 unsigned int reloc_count = 0; 741 oasys_reloc_type *src = (oasys_reloc_type *) (section->relocation); 742 743 if (src != NULL) 744 abort (); 745 746 *relptr = NULL; 747 return section->reloc_count = reloc_count; 748 } 749 750 751 /* Writing. */ 752 753 /* Calculate the checksum and write one record. */ 754 755 static bfd_boolean 756 oasys_write_record (bfd *abfd, 757 oasys_record_enum_type type, 758 oasys_record_union_type *record, 759 size_t size) 760 { 761 int checksum; 762 size_t i; 763 unsigned char *ptr; 764 765 record->header.length = size; 766 record->header.type = (int) type; 767 record->header.check_sum = 0; 768 record->header.fill = 0; 769 ptr = (unsigned char *) &record->pad[0]; 770 checksum = 0; 771 for (i = 0; i < size; i++) 772 checksum += *ptr++; 773 record->header.check_sum = 0xff & (-checksum); 774 if (bfd_bwrite ((void *) record, (bfd_size_type) size, abfd) != size) 775 return FALSE; 776 return TRUE; 777 } 778 779 780 /* Write out all the symbols. */ 781 782 static bfd_boolean 783 oasys_write_syms (bfd *abfd) 784 { 785 unsigned int count; 786 asymbol **generic = bfd_get_outsymbols (abfd); 787 unsigned int sym_index = 0; 788 789 for (count = 0; count < bfd_get_symcount (abfd); count++) 790 { 791 oasys_symbol_record_type symbol; 792 asymbol *const g = generic[count]; 793 const char *src = g->name; 794 char *dst = symbol.name; 795 unsigned int l = 0; 796 797 if (bfd_is_com_section (g->section)) 798 { 799 symbol.relb = RELOCATION_TYPE_COM; 800 H_PUT_16 (abfd, sym_index, symbol.refno); 801 sym_index++; 802 } 803 else if (bfd_is_abs_section (g->section)) 804 { 805 symbol.relb = RELOCATION_TYPE_ABS; 806 H_PUT_16 (abfd, 0, symbol.refno); 807 } 808 else if (bfd_is_und_section (g->section)) 809 { 810 symbol.relb = RELOCATION_TYPE_UND; 811 H_PUT_16 (abfd, sym_index, symbol.refno); 812 /* Overload the value field with the output sym_index number */ 813 sym_index++; 814 } 815 else if (g->flags & BSF_DEBUGGING) 816 /* Throw it away. */ 817 continue; 818 else 819 { 820 if (g->section == NULL) 821 /* Sometime, the oasys tools give out a symbol with illegal 822 bits in it, we'll output it in the same broken way. */ 823 symbol.relb = RELOCATION_TYPE_REL | 0; 824 else 825 symbol.relb = RELOCATION_TYPE_REL | g->section->output_section->target_index; 826 827 H_PUT_16 (abfd, 0, symbol.refno); 828 } 829 830 #ifdef UNDERSCORE_HACK 831 if (src[l] == '_') 832 dst[l++] = '.'; 833 #endif 834 while (src[l]) 835 { 836 dst[l] = src[l]; 837 l++; 838 } 839 840 H_PUT_32 (abfd, g->value, symbol.value); 841 842 if (g->flags & BSF_LOCAL) 843 { 844 if (! oasys_write_record (abfd, 845 oasys_record_is_local_enum, 846 (oasys_record_union_type *) & symbol, 847 offsetof (oasys_symbol_record_type, 848 name[0]) + l)) 849 return FALSE; 850 } 851 else 852 { 853 if (! oasys_write_record (abfd, 854 oasys_record_is_symbol_enum, 855 (oasys_record_union_type *) & symbol, 856 offsetof (oasys_symbol_record_type, 857 name[0]) + l)) 858 return FALSE; 859 } 860 g->value = sym_index - 1; 861 } 862 863 return TRUE; 864 } 865 866 /* Write a section header for each section. */ 867 868 static bfd_boolean 869 oasys_write_sections (bfd *abfd) 870 { 871 asection *s; 872 static oasys_section_record_type out; 873 874 for (s = abfd->sections; s != NULL; s = s->next) 875 { 876 if (!ISDIGIT (s->name[0])) 877 { 878 (*_bfd_error_handler) 879 (_("%s: can not represent section `%s' in oasys"), 880 bfd_get_filename (abfd), s->name); 881 bfd_set_error (bfd_error_nonrepresentable_section); 882 return FALSE; 883 } 884 out.relb = RELOCATION_TYPE_REL | s->target_index; 885 H_PUT_32 (abfd, s->size, out.value); 886 H_PUT_32 (abfd, s->vma, out.vma); 887 888 if (! oasys_write_record (abfd, 889 oasys_record_is_section_enum, 890 (oasys_record_union_type *) & out, 891 sizeof (out))) 892 return FALSE; 893 } 894 return TRUE; 895 } 896 897 static bfd_boolean 898 oasys_write_header (bfd *abfd) 899 { 900 /* Create and write the header. */ 901 oasys_header_record_type r; 902 size_t length = strlen (abfd->filename); 903 904 if (length > (size_t) sizeof (r.module_name)) 905 length = sizeof (r.module_name); 906 else if (length < (size_t) sizeof (r.module_name)) 907 (void) memset (r.module_name + length, ' ', 908 sizeof (r.module_name) - length); 909 910 (void) memcpy (r.module_name, abfd->filename, length); 911 912 r.version_number = OASYS_VERSION_NUMBER; 913 r.rev_number = OASYS_REV_NUMBER; 914 915 return oasys_write_record (abfd, oasys_record_is_header_enum, 916 (oasys_record_union_type *) & r, 917 offsetof (oasys_header_record_type, 918 description[0])); 919 } 920 921 static bfd_boolean 922 oasys_write_end (bfd *abfd) 923 { 924 oasys_end_record_type end; 925 unsigned char null = 0; 926 927 end.relb = RELOCATION_TYPE_ABS; 928 H_PUT_32 (abfd, abfd->start_address, end.entry); 929 H_PUT_16 (abfd, 0, end.fill); 930 end.zero = 0; 931 if (! oasys_write_record (abfd, 932 oasys_record_is_end_enum, 933 (oasys_record_union_type *) & end, 934 sizeof (end))) 935 return FALSE; 936 937 return bfd_bwrite ((void *) &null, (bfd_size_type) 1, abfd) == 1; 938 } 939 940 static int 941 comp (const void * ap, const void * bp) 942 { 943 arelent *a = *((arelent **) ap); 944 arelent *b = *((arelent **) bp); 945 946 return a->address - b->address; 947 } 948 949 static bfd_boolean 950 oasys_write_data (bfd *abfd) 951 { 952 asection *s; 953 954 for (s = abfd->sections; s != NULL; s = s->next) 955 { 956 if (s->flags & SEC_LOAD) 957 { 958 bfd_byte *raw_data = oasys_per_section (s)->data; 959 oasys_data_record_type processed_data; 960 bfd_size_type current_byte_index = 0; 961 unsigned int relocs_to_go = s->reloc_count; 962 arelent **p = s->orelocation; 963 964 if (s->reloc_count != 0) 965 /* Sort the reloc records so it's easy to insert the relocs into the 966 data. */ 967 qsort (s->orelocation, s->reloc_count, sizeof (arelent **), comp); 968 969 current_byte_index = 0; 970 processed_data.relb = s->target_index | RELOCATION_TYPE_REL; 971 972 while (current_byte_index < s->size) 973 { 974 /* Scan forwards by eight bytes or however much is left and see if 975 there are any relocations going on. */ 976 bfd_byte *mod = &processed_data.data[0]; 977 bfd_byte *dst = &processed_data.data[1]; 978 979 unsigned int i = 0; 980 *mod = 0; 981 982 H_PUT_32 (abfd, s->vma + current_byte_index, 983 processed_data.addr); 984 985 /* Don't start a relocation unless you're sure you can finish it 986 within the same data record. The worst case relocation is a 987 4-byte relocatable value which is split across two modification 988 bytes (1 relocation byte + 2 symbol reference bytes + 2 data + 989 1 modification byte + 2 data = 8 bytes total). That's where 990 the magic number 8 comes from. */ 991 while (current_byte_index < s->size && dst <= 992 & processed_data.data[sizeof (processed_data.data) - 8]) 993 { 994 if (relocs_to_go != 0) 995 { 996 arelent *r = *p; 997 998 /* There is a relocation, is it for this byte ? */ 999 if (r->address == current_byte_index) 1000 abort (); 1001 } 1002 1003 /* If this is coming from an unloadable section then copy 1004 zeros. */ 1005 if (raw_data == NULL) 1006 *dst++ = 0; 1007 else 1008 *dst++ = *raw_data++; 1009 1010 if (++i >= 8) 1011 { 1012 i = 0; 1013 mod = dst++; 1014 *mod = 0; 1015 } 1016 current_byte_index++; 1017 } 1018 1019 /* Don't write a useless null modification byte. */ 1020 if (dst == mod + 1) 1021 --dst; 1022 1023 if (! (oasys_write_record 1024 (abfd, oasys_record_is_data_enum, 1025 ((oasys_record_union_type *) &processed_data), 1026 (size_t) (dst - (bfd_byte *) &processed_data)))) 1027 return FALSE; 1028 } 1029 } 1030 } 1031 1032 return TRUE; 1033 } 1034 1035 static bfd_boolean 1036 oasys_write_object_contents (bfd *abfd) 1037 { 1038 if (! oasys_write_header (abfd)) 1039 return FALSE; 1040 if (! oasys_write_syms (abfd)) 1041 return FALSE; 1042 if (! oasys_write_sections (abfd)) 1043 return FALSE; 1044 if (! oasys_write_data (abfd)) 1045 return FALSE; 1046 if (! oasys_write_end (abfd)) 1047 return FALSE; 1048 return TRUE; 1049 } 1050 1051 /* Set section contents is complicated with OASYS since the format is 1052 not a byte image, but a record stream. */ 1053 1054 static bfd_boolean 1055 oasys_set_section_contents (bfd *abfd, 1056 sec_ptr section, 1057 const void * location, 1058 file_ptr offset, 1059 bfd_size_type count) 1060 { 1061 if (count != 0) 1062 { 1063 if (oasys_per_section (section)->data == NULL) 1064 { 1065 oasys_per_section (section)->data = bfd_alloc (abfd, section->size); 1066 if (!oasys_per_section (section)->data) 1067 return FALSE; 1068 } 1069 (void) memcpy ((void *) (oasys_per_section (section)->data + offset), 1070 location, (size_t) count); 1071 } 1072 return TRUE; 1073 } 1074 1075 1076 1077 /* Native-level interface to symbols. */ 1078 1079 /* We read the symbols into a buffer, which is discarded when this 1080 function exits. We read the strings into a buffer large enough to 1081 hold them all plus all the cached symbol entries. */ 1082 1083 static asymbol * 1084 oasys_make_empty_symbol (bfd *abfd) 1085 { 1086 bfd_size_type amt = sizeof (oasys_symbol_type); 1087 oasys_symbol_type *new_symbol_type = bfd_zalloc (abfd, amt); 1088 1089 if (!new_symbol_type) 1090 return NULL; 1091 new_symbol_type->symbol.the_bfd = abfd; 1092 return &new_symbol_type->symbol; 1093 } 1094 1095 /* User should have checked the file flags; perhaps we should return 1096 BFD_NO_MORE_SYMBOLS if there are none? */ 1097 1098 static bfd * 1099 oasys_openr_next_archived_file (bfd *arch, bfd *prev) 1100 { 1101 oasys_ar_data_type *ar = OASYS_AR_DATA (arch); 1102 oasys_module_info_type *p; 1103 1104 /* Take the next one from the arch state, or reset. */ 1105 if (prev == NULL) 1106 /* Reset the index - the first two entries are bogus. */ 1107 ar->module_index = 0; 1108 1109 p = ar->module + ar->module_index; 1110 ar->module_index++; 1111 1112 if (ar->module_index <= ar->module_count) 1113 { 1114 if (p->abfd == NULL) 1115 { 1116 p->abfd = _bfd_create_empty_archive_element_shell (arch); 1117 p->abfd->origin = p->pos; 1118 p->abfd->filename = xstrdup (p->name); 1119 1120 /* Fixup a pointer to this element for the member. */ 1121 p->abfd->arelt_data = (void *) p; 1122 } 1123 return p->abfd; 1124 } 1125 1126 bfd_set_error (bfd_error_no_more_archived_files); 1127 return NULL; 1128 } 1129 1130 #define oasys_find_nearest_line _bfd_nosymbols_find_nearest_line 1131 #define oasys_find_line _bfd_nosymbols_find_line 1132 #define oasys_find_inliner_info _bfd_nosymbols_find_inliner_info 1133 1134 static int 1135 oasys_generic_stat_arch_elt (bfd *abfd, struct stat *buf) 1136 { 1137 oasys_module_info_type *mod = (oasys_module_info_type *) abfd->arelt_data; 1138 1139 if (mod == NULL) 1140 { 1141 bfd_set_error (bfd_error_invalid_operation); 1142 return -1; 1143 } 1144 1145 buf->st_size = mod->size; 1146 buf->st_mode = 0666; 1147 return 0; 1148 } 1149 1150 static int 1151 oasys_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED, 1152 struct bfd_link_info *info ATTRIBUTE_UNUSED) 1153 { 1154 return 0; 1155 } 1156 1157 #define oasys_close_and_cleanup _bfd_generic_close_and_cleanup 1158 #define oasys_bfd_free_cached_info _bfd_generic_bfd_free_cached_info 1159 #define oasys_slurp_armap bfd_true 1160 #define oasys_slurp_extended_name_table bfd_true 1161 #define oasys_construct_extended_name_table ((bfd_boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_true) 1162 #define oasys_truncate_arname bfd_dont_truncate_arname 1163 #define oasys_write_armap ((bfd_boolean (*) (bfd *, unsigned int, struct orl *, unsigned int, int)) bfd_true) 1164 #define oasys_read_ar_hdr bfd_nullvoidptr 1165 #define oasys_write_ar_hdr ((bfd_boolean (*) (bfd *, bfd *)) bfd_false) 1166 #define oasys_get_elt_at_index _bfd_generic_get_elt_at_index 1167 #define oasys_update_armap_timestamp bfd_true 1168 #define oasys_bfd_is_local_label_name bfd_generic_is_local_label_name 1169 #define oasys_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false) 1170 #define oasys_get_lineno _bfd_nosymbols_get_lineno 1171 #define oasys_get_symbol_version_string _bfd_nosymbols_get_symbol_version_string 1172 #define oasys_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol 1173 #define oasys_read_minisymbols _bfd_generic_read_minisymbols 1174 #define oasys_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol 1175 #define oasys_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup 1176 #define oasys_bfd_reloc_name_lookup _bfd_norelocs_bfd_reloc_name_lookup 1177 #define oasys_set_arch_mach bfd_default_set_arch_mach 1178 #define oasys_get_section_contents_in_window _bfd_generic_get_section_contents_in_window 1179 #define oasys_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents 1180 #define oasys_bfd_relax_section bfd_generic_relax_section 1181 #define oasys_bfd_gc_sections bfd_generic_gc_sections 1182 #define oasys_bfd_lookup_section_flags bfd_generic_lookup_section_flags 1183 #define oasys_bfd_merge_sections bfd_generic_merge_sections 1184 #define oasys_bfd_is_group_section bfd_generic_is_group_section 1185 #define oasys_bfd_discard_group bfd_generic_discard_group 1186 #define oasys_section_already_linked _bfd_generic_section_already_linked 1187 #define oasys_bfd_define_common_symbol bfd_generic_define_common_symbol 1188 #define oasys_bfd_link_hash_table_create _bfd_generic_link_hash_table_create 1189 #define oasys_bfd_link_add_symbols _bfd_generic_link_add_symbols 1190 #define oasys_bfd_link_just_syms _bfd_generic_link_just_syms 1191 #define oasys_bfd_copy_link_hash_symbol_type \ 1192 _bfd_generic_copy_link_hash_symbol_type 1193 #define oasys_bfd_final_link _bfd_generic_final_link 1194 #define oasys_bfd_link_split_section _bfd_generic_link_split_section 1195 #define oasys_bfd_link_check_relocs _bfd_generic_link_check_relocs 1196 1197 const bfd_target oasys_vec = 1198 { 1199 "oasys", /* Name. */ 1200 bfd_target_oasys_flavour, 1201 BFD_ENDIAN_BIG, /* Target byte order. */ 1202 BFD_ENDIAN_BIG, /* Target headers byte order. */ 1203 (HAS_RELOC | EXEC_P | /* Object flags. */ 1204 HAS_LINENO | HAS_DEBUG | 1205 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), 1206 (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS 1207 | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* Section flags. */ 1208 0, /* Leading underscore. */ 1209 ' ', /* AR_pad_char. */ 1210 16, /* AR_max_namelen. */ 1211 0, /* match priority. */ 1212 bfd_getb64, bfd_getb_signed_64, bfd_putb64, 1213 bfd_getb32, bfd_getb_signed_32, bfd_putb32, 1214 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Data. */ 1215 bfd_getb64, bfd_getb_signed_64, bfd_putb64, 1216 bfd_getb32, bfd_getb_signed_32, bfd_putb32, 1217 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Headers. */ 1218 1219 {_bfd_dummy_target, 1220 oasys_object_p, /* bfd_check_format. */ 1221 oasys_archive_p, 1222 _bfd_dummy_target, 1223 }, 1224 { /* bfd_set_format. */ 1225 bfd_false, 1226 oasys_mkobject, 1227 _bfd_generic_mkarchive, 1228 bfd_false 1229 }, 1230 { /* bfd_write_contents. */ 1231 bfd_false, 1232 oasys_write_object_contents, 1233 _bfd_write_archive_contents, 1234 bfd_false, 1235 }, 1236 1237 BFD_JUMP_TABLE_GENERIC (oasys), 1238 BFD_JUMP_TABLE_COPY (_bfd_generic), 1239 BFD_JUMP_TABLE_CORE (_bfd_nocore), 1240 BFD_JUMP_TABLE_ARCHIVE (oasys), 1241 BFD_JUMP_TABLE_SYMBOLS (oasys), 1242 BFD_JUMP_TABLE_RELOCS (oasys), 1243 BFD_JUMP_TABLE_WRITE (oasys), 1244 BFD_JUMP_TABLE_LINK (oasys), 1245 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), 1246 1247 NULL, 1248 1249 NULL 1250 }; 1251